修改函数头5个字节Hook,不明白解决办法
修改函数头5个字节Hook,不明白
把函数头5个字节修改为jmp XXXX,其中XXXX的值是这样计算出来的
DWORD dwNew = (DWORD)MyHookAPI - (DWORD)m_AddrAPI - 5;
不明白上面是根据什么原理计算出来的,请了解的朋友帮解释下,谢谢!
------解决方案--------------------
长跳转jmp XXXX指令占5字节
偏移 = 目标地址 - JMP的下一条指令地址
即是:偏移 = 目标地址 - ( JMP的地址 + 5 )
展开:偏移 = 目标地址 - JMP的地址 - 5
具体语法查CPU指令手册或相关汇编资料
------解决方案--------------------
------解决方案--------------------
汇编啊,都是高手. 学习之..
------解决方案--------------------
你就直接写jmp就OK了,编译器知道这是什么跳转,是远跳还是近跳。什么东西的存在都是有道理的,比如这个jmp far 和jmp near,如果你看一下对应的机器指令就清楚了,你想一个字节能跳多远?4个字节能跳多远?
------解决方案--------------------
e9是近跳,就是段内跳
e9后面的4字节的意义是,跳的目标地址减去jmp下一个指令的地址
这是为了看起来像最初cpu执行指令的过程,先取指令,增加pc,执行指令
把函数头5个字节修改为jmp XXXX,其中XXXX的值是这样计算出来的
DWORD dwNew = (DWORD)MyHookAPI - (DWORD)m_AddrAPI - 5;
不明白上面是根据什么原理计算出来的,请了解的朋友帮解释下,谢谢!
- C/C++ code
// hook5bytes_.cpp : 定义 DLL 应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> #include <stdio.h> #define HookModName "user32.dll" #define HookApiName "MessageBoxW" //修改API入口为jmp eax是程序能跳转到自己的函数 BYTE g_btNew5Bytes[5] = { 0xE9, 0x0, 0x0,0x0, 0x0}; //保存原API入口的5个字节 BYTE g_dwOld5Bytes[5] = { 0x0, 0x0, 0x0, 0x0, 0x0}; //API地址 void * m_AddrAPI; //定义自己的API,参数表和原函数一致,MyHookAPI中调用的也一样 int WINAPI MyHookAPI(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType); BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { if(ul_reason_for_call==DLL_PROCESS_ATTACH) { //找到API地址 HMODULE hModule = LoadLibrary(HookModName); m_AddrAPI = (void *)GetProcAddress( hModule,HookApiName); /*修改5字节*/ //保存原始字节 ReadProcessMemory(INVALID_HANDLE_VALUE,m_AddrAPI, ( void * )g_dwOld5Bytes, sizeof( DWORD )+1, NULL ); DWORD dwNew = (DWORD)MyHookAPI - (DWORD)m_AddrAPI - 5; memcpy(&g_btNew5Bytes[1], &dwNew, 4); WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNew5Bytes, sizeof( DWORD )+1, NULL ); } return TRUE; } int _stdcall MyHookAPI(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType) { WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_dwOld5Bytes, sizeof( DWORD )+1, NULL ); ::MessageBoxW(hWnd,lpText,L"HOOK",uType); WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNew5Bytes, sizeof( DWORD )+1, NULL ); return 0; }
------解决方案--------------------
长跳转jmp XXXX指令占5字节
偏移 = 目标地址 - JMP的下一条指令地址
即是:偏移 = 目标地址 - ( JMP的地址 + 5 )
展开:偏移 = 目标地址 - JMP的地址 - 5
具体语法查CPU指令手册或相关汇编资料
------解决方案--------------------
------解决方案--------------------
汇编啊,都是高手. 学习之..
------解决方案--------------------
你就直接写jmp就OK了,编译器知道这是什么跳转,是远跳还是近跳。什么东西的存在都是有道理的,比如这个jmp far 和jmp near,如果你看一下对应的机器指令就清楚了,你想一个字节能跳多远?4个字节能跳多远?
------解决方案--------------------
e9是近跳,就是段内跳
e9后面的4字节的意义是,跳的目标地址减去jmp下一个指令的地址
这是为了看起来像最初cpu执行指令的过程,先取指令,增加pc,执行指令