静态分析高级技术
知识点
本章内容为静态分析高级技术,知识点内容较多,很多知识点都是与x86体系结构下的指令等相关知识。
微指令|机器码:微指令层又称为固件,微指令只能在特定的电路上执行,其通常由更高的机器码层翻译而来,提供了访问硬件的接口;机器码层由操作码组成,操作吗是一些十六进制的数字,机器码一般由多条微指令实现,用于告诉底层硬件如何执行实际的代码。
逆向工程:逆向工程是将程序的二进制文件作为输入,由反汇编软件将其输出为汇编语言再进行分析的过程,汇编语言是一类语言的统称,例如x86、x64、SPARC、PowerPC、MIPS、ARM等。
内存:
一个程序的内存可以分为一下四个主要部分
1 |
|
指令:指令时汇编程序的构成块,格式如下:
助记符 | 目标操作数 | 源操作数 |
---|---|---|
mov | ecx | 0x42 |
操作码|字节序:每条指令使用操作码opcode
告诉CPU执行什么样的操作,反汇编器将操作码翻译为人类易读的指令,如下对比:
指令 | mov ecx | 0x42 |
---|---|---|
操作码 | B9 | 42 00 00 00 |
大端序|小端序:x86
架构使用小端字节序。数据的字节序指的是在一个数据项中,最高位(大端)还是最低位(小端)被排在第一位,一些恶意代码必须在网络通信时改变字节序,因为网络数据使用大端序,而x86
程序使用小端序,再大端序下,网络地址127.0.0.1
被表示为0x7f000001
,而在小端序下表示为0x1000007f
。
操作数:操作数说明指令要使用的数据,有以下三种类型:
- 立即数:操作数是一个固定的值。
- 寄存器:操作数指向寄存器。
- 内存地址:操作数指向一个内存地址,一般由方括号内包含值、寄存器或方程式组成,如
[eax]
寄存器:寄存器是可以被CPU使用的少量数据存储器,访问速度极快,寄存器分为以下四类:
- 通用寄存器,在CPU执行期间使用
- 段寄存器,用于定位内存节
- 状态标志,用于做出决定
- 指令指针,用于定位下一条要执行的指令
在x86环境下,这些寄存器的大小都为32位,有四个写寄存器可以以8位值的方式引用,应用示例如下:
1 |
|
通用寄存器:通用寄存器一般用于存储数据或者地址,但是一些寄存器并不通用,如乘法和除法指令只使用EAX
和EDX
,而EAX
一般也会作为存储程序返回值的寄存器。
标志寄存器:EFLAGES是一个标志寄存器,在x86架构中,他是32位的,每一位是一个标志,在运行时每一位要不么置位,要么清零,常见的标志如下:
- ZF:当一个运算结果等于0时,ZF为1,否则为0
- CF:当一个运算的结果相对于目标操作数太大或太小时,CF为1,否则为0
- SF:当一个运算的结果为负数,SF为1,否则为0,且当运算结果的最高位为1,SF也为1
- TF:TF用于调试,当TF为1时,x86处理器每次只执行一条指令
EIP:EIP寄存器保存了程序将要执行的下一条指令的地址。、
NOP指令:nop
指令即空指令,实际上此指令是xchg eax
的一个伪名。
栈:用于函数的内存,局部变量,流程控制结构等存储在栈中,栈智能用于短期存储,其主要用途是管理函数调用之间的数据交换。不同的编译器对这种管理方法实现的方式有所不同,但是大部分常见约定都使用相对EBP的地址来引用局部变量和参数。
函数调用:在函数调用时,最常见的调用方式是cdecl
,调用函数的流程一般如下:
- 使用push将参数压入栈中
- 使用call memory_location来调用函数,当前指令地址被压入栈中
- 分配空间给局部变量,同时基地址EBP也被压入栈中
- 函数工作
- 恢复栈,调整ESP来释放局部变量占用的空间,从栈中弹出EBP
- 函数通过ret指令返回,从栈中弹出先前存储的EIP中的值给EIP,程序从原来调用的地方继续执行
- 调整栈,以移除之前压入的参数
汇编指令:常见的汇编指令数量较多,可从网上参阅。
C语言主函数和主函数参数:一个标准的C程序的主函数通常有两个参数:
1 |
|
参数argc
和argv
在运行时决定。其中参数argc
是一个整数,说明了命令行中参数的个数。参数argv
是一个字符串数据指针,指向了所有命令行参数。
课后练习
本章无课后练习。
本章结束🎊
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!