第6章 识别汇编中的C代码结构

Author Avatar
kabeor 4月 11, 2018

第6章 识别汇编中的C代码结构

6x1 全局与局部变量

全局变量可以被一个程序中的任意函数访问和使用
局部变量只能在它被定义的函数中访问

在反汇编代码中:

全局变量通过内存地址引用
局部变量通过栈地址引用

6x2 反汇编算术操作

C代码

mark

反汇编代码

mark

反汇编中,1~2行为赋值,3~5行为a=a+11,6~9行为a=a-b,10~12和13~15分别为a–和b++,16~19为b=a%3

6x3 识别if语句

C代码

mark

反汇编代码

mark

cmp比较var_4是否等于var_8

1. 用IDA Pro图形化分析函数

mark

2. 识别嵌套的if语句

C代码

mark

反汇编代码

mark
mark

6x4 识别循环

1. 找到for循环

C代码

mark

反汇编代码

mark

IDA Pro图形化

mark

汇编代码中,for循环可通过以下4个组件识别出来

初始化
比较
执行指令
递增/递减

2. 找到while循环

C代码

mark

反汇编代码

mark

汇编代码和for循环非常相似,唯一区别在于它缺少一个递增

6x5 理解函数调用约定

一个函数调用的伪代码

mark

最常见的三个调用约定:cdecl,stdcall,fastcall

1. cdecl

mark

在cdecl约定中,参数从右到左按序被压入栈,当函数完成时由调用者清理栈。

2. stdcall

stdcall是Windows API的标准调用约定。任何调用这些API的代码都不需要清理栈,清理栈由实现API函数代码的DLL程序所承担

3. fastcall

在fastcall中,前面的一些参数被传到寄存器,备用的寄存器是EDX和ECX。如果需要,剩下的参数再以从右到左的次序被加载到栈上。
使用fastcall比其他约定更高效,因为代码不需要涉及过多的栈操作

4. 压栈与移动

C代码

mark

adder函数汇编代码

mark

使用两种不同调用约定时一个函数调用的汇编代码

mark

6x6 分析switch语句

switch语句通常以两种方式被编译:

  1. if样式
  2. 跳转表

1. if样式

C代码

mark

反汇编代码

mark
mark

IDA Pro图形化

mark

2. 跳转表

C代码

mark

反汇编代码

mark

IDA Pro图形化

mark

6x7 反汇编数组

C代码

mark

反汇编代码

mark

数组a的基地址对应var_14,数组b的基地址对应dword_40A000.

ecx被作为索引使用,它被乘以4,来指明元素的大小,结果值与数组的基地址相加,来访问正确的数组元素。

6x8 识别结构体

C代码

mark

main函数反汇编代码

mark

test函数反汇编代码

mark
mark

arg_0是这个结构体的基地址,偏移0x14保存了结构中的字符,并且0x61对应ASCII中的字母a

6x9 分析链表遍历

C代码

mark
mark

反汇编代码

mark
mark

var_C对应i,它是这个循环的计数。
var_8对应head变量。
var_4是一个指向拥有两个被赋值变量结构体的指针

From https://kabeor.github.io/第6章 识别汇编中的C代码结构/ bye

This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接:https://kabeor.github.io/第6章 识别汇编中的C代码结构/