每日打卡3:HelloWorld

督促自己:2020-9-8

学习记录:

《逆向工程权威指南》上

Hello Word!

cl 1.cpp /Fa 1.asm

通过MSVC编译程序,/Fa选项将使编译器生成汇编指令清单文件,并指定汇编列表文件的文件名。

.exe 文件生成过程:先生成 .asm 文件,然后会生成 .obj文件,再将之链接为可执行文件 .exe。

在汇编指令清单里,所有函数(包括主函数)的函数体有标志性的函数序言和函数尾声。在函数的需要标志后就是call _printf指令。通过push,程序把字符串的指针推送如入栈,printf()就能调用栈里面的指针进行输出。

.text:0040102D                 call    _printf
.text:00401032                 add     esp, 4

在这之后的语句是为了释放数据栈,这里是32位所以为4,同理64位为8(可以理解为 pop 某寄存器)。在有些如Intel C++编译器中不适用add指令,使用POP ECX指令。

原因:1、有相同的功能内,修改ECX的值得同时是释放了栈空间;2、POP ECX对应的OPCODE(1字节)比ADD ESP的OPCODE(3字节)更短。

返回值由 ’XOR EAX,EAX ’ 或者 ’ SUB EAX,EAX '计算出来的,一般不用‘ mov eax,0 ’,因为异或运算的opcode较短。

在 GCC 编译中生成 Intel 语体的汇编列表文件可以使用GCC的选项 " -S-masm=intel"。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s7B0Ddgu-1599659106588)(C:%5CUsers%5CWEI%5CDesktop%5Cfile%5C%E7%9D%A3%E4%BF%83%E8%87%AA%E5%B7%B1%EF%BC%9A2020-9-8.assets%5Cimage-20200909141141067.png)]

此指令是为了让栈地址(ESP的值)想16字节边界对齐(成为16的整数倍),属于初始化的指令。

程序开始:
PUSH EBP
MOV EBP,ESP
程序结束
LEAVE
retn
-- LEAVE = MOV ESP,EBP ; POP EBP --

LEAVE指令是为了调整数据栈指针ESP,并将EBP的数值恢复到调用之前的的初始状态。

AT&T语体区别:

  • Intel格式:<指令><目标><源>

    赋值:=

    语体使用方括号[]

  • AT&T格式:<指令><源><目标>

    赋值:→

    寄存器前使用百分号(%)标记,立即数之前用美元符号($)标记

    语体使用圆括号()

    每个运算操作符都需要声明操作数据的类型

X86-64中所有物理寄存器都会被扩展为64位寄存器(通过以R-字头的名称调用)

MSVC的应用程序:

编译器会优先使用寄存器传递部分参数,再利用内存(数据栈)传递其余的参数。还会使用:RCX、RDX、r8、r9四个寄存器来存放函数参数。

Linux、BSD和Mac OS X系统的应用程序:

会优先使用RDI、RSI、RDX、RCX、R8、R9这六个寄存器传递函数所需的头6个参数,然后使用数据栈传递其余的参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gw9MaPY9-1599659106590)(C:%5CUsers%5CWEI%5CDesktop%5Cfile%5C%E7%9D%A3%E4%BF%83%E8%87%AA%E5%B7%B1%EF%BC%9A2020-9-8.assets%5Cimage-20200909152533435.png)]

ARM常用编译器:Keil

用Keil编译器把hello world程序编译为ARM指令集架构的汇编程序:

armcc.exe --aarm --c90 -O0 1.c

ARM模式的指令集中没有PUSH指令,只有Thumb模式里的指令集里才有“PUSH/POP”指令。

STMFD SP!,{R4,LR}   相当于  PUSH

“BL2printf”调用printf()函数。BL实施的具体操作实际上是:

  • 将下一条指令的地址,即地址OxC处“MOVRO,#0”的地址,写入LR寄存器。
  • 然后将printf()函数的地址写入PC寄存器,以引导系统执行该函数.

编译器通常帮助PC把某些指令强制变为“位置无关代码/position-independent code”。在(多数)
操作系统把程序加载在内存里的时候,OS分配给程序代码的内存地址是不固定的:但是程序内部既定指令和
数据常量之间的偏移量是固定的(由二进制程序文件决定)。这种情况下,要在程序内部进行指令寻址(例如
跳转等情况),就需要借助PC指针”。

CISC(复杂指令集)处理器与RISC(精简指令集)处理器在工作模式的区别:

当`printf()`完成工作之后,计算机必须知道返回地址,即它应当从哪里开始继续执行下一条指令。所以,
每次使用BL指令调用其他函数之前,都要把BL指令的下一个指令的地址存储到LR寄存器。

以Thumb模式编译:

armcc.exe --thmub --c90 -O0 1.c

Thmub模式特征:

  • Thmub模式程序的每条指令都对应着2个字节/16位的opcode。(包括BL跳转指令,BL和BLX指令成对出现)

ARM模式下优化:

指定编译选项  -O3可以启用优化选项-O3,防止代码冗余

Thmub-2模式下开启优化:

默认情况下,Xcode4.6.3会启用优化模式。

在Thmub模式下:BL和BLX指令对应的伪opcode有明显的32位指令特征,其对应的opcode都以0xFx或者0xEx开头。

。。。。

今日大扫除,待续。。。。

明日任务:完成9号任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值