学习汇编对我们分析程序有极大的帮助。
由于不同程序使用不同的编译器进行编译,在反编译生成伪代码的时候会有所差异,有些甚至会直接影响对程序的分析。
而汇编和机器码一一对应,不存在转化差异,我们就可以通过分析汇编代码来了解程序。
2.1 程序的编译
2.2 常用汇编指令
-
MOV
#eg: MOV DEST, SRC #把源操作数传送给目标 MOV EAX,1234H #执行结果$eax = 1234H MOV EBX, EAX #将$eax的值赋给$ebx MOV EAX, [00404011H] #[]表示取地址内的值 MOV EAX, [ESI]
-
LEA
#eg: LEA DEST, SRC #取有效地址,将源操作数有效地址传给目的操作数。注:现在的编译器已经不用他来传递有效地址了,现在的lea主要是计算 LEA RAX,[RBP-0x18] #将RBP-0x18的值传给RAX
-
ADD
#eg: ADD SRC, VALUE #加法指令,等效于:SRC += VALUE ADD EAX, 0x57 #EAX += 0x57
-
PUSH
#eg: PUSH VALUE #把目标值压栈,同时SP指针-1字长 PUSH 1234H #把1234H压入堆栈 PUSH EAX #把EAX的值压入堆栈
-
POP
#eg: POP DEST #将栈顶的值弹出至目的存储位置,同时SP指针+1字长 POP EAX #将栈顶的值弹出并赋值给$eax
-
CMP
#eg: CMP OPRD1,OPRD2 #比较两个操作数是否相等,本质上也是减法,但是不储存结果
-
JMP
#eg: JMP DEST #无条件跳转指令,可转到内存中任何程序段 JMP 4005a0 #跳转到0x4005a0
-
CALL
#eg: CALL DEST #调用其他函数 CALL 400510 #调用地址为0x400510的函数 #与JMP的区别 CALL会操作调用栈,JMP不会。这意味着JMP不会回到原处。
-
LEAVE
LEAVE #在函数返回时,恢复父函数栈帧的指令 等效于: MOV ESP, EBP POP EBP
-
RET
RET #在函数返回时,控制程序执行流返回父函数的指令 等效于: POP RIP #(这条指令实际是不存在的,不能直接向RIP寄存器传送数据)