BetaMao

静态分析工具之ida

字数统计: 1.8k阅读时长: 7 min
2018/02/18 Share

啦啦啦啦~

ida

ida使用的是数据库文件,在第一次分析binary时会生成它,并且之后的几乎所有操作都是对数据库的操作上,并且它的操作是不可撤回的。

复合结构

数组

不算吧,反正在首地址Edit->Array即可定义,对于伪代码可以Y来定义

结构体

直接看就懂了,主要问题是笔记本的del和ins键在一起,可以使用fn+del新建。

另外也可以使用local types来新建结构体,包含头文件也可以,只是需要自己手动将其添加进数据窗口。

错误

Decompilation failure: XXXXXX: call analysis failed Please refer to the man

类似的错误是因为不能正确识别函数原型,手动设置下函数类型即可,对于间接调用设置调用地址。

positive sp value

IDA会自动分析SP,寄存器的变化量,由于缺少调用约定、参数个数等信息,导致分析出错,Option→Generala中设置显示Stack pointer,然后去检查对应地址附近调用的函数的调用约定以及栈指针变化

cannot convert to microcode

部分指令无法被反编译,最常见起因是函数中间有未设置成指令的数据字节,按c将其设置为指令即可,其次常见的是x86中的rep前缀,比如repXX jmp等,可以将该指令的第一个字节(repXX前缀的对应位置)patch为0x90(NOP)

stack frame is too big

在分析栈帧时,IDA出现异常,导致分析出错。找到明显不合常理的stackvariable offset,双击进入栈帧界面,按u键删除对应stack variable;如果是壳导致的原因,先用OD等软件脱壳;可能由花指令导致,请手动或自动检查并去除花指令

local variable allocation failed

分析函数时,有部分变量对应的区域发生重叠,多见于ARM平台出现Point、Rect等8字节、16字节、32字节结构时尤其多见;修改对应参数为多个int;修改ida安装目录下的hexrays.cfg中的HO_IGNORE_OVERLAPS

F5分析结果不正确

F5会自动删除其认为不可能到达的死代码,常见起因是一个函数错误的被标注成了noreturn函数,进到目前反编译结果,找到最后被调用的函数(被错误分析的函数),双击进入,再返回(迫使HexRays重新分析相应函数);如果上述方案不成功,那么进到被错误分析的函数,按Tab切换到反汇编界面,按Alt-P进入界面取消函数的Does not return属性

调试

直接把idadbg文件夹下对应调试器放在目标环境并运行,然后选择调试器,在debugger->process options下设置调试选项:

idc

ida提供的类C脚本语言,下面介绍也和C对照着来:

变量

变量区分大小写,需要先声明后使用,可在局部声明:

1
2
auto addr,reg,valu=0;     //局部变量
extern globalVar; //全局变量,不能在声明时赋值

对于整数全部作为有符号数处理。

表达式

支持C里面除+= /= *= -=外所有运算,支持字符串赋值复制及切片:

1
2
3
auto str1 = "what the fa?";
auto str2 = str1;
auto str3 = str2[3:];

语句

支持C里面除switch外所有语句,支持try/catch/throw

函数

在idc文件中支持定义函数(idc命令行不行),函数参数是传值还是传引用有调用者确定:

1
2
3
4
5
6
7
8
static printAB(a,b){
b = a * b;
Message(b);
}
auto a = 3;
auto b = 4;
printAB(a,b); //a=3,b=4
printAB(a,&b); //a=3,b=12

函数可以返回任意类型,若不显示指出返回0.

注释

插件

注意:安装插件时,若缺少dll最好去安装微软的运行时库而不要直接百度下载dll,不然将会被奇妙的问题带到奇妙的坑里

  • keypatch:用来修改程序,也可以用来搜索指令。
  • findcrypt:使用yara来发现加密算法中的常数
  • ida_clemency:肝clemency的
  • auto_re:增强标记
  • sk3wldbg:一个基于unicorn的调试器
  • lighthouse:神奇的工具,似乎很厉害,还不会用
  • IDASkins:皮肤
  • ida_nightfall:一种配色
  • idastealth:对抗反调试的(三年没更新了)
  • sig-database:用于识别静态编译的库函数
  • ida-signsrch:通过特征识别函数,能够识别很多压缩、多媒体、密码算法、字符串、反调试等算法
  • Ponce
  • idaemu:使用UNicorn进行模拟执行的,其实感觉和unicorn一样
  • diaphora:用于diff,可以比较F5的伪代码,现在已经支持7.0啦
  • bindiff:用于diff,目前只支持到6.8,但是很强大
  • FRIEND:指令、寄存器扩展与帮助文档
  • SimplifyGraph:一个十分好用的绘图工具,用于增强ida的流图界面
  • HexRaysPyTools:自动创建结构体,类与虚表
  • nao:简化一些没意义的汇编指令

例题

pwnhub-无题

想用这道题来练习下idc脚本编写,但是没找到原题的binary了,只能自己根据题目writeup描述自己写一个类似的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python
# coding=utf-8
import random
with open("outfile.c","w") as of:
protype = []
cases = []
funs = []
for i in range(1,30000 + 1):
protype.append("int func_%d();\n"%i)
cases.append("case %d:func_%d();break;\n"%(i,i))
bufLen = random.randrange(15,30)
inputableLen = 0x20+0x10 if i == 2314 else random.randrange(bufLen-10,bufLen-1)
funs.append("""
int func_%d(){
char buf[%d];
fread(buf,%d,1,stdin);
return fwrite("thank you for testing!!\\n",1,0x18,stdout);
}
"""%(i,bufLen,inputableLen))
of.write("""
#include<stdlib.h>
#include<stdio.h>
""")
of.writelines(protype)
of.write("""
int main(){
setvbuf(stdout,0,_IONBF,0);
setvbuf(stdin,0,_IONBF,0);
setvbuf(stderr,0,_IONBF,0);
int fun;
puts("~~~~~~~~~~fxxk ada~~~~~~~~~");
puts("fun No.?(1~3000):");
scanf("%d",&fun);
switch(fun){
""")
of.writelines(cases)
of.write("""
default:puts("err No.");
}
return 0;
}
""")
of.writelines(funs)

编译:

1
gcc -fno-stack-protector -no-pie outfile.c -o test

假装不知道漏洞在哪个函数里面,就写了下面的脚本来分析咯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
for addr in XrefsTo(0x00400550, flags=0):
func=addr.frm;
writesize=0;
buffersize=0;
while(1):
if(Byte(func)==0xBE and Byte(func+2)==0x00 and Byte(func+3)==0x00 and Byte(func+4)==0x00):
writesize=Byte(func+1)
elif(Byte(func)==0xBE and Byte(func+3)==0x00 and Byte(func+4)==0x00 and Byte(func+5)==0x00):
writesize=Word(func+1)
if(Byte(func)==0x48 and Byte(func+1)==0x83 and Byte(func+2)==0xEC):
buffersize=Byte(func+3)
break;
elif(Byte(func)==0x48 and Byte(func+1)==0x81 and Byte(func+2)==0xEC):
buffersize=Byte
break;
elif(Byte(func)==0x48 and Byte(func+1)==0x83 and Byte(func+2)==0xC4):
buffersize=Byte
break;
func-=1;
if(addr.frm-func > 0x40):
break;
if writesize==0 or buffersize==0:
print "not found!",hex(addr.frm)
elif buffersize<writesize:
print "find overflow",hex(addr.frm),"buffersize="+str(hex(buffersize)),"writesize="+str(hex(writesize))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.text:0000000000435E7B                 public func_2314
.text:0000000000435E7B func_2314 proc near ; CODE XREF: .text:00000000004099B0↑p
.text:0000000000435E7B
.text:0000000000435E7B ptr = byte ptr -20h
.text:0000000000435E7B
.text:0000000000435E7B ; __unwind {
.text:0000000000435E7B push rbp
.text:0000000000435E7C mov rbp, rsp
.text:0000000000435E7F sub rsp, 20h ;;buf 0x20
.text:0000000000435E83 mov rdx, cs:stdin@@GLIBC_2_2_5
.text:0000000000435E8A lea rax, [rbp+ptr]
.text:0000000000435E8E mov rcx, rdx ; stream
.text:0000000000435E91 mov edx, 1 ; n
.text:0000000000435E96 mov esi, 2Fh ; size ;;可写0x2f
.text:0000000000435E9B mov rdi, rax ; ptr
.text:0000000000435E9E call _fread
.text:0000000000435EA3 mov rax, cs:stdout@@GLIBC_2_2_5
.text:0000000000435EAA mov rcx, rax ; s
.text:0000000000435EAD mov edx, 18h ; n
.text:0000000000435EB2 mov esi, 1 ; size
.text:0000000000435EB7 lea rdi, aThankYouForTes ; "thank you for testing!!\n"
.text:0000000000435EBE call _fwrite
.text:0000000000435EC3 leave
.text:0000000000435EC4 retn
.text:0000000000435EC4 ; } // starts at 435E7B
.text:0000000000435EC4 func_2314 endp

可以看到溢出了0xf字节,比原题要多5字节

CATALOG
  1. 1. ida
    1. 1.1. 复合结构
      1. 1.1.1. 数组
      2. 1.1.2. 结构体
    2. 1.2. 错误
      1. 1.2.1. Decompilation failure: XXXXXX: call analysis failed Please refer to the man
      2. 1.2.2. positive sp value
      3. 1.2.3. cannot convert to microcode
      4. 1.2.4. stack frame is too big
      5. 1.2.5. local variable allocation failed
      6. 1.2.6. F5分析结果不正确
    3. 1.3. 调试
    4. 1.4. idc
      1. 1.4.1. 变量
      2. 1.4.2. 表达式
      3. 1.4.3. 语句
      4. 1.4.4. 函数
      5. 1.4.5. 注释
      6. 1.4.6.
    5. 1.5. 插件
  2. 2. 例题
    1. 2.1. pwnhub-无题