4)
собственно сам "сплайсинг"
идея заключается в том чтобы в начале оригинальной функции записать "jmp куда_нам_надо" и тогда поциэнт будет вызывать "то_что_нам_надо"
код инструкции jmp xxxxx выглядит так:
1байт опкод 0xe9 + 4 байта смещение(какраз 5 байт, тоже "совпадение"),
"смещение" означает сколько байт нам надо перепрыгнуть,
если нам надо прыгнуть на 500 байт вперед, пишем туда 500,
если нам 300 байт назад пишем туда -300.
вычеслить нужное нам значение нужно так:
v = targetaddr - posjmpaddr;
targetaddr, адрес куда надо прыгнуть (в нашем случае это адрес hookMessageBoxW)
posjmpaddr, адрес инструкции jmp
+ ее размер (+5 байт).
тоесть,
c++ Код:
//делаем доступной память для записи.
target = (DWORD)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxW");
VirtualProtect((void*)target,PAGE_EXECUTE_READWRITE,10,&oldprotect);
//вычисляем адрес куда будем писать опкод:
BYTE * pE9 = (BYTE*)target;
//вычисляем адрес, куда будем писать смещение
DWORD * pofset = (DWORD*)(pE9+1);
//пишем в память:
*pE9 = 0xe9;
*pofset = (DWORD)hookMessageBoxW - (target+5);
5)
собираем в кучу написанное выше и оформляем в виде длл:
c++ Код:
#include <Windows.h>
//трамлин
DWORD addr;
int __stdcall jmpMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption, UINT uType)
{
__asm jmp [addr];
};
//обработчик
int __stdcall hookMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption, UINT uType)
{
int result = 0;
if(lstrcmpW(lpCaption,L"угнова(c)")==0)
{
//если в заголовке окна есть нецензурное слово, вызываем оригинал со своими параметрами
result = jmpMessageBoxW(hWnd, L"слава роботам!!! убить всех человеков!!", L"какойто робот(с)", MB_ICONINFORMATION);
}
else
{
//если в заголове чтото другое, ничего не трогаем, вызываем оригинал
result = jmpMessageBoxW(hWnd, lpText, lpCaption, uType);
};
return result;
};
BOOL WINAPI DllMain( HINSTANCE hModule,DWORD Reason, LPVOID lpReserved )
{
DWORD target;
DWORD oldprotect;
BYTE * pE9;
DWORD * pofset;
switch(Reason)
{
case DLL_PROCESS_ATTACH:
target = (DWORD)GetProcAddress(GetModuleHandleW(L"user32.dll"),"MessageBoxW");
if(!VirtualProtect((void*)target,10,PAGE_EXECUTE_READWRITE,&oldprotect))return FALSE; // а вдруг?
//настраиваем трамплин
addr = target + 5; //прыгать мы будем не в "начало" функции, а на пять байт дальше.
//правим оригинал, в начало записываем джамп на наш обработчик
pE9 = (BYTE*)target;
pofset = (DWORD*)(pE9+1);
*pE9 = 0xe9;
*pofset = (DWORD)hookMessageBoxW - (target+5);
break;
case DLL_PROCESS_DETACH:
//тут выгрузка длл
//надо восстановить оригинальный код функции,
//но нам по*уй, такой херней страдают только в конец задроченные ботаны,
//а все чоткие праграмисты знают что "меньше кода = меньше багов"
break;
};
return TRUE;
};
жмем компилить, должна получится
tabletka.rar
теперь если рядом с нашим поциэнтом положить таблетку, мы сможем наблюдать чудесное исцеление.
какашками кидацо незя, т.к. это часный\стерильный случай