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))returnFALSE; // а вдруг?//настраиваем трамплин
addr = target + 5; //прыгать мы будем не в "начало" функции, а на пять байт дальше.//правим оригинал, в начало записываем джамп на наш обработчик
pE9 = (BYTE*)target;
pofset = (DWORD*)(pE9+1);
*pE9 = 0xe9;
*pofset = (DWORD)hookMessageBoxW - (target+5);
break;
case DLL_PROCESS_DETACH:
//тут выгрузка длл//надо восстановить оригинальный код функции,//но нам по*уй, такой херней страдают только в конец задроченные ботаны,//а все чоткие праграмисты знают что "меньше кода = меньше багов"break;
};
returnTRUE;
};
жмем компилить, должна получится tabletka.rar
теперь если рядом с нашим поциэнтом положить таблетку, мы сможем наблюдать чудесное исцеление.
какашками кидацо незя, т.к. это часный\стерильный случай
__________________
Шожиделать.. ботить хочется..
Последний раз редактировалось destructor, 29.01.2010 в 23:32.
За это сообщение destructor нажился 7 спасибками от:
destructor, то что первые 5 байт совпали в этом примере эт конечно хорошо, но это довольно редкий случай и охрененно упрощающий код притом. А вот если первые 5 байт не совпадают, то начинается веселье, надо переместить первые инструкции (естественно целое количество инструкций) которые заполняют первые 5 или больше байт куданить себе в массив и ещё дописать в массив джамп на оригинальную функцию (со смещением равным количеству списанных из начала байт), оформить этот массив как имеющий возможность быть выполненным (ну VirtualProtect'ом обработать опять же), а вот уже дальше записать на место первых 5 байт оригинала джамп, ну и в своей функции вместо оригинала уже вызывать не оригинал со смещением, а наш массив.
ЗЫ и эт ещё хорошо если мы можем функцию перехватываемую в дизассемблере посмотреть и посчитать сколько байт занимает целое число команд в начале, а если не можем то надо ещё как то программно это определять...
__________________
Я здесь практически не появляюсь!, Skype - ikskor
адрес jmpMessageBoxW это начало "массива",
потом просто делаю копипасту нужного количества инструкций:
memcpy(jmpMessageBoxW,MessageBoxW, X);
и все, код не сильно усложняется
__________________
Шожиделать.. ботить хочется..
Последний раз редактировалось destructor, 30.01.2010 в 17:19.
За это сообщение destructor нажился 3 спасибками от: