流沙团
测试InlineHook
2018-2-4 流沙团


0x01主要是针对内部函数的hook



这里有需要注意的地方



内部含糊的地址



HOOK的位置



保存现场: pushfd  pushad



原本硬编码的恢复






extern "C" _declspec(naked)void HookProc()
{
//保存现场
_asm
{
pushad
pushfd
}
//获取寄存器
_asm
{
mov reg.Eax,eax
mov reg.Ecx,ecx
mov reg.Ebx,ebx
mov reg.Edx,edx
mov reg.Esp,esp
mov reg.Ebp,ebp
mov reg.Esi,esi
mov reg.Edi,edi

mov EAX,DWORD PTR SS:[esp+0x28]
mov dwParaX,EAX
mov EAX,DWORD PTR SS:[esp+0x2C]
mov dwParaY,EAX
}

//当前寄存器的内容

OutputDebugStringF("Eax:%d,Ebx:%d,Ecx,%d,Edx:%d",reg.Eax,reg.Ebx,reg.Ecx,reg.Edx);
OutputDebugStringF("esp:%d,ebp:%d,esi,%d,edi:%d",reg.Esp,reg.Ebp,reg.Esi,reg.Edi);


//参数内容
OutputDebugStringF("X:%d.Y:%d",dwParaX,dwParaY);

//恢复现场
_asm
{
popfd
popad
}
//执行覆盖代码
_asm
{
push ebp
mov ebp,esp
sub esp,40h
}

//跳回去
_asm
{
jmp g_dwRetAddr
}

}






裸函数的运用







0x02 跳转地址的注意事项






	//备份硬编码
g_pCodePatch = new BYTE[bytes];
memcpy(g_pCodePatch,(void*)dwHookAddr,bytes);

//填充90
dwJumpCode = dwProcAddr - dwHookAddr - 5;
memset((void*)dwHookAddr,0x90,bytes);

// jmp 0x0000
*(PBYTE)dwHookAddr = 0xE9;
*(PDWORD)((PBYTE)dwHookAddr + 1) = dwJumpCode;






0x03 上面贴的是核心代码



详细代码如下






// 20180203_01.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "DebugTool.h"


DWORD g_dwHookAddr; //Hook开始的地方
DWORD g_dwRetAddr; //Hook结束的地方
DWORD g_dwLength; //Hook字节数
PBYTE g_pCodePatch; //存储Hook原来的硬编码
DWORD g_dwHookFlag; //HOOK状态, 1 Hook成功, 0 HOOK 失败

typedef struct _REGISTER
{
DWORD Eax;
DWORD Ecx;
DWORD Edx;
DWORD Ebx;
DWORD Esp;
DWORD Ebp;
DWORD Esi;
DWORD Edi;
}Register;

DWORD dwParaX;
DWORD dwParaY;

Register reg= {0};
TCHAR szBuffer[100] = {0};


extern "C" _declspec(naked)void HookProc()
{
//保存现场
_asm
{
pushad
pushfd
}
//获取寄存器
_asm
{
mov reg.Eax,eax
mov reg.Ecx,ecx
mov reg.Ebx,ebx
mov reg.Edx,edx
mov reg.Esp,esp
mov reg.Ebp,ebp
mov reg.Esi,esi
mov reg.Edi,edi

mov EAX,DWORD PTR SS:[esp+0x28]
mov dwParaX,EAX
mov EAX,DWORD PTR SS:[esp+0x2C]
mov dwParaY,EAX
}

//当前寄存器的内容

OutputDebugStringF("Eax:%d,Ebx:%d,Ecx,%d,Edx:%d",reg.Eax,reg.Ebx,reg.Ecx,reg.Edx);
OutputDebugStringF("esp:%d,ebp:%d,esi,%d,edi:%d",reg.Esp,reg.Ebp,reg.Esi,reg.Edi);


//参数内容
OutputDebugStringF("X:%d.Y:%d",dwParaX,dwParaY);

//恢复现场
_asm
{
popfd
popad
}
//执行覆盖代码
_asm
{
push ebp
mov ebp,esp
sub esp,40h
}

//跳回去
_asm
{
jmp g_dwRetAddr
}

}

DWORD Plus(DWORD x,DWORD y)
{
return x+y;
}


BOOL SetInlineHook(DWORD dwHookAddr,DWORD dwProcAddr,int bytes)
{
BOOL bRet = FALSE;
DWORD dwOldProtect = 0;
DWORD dwJumpCode = 0;

if(dwHookAddr == NULL || dwProcAddr==NULL)
{
OutputDebugStringF("Function Address Error!");
return bRet;
}

if(bytes<5)
{
OutputDebugStringF("字节长度不够,操作失败!");
return bRet;
}

bRet = VirtualProtectEx(::GetCurrentProcess(),(LPVOID)dwHookAddr,(DWORD)bytes,PAGE_EXECUTE_READWRITE,&dwOldProtect);

if(!bRet)
{
OutputDebugStringF("内存空间申请权限失败");
return bRet;
}

//备份硬编码
g_pCodePatch = new BYTE[bytes];
memcpy(g_pCodePatch,(void*)dwHookAddr,bytes);

//填充90
dwJumpCode = dwProcAddr - dwHookAddr - 5;
memset((void*)dwHookAddr,0x90,bytes);

// jmp 0x0000
*(PBYTE)dwHookAddr = 0xE9;
*(PDWORD)((PBYTE)dwHookAddr + 1) = dwJumpCode;

//修改HOOK状态
g_dwHookFlag = 1;
g_dwHookAddr = dwHookAddr;
g_dwLength = (DWORD)bytes;
g_dwRetAddr = dwHookAddr + g_dwLength;

return TRUE;

}

BOOL UnInlineHook()
{
BOOL bRet = FALSE;
DWORD dwOldProtect;
if(!g_dwHookFlag)
{
OutputDebugStringF("no hook inline");
return bRet;
}
bRet = VirtualProtectEx(::GetCurrentProcess(),(LPVOID)g_dwHookAddr,(DWORD)g_dwLength,PAGE_EXECUTE_READWRITE,&dwOldProtect);

if(!bRet)
{
OutputDebugStringF("内存空间申请权限失败");
return bRet;
}

//恢复硬编码
memcpy((PDWORD)g_dwHookAddr,g_pCodePatch,g_dwLength);

//修改HOOK状态
delete[] g_pCodePatch;
g_dwHookFlag = 0;
g_dwHookAddr = 0;
g_dwLength = 0;
g_dwRetAddr = 0;
g_pCodePatch= NULL;

return TRUE;
}


VOID TestInlineHook(DWORD dwHookAddr,DWORD dwProcAddr,int bytes)
{

SetInlineHook(dwHookAddr,dwProcAddr,bytes);
Plus(11,55);
//卸载HOOK
UnInlineHook();
}



int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DWORD TestFuncAddr = 0x004012A0;
Plus(1,2);
OutputDebugStringF("HookProc: %08X",HookProc);
OutputDebugStringF("TestFuncAddr: %08X",TestFuncAddr);
//安装HOOK
TestInlineHook(TestFuncAddr,(DWORD)HookProc,6);

return 0;
}







0x04 工程下载

inlineHook.rar

直接分享代码吧,

记住不同机器上 Plus的地址不一样, 自己先测试吧!!













发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容