IDA pro
网上可以找多许多讲解IDA pro的使用教程,想着自己能写一个尽量全一点的,于是补写了本片文章(本篇文章只讲解使用,默认大家都会下载与安装)
参考:
https://lazzzaro.github.io/2020/05/12/reverse-IDA/
https://www.cnblogs.com/Chary/p/17195663.html
页面介绍
静态分析界面
动调分析界面
常用快捷键
Shift+F12:查看所有字符串
F5:查看伪代码
Alt+T:查找字符串
空格:切换图形视图&汇编视图
/:在反编译后伪代码的界面中写下注释
x:对着某个函数、变量按该快捷键,可以查看它的交叉引用
n:改变量名
y:改变量类型
c:强转为汇编代码
d:改变数据类型,如:db,dw,dd
ctrl+F:查找函数
p:定义函数
u:取消定义
Shift+E:提取数据
Alt+T:文本搜索
g:跳转地址
IDA-Python
三种在IDA中使用脚本的方法:
第一种,直接按Shift+F2快捷键调出界面,也可以直接在菜单中选择命令脚本(File -> Script command);
第二种,写一个脚本文件直接进行引用(File -> Script file);
第三种,直接在IDA底部写命令。
IDAPython的三个独立模块:
idc: idc函数的兼容模块,包含IDA内置函数声明和内部定义
idautils: 实用函数模块
idaapi: 用于访问更多底层数据的模块
指令操作
import idc
import idaapi
import idautils
ea = idc.here();
print("当前模块基址为: {}".format(hex(idaapi.get_imagebase())))
print("当前的汇编语句为: {}".format(idc.GetDisasm(ea)))
print("当前的汇编指令为: {}".format(idc.print_insn_mnem(ea)))
print("当前的操作数为: {}".format(idc.print_operand(ea,0)))
print("当前的操作数值为: {}".format(idc.get_operand_value(ea,0)))
段操作
用于查看程序段的划分
import idc
import idaapi
import idautils
for seg in idautils.Segments():
segname = idc.get_segm_name(seg)
segstart = idc.get_segm_start(seg)
segend = idc.get_segm_end(seg)
print("段名 = {} 起始地址= {} 结束地址 = {} ".format(segname,hex(segstart),hex(segend)));
函数操作
import idc
import idaapi
import idautils
for seg in idautils.Segments():
segname = idc.get_segm_name(seg)
segstart = idc.get_segm_start(seg)
segend = idc.get_segm_end(seg)
print("段名 = {} 起始地址 = {} 结束地址 = {} ".format(segname,hex(segstart),hex(segend)));
if (segname == '.text'):
for funcaddr in Functions(segstart,segend):
funname = idc.get_func_name(funcaddr)
funend = idc.find_func_end(funcaddr)
funnext = idc.get_next_func(funcaddr)
funnextname = idc.get_func_name(funnext)
print("当前函数名 = {} 当前结束地址 = {} 下一个函数地址 = {} 下一个函数名 = {}".format(funname,hex(funend),hex(funnext),funnextname))
ea = idc.get_screen_ea()
funnextoffset = idc.get_func_off_str(ea)
print("当前选择地址距离当前函数的偏移为: {} ".format(funnextoffset))
搜索
多用于去除花指令,之后也会发布专门对花指令的文章
ea = here()
value = idc.find_binary(ea,SEARCH_DOWN,'8B 4D 08') #从ea位置向下查找 查找的二进制为8B 4D 08 返回查找到的地址
value1 = idc.find_code(ea,SEARCH_DOWN) #从ea查找找到ea下的第一行code代码地址
value2 = idc.find_data(ea,SEARCH_DOWN) #从ea查找找到ea下的第一行code数据
数据校验
import idc
ea = here()
value1 = idc.find_code(ea,SEARCH_DOWN)
print(hex(value1))
flag = ida_bytes.get_full_flags(value1) #获取标志
print(flag)
print(ida_bytes.is_code(flag)) #判断是否是代码传入标志,根据标志返回True/False
交叉引用
import idc
ea = here()
for i in CodeRefsTo(ea,False):
print(hex(i))
# 获取地址处引用位置。A调用B,对B函数地址使用此函数则找到A调用,返回列表,遍历列表则可以找出所有引用位置。参数1是ea也就是地址,参数2告诉IDA是否跟踪这些代码。
创建结构体
View -> Open subviews -> Local types,右键->Insert,即可输入结构体定义,示例如下:
struct hello
{
_BYTE a;
_BYTE c;
_WORD b;
};
如果要修改,选中相应行,右键->Edit 即可。
位操作
def LOBYTE(x): return x & 0xff
def HIBYTE(x): return (x >> 8) & 0xff
def LOWORD(x): return x & 0xffff
def HIWORD(x): return (x >> 16) & 0xffff
def LODWORD(x): return x & 0xffffffff
def HIDWORD(x): return (x >> 32) & 0xffffffff
提取数据
from ida_bytes import *
from idaapi import *
addr = 0x00404000
enc = []
for i in range(64//4):
enc.append(get_dword(addr + i * 4))
print(enc)
#[3036486489, 3653154923, 3598177203, 408905200, 1396350368, 645614189, 1318861428, 3625534240, 3046501746, 1445070236, 2433841867, 213678751, 3463276874, 699118653, 845347425, 3058494644]
处理SMC
from ida_bytes import *
addr = 0x00401890
for i in range(170):
patch_byte(addr + i,get_wide_byte(addr + i)^0x66)
动态调试
动调指令&操作
F7 | 单步步进 |
---|---|
F8 | 单步步过 |
F9 | 继续运行程序 |
F4 | 运行到光标所在行 |
Ctrl + F7 | 直到该函数返回时才停止 |
Ctrl + F2 | 终止一个正在运行的进程 |
F2 | 设置断点 |
双击ZF | 更改ZF标志寄存器,控制函数跳转 |
点击蓝色寄存器蓝色箭头 | 跳转至寄存器位置 |
本地动调
找到Local Windows debugger即可
远程动调
以使用kail远程动调Linux为例
一定要配置好后再看下面的步骤,这里我采用kail虚拟机
在ida目录下找到dbgsrv文件夹
选择对应的文件安装到我们的虚拟机当中,这里我们选择linux_server64
下面是ida中的操作
找到remote Linux debugger
点击绿色三角,yes
需要修改一些信息
kail中查看,获得ip地址,路径
配置完成后还差一步,必须在kail中运行我们的linux_server64
先下个断点,不然会闪退,找到free函数,这是清空存储的地方,在此下断点
成功进入动调模式
其他常用的操作
修改指令
修改16进制常用于去除花指令
IDA——Edit——Patch Program——Change word
修改内容
IDA——Edit——Patch Program——Assemble
手动修复栈指针
用于处理无法反编译
修复
对标红位置按 Alt+K 修改栈偏移:
Dump代码生成新脚本
使用IDA Pro调试程序时偶尔会遇到dump内存的需求,IDA Pro并没有直接提供内存dump的功能,但可以通过其提供的接口用脚本来实现相关功能
IDC脚本:
auto i,fp;
fp = fopen("d:\\dump.dex","wb");
for (i = start_address; i <= end_address; i++)
fputc(Byte(i),fp);
IDApython脚本:
import idaapi
data = idaapi.dbg_read_memory(start_address, data_length)
fp = open('d:\\dump', 'wb')
fp.write(data)
fp.close()
安装插件
IDApro支持插件功能,这里顺带介绍一些在CTF当中常用的插件
KeyPatch
下载:http://github.com/keystone-engine/keypatch
安装:
1.pip install keystone-engine
2.拷贝keypatch.py到IDA路径下的\plugins下即可
LazyIDA
作用:对数据进行处理
下载:http://github.com/P4ndaOs/LazyIDA
安装:
1.pip install PyQt5
2.拷贝LazyIDA.py到IDA路径下的\plugins下即可
FindCrypto
作用:找加密方式
下载:http://github.com/polymorf/findcrypt-yara
安装:
1.pip install PyQt5
2.拷贝findcrypt3.py和findcrypt3.rules到IDA路径下的\plugins下即可
E-Decompiler
作用:汉化,支持备注汉字函数
下载:http://github.com/fjqisba/E-Decompiler
安装:
1.pip install finger_sdk
2.拷贝finger.py到IDA路径下的\plugins下即可
使用说明:
在使用插件之前,需要给IDA7.5做一个patch,使之支持中文函数。详细情况见IDA7.5支持中文函数命名的办法
将E-Decompiler.dll和esig文件夹放置于插件目录,例如D:\IDA 7.5 SP3\plugins
运行IDA后,按Ctrl+3快捷键呼出插件菜单,运行插件即可。