首页
社区
课程
招聘
[求助]关于call相对地址转换为绝对地址的问题
发表于: 2013-6-11 20:40 15650

[求助]关于call相对地址转换为绝对地址的问题

2013-6-11 20:40
15650
0091A0BB  |.  68 30D7F000   PUSH 00F0D730        
0091A0C0  |.  50            PUSH EAX  
[COLOR="Red"]0091A0C1  |.  E8 BA845100   CALL 00E32580           
[/COLOR]0091A0C6  |.  83C4 08       ADD ESP,8
0091A0C9  |>  32C0          XOR AL,AL


0091A0C1  |.  E8 BA845100   CALL 00E32580           

请问这儿的call地址应该如何计算才能够得到绝对地址呢?就是00E32580  这个地址.

我这边打算读取一个应用程序的函数段,但是读取好后我将读取来的十六进制码写入拷贝到我自己的函数里时,发生了一个情况,就是这个相对 读取到的E8 BA845100 这个指令写入我的模块函数里后生成的call函数地址不正确并不是 00E32580,所以我想在读取的时候,读取到这类
相对call地址时自动转换为绝对地址也就是   00E32580   这个地址。请问应该如何做呢??

求思路与转换的公式..

         

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 7
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
0F28372B    68 30D7F000     PUSH 0F0D730
0F283730    50              PUSH EAX
0F283731    E8 BA845100     CALL 0F79BBF0
0F283736    83C4 08         ADD ESP,8
0F283739    32C0            XOR AL,AL
0F28373B    5E              POP ESI
0F28373C    8BE5            MOV ESP,EBP
0F28373E    5D              POP EBP
0F28373F    C2 0800         RETN 8

这里是我拷贝到我自己函数里的转换的call地址。。求解。
我想将生成这里的call 0F79BBF0 转换为 00E32580

求解有何方法呢??因为代码实在太长了,手工拷贝到我的函数里能累死了。

所以想自动读取了,这样我更新起来也方便点,但遇到这个问题,求解,有经验的朋友帮帮忙咯。。
2013-6-11 20:50
0
雪    币: 39
活跃值: (2906)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
汇编没有好好学吧?
0091A0C1  |.  E8 BA845100   CALL 00E32580           
0091A0C6  |.  83C4 08       ADD ESP,8
目标地址-下条指令的地址=机器码E8后面所跟的32位数
据此可以推出
目标地址=下条指令的地址+机器码E8后面所跟的32位数
代入你的数据得
目标地址=91A0C6+005184BA = 00E32580
注意,机器码E8后面所跟的32位数 是 little-endian 格式的,低8位在前,高8位在后。
2013-6-11 21:06
0
雪    币: 7
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
o(╯□╰)o,书看了不少,但是运用的少.. 这些原理早忘差不多了。



表示一声感谢啊!!! 帮了大忙了..
2013-6-11 21:28
0
雪    币: 1632
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
很简单啊,目标地址 - 当前指令地址的下个指令地址 = 距离,倒序。

我的通俗。。。哈哈
2013-6-11 21:29
0
雪    币: 7
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
void Replace_Code(DWORD Original_Address ,DWORD New_Address, BYTE *PData,DWORD LengthA)
{
BYTE Array[1024] = {0};
DWORD Code = 0;

for (int i=0;i< LengthA;++i)
{
Array= PData;
}


_asm
{
pushad
mov ecx,0
NEXT:
mov bl,byte ptr Array[ecx]
inc ecx
cmp ecx,LengthA
jz exitA
cmp bl,0x0E8
jnz NEXT

pushad
mov edx,0
lea ebx,Code
Hex_Code:

lea eax,[ecx+edx]
mov al,byte ptr Array[eax]
mov [ebx],al
inc ebx
inc edx
cmp edx,4
jnz Hex_Code
mov eax,Original_Address
lea eax,[ecx+eax]
add eax,Code
add eax,5

Write_Addr:
mov ebx,New_Address
lea ebx,[ebx+5+ecx]
sub eax,ebx
mov dword ptr Array[ecx],eax
mov Code,eax
popad
cmp ecx,LengthA
jz exitA
jmp NEXT
exitA:
popad
}

}


为感谢楼上大神的提点,分享转换call地址的代码函数一份..写的有点乱,但是可以转换的..

经过测试写入到我自己函数里生成的call地址是正确的了..

2013-6-12 16:53
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这是我以前写Hot Patch时的一段代码,作用是将绝对地址转换成相对地址
;********************************************************************
;写入远程跳转
;bJmpFar		db	0E9h
;********************************************************************
		mov	eax,0E9h
		cld
		stosb
;********************************************************************
;计算Jmp的偏移
;********************************************************************
		mov	eax,_lpNew		;_lpNew是将要跳转到的绝对地址
		sub	eax,edi			;edi指向的是将要写入的地址,前面已经放了一个E9,这里只需要放置偏移量
		sub	eax,4			;偏移量要减去偏移量自身的长度,上面减法后是相对E9的偏移,而不是指令末尾的偏移,因为跳转都是针对EIP操作的
		cld
		stosd

所以你的代码感觉有很多不必要的操作了,整个的操作应该就是
mov		eax,dword ptr [代码所在的地址]
add		eax,4
add		eax,代码在内存内的地址

这就完成了相对地址转换为绝对地址,如果是直接修改运行中的二进制文件上面两个地址是一样的,不然就要你自己考虑了
不要忘记x86是小尾模式,所以如果一个数字看上去是反着的那么直接读取就可以了
		mov edx,0
		lea ebx,Code
Hex_Code: 
		lea  eax,[ecx+edx]
		mov  al,byte ptr Array[eax]
		mov  [ebx],al
		inc  ebx
		inc  edx
		cmp  edx,4
		jnz  Hex_Code

我说的就是这个
其他的代码看不懂再说什么...或者说看懂了但是不知道到底在干什么,PData感觉还是莫名其妙
2013-6-12 17:58
0
雪    币: 7
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
估计是我写的太繁琐了.. 测试用的.有很多东西都可以省略了。。

这函数主要作用就是给读取来的函数块里的所有call地址都根据我自己的函数地址转换。
然后写入到我自己的函数里去。
2013-6-12 21:21
0
雪    币: 7
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
那个循环是多余的。我用来测试传递过来的数据的。

我这边已经删了.
2013-6-12 21:39
0
游客
登录 | 注册 方可回帖
返回
//