(转)VS 反汇编方法及常用汇编…
来源:互联网 发布:java获取当前路径 编辑:程序博客网 时间:2024/05/24 06:37
在调试没有源码的文件时,我们可能要用到反汇编设计。
一、VS反汇编方法
1、调出反汇编窗口。
2、调用寄存器窗口(只有在反汇编下才可见)
如果在调试状态还是没有此菜单项,可试着以下操作:
在VS中点击“工具”->“导入和导出设置”,选择“重置所有设置”,下一步,这时你可以保存当前设置或不保存,我觉得无所谓,下一步,选择“VisualC#开发设置”,“完成”。这样,“调试”->“窗口”->“寄存器”菜单项应该用显示出来了,记得要确保你的程序是在调试的过程中。
3、查看内存
点击“调试”->“窗口”->“内存”->“内存1”...“内存4”(选一个就可以了。)。在内存窗口中的“地址”栏输入地址,按回车即可看到该地地址处的内存信息。
二、常用汇编指令介绍
1、常用指令
为了照顾到没学过汇编程序的同志们,这里简单介绍一下常见的几种汇编指令。
A、add:加法指令,第一个是目标操作数,第二个是源操作数,格式为:目标操作数 = 目标操作数 + 源操作数;
B、sub:减法指令,格式同 add;
C、call:调用函数,一般函数的参数放在寄存器中;
D、ret:跳转会调用函数的地方。对应于call,返回到对应的call调用的下一条指令,若有返回值,则放入eax中;
E、push:把一个32位的操作数压入堆栈中,这个操作在32位机中会使得esp被减4(字节),esp通常是指向栈顶的(这里要指出的是:学过单片机的同学请注意单片机种的堆栈与Windows下的堆栈是不同的,请参考相应资料),这里顶部是地址小的区域,那么,压入堆栈的数据越多,esp也就越来越小;
F、pop:与push相反,esp每次加4(字节),一个数据出栈。pop的参数一般是一个寄存器,栈顶的数据被弹出到这个寄存器中;
一般不会把sub、add这样的算术指令,以及call、ret这样的跳转指令归入堆栈相关指令中。但是实际上在函数参数传递过程中,sub和add最常用来操作堆栈;call和ret对堆栈也有影响。
G、mov:数据传送。第一个参数是目的操作数,第二个参数是源操作数,就是把源操作数拷贝到目的一份。
H、xor:异或指令,这本身是一个逻辑运算指令,但在汇编指令中通常会见到它被用来实现清零功能。
I、lea:取得第二个参数地址后放入到前面的寄存器(第一个参数)中。
方括号表示存储单元,也就是提取方括号中的数据所指向的内容,然而lea提取内容的地址,这样就实现了把(ebx-0ch)放入到了edi中,但是mov指令是不支持第二个操作数是一个寄存器减去一个数值的。
J、stos:串行存储指令,它实现把eax中的数据放入到edi所指的地址中,同时edi后移4个字节,这里的stos实际上对应的是stosd,其他的还有stosb,stosw分别对应1,2个字节。
K、jmp:无条件跳转指令,对应于大量的条件跳转指令。
L、jg:条件跳转,大于时成立,进行跳转,通常条件跳转之前会有一条比较指令(用于设置标志位)。
M、jl:小于时跳转。
N、jge:大于等于时跳转。
O、cmp:比较大小指令,结果用来设置标志位。
2 、函数参数传递方式
函数调用规则指的是调用者和被调用函数间传递参数及返回参数的方法,在Windows上,常用的有Pascal方式、WINAPI方式(_stdcall)、C方式(_cdecl)。
A、_cdecl C调用规则:
(a)参数从右到左进入堆栈;
(b)在函数返回后,调用者要负责清除堆栈,这种调用方式通常会生成较大的可执行程序。
B、_stdcall又称为WINAPI,调用规则如下:
(a)参数从右到左进入堆栈;
(b)被调用的函数在返回前自行清理堆栈,这种方式生成的代码比cdecl小。
C、Pascal调用规则(主要用于Win16函数库中,现在基本不用):
(a)参数从左到右进入堆栈;
(b)被调用的函数在返回前自行清理堆栈。
(c)不支持可变参数的函数调用。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
空程序:
int main()
{
00411360
00411361
00411363
;将其他指针或寄存器中的值入栈,以便在函数中使用这些寄存器。
00411369
0041136A
0041136B
0041136C
00411372
00411377
0041137C
return 0;
0041137E
}
;各指针出栈
00411380
00411381
00411382
00411383
00411385
00411386
函数调用:
int _tmain(int argc, _TCHAR* argv[])
{
同上理解,
004113D0
004113D1
004113D3
004113D9
004113DA
004113DB
004113DC
004113E2
004113E7
004113EC
同上理解.
定义a,b,c并存储在为函数留出的临时存储空间中.
004113EE
004113F5
004113FC
参数反向入栈
00411403
00411406
00411407
0041140A
0041140B
0041140E
调用Fun1
0041140F
恢复因为Fun1参数入栈改变的栈指针,因为Fun1有3个参数,一个整数4个字节,共0Ch(12)个字节
00411414
00411417
将返回值保存在d中.
返回值为0,让eax清零
0041141A
}
恢复现场
0041141C
0041141D
0041141E
以下全为运行时ESP检查:
先恢复因为为main预留空间而改变的栈指针
0041141F
00411425
00411427
正常时只需要以下两句就可以正常恢复esp,再出栈,又可以恢复ebp.
0041142C
0041142E
0041142F
int
{
同上理解,
00411A70
00411A71
00411A73
00411A79
00411A7A
00411A7B
00411A7C
00411A82
00411A87
00411A8C
定义变量
00411A8E
00411A95
再次参数反向入栈
00411A9C
00411A9F
00411AA0
00411AA3
00411AA4
00411AA7
00411AA8
00411AAB
00411AAC
00411AAF
调用Fun2
00411AB0
00411AB5
将Fun2函数的返回值(保存在eax中),赋值给f;
00411AB8
将保留在f中的Fun1的返回值保存在eax中返回
00411ABB
}
恢复现场
00411ABE
00411ABF
00411AC0
以下全为运行时ESP检查:
先恢复因为预留函数存储控件而改变的栈指针,
00411AC1
再比较ebp,esp,假如程序运行正确,两个值应该相等.
00411AC7
00411AC9
正常时只需要以下两句就可以正常恢复esp,再出栈,又可以恢复ebp.
00411ACE
00411AD0
返回main从pop堆栈中的EIP开始执行
00411AD1
int
{
同上理解,
00412050
00412051
00412053
00412059
0041205A
0041205B
0041205C
00412062
00412067
0041206C
定义变量
0041206E
00412075
相加,存入a,再保存在h
0041207C
0041207F
00412082
00412085
00412088
0041208B
0041208E
00412091
将返回值h的值保存在eax中
00412094
}
恢复现场
00412097
00412098
00412099
0041209A
0041209C
0041209D
- (转)VS 反汇编方法及常用汇编…
- VS 反汇编方法及常用汇编指令介绍
- VS 反汇编方法及常用汇编指令介绍
- VS 反汇编方法及常用汇编指令介绍
- VS 反汇编方法及常用汇编指令介绍
- VS反汇编窗口
- VS的反汇编
- arm反汇编方法
- arm反汇编方法
- 使用VS反汇编调试
- 【转】反汇编工具
- BIN文件反汇编方法
- vs调试可开启反汇编
- vs中c++的反汇编分析
- VS中的反汇编代码学习
- 汇编反汇编
- 反汇编
- 反汇编
- 拷贝构造函数的参数类型必须是引用
- 堆和栈的区别(转帖)
- VC++调试大全
- C++命名规范
- #pragma 详解(转)
- (转)VS 反汇编方法及常用汇编…
- (转)汇编中各寄存器的作用
- C++中的虚函数表(转)
- Win7下从U盘安装CentOSo6.1的经验
- Win7+VMware Workstation环境…
- (转) OSI七层模型与TCP/IP五层模型
- Makefile 中:= ?= += =的区别(转)
- Win7&CentOS双系统问题解决
- 初级X编程(非常好的入门学习资料)