免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3791 | 回复: 18
打印 上一主题 下一主题

我这段hook代码有什么问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-25 09:05 |只看该作者 |倒序浏览
本帖最后由 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;
}

论坛徽章:
0
2 [报告]
发表于 2010-03-25 10:32 |只看该作者
本帖最后由 huangwei0413 于 2010-03-25 10:43 编辑

回复 1# li574000


    jmp指令后面的4个字节应该填目标地址(second)与IP(jmp下一条指令)的差值。

论坛徽章:
0
3 [报告]
发表于 2010-03-25 10:44 |只看该作者
是的,这样返回是会有问题,不过我现在测试的是调用,所以没有恢复的动作,但是现在是调用都不行,我用反汇编单步调试,就是执行到说的那个跳转的地方莫名其妙的就跳到了一个地址,这个地址都不知道是从哪里来的。

论坛徽章:
0
4 [报告]
发表于 2010-03-25 10:47 |只看该作者
我想应该是把(second - first + 6)赋给addfirst+2

论坛徽章:
0
5 [报告]
发表于 2010-03-25 10:47 |只看该作者
回复  li574000


    jmp指令后面的4个字节应该填目标地址(second)与IP(jmp下一条指令)的差值。
huangwei0413 发表于 2010-03-25 10:32



    jmp指令的用法是规定IP的差值吗?我印象中好像可以直接跳转到某个虚拟地址的

论坛徽章:
0
6 [报告]
发表于 2010-03-25 10:48 |只看该作者
我想应该是把(second - first + 6)赋给addfirst+2
huangwei0413 发表于 2010-03-25 10:47



    好的,我先试验下,有结果再回复你

论坛徽章:
0
7 [报告]
发表于 2010-03-25 10:51 |只看该作者
好的,我先试验下,有结果再回复你
li574000 发表于 2010-03-25 10:48



    不好意思,搞错了,应该把second-first-6赋给addfirst+2

论坛徽章:
0
8 [报告]
发表于 2010-03-25 10:55 |只看该作者
不行,jmp执行的时候不是按照IP的偏移来执行的,还是按照绝对的虚拟地址来执行的。所以刚才的方法还是不行。

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-09-23 06:20:00
9 [报告]
发表于 2010-03-25 11:20 |只看该作者
jmp dword ptr [address] 是 jmp 到 *address, 不是 address,
jmp 到 address应该是: 设 jmp 指令所在地址是 source, jmp 的目的地址是 destine, 则
jmp destine - source - 5

论坛徽章:
0
10 [报告]
发表于 2010-03-25 12:03 |只看该作者
本帖最后由 li574000 于 2010-03-25 12:06 编辑

不好意思,有点晕了,不知道上面的代码如何改正才能执行哪,我是抄周伟明那本《多核并行程序设计》上的代码段的。还有,你们给出跳转都是近跳转,相对于当前IP的,但是上面的汇编
应该是长跳转吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP