Показать сообщение отдельно
Старый 29.01.2010, 23:01   #1
Рыцарь
 
Аватар для destructor
 
Регистрация: 26.06.2009
Сообщений: 2,433
Сказал Спасибо: 154
Имеет 692 спасибок в 426 сообщенях
destructor на пути к лучшему
По умолчанию хуки для самых маленьких

участились случаи ногебания icq по вопросу "как перехватить функцию"
в гугл слал, в лес слал, в бабруйск слал, всеравно возвращаются с вопросами
незнаю куда еще можно послать... поэтому решил описать "своими словами" чтобы слать сюда.

существует стопицот способов перехвата, у всех есть свои плюсы\минусы
опишу простейший, называется "сплайсинг"


0)
есть приложение, компилить не надо,
просто качаем\запускаем\пробуем вложение поциэнт.rar,
исходник такой:
c++ Код:
#include <Windows.h> int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {     LoadLibrary(L"tabletka.dll"); //чтобы не засирать пример, "инжектить" лекарство будем так.     MessageBoxW(0,L"нажмите ок чтобы ботить, тока тсссс.....",L"ncsoft(c)",MB_ICONWARNING);     MessageBoxW(0,L"ботоводы, горите в аду!",L"угнова(c)",MB_ICONERROR | IDCANCEL );     return 0; };
как мы видим, данная программа имеет некоторые недостатки,
а именно, наглые, неполиткорректные высказывания.
а так делать незя.

1)
лезем сюда _http://msdn.microsoft.com/ изучаем нужную нам функцию (ну или хотябы код в заголовках),
она выглядит так: int __stdcall MessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
находится тут: Minimum DLL Version user32.dll

2)
теперь нужно научится ее вызывать хитрым способом (или изготовление функции трамплина),
делаем простой пример:
c++ Код:
DWORD addr=0; int __stdcall jmpMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption, UINT uType) {     __asm jmp &#91;addr]; }; main() {     DWORD target = (DWORD)GetProcAddress(LoadLibrary("user32.dll"),"messageboxW");     addr = target + 5;          //прыгать мы будем не в "начало" функции, а на пять байт дальше.     jmpMessageBoxW(0,L"текст",L"текст", UINT uType); }; //компилируем, убеждаемся что такая программа будет работать.  
мы пропускаем часть оригинального кода, а ошибок всеравно нету, обьясняю почему.
в отладчике это будет выглядить так:
asm Код:
test.exe:10001770 jmpMessageBoxW: test.exe:10001770        push    ebp            // выполняется, этот код дописал нам компилятор test.exe:10001771        mov     ebp, esp     // выполняется, этот код дописал нам компилятор test.exe:10001773        jmp     ds:addr       // наш джамп test.exe:10001779        pop     ebp            // сюда мы никогда не попадем test.exe:1000177A        retn    10h .. user32.dll:7E3B6534 MessageBoxW: user32.dll:7E3B6534    mov     edi, edi             //пропускаем, бессмысленная инструкция, типа x=x, так захотели в майкрософт. user32.dll:7E3B6536    push    ebp                  //пропускаем user32.dll:7E3B6537    mov     ebp, esp           //пропускаем user32.dll:7E3B6539    cmp     ds:dword_7E3C14BC, 0  //<<--мы прыгаем сюда user32.dll:7E3B6540    jz      short loc_7E3B6566
сравниваем инструкции которые мы пропустили в оригинальной функции,
и какие нам дописал компилятор в функции трамплине.
видно очень красивое "совпадение", вот какбы поэтому оно и работает.

значит если изуродовать первые 5 байт оригинальной функции, мы всеравно сможем ее вызвать.


3)
придумаем "функцию фильтр_обработчик"
c++ Код:
int __stdcall hookMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption, UINT uType) {        int result = 0;     if(lstrcmpW(lpCaption,L"угнова(c)"))     {         //если в заголовке окна есть нецензурное слово, вызываем оригинал со своими параметрами         result = jmpMessageBoxW(hWnd, L"слава роботам!!! убить всех человеков!!", L"какой то робот(с)", MB_ICONINFORMATION);     }     else     {         //если в заголове чтото другое, ничего не трогаем, вызываем оригинал         result = jmpMessageBoxW(hWnd, lpText, lpCaption, uType);     };     return result; };


продолжение ниже
__________________
Шожиделать.. ботить хочется..

Последний раз редактировалось destructor, 29.01.2010 в 23:13.
destructor вне форума   Ответить с цитированием
За это сообщение destructor нажился 7 спасибками от: