《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.10-1.12)
2016-12-19 08:45
567 查看
1.10. 关于返回结果
x86中通常用EAX保存返回结果。如果是byte或char类型,用EAX的低位AL。如果是float,用FPU寄存器ST(0)。在ARM中,结果用R0寄存器返回。1.10.1. 使用返回void函数的结果
因为所有函数都有push eax call exit。所以如果返回值是void,就不会返回任何值。EAX中就会有随机值。在一个例子中,源代码中没有返回指令。汇编代码中没有push eax但有leave,所以此时EAX中是一些随机的值。我们可以发现返回值为14。这个14取决于调用函数之前的EAX值。
1.10.2. 如果不使用返回结果?
printf()有返回结果,但一般不使用。其实关键在于,不要让此前没有使用的返回值影响后面的执行(EAX中保留值)。
1.10.3. 返回一个结构
如果需要返回超过一个寄存器能保存的长度的东西(比如结构),就要使用指针。如果返回的是结构,那么就需要用一个指针指向它。在例子中,指向结构的是$T3853。
整个函数就是修改结构中各变量的值,通过访问它们存放的地址。
1.11. 指针
指针通常用来返回多个值。1.11.1. 全局变量例子
因为是全局变量,所以不需要返回值。这里使用指针修改全局变量的值。main函数一开始就会把两个全局变量product和sum的地址入栈,然后f1()就可以调用了。两个全局变量是在数据段分配的。product存在地址00873388,sum存在地址00873384。由于是未初始化的,载入内存之前是放在BSS,载入之后初始化为0,放在.data段。
使用Ollydbg可以看到两个地址的值在函数f1调用后就变化了。
1.11.2. 局部变量例子
f1的代码没有改变,main的代码改变了。不是直接push offset了,而是需要间接访问地址。其他感觉也没啥区别。1.11.3. 结论
f1可以在内存的任何地址返回指针。C++也是一样的。1.12. GOTO操作
GOTO被看作anti-pattern。其实很简单,反汇编的时候就是用一个JMP指令实现了这个功能。给了一个直接修改二进制代码patch然后到达skip me输出的例子。1.12.1. 死代码
没有执行的printf()也叫做死代码。如果开了优化的话,编译器就会把这部分代码省略。不过有趣的是在MSVC2012例子中,skip me字符串并没有被省去。相关文章推荐
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.7)
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.18)
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.8-1.9)
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.4)
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.15-1.17)
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.14)
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.1-1.3)
- 《Reverse Engineering for Beginners》 - 第1章 代码模式 - 笔记(1.5-1.6)
- 逆向基础8:循环结构-Reverse Engineering for Beginners
- 设计模式笔记:单例模式(C++代码)
- 创建型模式之 工厂、简单工厂、抽象工厂 简单图析和代码分析 笔记
- 论文笔记 TIE: Principled Reverse Engineering of Types in Binary Programs
- 工作笔记:单例模式的作用好处和代码
- 《大话设计模式》之--第1章 代码无错就是优?----简单工厂模式
- 通用代码学习笔记--单例模式
- 大话设计模式 第1章 代码无错就是优? 简单工厂模式
- Java 基础一些代码练习笔记(策略模式)
- 大话设计模式-第1章代码无错就是优?-简单的工厂模式
- Reverse engineering NAND Flash for fun and profit
- 【笔记】Eclipse and Java for Total Beginners—007