The file injectManager.h has been added to support process injection. Of particular interest is CALL_ DATA_STRUCT. This is the structure filled out when ZwMapViewOfSection has found a function to hook.
The members of CALL_DATA_STRUCT are as follows:
index-Each process hook must have an index to identify it from other hooks.
parameters–The number of parameters passed to the hooked function must be saved.
hookFunction–The address of the hooked function must be saved.
callType–The call type, standard or C, must be known when returning from a call.
stackOffset–This is set to zero unless using a pattern that must start after the first instruction.
Following is the code:
// Copyright Ric Vieler, 2006 // Support header for injectManager.c #ifndef _USER_HOOK_INJECTION_H_ #define _USER_HOOK_INJECTION_H_ #define USERHOOK_beforeEncode 0 #define TOTAL_HOOKS 1 #define MAX_INSTRUCTION 36 #define STDCALL_TYPE 0 #define CDECL_TYPE 1 #define EMIT_FOUR( x ) __asm{ __asm _emit x __asm _emit x __asm _emit x __asm _emit x } #define PUSH_STACKFRAME( ) __asm{ __asm push ebp __asm mov ebp, esp __asm sub esp, __LOCAL_SIZE __asm push edi __asm push esi __asm push ebx __asm pushfd } #define POP_STACKFRAME( ) __asm{ __asm popfd __asm pop ebx __asm pop esi __asm pop edi __asm mov esp, ebp __asm pop ebp } #define INJECT_JUMP( from, to ) { ((PCHAR)from)[0] = (CHAR)0xe9; *((DWORD *)&(((PCHAR)(from))[1])) = (PCHAR)(to) - (PCHAR)(from) - 5; } #define GET_JUMP( from ) (((PCHAR)from)[0]==(CHAR)0xe9)? (*((DWORD *)&(((PCHAR)(from))[1])) + 5 + (DWORD)(from)) : 0 #pragma pack(1) // Prototypes for functions in kernel32.dll that are expected to be used in hook functions typedef int (__stdcall * PROTOTYPE_lstrlenA)( LPCSTR lpString ); typedef int (__stdcall * PROTOTYPE_lstrlenW)( LPCWSTR lpString ); typedef LPSTR (__stdcall * PROTOTYPE_lstrcpynA)( LPSTR lpString1, LPCSTR lpString2, int iMaxLength ); typedef LPWSTR (__stdcall * PROTOTYPE_lstrcpynW)( LPWSTR lpString1, LPCWSTR lpString2, int iMaxLength ); typedef LPSTR (__stdcall * PROTOTYPE_lstrcpyA)( LPSTR lpString1, LPCSTR lpString2 ); typedef LPWSTR (__stdcall * PROTOTYPE_lstrcpyW)( LPWSTR lpString1, LPCWSTR lpString2 ); typedef int (__stdcall * PROTOTYPE_lstrcmpiA)( LPCSTR lpString1, LPCSTR lpString2 ); typedef int (__stdcall * PROTOTYPE_lstrcmpiW)( LPCWSTR lpString1, LPCWSTR lpString2 ); typedef int (__stdcall * PROTOTYPE_lstrcmpA)( LPCSTR lpString1, LPCSTR lpString2 ); typedef int (__stdcall * PROTOTYPE_lstrcmpW)( LPCWSTR lpString1, LPCWSTR lpString2 ); typedef LPSTR (__stdcall * PROTOTYPE_lstrcatA)( LPSTR lpString1, LPCSTR lpString2 ); typedef LPWSTR (__stdcall * PROTOTYPE_lstrcatW)( LPWSTR lpString1, LPCWSTR lpString2 ); typedef VOID (__stdcall * PROTOTYPE_OutputDebugStringA)( LPCSTR lpOutputString ); typedef VOID (__stdcall * PROTOTYPE_OutputDebugStringW)( LPCWSTR lpOutputString ); typedef HANDLE (__stdcall * PROTOTYPE_CreateFileW)( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ); typedef VOID (__stdcall * PROTOTYPE_Sleep)( DWORD dwMilliseconds ); typedef BOOL (__stdcall * PROTOTYPE_CloseHandle)( HANDLE hObject ); typedef DWORD (__stdcall * PROTOTYPE_GetCurrentProcessId)( VOID ); typedef DWORD (__stdcall * PROTOTYPE_GetCurrentThreadId)( VOID ); typedef struct _CALL_DATA_STRUCT { UINT index; UINT parameters; PCHAR hookFunction; UINT callType; UINT stackOffset; } CALL_DATA_STRUCT; typedef struct _IN_PROCESS_DATA { // function addresses PROTOTYPE_lstrlenA plstrlenA; PROTOTYPE_lstrlenW plstrlenW; PROTOTYPE_lstrcpynA plstrcpynA; PROTOTYPE_lstrcpynW plstrcpynW; PROTOTYPE_lstrcpyA plstrcpyA; PROTOTYPE_lstrcpyW plstrcpyW; PROTOTYPE_lstrcmpiA plstrcmpiA; PROTOTYPE_lstrcmpiW plstrcmpiW; PROTOTYPE_lstrcmpA plstrcmpA; PROTOTYPE_lstrcmpW plstrcmpW; PROTOTYPE_lstrcatA plstrcatA; PROTOTYPE_lstrcatW plstrcatW; PROTOTYPE_OutputDebugStringA pOutputDebugStringA; PROTOTYPE_OutputDebugStringW pOutputDebugStringW; PROTOTYPE_CreateFileW pCreateFileW; PROTOTYPE_CloseHandle pCloseHandle; PROTOTYPE_Sleep pSleep; PROTOTYPE_GetCurrentProcessId pGetCurrentProcessId; PROTOTYPE_GetCurrentThreadId pGetCurrentThreadId; char debugString[64]; } IN_PROCESS_DATA; BOOL processInject( CALL_DATA_STRUCT* pCallData, int hooks2find, PCHAR pUserMem ); PCHAR allocateUserMemory( void ); BOOL createTrampoline( PCHAR originalAddress, PCHAR newStartAddress, PCHAR newEndAddress ); ULONG getx86Instruction( PCHAR originalCode, PCHAR instructionBuffer, ULONG bufferLength ); DWORD BeforeOriginalFunction( DWORD hookIndex, PDWORD originalStack, DWORD* returnParameter, IN_PROCESS_DATA* callData ); void AfterOriginalFunction( DWORD hookIndex, PDWORD originalStack, DWORD* returnParameter, IN_PROCESS_DATA* callData ); BOOL makeWritable( PVOID address, ULONG size ); // structures required to inject into PGP typedef struct _PGPOption { unsigned int type; unsigned int flags; unsigned int value; unsigned int valueSize; void* subOptions; void* handlerProc; } PGPOption; typedef struct _PGPVersion { unsigned short majorVersion; unsigned short minorVersion; } PGPVersion; typedef struct _PGPOptionList { unsigned int magic; PGPVersion version; void* context; int err; unsigned int flags; unsigned short maxOptions; unsigned short numOptions; PGPOption* options; } PGPOptionList; typedef struct _PFLFileSpec { unsigned int magic; void* memoryMgr; unsigned int type; unsigned int dataSize; void* vtbl; void* data; } PFLFileSpec; typedef struct _FILELIST { char* name; int IsDirectory; struct _FILELIST* next; } FILELIST; #define PGP_OK 0 #define PGP_BAD_API -11460 #define PGP_FILE_FAIL -11991 #endif