#include "stdafx.h"
#include "LDasm.h"
#include <windows.h>
DWORD proxyFunction;
void* HookFunc(char* ModuleName,char* FuncName,void* NewFunc)
{
void* proxyFunction = 0;
unsigned char* OpCode = 0;
ULONG BackupLength = 0;
unsigned char JmpCode[6]={0x68,0x00,0x00,0x00,0x00,0xc3};
unsigned char JmpBackCode[6]={0x68,0x00,0x00,0x00,0x00,0xc3};
/*
原代码用的是GetModuleHandle(ModuleName);这要成功的
前提是:只有欲获取的模块已映射到调用该函数的进程内,才会正确得到模块句柄。
常用模块映射函数:LoadLibrary(..)
*/
HMODULE hMod = GetModuleHandle(ModuleName);
void* sourFunc = GetProcAddress(hMod,FuncName);
if(!sourFunc)
return NULL;
*(ULONG*)(&JmpCode[1])=(ULONG)NewFunc;
while(BackupLength<6)
{
BackupLength += SizeOfCode((void*)((ULONG)sourFunc+BackupLength),&OpCode);
}
proxyFunction = VirtualAlloc(NULL,BackupLength + 6,MEM_RESERVE| MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (!proxyFunction)
return NULL;
*(ULONG*)((ULONG)JmpBackCode + 1) = (ULONG)sourFunc + BackupLength;
RtlCopyMemory(proxyFunction,sourFunc,BackupLength);
RtlCopyMemory((PVOID)((ULONG)proxyFunction + BackupLength),JmpBackCode, 6);
FlushInstructionCache((HANDLE) - 1,proxyFunction,BackupLength + 6);
DWORD OldProtect = 0;
VirtualProtect(sourFunc, 6,PAGE_EXECUTE_READWRITE, &OldProtect);
RtlCopyMemory(sourFunc,JmpCode, 6);
VirtualProtect(sourFunc, 6,OldProtect, &OldProtect);
FlushInstructionCache((HANDLE) -1,sourFunc, 6);
return proxyFunction;
}
int audit()
{
static int cnt;
DWORD Lab1Offset;
__asm
{
mov eax,Lab1;
mov Lab1Offset,eax;
}
DWORD OldProtect = 0;
VirtualProtect((void*)Lab1Offset, 4,PAGE_EXECUTE_READWRITE, &OldProtect);
cnt++;
//跳转前要绕过_chkesp
__asm
{
pop edi;
pop esi;
pop ebx;
mov esp,ebp;
pop ebp;
}
__asm
{
mov eax,proxyFunction;
mov ebx,Lab1;
mov [ebx],eax;
_emit 0x68;
Lab1:
_emit 0x90;
_emit 0x90;
_emit 0x90;
_emit 0x90;
ret;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
proxyFunction = (DWORD)HookFunc("user32.dll","MessageBoxA",audit);
MessageBox(NULL,"","",MB_OK);
return 0;
}