首页
社区
课程
招聘
[旧帖] [求助]retn、retn 4和retn 0C有什么区别?? 0.00雪花
发表于: 2008-4-19 15:44 16928

[旧帖] [求助]retn、retn 4和retn 0C有什么区别?? 0.00雪花

2008-4-19 15:44
16928
在破解的时候,我想在一个call的头部直接返回,如何判断到底是使用retn、retn 4还是retn 0C......
是看call头部的代码吗??
我知道的只是retn xx的结果是在ESP上+xx,可似乎有时候我都用retn也没什么关系,这是为什么?

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

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
使用retn,
因为你说的是在call的头部返回,也就是被调用过程的第一条指令处返回(我没有曲解你的意思吧)。
这是还没有分配局部变量,也没有往堆栈中压入数值,那么esp指令指向的依然是call指令的返回地址,所以你直接返回就可以了,使用retn

xxxxxxx1       call   xxxxxx10
xxxxxxx5

当执行call指令时,系统会把xxxxxxx5作为返回地址压入堆栈
而在被调用过程完成它的工作后,retn指令就是读取堆栈顶部的地址,然后返回到哪里
所以,通常情况下,在被调用过程里,分配了多少局部变量,也就是形如
add   esp   -xx
或着
sub   esp   xx
这就是在分配局部变量
最后过程最后也会释放多少
但是有时程序故意要修改返回地址让程序返回到另一个地方,最简单的就是这样
push   xxxxxx20
retn
这样由于修改了堆栈数据,retn指令是只管读出堆栈顶部的值作为返回地址,我们就返回
到了xxxxxx20的地方了。

如果你要在被调用过程的中间,只是返回到原来的返回地址,那么你注意好堆栈平衡就可以了。
2008-4-19 16:24
0
雪    币: 716
活跃值: (162)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
3
pascal 和C/C++的程序有区别,
delphi编译的一般会在子函数内部平衡堆栈,而VC编译的一般在CALL返回后平衡。
2008-4-19 17:53
0
雪    币: 427
活跃值: (65)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
[QUOTE='UD]Arthas;443163']使用retn,
因为你说的是在call的头部返回,也就是被调用过程的第一条指令处返回(我没有曲解你的意思吧)。
这是还没有分配局部变量,也没有往堆栈中压入数值,那么esp指令指向的依然是call指令的返回地址,所以你直接返回就可以了,使用retn

xxxxxxx1       call  ...[/QUOTE]

哈哈,谢谢!
你完全没曲解我的意思!!
感谢了

就是说我在头部返回只用retn就足够了,不用考虑其他是吧?
2008-4-19 18:35
0
雪    币: 297
活跃值: (27)
能力值: ( LV13,RANK:380 )
在线值:
发帖
回帖
粉丝
5
怎么可能不考虑其它。
调用约定为C型时,不用考虑,可以直接使用ret
调用约定为其它时,必须考虑ret n

没想到直接返回有什么用,爆破?
如果是面向对象的程序,这样修改类方法有可能死得很惨。
2008-4-19 19:00
0
雪    币: 427
活跃值: (65)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
我说的是汇编
不知道大虾所说的约定为C型、约定为其它是什么意思?
是观察call的头尾有没有对esp进行add或sub 吗?
2008-4-20 09:25
0
雪    币: 297
活跃值: (27)
能力值: ( LV13,RANK:380 )
在线值:
发帖
回帖
粉丝
7
不考虑其它情况,仅考虑维持堆栈平衡时,不管是C型调用约定、还是stdcall、...,函数原代码是ret n,你就必须是ret n。
2008-4-20 11:17
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
所谓的调用方式是指:
在调用一个函数时,约定的传递参数方式和平衡堆栈方式,例如:
有一个函数,它有两个参数
xyz(first,second)
当我们使用stdcall调用方式时,也就是Windows调用API的常见方式(又几个函数例外),它的调用方式如下:
xxxxxxx1    push     second
xxxxxxx2    push     first
xxxxxxx3    call        xyz
参数传递从右到左
堆栈的平衡也是有被调用函数负责,
如果是c调用方式如下:
xxxxxxx1    push     second
xxxxxxx2    push     first
xxxxxxx3    call        xyz
xxxxxxx4    add       esp     08
参数传递从右到左
堆栈的平衡要有调用函数负责,
如果是pascal调用方式如下:
xxxxxxx1     push    first
xxxxxxx2     push    second
xxxxxxx3     call       xyz
参数传递从左到右
堆栈的平衡有被调用函数负责。
这是简要的解释,不明白就去google上搜篇文章看看吧。
2008-4-20 12:41
0
游客
登录 | 注册 方可回帖
返回
//