首页
社区
课程
招聘
高分求助。文件偏移公式算法。
发表于: 2013-10-26 15:48 5734

高分求助。文件偏移公式算法。

2013-10-26 15:48
5734
我想在PE文件内写物理地址hook。

已知:
HOOK当前地址。
HOOK目标地址。

公式结果= HOOK目标地址 减 (HOOK当前地址+5) 加 20480

生成机器码=E9+公式结果

想知道 20480 是怎么来的。
或者求正确的计算方法。

主要是想生成这个jmp到目标地址的机器码。

。。。。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
意思是 把整个exe文件读入内存当中。通过文件位置偏移去改写代码。

然后通过要改写的偏移地址 jmp到目标地址。

问题遇到了。这个jmp偏移的机器码是怎么生成的。
然后直接替换旧的5字节代码。写进新生成的这个jmp机器码。
2013-10-26 16:34
0
雪    币: 1372
活跃值: (5343)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
3
JMP公式的计算其实是
JMP语句所在的地址+语句的后四个字节的相对位移+该语句的长度(一般为5)=要跳到的地址

一般由于HOOK是远跳,所以占五个字节
2013-10-26 16:53
0
雪    币: 1372
活跃值: (5343)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
4
BYTE b[5]={0xe9,0x90,0x90,0x90,0x90};//第一个为0XE9代表 远JMP 后面四个随便,反正待会要改为相对偏移的
myJmp=(DWORD)MyLoadLibraryExW-5-RealLoadLibraryExw;
*(DWORD*)(b+1)=myJmp;
这样得到的b里面的就是5个机器码了。
2013-10-26 16:59
0
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
努力理解中,谢谢你再次热心回答。
2013-10-26 17:10
0
雪    币: 5331
活跃值: (3562)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
[QUOTE=IamHuskar;1234257]BYTE b[5]={0xe9,0x90,0x90,0x90,0x90};//第一个为0XE9代表 远JMP 后面四个随便,反正待会要改为相对偏移的
myJmp=(DWORD)MyLoadLibraryExW-5-RealLoadLibraryExw;
*(DWORD*)(b+1)=myJmp;
这...[/QUOTE]

貌似他说的是HEX换算?
2013-10-26 18:40
0
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我也是云里雾里,还没有明白。

其实我就想实现。
已知:
当前要替换成JMP机器码的文件偏移。
JMP机器码跳到的文件偏移。

求生成这个JMP正确的机器码。
2013-10-26 18:47
0
雪    币: 1372
活跃值: (5343)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
8
不就是我说的了么??

BYTE b[5]={0xe9,0x90,0x90,0x90,0x90};//第一个为0XE9代表 远JMP 后面四个随便,反正待会要改为相对偏移的
DWORD myJmp=(DWORD)JMP机器码跳到的文件偏移-5-当前要替换成JMP机器码的文件偏移;
*(DWORD*)(b+1)=myJmp;

比如 我要HOOK 0x401000(当前要替换成JMP机器码的文件偏移)这个地址 跳到 0x500000(JMP机器码跳到的文件偏移)

BYTE b[5]={0xe9,0x90,0x90,0x90,0x90};

DWORD myJmp=(DWORD)JMP机器码跳到的文件偏移-5-当前要替换成JMP机器码的文件偏移;
那么Myjmp=0x500000-5-0x401000=0xFEFFB;

*(DWORD*)(b+1)=myJmp;
也就是从E9后一个字节开始,把跳转偏移写进去。
得到 b[5]=0XE9 0XFB 0XEF 0X0F 0X00
0XFB 0XEF 0X0F 0X00 就是 0xFEFFB (内存中表示是倒的,查一下大尾和小尾)

那么看这个字节码怎么找到要跳的位置呢?
JMP的地址 为0x401000 (0XE9 0XFB 0XEF 0X0F 0X00)占五个字节。
0x401000 +5=0x401005
然后+后面四位偏移 0XFB 0XEF 0X0F 0X00
0x401005+0xFEFFB=500000;
这么说如果你还不懂 那就先从一年级开始读起吧。

00401000 > /E9 FBEF0F00     JMP final.00500000
2013-10-26 18:59
0
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
先回复 在慢慢看  谢谢你在一次细心的解答
2013-10-26 19:10
0
雪    币: 200
活跃值: (38)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
其实很简单,绝大多数jmp都是near jmp,这个jmp的机器码为

E9 | rel 32

后面的rel32代表的是目标地址与jmp下面一条指令的相对偏移,因为jmp near指令本身的大小为5字节,所以

rel32 = target_addr - (jmp_ins_addr + 5)

至于说具体怎么改动,这里还要牵扯pe文件格式的问题,因为指令在pe文件中的偏移并不等于指令在代码段中的偏移,当然,如果jmp指令和要跳转到的指令处在同一个段内,比如都在.text段,那么直接用这两个指令在文件中的偏移去计算是可以的。如果jmp指令和要跳转到的指令不在一个段内,比如jmp指令在.text段,目标指令在.data段,或者说目标指令在堆或者栈上面,那么你需要用加载后的virtual address去计算,而不是文件偏移。

假设你的jmp在.text段,目标代码在.data段,那么

rel32 = target_addr - (jmp_ins_addr + 5)
= (target_addr_file_offset - text_segment_file_offset + text_segment_virtual_offset)
    - (jmp_ins_file_offset - data_segment_file_offset + data_segment_virtual_offset + 5)
2013-10-26 19:47
0
雪    币: 115
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
@ganboing 非常谢谢你的解答。

rel32 = target_addr - (jmp_ins_addr + 5)

难怪我用上面算法计算不出 原来是因为我的区段不相同的问题。

机器码码 = 目标跳的偏移位置 - (当前跳的偏移位置 + 5)

= (目标跳的偏移位置 - text_segment_file_offset + text_segment_virtual_offset)
    - (jmp_ins_file_offset - data_segment_file_offset + data_segment_virtual_offset + 5)

我对这些可以说一点都不知道  能不帮加我QQ给我指点一下啦。20 Q币的报酬。企鹅:三五八三扒扒零零零
2013-10-26 20:36
0
游客
登录 | 注册 方可回帖
返回
//