逆向练习2

每日逆向的理解和积累。

汇编阅读练习

练习1

1.汇编代码及解释如下:

  • main函数

  • age函数

2.对应c语言源码如下:

练习2

1.汇编代码及解释如下:

  • main函数

  • fact函数

2.对应c语言源码如下:

3.补充:该程序的目的是求阶乘。

练习3-1

1.汇编代码及解释如下:

  • main函数

2.对应c语言源码如下:

3.补充:该程序中值得注意的是对于二维数组中的每个元素的地址的计算和确定。这里是通过逻辑左移shl来实现的,具体如上图中红线框出来的部分。本题中对角线上的3个元素的地址分别为:基址、基址+16h、基址+32h(这里由于二维数组是int型的,每个元素占4个字节)。

练习3-2

1.汇编代码及解释如下:

  • main函数

  • fun函数

2.对应c语言源码如下:

问题

做到这里的时候,意识到一个很神奇的问题,对于每个练习的c源程序,我都用的是同样的命令gcc -o test test.c编译生成可执行文件,但是生成的可执行文件中,有的却开启了stack canary的保护机制,这是为什么?

gcc -o test test.c    // 默认情况下,不开启Canary保护
gcc -fno-stack-protector -o test test.c  //禁用栈保护
gcc -fstack-protector -o test test.c   //启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码
gcc -fstack-protector-all -o test test.c //启用堆栈保护,为所有函数插入保护代码

到目前为止的8到题目,开启canary保护的情况如下:

开启了canary保护的:1、3、4、5、8.1
没开启的:2、6、7、8.2

可能的猜测如下:

代码比较少的就不开启?
还是有某些函数如printfscanf(或者存在用户输入)的就要开启保护?
经过对这些题目的共同点的分析,觉得应该是存在用户输入(如scanf)就会开启canary保护机制;
同时由于1中并不存在用户输入还是开启了保护机制,而1的源代码如下,故可能是因为存在结构体(或是数组的定义长度超过了某个值)而开启的保护。

练习4

1.汇编代码及解释如下:

  • main函数

  • reverse函数

2.对应c语言源码如下:

3.补充1:该程序也开启了canary保护,由此猜测涉及到字符串处理的程序也会开启保护。

4.补充2:注意在分析过程中对于字符串变量的具体值识别出错,结合源码可发现对于ida解析出来的字符串,应该依次倒过来,然后再进行组合得到完整字符串。

5.补充3:注意对于reverse函数的分析中,红框框起来的部分分析出错,此处sar是算术右移指令,sar eax,1相当于将eax中的值/2,所以这里的操作其实是(字符串长度/2-1)而不是图中分析。

6.补充4:一般一个变量中存放的是内存地址,那么其可能为指针变量,如本题中的[rbp-0x8]

练习5-1

1.汇编代码及解释如下:

  • main函数

2.对应c语言源码如下:

3.补充:该程序就并未开启canary保护机制。在该程序中主要注意源码中红框框起来的两个num变量在汇编层面的定义以及赋值变化。

练习5-2

1.汇编代码及解释如下:

  • main函数

2.对应c语言源码如下:

3.补充:该程序就并未开启canary保护机制。在该程序中主要注意源码中红框框起来的变量i的定义方式,其是存在寄存器ebx中的。