#include <windows.h>
#pragma argsused
DWORD adr_MessageBoxA;
BOOL WINAPI Intercept_MessageBoxA(HWND hwnd, char *text,
char *hdr, UINT utype)
{
//здесь вы выполняете любые свои действия
char *str = "Hi From MessageBOX!!!!";
// вызываем оригинальную функцию через указатель
((BOOL (__stdcall*)(HWND, char*, char*, UINT))adr_MessageBoxA)(hwnd,
str, hdr, utype);
return TRUE;
}
// Эта функция ищет в таблице импорта - .idata нужный адрес и меняет на
// адрес процедуры-двойника
void InterceptFunctions(void)
{
// Начало отображения в памяти процесса
BYTE *pimage = (BYTE*)GetModuleHandle(NULL);
BYTE *pidata;
// Стандартные структуры описания PE заголовка
IMAGE_DOS_HEADER *idh;
IMAGE_OPTIONAL_HEADER *ioh;
IMAGE_SECTION_HEADER *ish;
IMAGE_IMPORT_DESCRIPTOR *iid;
DWORD *isd; //image_thunk_data dword
// Получаем указатели на стандартные структуры данных PE заголовка
idh = (IMAGE_DOS_HEADER*)pimage;
ioh = (IMAGE_OPTIONAL_HEADER*)(pimage + idh->e_lfanew
+ 4 + sizeof(IMAGE_FILE_HEADER));
ish = (IMAGE_SECTION_HEADER*)((BYTE*)ioh + sizeof(IMAGE_OPTIONAL_HEADER));
//если не обнаружен магический код, то у этой программы нет PE заголовка
if (idh->e_magic != 0x5A4D)
{
MessageBox(NULL, "Not exe hdr", "Error!", 0);
return;
}
//ищем секцию .idata
for(int i=0; i<16; i++)
{
if(strcmp((char*)((ish+ i)->Name) , ".idata") == 0) break;
if(i==16)
{
MessageBox(NULL, "Unable to find .idata section", "Error!", 0);
return;
}
// Получаем адрес секции .idata(первого элемента IMAGE_IMPORT_DESCRIPTOR)
iid = (IMAGE_IMPORT_DESCRIPTOR*)(pimage + (ish +i)->VirtualAddress );
// Получаем абсолютный адрес функции для перехвата
adr_MessageBoxA = (DWORD)GetProcAddress(
GetModuleHandle("user32.dll"), "MessageBoxA");
if(adr_MessageBoxA == 0)
{
MessageBox(NULL, "Can`t get addr_MessageBoxA", "Error!", 0);
return;
}
}
// В таблице импорта ищем соответствующий элемент для
// библиотеки user32.dll
while(iid->Name) //до тех пор пока поле структуры не содержит 0
{
if(strcmp((char*)(pimage + iid->Name), "user32.dll") ==0 ) break;
iid++;
}
// Ищем в IMAGE_THUNK_DATA нужный адрес
isd = (DWORD*)(pimage + iid->FirstThunk);
while(*isd!=adr_MessageBoxA && *isd!=0) isd++;
if(*isd == 0)
{
MessageBox(NULL, "adr_MessageBoxA not found in .idata", "Error!", 0);
return;
}
// Заменяем адрес на свою функцию
DWORD buf = (DWORD)&Intercept_MessageBoxA;
DWORD op;
// Обычно страницы в этой области недоступны для записи
// поэтому принудительно разрешаем запись
VirtualProtect((void*)(isd),4,PAGE_READWRITE, &op);
DWORD written;
// Пишем новый адрес
WriteProcessMemory(GetCurrentProcess(), (void*)(isd),
(void*)&buf,4,&written);
//восстанавливаем первоначальную защиту области по записи
VirtualProtect((void*)(isd),4,op, &op);
//если записать не удалось – увы, все пошло прахом…
if(written!=4)
{
MessageBox(NULL, "Unable rewrite address", "Error!", 0);
return;
}
MessageBox(NULL, "Вроде заменил.", "Инфо!", 0);
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,
LPVOID lpReserved)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
InterceptFunctions();
return TRUE;
}
Ошибка в dll заменяющей API функцию
Я исправил, но видимо ошибся. Помогите найти ошибку.
Вот dll
Код:
Возникает ошибка :An exception (C0000005) occurred during DllEntryPoint or DllMain in module: ... \Project1.dll
Я предпологаю она возникает при выполнении кода
Код:
// В таблице импорта ищем соответствующий элемент для
// библиотеки user32.dll
while(iid->Name) //до тех пор пока поле структуры не содержит 0
{
if(strcmp((char*)(pimage + iid->Name), "user32.dll") ==0 ) break;
iid++;
}
// библиотеки user32.dll
while(iid->Name) //до тех пор пока поле структуры не содержит 0
{
if(strcmp((char*)(pimage + iid->Name), "user32.dll") ==0 ) break;
iid++;
}