Просто неполучаеться перехват((( Подскажите плз где я ошибься: Код (Text): DWORD origadr; typedef HANDLE (WINAPI *CreateThrPrototype)( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId); void SetHook(DWORD libB,DWORD HookAdr) { DWORD toNT=( (IMAGE_DOS_HEADER*) libB)->e_lfanew; IMAGE_NT_HEADERS *nt=(IMAGE_NT_HEADERS *)(libB+toNT); IMAGE_EXPORT_DIRECTORY *exp=(IMAGE_EXPORT_DIRECTORY *)(libB+nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); DWORD *Names=(DWORD*)(exp->AddressOfNames+libB); DWORD *Funcs=(DWORD*)(exp->AddressOfFunctions+libB); char *name; DWORD old; if(VirtualProtect(Funcs,4*exp->NumberOfFunctions,PAGE_EXECUTE_READWRITE,&old)) { for(DWORD i=0;i<exp->NumberOfNames;i++) { name=( (char*) (Names[i]+libB) ); if(strcmp("CreateThread",name)==0) { //printf("%X\n",Funcs[i]); origadr=Funcs[i]+libB; Funcs[i]=HookAdr-libB; } } VirtualProtect(Funcs,4*exp->NumberOfFunctions,old,&old); } } HANDLE WINAPI HOOKf( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId) { printf("thread hook!\n"); CreateThrPrototype CreateThr=(CreateThrPrototype)origadr; CreateThr(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId); return 0; } DWORD WINAPI ThrFunc(LPVOID lParam) { printf("thread func!\n"); return 0; } int _tmain(int argc, _TCHAR* argv[]) { HMODULE kernel=GetModuleHandle(L"kernel32.dll"); SetHook((DWORD)kernel,(DWORD)&HOOKf); CreateThrPrototype CreateThr=(CreateThrPrototype)GetProcAddress(kernel,"CreateThread"); CreateThr(0,0,ThrFunc,0,0,0); getch(); return 0; } ЗЫ:или так невозможно?
_nic Кроме таблицы экспорта надо перехватить функцию в таблице импорта каждого модуля, который импортирует эту функцию.
Импорт не экспорт.По этому я пытаюсь через экспорт.Кто то может сказать.Есть какие то ограничения на адрес в таблице экспорта или нет??Он что не может за грань образа модуля выходить?Тем более хрен поймешь когда в список модулей еще что то добавилось.
_nic Может. Если перехватывать тольк экспорт, то GetProcAddress будет возвращать адрес вашей функции, но если вы не поставите перехват на импорт, то все вызовы через таблицу импорта продут мимо вас. Если добавилось после перехвата экспорта, то там будет адрес вашей функции.
Смотрим код внимательно.Функция используеться динамически,после правки адреса в таблице экспорта. Но у меня или не тот адрес правился,то или вообще какая то магия =/ Несрабатывает функция заглушка.
_nic Честно говоря сначала я в код особо не вчитывался. 1) Проще будет искать не имя, а адрес: (OriginalCreateThread-libB) в AddressOfFunctions, и там-же его менять. 2) Если большое желание именно по имени, то: I. Смотрим какой индекс в AddressOfNames. II. Достаём ординал по найденному индексу из AddressOfNameOrdinals. III. Используем этот ординал в качестве индекса в AddressOfFunctions. Если не ошибаюсь, то так. PS Тут есть:http://wasm.ru/article.php?article=1002007
1й вариант работает.НО.При перехвате _beginthreadex,проблема.В дизассемблере видно что _beginthreadex обертка для CreateThread.Хук ф-ция вызываеться нормально,но когда вызываеться оригинальная CreateThread,то вылазит исключение о том что в нужном месте память не читаема( Код (Text): DWORD origadr; typedef HANDLE (WINAPI *CreateThrPrototype)( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId); void SetHook(DWORD libB,DWORD HookAdr,DWORD funcVA) { DWORD toNT=( (IMAGE_DOS_HEADER*) libB)->e_lfanew; IMAGE_NT_HEADERS *nt=(IMAGE_NT_HEADERS *)(libB+toNT); IMAGE_EXPORT_DIRECTORY *exp=(IMAGE_EXPORT_DIRECTORY *)(libB+nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); DWORD *Names=(DWORD*)(exp->AddressOfNames+libB); DWORD *Funcs=(DWORD*)(exp->AddressOfFunctions+libB); //char *name; DWORD funcRVA=funcVA-libB; DWORD old; if(VirtualProtect(Funcs,4*exp->NumberOfFunctions,PAGE_EXECUTE_READWRITE,&old)) { for(DWORD i=0;i<exp->NumberOfFunctions;i++) { /*name=( (char*) (Names[i]+libB) ); if(strcmp("CreateThread",name)==0) { //printf("%X\n",Funcs[i]); origadr=Funcs[i]+libB; Funcs[i]=HookAdr-libB; }*/ if(Funcs[i]==funcRVA) { Funcs[i]=HookAdr-libB; break; } } VirtualProtect(Funcs,4*exp->NumberOfFunctions,old,&old); } } HANDLE WINAPI HOOKf( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId) { printf("thread hook!\n"); CreateThrPrototype CreateThr=(CreateThrPrototype)origadr; CreateThr(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId); return 0; } DWORD WINAPI ThrFunc(LPVOID lParam) { printf("thread func!\n"); return 0; } typedef uintptr_t (__cdecl *_beginthreadexProt)(_In_opt_ void * _Security, _In_ unsigned _StackSize, _In_ unsigned (__stdcall * _StartAddress) (void *), _In_opt_ void * _ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned * _ThrdAddr); static unsigned __stdcall bgThrEx(void *Params) { printf("_beginthreadex\n"); return 0; } int _tmain(int argc, _TCHAR* argv[]) { HMODULE kernel=GetModuleHandle(L"kernel32.dll"); origadr=(DWORD)GetProcAddress(kernel,"CreateThread"); SetHook((DWORD)kernel,(DWORD)&HOOKf,origadr); CreateThrPrototype CreateThr=(CreateThrPrototype)GetProcAddress(kernel,"CreateThread"); CreateThr(0,0,ThrFunc,0,0,0); HMODULE CRT=LoadLibrary(L"msvcrt.dll"); if(CRT!=NULL) { _beginthreadexProt bgthreEX=(_beginthreadexProt)GetProcAddress(CRT,"_beginthreadex"); bgthreEX(0,0,bgThrEx,0,0,0); } getch(); return 0; } Почему так?
Плохо, что не говорит. Приведите больше кода, в окрестностях ошибки (из отладчика). P.S. Это говорит что у вас проблема с указателями.
_nic Нормальный отладчик должен показать не только адреса, но и имена DLL и даже имя функции. Тогда проще будет анализировать. А так - никому это тоже почти ничего не говорит. Ну и просто мысли : то что хук отработал, еще не значит что вы ничего не запортили. Возможно ваша вставка и привела к падению в следующем вызове. Смотрите на отладчике вызов "проблемной" CreateThread с хуком и без хука - в чем там разница?
немного видоизменил код: Код (Text): DWORD origadr; typedef HANDLE (WINAPI *CreateThrPrototype)( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId); void SetHook(DWORD libB,DWORD HookAdr,DWORD funcVA) { DWORD toNT=( (IMAGE_DOS_HEADER*) libB)->e_lfanew; IMAGE_NT_HEADERS *nt=(IMAGE_NT_HEADERS *)(libB+toNT); IMAGE_EXPORT_DIRECTORY *exp=(IMAGE_EXPORT_DIRECTORY *)(libB+nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); DWORD *Names=(DWORD*)(exp->AddressOfNames+libB); DWORD *Funcs=(DWORD*)(exp->AddressOfFunctions+libB); //char *name; DWORD funcRVA=funcVA-libB; DWORD old; if(VirtualProtect(Funcs,4*exp->NumberOfFunctions,PAGE_EXECUTE_READWRITE,&old)) { for(DWORD i=0;i<exp->NumberOfFunctions;i++) { /*name=( (char*) (Names[i]+libB) ); if(strcmp("CreateThread",name)==0) { //printf("%X\n",Funcs[i]); origadr=Funcs[i]+libB; Funcs[i]=HookAdr-libB; }*/ if(Funcs[i]==funcRVA) { Funcs[i]=HookAdr-libB; break; } } VirtualProtect(Funcs,4*exp->NumberOfFunctions,old,&old); } } typedef unsigned (WINAPI *TrhRoutine)(LPVOID lParam); DWORD WINAPI ThrStub(LPVOID lParam) { TrhRoutine Func=(TrhRoutine)lParam; return(Func(lParam));//отладчик стопает тут } HANDLE WINAPI HOOKf( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId) { printf("thread hook!\n"); CreateThrPrototype CreateThr=(CreateThrPrototype)origadr; //CreateThr(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId); CreateThr(lpThreadAttributes,dwStackSize,ThrStub,lpStartAddress,dwCreationFlags,lpThreadId); return 0; } DWORD WINAPI ThrFunc(LPVOID lParam) { printf("thread func!\n"); return 0; } typedef uintptr_t (__cdecl *_beginthreadexProt)(_In_opt_ void * _Security, _In_ unsigned _StackSize, _In_ unsigned (__stdcall * _StartAddress) (void *), _In_opt_ void * _ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned * _ThrdAddr); static unsigned __stdcall bgThrEx(void *Params) { printf("_beginthreadex\n"); return 0; } int _tmain(int argc, _TCHAR* argv[]) { HMODULE kernel=GetModuleHandle(L"kernel32.dll"); origadr=(DWORD)GetProcAddress(kernel,"CreateThread"); SetHook((DWORD)kernel,(DWORD)&HOOKf,origadr); CreateThrPrototype CreateThr=(CreateThrPrototype)GetProcAddress(kernel,"CreateThread"); CreateThr(0,0,ThrFunc,0,0,0); //CreateThr(0,0,ThrFunc,0,0,0); HMODULE CRT=LoadLibrary(L"msvcrt.dll"); if(CRT!=NULL) { _beginthreadexProt bgthreEX=(_beginthreadexProt)GetProcAddress(CRT,"_beginthreadex"); bgthreEX(0,0,bgThrEx,0,0,0); } getch(); return 0; } Теперь вылазит исключение об повреждение кучи.Ничего непонимаю(
_nic В дизасме видно, что это не простая обертка, и в CreateThread передается вовсе не сама функция _StartAddress, а спец.функция из самой msvcrt, а исходный адрес _StartAddress и _ArgList упаковываются в динамич.структуру, адрес которой передается в качестве lpParameter в CreateThread. Поэтому почему валится последний вариант вообще очевидно, т.к. так делать нельзя. А предыдущий валится из-за твоего собственного бага, т.к. твой HOOKf почему-то возвращает 0, а не результат CreateThread - в итоге _beginthreadex считает вызов неудачным и освобождает дин.блок данных с адресом функции, и когда msvcrt-шная функция потока начинает работать, то lpParameter, из которого она должна взять исходный _StartAddress уже давно затерт каким-то мусором