Jump to content
Nytro

InjHookTHM.c

Recommended Posts

Posted
// InjHookTHM.c pour The Hackademy Manuel #10 (auteur: Carib)
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>

#define SIZE_HOOKFUNCTION 4096
#define SIZE_RPLFUNCTION 4096

typedef HMODULE (WINAPI *pfGetModuleHandle)(LPCTSTR);
typedef FARPROC (WINAPI *pfGetProcAddress)(HMODULE, LPCSTR);
typedef BOOL (WINAPI *pfVirtualProtect)(LPVOID, DWORD, DWORD, PDWORD);
typedef INT (WINAPI *pfMessageBox)(HWND, LPCSTR, LPCTSTR, UINT);
typedef LONG (WINAPI *pfDispatchMessage)(CONST MSG *lpmsg);

// La structure de données que nous allons injecter
typedef struct
{
CHAR szRplFunctionModule[20];
CHAR szRplFunction[20];
PVOID pMyRplFunction;
PVOID pOrigRplFunction;

pfLoadLibrary _LoadLibraryA;
pfGetModuleHandle _GetModuleHandleA;
pfGetProcAddress _GetProcAddress;
pfVirtualProtect _VirtualProtect;

CHAR szUser32[20];
CHAR szMessageBoxW[20];
pfMessageBox _MessageBoxW;
}
INJECTEDDATA;

// Obtenir un handle en accès complet d'un processus
HANDLE GetProcessByName(CHAR *szProcessName)
{
HANDLE hProcessSnap;
DWORD th32ProcessID;
PROCESSENTRY32 pe32;
HANDLE hProcess = NULL;
BOOL bFound = FALSE;

// Snapshot de tous les processus
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

// Initialisation de la structure qui contiendra les infos
pe32.dwSize = sizeof(PROCESSENTRY32);

// Parcours de tous les processus
th32ProcessID = Process32First(hProcessSnap, &pe32);

while(th32ProcessID)
{
// Essai d'obtenir un handle en écriture sur le processus
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);

if(hProcess != NULL && strcmp(pe32.szExeFile, szProcessName) == 0)
{
bFound = TRUE;
break;
}

pe32.dwSize = sizeof(PROCESSENTRY32);
th32ProcessID = Process32Next(hProcessSnap, &pe32);
}

CloseHandle(hProcessSnap);
return (bFound ? hProcess: NULL);
}

int main(void)
{
HANDLE hProcess;
HMODULE hKernel32;
INJECTEDDATA Data, *pData;
PVOID pHookFunction;
DWORD dwNbBytesWritten, dwThreadID, dwExitCode;
HANDLE hThread;


if((hProcess = GetProcessByName("notepad.exe")) == NULL)
{
printf("Le processus ne peut etre ouvert\n");
return 0;
}

hKernel32 = LoadLibrary("kernel32.dll");
Data._GetModuleHandleA = (pfGetModuleHandle)GetProcAddress(hKernel32, "GetModuleHandleA");
Data._GetProcAddress = (pfGetProcAddress)GetProcAddress(hKernel32, "GetProcAddress");
Data._VirtualProtect = (pfVirtualProtect)GetProcAddress(hKernel32, "VirtualProtect");


// APIs utiles au hook => APIs de user32, etc.
lstrcpy(Data.szUser32, "user32.dll");
lstrcpy(Data.szMessageBoxA, "MessageBoxW");

// API hookée : DispatchMessage afin d'intercepter les messages WM_CHAR
lstrcpy(Data.szRplFunctionModule, "user32.dll");
lstrcpy(Data.szRplFunction, "DispatchMessageW");

// Injection de la fonction de remplacement. L'adresse de cette fonction est stockée dans la structure de données injectée.
Data.pMyRplFunction = VirtualAllocEx(hProcess, NULL, SIZE_RPLFUNCTION, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, Data.pMyRplFunction, MyDispatchMessage, SIZE_RPLFUNCTION, &dwNbBytesWritten);

// Injection de la fonction qui va coordonner le hook.
pHookFunction = VirtualAllocEx(hProcess, NULL, SIZE_HOOKFUNCTION, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pHookFunction, HookFunction, SIZE_HOOKFUNCTION, &dwNbBytesWritten);

// Injection de la structure de données.
pData = VirtualAllocEx(hProcess, NULL, sizeof(INJECTEDDATA), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pData, &Data, sizeof(INJECTEDDATA), &dwNbBytesWritten);



// Création de thread dans le processus cible.
if((hThread = CreateRemoteThread(hProcess, NULL, 0, pHookFunction, pData, 0, &dwThreadID)) == NULL)
{
printf("Erreur lors de CreateRemoteThread\n");
return 0;
}

WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &dwExitCode);
if(dwExitCode == 0)
{
printf("Erreur lors du hook\n");
return 0;
}

return 1;
}


// Fonction de hook exécutée lors de la création du thread
static DWORD WINAPI HookFunction(INJECTEDDATA *pData)
{
// Variables automatiques placées sur la pile => pas de problème
HMODULE hModule, hRplFunctionModule, hUser32;
PVOID address;
DWORD dwOldProtection;


// Modification de pData dans la fonction de remplacement => voir plus loin
*((DWORD *)((DWORD)(pData->pMyRplFunction) + 9)) = (DWORD)pData;


// Récupération des adresses des APIs annexes nécessaires à la fonction de remplacement. On va pouvoir accéder à l'API MessageBoxA
hUser32 = pData->_GetModuleHandleA(pData->szUser32);
pData->_MessageBoxW = (pfMessageBox)pData->_GetProcAddress(hUser32, pData->szMessageBoxW);

// Adresse du module exécutable cible
hModule = pData->_GetModuleHandleA(NULL);

// Récupération de l'adresse originale de l'API que l'on va hooker
hRplFunctionModule = pData->_GetModuleHandleA(pData->szRplFunctionModule);
pData->pOrigRplFunction = pData->_GetProcAddress(hRplFunctionModule, pData->szRplFunction);

address = pData->pOrigRplFunction;
// Recherche de l'adresse à patcher dans l'IAT du module exe
__asm
{
mov esi, address

mov eax, hModule // BaseAddress du module exe
mov ebx, [eax + 3Ch] // offset e_lfanew
add ebx, eax // ptr vers la struct IMAGE_NT_HEADERS32

mov ecx, [ebx + 0D8h] // RVA de l'Import Address Table
add ecx, eax // adresse de l'Import Address Table
mov edx, [ebx + 0DCh] // taille de l'IAT
shr edx, 2 // nb d'adresses dans l'IAT

NextAPI:
cmp [ecx], esi
je APIFound // adresse trouvée => sortie
add ecx, 4 // sinon, adresse suivante
dec edx // on continue tant qu'il reste des adresses
jz APINotFound
jmp NextAPI

APINotFound:
mov ecx, 0
APIFound:
mov address, ecx
}

if(address == 0)
return 0;

// Modification de l'adresse dans l'IAT
pData->_VirtualProtect(address, 4, PAGE_READWRITE, &dwOldProtection);
*((PDWORD)address) = (DWORD)(pData->pMyRplFunction);
pData->_VirtualProtect(address, 4, dwOldProtection, &dwOldProtection);

return 1;
}

static LONG MyDispatchMessage(CONST MSG *lpmsg)
{
INJECTEDDATA *pData = (INJECTEDDATA *)0x12345678;
WCHAR s[2];


if(lpmsg->message == WM_CHAR)
{
s[0] = (WCHAR)(lpmsg->wParam);
s[1] = 0;
pData->_MessageBoxW(NULL, s, s, MB_OK);
}

return ((pfDispatchMessage)pData->pOrigRplFunction)(lpmsg);
}

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...