啦啦啦啦~
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,不然将会被奇妙的问题带到奇妙的坑里
例题 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 import randomwith 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字节