- 论坛徽章:
- 0
|
本帖最后由 li574000 于 2010-03-25 09:06 编辑
目的:我想hook first函数,好让调用first函数的时候实际调用的是second函数。方式就是改写first函数地址处的指令,改成成jmp second这种指令,也就是跳转到second函数运行。
试验平台是WINDOWSXP ,VS2005.
出现问题:当我调用first函数的时候,通过汇编跟踪,发现最终调用的汇编代码是下面这句
0041124E FF 25 5A 10 41 00 jmp dword ptr [second (41105Ah)]
但是当执行上面这句的时候,不知道为什么他跳转的地址不是上面列出的地址,也就是(41105Ah),而是下面这个地址:
000621E9 ?? ???
显然,这个地址啥都没有,所以指令执行失败,弹出内存访问错误。这里不解的是明明跳转的地址是对的,但是运行的时候就跳到了另一个未知的地址哪?困惑好久,实在无法解决。
下面就是代码部分
include "stdafx.h"
#include "iostream"
#include <windows.h>
using namespace std;
void first(void);
void second(void);
int _tmain(int argc, _TCHAR* argv[])
{
DWORD old,newp;
DWORD addfirst=(DWORD)first;
DWORD addsecond=(DWORD)second;
DWORD newfunc=(DWORD)(&addsecond);
//更改代码段的读写属性,否则XP下写这个内存违法
if (::VirtualProtect((LPVOID)addfirst,6,PAGE_EXECUTE_READWRITE,&old)==0)
{
cout<<"error"<<endl;
}
//0xff25是INTEL指令的 jmp
*(unsigned char*)addfirst=(unsigned char)0xff;
*(((unsigned char*)addfirst) +1)=(unsigned char)0x25;
//下面是把second函数的地址写入到jmp指令后面
DWORD lpnew=(DWORD)&second;
memcpy((void*)(addfirst+2),(const void *)&lpnew,sizeof(DWORD));
//把内存读写属性恢复
if (::VirtualProtect((LPVOID)addfirst,6,old,&newp)==0)
{
cout<<"error"<<endl;
}
//强制更新cache,防止写了内存但是没有更新内存对应的cache。
FlushInstructionCache(GetCurrentProcess(),NULL,0);
//调用first,执行的时候弹出内存访问错误
first();
char c;
cin>>c;
}
void first(void)
{
cout<<"it is in first"<<endl;
}
void second(void)
{
cout<<"it is in second"<<endl;
} |
|