汇编基础

通用寄存器

  • EAX:(针对操作数和结果数据的)累加器
  • EBX:(DS段的数据指针)基址寄存器
  • ECX:(字符串和循环操作的)计数器
  • EDX:(I/O指针)数据寄存器
  • ESI:(字符串操作源指针)源变址寄存器
  • EDI:(字符串操作目标指针)目的变址寄存器
  • EBP:(SS段中栈内数据指针)扩展基址指针寄存器[栈帧寄存器、栈底指针寄存器]
  • ESP:(SS段中栈指针)栈指针寄存器[指向栈顶]

段寄存器

  • CS:代码段寄存器
  • SS:栈段寄存器
  • DS:数据段寄存器
  • FS:数据段寄存器
  • ES:附加数据寄存器
  • GS:数据段寄存器

指令指针寄存器

  • EIP / RIP:保存CPU要执行的指令地址

程序状态与控制寄存器

  • EFLAGS:标志寄存器,32个位元的01控制
  • ZF(零标志器,运算结果为0时置1)
  • CF(进位标志,运算结果向最高位以上进位时置1)
  • OF(溢出标志)
  • AF(辅助进位标志,运算结果在第3位的时候置1)
  • SF(符号标志,有符号整型的符号位为1时置1)

常用指令

操作码 目的操作数 源操作数

  • PUSH/POP:压栈/出栈

  • PUSHA/POPA 、 PUSHAD/POPAD

  • MOV/CALL/RET/LEA/INT/EMD:传送 / 调用 / 返回 / 加载 / 中断 / 结束

  • CMP/TEST:比较/测试(结果丢弃,只修改标志位寄存器)

  • JMP系列跳转指令

    • JZ : 当零标志位(ZF)为 1 时跳转
    • JNZ : 当零标志位(ZF)为 0 时跳转
    • JG : 结果大于则跳转
    • JNG : 结果不大于则跳转
  • ADD/SUB/SHL/SHR/ROL/ROR:加 / 减 / 逻辑左移 / 逻辑右移 / 循环左移 / 循环右移

  • INC/DEC :加一 / 减一

  • MUL/IMUL:无符号乘法、整数乘法

  • DIV/IDIV:无符号除法、整数除法

  • AND/XOR/OR/NOT:与 / 异或 / 或 / 取反

栈帧

1
2
3
4
5
6
7
8
PUSH EBP          ;函数开始
MOV EBP,ESP ;将栈顶地址存入EBP中

.... ;函数执行,期间EBP地址不变

MOV ESP,EBP ;基准点地址给到ESP
POP EBP ;栈状态恢复,弹出EBP
RETN ;函

db,dw,dd

  • db定义字节类型变量,一个字节数据占1个字节单元,读完一个,偏移量加1

  • dw定义字类型变量,一个字数据占2个字节单元,读完一个,偏移量加2

  • dd定义双字类型变量,一个双字数据占4个字节单元,读完一个,偏移量加4

IDA

IDA常用快捷键

F系列【主要是调试状态的处理】

  • F2 添加/删除断点
  • F4 运行到光标所在位置
  • F5 反汇编
  • F7 单步步入
  • F8 单步跳过
  • F9 持续运行直到输入/断点/结束

shift系列【主要是调出对应的页面】

  • shift+F1 Local types
  • shift+F2 execute scripts【常用】
  • shift+F3 Functions
  • shift+F4 Names
  • shift+F5 Signatures
  • shift+F7 Segments
  • shift+F8 Segments registers
  • shift+F9 Structures
  • shift+F10 Enumerations
  • shift+F11 Type libraries
  • shift+F12 Strings【常用】
  • Shift+E 导出数据(提取数据)【常用】

单字符系列【基本是数据处理转换相关】

  • G 按地址查找
  • D 将字符串等元素转为数据
  • A 将数据转变为字符串类型
  • N 重命名(函数名、变量名等)
  • Y 修改变量类型等(比如int改char等等)
  • H 十六进制数据和十进制数据的快速转换
  • C code(将数据转变为汇编代码,分为自动和强制执行)
  • U undefined(将字符串转变为原始数据)
  • X 交叉引用(反汇编页面)
  • P 选中位置识别为函数

Ctrl、Alt系列

  • Ctrl+F 搜索【常用】
  • Ctrl+X 交叉引用(汇编页面)【常用】
  • Alt+T 查找Text
  • Ctrl+T 查找下一个text
  • Alt+C Next Code
  • Ctrl+D Next Data
  • Ctrl+Z 撤销
  • Ctrl+Shift+Z 恢复
  • Alt+K 修改堆栈值

else

  • / 添加注释(or 右键选择edit comment【常用】
  • \ hide cast,隐藏/显示一些变量类型注解
  • Ins 添加区块注释

IDA 常用脚本

IDC

1
2
3
//获取寄存器的值
auto eax = GetRegValue("EAX");
Message("%c",eax&0xff);
1
2
3
4
5
6
7
8
9
auto addr = 0x0;
auto i = 0;
for(i; i < 10; i = i+1)
{
//打印字节
Message("%x",Byte(addr+i));
//修改字节
PatchByte(addr+i,Byte());
}
1
2
3
4
5
6
7
8
//dump数据
auto i,fp;

fp = fopen("D:\\dump2","wb");

for(i=0x10;i<0x12;i++)
fputc(Byte(i),fp);
print("end");

python

1
2
3
4
5
6
7
8
# 导入头文件
from idaapi import *
# 获取寄存器的值
espval = get_reg_val('esp')
# 获取字节值ida_bytes.get_word()
value = ida_bytes.get_word(address)
# 获取16字节长度的数据
ida_bytes.get_bytes(address, 16)