逆向so文件调试工具IDA基础知识点
1.界面介绍
https://www.freebuf.com/column/157939.html
2.IDA常用快捷键
切换文本视图与图表视图
空格键
返回上一个操作地址
ESC
搜索地址和符号
G
对符号进行重命名
N
常规注释
'冒号键
可重复注释
分号键
添加标签
Alt+M
查看标签
Ctrl+M
查看段的信息
Ctrl+S
查看交叉应用
X
查看伪代码
F5
搜索文本
Alt+T
搜索十六进
Alt+B
3.命令快捷键
F2:下断点
F3:打开程序
F4:运行到当前光标处(可应用在跳出 循坏)
F7:单步步入(进函数)
F8:单步 步过
F9;运行
F10:打开反汇编选项菜单快捷键
F12:暂时停止
Ctrl+F2:重新开始
Art+F2:结束跟踪
Shift+F2:打开附加选项窗口
Shift+F4:打开条件对话窗
Shift+F7:与F7相同,但是如果被调试程序发生异常而中止,调试器会首先尝试步入被调试程序指定的异常处理
Ctrl+F7:自动步入,在所有的函数调用中一条一条地执行命令,断点或异常时,自动 停止
Shift+F8与F8相同,但是如果被调试程序发生异常而中止,调试器会首先尝试步过被调试程序指定的异常处理
Ctrl+F8:自动步过,一条一条的执行命令,程序到达断点,或者发生异常时,自动步过过程都会停止
Shift+F9:与F9相同,但是如果被调试程序发生异常而中止,调试器会首先尝试执行被调试程序指定的异常处理
Ctrl+F9 :执行直到返回,跟踪程序直到遇到返回,在此期间不进入子函数也不更新CPU数据。因为程序是一条一条命令执行的,所以速度可能会慢一些。按Esc键,可以停止跟踪。
Alt+F9:执行直到返回到用户代码段,跟踪程序直到指令所属于的模块不在系统目录中,在此期间不进入子函数也不更新CPU数据。按Esc键,可以停止跟踪。
Ctrl+F11:Run跟踪步入,一条一条执行命令,进入每个子函数调用,并把寄存器的信息加入到Run跟踪的存储数据中。Run跟踪不会同步更新CPU窗口。
Ctrl+F12 :Run跟踪。步过,一条一条执行命令,但是不进入子函数调用,并把寄存器的信息加入到Run跟踪的存储数据中。Run跟踪不会同步更新CPU窗口。
Art+C:快速回到主界面
Alt+B:显示断点窗口
Alt+E:显示模块窗口
Art+L:显示记录窗口
Alt+M:显示内存窗口
Alt+O:显示调试选项窗口
Alt+K:显示呼叫堆栈
Ctrl+E:编辑机器码
Ctrl+G:输入跟随地址
Ctrl+N:查找名称标志,选择你要下断的内容
Ctrl+S:打开查找命令次序窗口
Ctrl+P:显示补丁窗口
Ctrl+F9:返回到跟踪
Ctrl+F8:自动步进扫描,按F12可停止
Ctrl+F7:同上,功能略有不同
Ctrl+F6:回到OL主窗口
4.命令
CALC :判断表达式
WATCH :添加监视表达式
AT / FOLLOW:(Disassemble at address)在地址进行反汇编
ORIG :(Disassemble at EIP )反汇编于 EIP
DUMP :(Dump at address )在地址转存
DA :(Dump as disassembly)转存为反汇编代码
DB :(Dump in hex byte format )转存在十六进制字节格式
DC :(Dump in ASCII format )转存在 ASCII 格式
DD :(Dump in stack format )转存在堆栈格式
DU :(Dump in UNICODE format )转存在 UNICODE 格式
DW :(Dump in hex word format )转存在十六进制字词格式
STK :(Go to address in stack )前往堆栈中的地址
AS + 地址 + 字符串 :(Assemble at address )在地址进行汇编
L + 地址 + 字符串 :(Label at address )在地址进行标号
C + 地址 + 字符串 :(Comment at address )在地址进行注释
BP :(Break with condition )使用条件中断
BPX :(Break on all calls )中断在全部调用
BPD :(Delete break on all calls )清除位于全部调用的断点
BC :(Delete breakpoint )清除断点
MR :(Memory breakpt on access )内存断点于访问时
MW :(Memory breakpt on write )内存断点于写入时
MD :(Remove memory breakpoint )清除内存断点
HR :(HW break on access )硬件中断在访问
HW :(HW break on write )硬件中断在写入
HE :(HW break on execution )硬件中断在执行
HD :(Remove HW breakpoint )清除硬件断点
STOP :(Pause execution )暂停执行
RUN :(Run program )运行程序
GE :(Run and pass exception )运行和通过例外
SI :(Step into )步入
SO :(Step over )步过
TI :(Trace in till address )跟踪进入直到地址
TO :(Trace over till address)跟踪步过直到地址
TC :(Trace in till condition)跟踪进入直到条件
TOC :(Trace over till condition )跟踪步过直到条件
TR :(Till return)直到返回
TU :(Till user code )直到用户代码
LOG :(View Log window )查看记录窗口
MOD :(View Modules window )查看模块窗口
MEM :(View Memory window )查看内存窗口
CPU :(View CPU window )查看 CPU 窗口
CS :(View Call Stack )查看 Call 堆栈
BRK :(View Breakpoints window )查看断点窗口
HELP :(Help on API function )API 函数的帮助
DASM :(Disassemble immediate opcode )反汇编直接的机器码
FR :(Find reference to selected command/address)查找参考到选定的命令/地址
AC :(Analyse code )分析代码
SN :(Search for Name(label) in current module )在当前模块中搜索名称(标号)
5.二进制命令
参考https://blog.csdn.net/qq_36982160/article/details/82950848
简单传送指令
指令 |
中文名 |
格式 |
解释 |
备注 |
MOV |
传送指令 |
MOV DEST,SRC |
DEST<=SRC |
|
XCHG |
交换指令 |
XCHG OPER1,OPER2 |
把操作数oper1的内容与操作数oper2的内容交换 |
oper1和oper2可以是通用寄存器或存储单元,但不能同时是操作单元,也不能是立即数。 |
简单加减指令
指令 |
中文名 |
格式 |
解释 |
备注 |
ADD |
加法指令 |
ADD DEST,SRC |
DEST<=DEST SRC |
两数相加 |
SUB |
减法指令 |
SUB DEST,SRC |
DEST<=DEST-SRC |
两数相减 |
INC |
加1指令 |
INC DEST |
DEST<=DEST 1 |
|
DEC |
减1指令 |
DEC DEST |
DEST<=DEST-1 |
|
NEG |
取补指令 |
NEG OPRD |
OPRD=0-OPRD |
对操作数取补(相反数) |
状态标志
标志 |
中文名 |
解释 |
CF(carry flag) |
进位标志 |
主要反映算术运算是否产生进位或借位,若产生,则CF=1,否则CF=0 |
ZF |
零标志 |
反映运算结果是否为0 |
SF(sign flag) |
符号标志 |
根据运算结果的最高位,若最高位为1则SF为1,否则为0,反映了有符号数运算结果的正负(0正1负) |
OF(overflow flag) |
溢出标志 |
反映有符号数运算结果是否产生溢出,是置1,否置0 |
PF(parity flag) |
奇偶标志 |
偶数置1奇数置0 |
AF |
辅助进位标志 |
|
状态标志操作指令
指令 |
中文名 |
格式 |
解释 |
CLC(clear carry flag) |
清进位标志指令 |
CLC |
使进位标志CF为0 |
STC(set carry flag) |
置进位标志指令 |
STC |
使进位标志CF为1 |
CMC(complement carry flag) |
进位标志取反指令 |
CMC |
使进位标志CF取反 |
LAHF(load status flags into AH register) |
获取状态标志操作指令 |
LAHF |
把位于标志寄存器低端的5个状态标志位(p26图2.3)信息同时送到寄存器AH的对应位 |
SAHF(store AH into Flags) |
设置状态标志操作指令 |
SAHF |
对标志寄存器中的低8位产生影响,使得状态标志位SF、ZF、AF、PF和CF分别成为来自寄存器AH中对应位的值,但保留位(位1、位3、位5)不受影响 |
带进位加减指令
指令 |
中文名 |
格式 |
解释 |
备注 |
ADC(add with carry) |
带进位加法指令 |
ADC DEST,SRC |
DEST<=DEST SRC CF |
与add指令不同之处是要再加上进位标志cf的值 |
SBB(substraction with borrow) |
带借位减法 |
SBB DEST,SRC |
DEST<=DEST-(SRC CF) |
与sub指令不同之处是要再减上借位标志cf的值 |
取有效地址指令
指令 |
中文名 |
格式 |
解释 |
备注 |
LEA(load effective address) |
取有效地址指令 |
LEA REC,OPRD |
把操作数oprd的有效地址传送到操作数rec,源操作数oprd必须是一个存储器操作数,目的操作数rec必须是一个16位或32位的通用寄存器 |
与mov指令的区别:mov:移动地址中的值lea:将地址进行移动 |
堆栈和堆栈操作
指令 |
中文名 |
格式 |
解释 |
备注 |
PUSH |
进栈指令 |
PUSH SRC |
把源操作数src压入堆栈 |
源操作数src可以是32位通用寄存器、16位通用寄存器和段寄存器,也可以是双字存储单元或者字符存储单元,还可以是立即数 |
POP |
出栈指令 |
POP DEST |
从栈顶弹出一个双字或字数据到目的操作数 |
如果目的操作数是双字的,那么就从栈顶弹出一个双字数据,否则,从栈顶弹出一个字数据,出栈至少弹出一个字(16位) |
PUSHA |
16位通用寄存器全进栈指令 |
PUSHA |
将所有8个16位通用寄存器的内容压入堆栈 |
压入顺序是AX CX DX BX SP BP SI DI,然后对战指针寄存器SP的值减16,所以SP进栈的内容是PUSHA指令执行之前的值 |
POPA |
16位通用寄存器全出栈指令 |
POPA |
以PUSHA相反的顺序从堆栈中弹出内容,从而恢复PUSHA之前的寄存器状态 |
SP的值不是由堆栈弹出的,而是通过增加16来恢复 |
PUSHAD |
32位通用寄存器全进栈指令 |
PUSHAD |
将所有8个32位通用寄存器的内容压入堆栈 |
压入顺序是EAX ECX EDX EBX ESP EBP ESI EDI,然后对战指针寄存器SP的值减32,所以SP进栈的内容是PUSHAD指令执行之前的值 |
POPAD |
32位通用寄存器全出栈指令 |
POPAD |
以PUSHAD相反的顺序从堆栈中弹出内容,从而恢复PUSHAD之前的寄存器状态 |
ESP的值不是由堆栈弹出的,而是通过增加32来恢复 |
过程调用和返回指令
指令 |
中文名 |
格式 |
解释 |
备注 |
CALL |
过程调用指令 |
CALL LABEL |
段内直接调用LABEL |
与jmp的区别在于call指令会在调用label之前保存返回地址(call 中return之后主程序还可以继续执行,jmp 当label执行完毕后不能返回主程序继续执行) |
RET |
段内过程返回指令 |
RET |
使子程序结束,继续执行主程序 |
|
算术逻辑运算指令
指令 |
中文名 |
MUL |
无符号数乘法指令 |
IMUL |
有符号数乘法指令 |
IMUL DEST,SRC |
有符号数乘法指令 |
IMUL DEST,SRC1,SRC2 |
有符号数乘法指令 |
DIV |
无符号数除法指令 |
IDIV OPRD |
有符号数除法指令 |
符号拓展指令
指令 |
中文名 |
格式 |
解释 |
CBW |
字节转化为字指令 |
CBW |
把寄存器AL中的值符号拓展到寄存器AH |
CWD |
字转化为双字指令 |
CWD |
把寄存器AX中的值符号拓展到寄存器DX |
CDQ |
双字转化为四字指令 |
CDQ |
把寄存器EAX中的值符号拓展到EDX |
CWDE |
字转化为双字指令 |
CWDE |
把AX中的值符号拓展到EAX的高16位 |
拓展传送指令
指令 |
中文名 |
格式 |
解释 |
备注 |
MOVSX |
符号拓展传送指令 |
MOVSX DEST,SRC |
把源操作数SRC符号拓展后送至目的操作数DEST |
src可以是通用寄存器或者存储单元,但是dest只能是通用寄存器(零拓展传送指令不会改变源操作数,也不影响标志寄存器的状态) |
MOVZX |
|
MOVZX DEST,SRC |
把源操作数SRC零拓展后送至目的操作数DEST |
零拓展传送指令不会改变源操作数,也不影响标志寄存器的状态 |
逻辑运算指令
指令 |
中文名 |
格式 |
解释 |
备注 |
NOT |
否运算指令 |
NOT OPRD |
把操作数OPRD按位取反,然后送回OPRD |
|
AND |
与运算指令 |
AND DEST,SRC |
把两个操作数进行与运算之后结果送回DEST |
同1得1,否则得0 |
OR |
或运算指令 |
OR DEST,SRC |
把两个操作数进行或运算之后结果送回DEST |
同0得0,否则得1 |
XOR |
异或运算 |
XOR DEST,SRC |
把两个操作数进行异或运算之后结果送回DEST |
相同得0不同得1 |
TEST |
测试指令 |
TEST DEST,SRC |
与AND指令类似,将各位相与,但是结果不送回DEST,仅影响状态位标志,指令执行后,ZF、PF、SF反映运算结果,CF和OF被清零 |
通常用于检测某些位是否为1,但又不希望改变操作数的值 |
移位指令
一般移位指令
指令 |
中文名 |
格式 |
解释 |
备注 |
SAL |
算术左移 |
SAL OPRD,count |
把操作数oprd左移count位,右边补0 |
与shl指令一样 通过截取count的低5位,实际的移位数被限于0到31之间。 |
SHL |
逻辑左移 |
SHL OPRD,count |
把操作数oprd左移count位,右边补0 |
与sal指令一样 通过截取count的低5位,实际的移位数被限于0到31之间。 |
SAR |
算术右移 |
SAR OPRD,count |
把操作数oprd右移count位,同时每右移一位,左边补符号位,移出的最低位进入标志位CF |
通过截取count的低5位,实际的移位数被限于0到31之间。 |
SHR |
逻辑右移 |
SHR OPRD,count |
把操作数oprd右移count位,左边补0,移出的最低位进入标志位CF |
通过截取count的低5位,实际的移位数被限于0到31之间。 |
循环移位指令
指令 |
中文名 |
格式 |
解释 |
备注 |
ROL |
左循环移位指令 |
ROL OPRD,count |
|
通过截取count的低5位,实际的移位数被限于0到31之间。 |
ROR |
右循环移位指令 |
ROR OPRD,count |
|
通过截取count的低5位,实际的移位数被限于0到31之间。 |
RCL |
带进位左循环移位 |
RCL OPRD,count |
相当于CF在最高位参与循环移位 |
大循环左移 通过截取count的低5位,实际的移位数被限于0到31之间。 |
RCR |
带进位右循环移位 |
RCR OPRD,count |
相当于CF在最高位参与循环移位 |
大循环右移 通过截取count的低5位,实际的移位数被限于0到31之间。 |
循环指令
指令 |
中文名 |
格式 |
解释 |
备注 |
LOOP |
计数循环指令 |
LOOP LABEL |
使ECX的值减1,当ECX的值不为0的时候跳转至LABEL,否则执行LOOP之后的语句 |
|
LOOPE |
等于循环指令 |
LOOPE LABEL |
使ECX的值减1,如果结果不等于0并且零标志ZF等于1(表示相等),那么就转移到LABEL,否则执行LOOPE之后的语句 |
|
LOOPZ |
零循环指令 |
LOOPZ LABEL |
使ECX的值减1,如果结果不等于0并且零标志ZF等于1(表示相等),那么就转移到LABEL,否则执行LOOPZ之后的语句 |
|
LOOPNE |
不等于循环指令 |
LOOPE LABEL |
使ECX的值减1,如果结果不等于0并且零标志ZF等于0(表示不相等),那么就转移到LABEL,否则执行LOOPNE之后的语句 |
|
LOOPNZ |
非零循环指令 |
LOOPNZ LABEL |
使ECX的值减1,如果结果不等于0并且零标志ZF等于0(表示不相等),那么9就转移到LABEL,否则执行LOOPNZ之后的语句 |
|
JECXZ |
计数转移指令 |
JECXZ LABEL |
当寄存器ECX的值为0时转移到LABEL,否则顺序执行 |
通常在循环开始之前使用该指令,所以循环次数为0时,就可以跳过循环体 |