菜鸟学逆向——简单的反汇编阅读与逆向(1)
本帖最后由 cu629944 于 2012-4-1 13:20 编辑【文章标题】: 菜鸟学逆向——简单的反汇编阅读与逆向(1)
【文章作者】: Silence(cu629944,等试用期通过,我会修改ID为Silecne)
【作者邮箱】: mohen_ng@sina.cn
【下载地址】: 自己搜索下载
【编写语言】: VC++6.0
【操作平台】: WIN 7
【软件介绍】: IDA VC++6.0
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
我会写一个系列的文,希望大家能够支持,这是第一篇
我们先启动VC++6.0,输入下面的程序
程序很短,大家看我输入一次,留意成对编码原则,防止对低级的错误
#include <stdio.h>
void Silence(int a,int b)
{
int c =a + b;
}
void main()
{
Silence(1,2);
}
一个简单的有2个形参的Silence()函数,接着在main()主函数调用Silence()函数。
编译成Debug模式,Realse版本会把调试信息等去掉。
我们用VC6.0自带的调试器,复制一个反汇编代码出来(为什么不立即用IDA看呢?因为VC6.0会把源码和反汇编代码一一对应起来,方便我们在IDA对照查看)
void main()
9: {
00401060 push ebp
00401061 mov ebp,esp
00401063 sub esp,40h
00401066 push ebx
00401067 push esi
00401068 push edi
00401069 lea edi,
0040106C mov ecx,10h
00401071 mov eax,0CCCCCCCCh
00401076 rep stos dword ptr
10: Silence(1,2);
00401078 push 2
0040107A push 1
0040107C call @ILT+5(_Silence) (0040100a)
00401081 add esp,8
11: }
00401084 pop edi
00401085 pop esi
00401086 pop ebx
00401087 add esp,40h
0040108A cmp ebp,esp
0040108C call __chkesp (004010b0)
00401091 mov esp,ebp
00401093 pop ebp
00401094 ret
然后我们载入IDA里面。IDA非常智能,载入分析完成后,直接停到了我们的main()函数处。我们就离线分析下他的每句话的作用。
; Attributes: bp-based frame
_main proc near
var_40= byte ptr -40h
push ebp ; 保存EBP
mov ebp, esp ; 原EBP值已经被压栈(位于栈顶),而新的EBP又恰恰指向栈顶。
; 此时EBP寄存器就已经处于一个非常重要的地位,该寄存器中存储着栈中的一个地址(原EBP入栈后的栈顶),
; 从该地址为基准,向上(栈底方向)能获取返回地址、参数值,向下(栈顶方向)能获取函数局部变量值,
; 而该地址处又存储着上一层函数调用时的EBP值!
sub esp, 40h ; 为局部变量申请空间,大小为40h(注意40h是16进制数,用IDA看看转换成10进制为多少,为64)
push ebx
push esi
push edi
lea edi, ; Var_40是IDA自己分析出来的,表示为局部变量,就是SUB ESP,40h分配的40h个大小,目的是保存局部变量的区域
mov ecx, 10h
mov eax, 0CCCCCCCCh ; 从ebp-40h开始的区域初始化成全部0CCCCCCCCh,就是int3断点
rep stosd ; 拷贝字符串,初始化局部变量空间
; 以上的语句就是在栈中开辟一块空间放局部变量
; 然后把这块空间都初始化为0CCCCCCCCh,就是int3断点,一个中断指令。
; 因为局部变量不可能被执行,执行了就会出错,这时候发生中断提示开发者。
push 2 ;
; 参数2入栈
; 这里就是我们在test.c的源代码里面写的那个Silence(1,2);函数,这里有一个很重要的概念
; 就是调用约定,在 c/c++ 中, 函数的默认调用约定为 cdecl, 它约定参数从右到左入栈,
; 由调用者清理堆栈, 所谓清理, 即调整ESP的值, 使得原来的局部数据不再属于栈
;
push 1 ; 参数1入栈
;
call Func__Silence ; 调用我们定义的Silence函数
; 其实call 指令调用一个过程, 但它有一个小动作
; 在参数入栈以后, 被调用函数执行 之前, 它会将当前函数的下一条指令地址, 即EIP的值压入
;
add esp, 8 ; 调用完函数后恢复/释放栈
pop edi ; 以下三句都是恢复三个保存的寄存器
pop esi
pop ebx
add esp, 40h ; 这句对应的是上面的SUB ESP,40h,恢复堆栈,
cmp ebp, esp ; 检测ESP是否恢复正常,如果不正常将调用下面的Chkesp
call __chkesp ; 处理可能出现的堆栈错误(如果出错,将陷入debug)。
mov esp, ebp ; 还记得上面那句mov ebp,esp吗?EBP里面保存着我们初始状态的ESP值,这句是将栈顶指针放回esp
pop ebp ; 恢复原来的ebp和esp,让上一个调用的函数正常使用
retn ; 将返回地址存入EIP, 转移流程
_main endp ;
; 以上那部分代码在VC的Debug调试版才会有,主要检查栈是否被破坏了。这样就能及时在你出错的地方停下了告诉你。
; 发行版自动消除这些代码(调试产生的)。
; 如果函数有返回值,返回值将放在eax返回(这就是很多软件给秒杀爆破的原因了,因为eax的返回值是可以改的)
下面来看看Silence()函数
; Attributes: bp-based frame
_Silence proc near
var_44= byte ptr -44h
var_4= dword ptr -4
arg_0= dword ptr8
arg_4= dword ptr0Ch
push ebp ; 下面的这几句和上面我们分析的一样,所以我们对Silence函数只分析不同的地方
mov ebp, esp
sub esp, 44h ; 这里将局部变量的大小分配为44h
push ebx
push esi
push edi
lea edi,
mov ecx, 11h
mov eax, 0CCCCCCCCh
rep stosd
mov eax, ; 取第一个参数放到EAX里面,即参数a
add eax, ; 与保存在EBP+0Ch里面的参数b相加
mov , eax ; 返回值放到ebp - 4里面,即最终结果放到参数c里面
;
; 一般而言,ss:处为返回地址
; ss:处为第一个参数值(这里是a),ss:处为第二个参数(这里是b,这里8+4=12=0Ch)
; ss:处为第一个局部变量(这里是c),ss:处为上一层EBP值
; ebp和函数返回值是32位,所以占4个字节
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
retn
_Silence endp
到此处,我们就将这些代码翻译完毕了。有很多收获。
根据我们这些分析,我们就可以逆向出我们的源码了(只看IDA反汇编的部分哈!):
我们可以在IDA里面看到main函数没有返回值,和Cdecl调用约定的规则,我们就可以恢复出来main函数的代码。
void main()
{
Silence(1,2);
}
我们分析Silecne函数的反汇编代码,可以看出在每个局部变量里面,都是用的, ,等,我们可以发现都是4的倍数,我们知道INT类型,占4个字节,且这个函数有三个参数,而且也没有返回值,下面我们就可以恢复Silence的函数部分的代码:
voidSilence(int a,int b)
{
int c = a + b;
}
然后我们整理下,就可以得到完整的代码:
void Silence(int a,int b)
{
int c = a +b;
}
void main()
{
Silence(1,2);
}
--------------------------------------------------------------------------------
【经验总结】
里面讲了比较重要的,调用约定,大家可以百度下看看什么叫做调用约定。还有局部变量等是怎么在汇编中存在的,已经返回值的保存地址,及如何对返回值修改达到对程序的爆破。这就是一个简单的反汇编阅读和逆向了。我们可以恢复出我们的代码。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于吾爱破解技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2012年04月01日 11:38:05
期待后续{:1_921:} 给你加分,楼主辛苦了 good, 继续加油 LZ可以将几种调用约定都讲下就更好了,不错的文章 膜拜,给我加分!{:301_1005:} 好,支持笨笨阿姨 实用的教程 支持原创,期待后续 先压箱底,以后绝对能用上 感谢原创