首先下面是利用IATHOOK HOOK自身MessageBox函数!测试是通过的
// HookDll.cpp : 定义 DLL 应用程序的导出函数。
//
#include <windows.h>
#include <delayimp.h>
#include <stdio.h>
//定义函数原型
typedef int (WINAPI *PFNMESSAGEBOX)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
//保存原始的MessageBox地址,注意这里
PROC g_orgProc = (PROC)MessageBoxA;
//WINUSERAPI
int WINAPI MyMessageBoxA(__in_opt HWND hWnd,
__in_opt LPCWSTR lpText,
__in_opt LPCWSTR lpCaption,
__in UINT uType)
{
//todo yourself
return ((PFNMESSAGEBOX)g_orgProc)(NULL, "IATHook 成功", "caption", MB_OK);
}
void SetHook()
{
HMODULE hModule = NULL;
hModule = GetModuleHandle(NULL); //定位到当前EXE的基地址
IMAGE_DOS_HEADER* pImageDosHearder = (IMAGE_DOS_HEADER*)hModule; // 定位到DOS头
IMAGE_OPTIONAL_HEADER* pImageOptionalHeader = (IMAGE_OPTIONAL_HEADER*)((DWORD)hModule+pImageDosHearder->e_lfanew+24);
IMAGE_IMPORT_DESCRIPTOR* pImageImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR*)
((DWORD)hModule+ pImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
BOOL bFindDll = FALSE;
while(pImageImportDescriptor->FirstThunk)
{
char* pszDllName = (char*)((BYTE*)hModule + pImageImportDescriptor->Name);
printf("模块名称:%s\n", pszDllName);
if (_stricmp(pszDllName, "user32.dll") == 0)//如果是user32.dll
{
bFindDll = TRUE;
break;
}
pImageImportDescriptor++;
}
if (bFindDll)
{
printf("准备写入:\n");
DWORD n = 0; //计数器
//一个IMAGE_THUNK_DATA就是一个导入函数
IMAGE_THUNK_DATA *pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hModule + pImageImportDescriptor->OriginalFirstThunk);
while(pThunk->u1.Function)
{
//取得函数名称
char* pszFuncName = (char*)((BYTE*)hModule+pThunk->u1.AddressOfData+2); //函数名前面有两个..
//比较函数名称
if (_stricmp(pszFuncName, "MessageBoxA") == 0)
{
PDWORD lpAddr = (DWORD*)((BYTE*)hModule + pImageImportDescriptor->FirstThunk) + n;
DWORD* lpNewProc = (DWORD*)MyMessageBoxA;
DWORD OldProtect = 0;
DWORD NewProtect = 0;
VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &OldProtect); //将指定内存设为可读写
if (!WriteProcessMemory(GetCurrentProcess(), lpAddr, &lpNewProc, sizeof(DWORD), NULL))
{
return;
}
//VirtualProtect(lpAddr, sizeof(DWORD), OldProtect, &NewProtect ); //还原内存属性
printf("成功写入:\n");
return;
}
n++;
}
}
}
/*
VOID WINAPI DllMain(_In_ HANDLE _HDllHandle, _In_ DWORD _Reason, _In_opt_ LPVOID _Reserved)
{
switch (_Reason)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "原来的", "原来的", 0);
printf("准备注入\n");
SetHook();
break;
case DLL_PROCESS_DETACH:
break;
}
}*/
int main(int argc, char* argv[])
{
::MessageBoxA(NULL, "before hook", "", MB_OK);
SetHook();
::MessageBoxA(NULL, "AFTERE hook", "", MB_OK);
return 0;
}
去掉上段代码中的注释,将入口函数改为DllMain,并且编译成为DLL 远程注入到DEMO程序就会出现:"xxxx"内存不能为READ 之类的错误!实在不解!
DEMO在此:求指点,是不是DLL加载后不存在内存中?还是怎么样?要怎么解决?
IATHookTest.rar今天有空,我分析了一下!我发现了一个问题:
DLL注入函数执行成功但是DLL在函数执行完成之后被卸载了,并没有长驻在内存中。到底为何?
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)