标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-2955]   作者: 大猪 发表于: [2021-11-17]

本文共 [278] 位读者顶过

[出自:jiwo.org]

交互式反汇编器,简称为IDA。是目前最好的反汇编工具,常用于0day挖掘,逆向等领域,网上关于IDC脚本的说明少之又少,这里我就把我的一些常用使用技巧分享一下,在IDA中按下【shift + F2】可调出脚本编辑器,可以简单的学习一下IDA IDC脚本的编写与使用,IDC脚本借鉴的C语言的语法,所以其看起来很像。

简单的IF语句

#include <idc.idc> static main() { auto CurrAddress = ScreenEA(); if(CurrAddress == 0x401161) { Message("程序OEP => 0x%x \n",CurrAddress); } else { Message("没有扎到OEP \n"); } } 

for语句

#include <idc.idc> static main() { auto origEA,currEA,funcStart,funcEnd; origEA = ScreenEA(); // origEA = OEP 如果origEA 不在函数内则返回-1 funcStart = GetFunctionAttr(origEA,FUNCATTR_START); funcEnd = GetFunctionAttr(origEA,FUNCATTR_END); //Message("OEP: %x 起始地址: %x --> 结束地址: %x \n",origEA,funcStart,funcEnd); // NextHead 在currEA开始的位置寻找下一条指令的地址 for(currEA = funcStart; currEA != -1; currEA=NextHead(currEA,funcEnd)) { Message("--> %8x \n",currEA); } } 

while语句实现

#include <idc.idc> static main() { auto origEA,currEA,funcStart,funcEnd; origEA = ScreenEA(); // origEA = OEP 如果origEA 不在函数内则返回-1 funcStart = GetFunctionAttr(origEA,FUNCATTR_START); funcEnd = GetFunctionAttr(origEA,FUNCATTR_END); //Message("OEP: %x 起始地址: %x --> 结束地址: %x \n",origEA,funcStart,funcEnd); while(currEA != BADADDR) { Message("--> %x \n",currEA); currEA = NextHead(currEA,funcEnd); } } 

idc 函数

#include <idc.idc> // 定义一个函数 static OutPutAddress(MyString) { auto currAddress; currAddress = ScreenEA(); Message("%d \n",MyString); return currAddress; } static main() { auto ret = OutPutAddress(123); Message("%x \n",ret); } 

idc 获取函数名

#include <idc.idc> static main() { auto origEA,currEA,funcStart,funcEnd; origEA = ScreenEA(); // origEA = OEP 如果origEA 不在函数内则返回-1 funcStart = GetFunctionAttr(origEA,FUNCATTR_START); funcEnd = GetFunctionAttr(origEA,FUNCATTR_END); //Message("OEP: %x 起始地址: %x --> 结束地址: %x \n",origEA,funcStart,funcEnd); while(currEA != BADADDR) { Message("--> %x name: %s \n",currEA,GetFunctionName(currEA)); currEA = NextHead(currEA,funcEnd); } } 

idc 枚举所有函数

#include <idc.idc> static main() { auto currAddr,func,endSeg,funcName,counter; currAddr = ScreenEA(); func = SegStart(currAddr); endSeg = SegEnd(currAddr); Message("%x --> %x \n",func,endSeg); counter = 0; while(func != BADADDR && func < endSeg) { funcName = GetFunctionName(func); if(funcName != " ") { Message("%x --> %s \n",func,funcName); counter++; } func = NextFunction(func); } } 

枚举指定函数并输出

#include <idc.idc> static main() { auto currAddr,func,endSeg,funcName,counter; currAddr = ScreenEA(); func = SegStart(currAddr); endSeg = SegEnd(currAddr); Message("%x --> %x \n",func,endSeg); counter = 0; while(func != BADADDR && func < endSeg) { funcName = GetFunctionName(func); if(funcName != " ") { if(funcName == "__lock") { Message("%x --> %s \n",func,funcName); } counter++; } func = NextFunction(func); } } 

寻找特殊指令,并高亮显示

#include <idc.idc> static main(void) { auto head, op; head = NextHead(0x00000000, 0xFFFFFFFF); while ( head != BADADDR ) { op = GetMnem(head); Message("%x %s \n",head,op); if ( op == "jmp" || op == "call" ) SetColor(head, CIC_ITEM, 0x010187); if (op == "xor") SetColor(head, CIC_ITEM, 0x010198); head = NextHead(head, 0xFFFFFFFF); } } 

ida dump 将函数dump到本地。

#include <idc.idc> static getFuncName(ea) { auto funcName = get_func_name(ea); auto dm = demangle_name(funcName, get_inf_attr(INF_LONG_DN)); if(dm != 0) { funcName = dm; } return funcName; } static functionDump(ea) { auto funcName = 0; auto end = 0x0; auto file_open = get_idb_path()[0:-4] + "_dump.log"; auto stream = fopen(file_open, "w"); auto peekAhead; while( ea != BADADDR ) { ea = NextFunction(ea); peekAhead = NextFunction(ea); end = FindFuncEnd(ea); funcName = getFuncName(ea); if(peekAhead == BADADDR) { fprintf(stream, "{ 0x%X, 0x%X, \"%s\" }\n", ea, end, funcName); ea = peekAhead; continue; } end = peekAhead - 1; fprintf(stream, "{ 0x%X, 0x%X, \"%s\" }\n", ea, end,funcName); } fclose(stream); } static main() { functionDump(0x40000); } 

全量反汇编:

#include <idc.idc> static main(void) { auto decode = 0x401000; auto xref; for(xref = RfirstB(decode); xref != BADADDR; xref = RnextB(decode,xref)) { Message("xref: %x\n",xref); auto i = 0; auto inst = xref; auto op; while((i < 100) ) { inst = FindCode(inst,0x00); // flag set to backwards op = GetDisasm(inst); // get Message("%x --> %s \n",inst,op); i++; } } } 

查找特定指令片段

#include <idc.idc> static main() { auto currAddr,startSeg,endSeg; currAddr = ScreenEA(); startSeg = SegStart(currAddr); endSeg = SegEnd(currAddr); Message("OEP = %x 起始地址: %x 结束地址: %x \n",currAddr,startSeg,endSeg); while(startSeg < endSeg) { auto op = GetDisasm(startSeg); // 查找第一条指令 if(strstr(op,"push    esi")==0) { startSeg++; op = GetDisasm(startSeg); if(strstr(op,"push    edi")) { Message("特征: %x \n",startSeg-1); } } startSeg++; } } 

全局数组操作: 数组是全局的,并写入数据库,白嫖完了,一定得释放。

#include <idc.idc> static main() { // 创建数组元素 auto array_ptr = CreateArray("array"); // 获取数组指针 auto ptr = GetArrayId("array"); Message("获取到的操作指针: %x \n",ptr); // 设置两个字符串变量 SetArrayString(ptr,0,"hello"); SetArrayString(ptr,1,"lyshark"); // 设置两个整数变量 SetArrayLong(ptr,2,100); SetArrayLong(ptr,3,200); // 如果提取字符串使用 AR_STR 标记 ,提取整数使用 AR_LONG auto st = GetArrayElement(AR_STR,ptr,0); auto st1 = GetArrayElement(AR_STR,ptr,1); Message("提取字符串变量: %s %s !\n",st,st1); auto lo = GetArrayElement(AR_LONG,ptr,2); Message("提取整数变量: %d \n",lo); // 删除数组的0号元素 DelArrayElement(AR_STR,ptr,0); // 注销整个数组 DeleteArray(ptr); } 

字符串处理函数:

#include <idc.idc> static main() { // 格式化字符串,类似于sprintf auto name = form("hello %s","lyshark"); Message("格式化后的内容: %s \n",name); Message("十六进制转为整数: %d \n",xtol("0x41")); Message("十进制100转为八进制: %d \n",ltoa(100,8)); Message("十进制100转换二进制: %d \n",ltoa(100,2)); Message("字符A的ASCII: %d \n",ord("A")); Message("计算字符串长度: %d \n",strlen("hello lyshark")); // 在著字符串中寻找子串 auto main = "hello lyshark"; auto sub = "lyshark"; Message("寻找子串: %d \n",strstr(main,sub)); } 

反汇编函数:

#include <idc.idc> static main() { // 索索特征码 auto code = FindBinary(0x401020,1,"55 8B EC"); Message("%x \n",code); // 反汇反汇编代码 code = GetDisasm(0x401000); Message("%s \n",code); // 反汇 位于地址处的指令 code = GetMnem(0x401000); Message("%s \n",code); // 反汇opcode code = GetOpnd(0x401070,0); Message("%s \n",code); } 

枚举函数(枚举栈帧)

#include <idc.idc> static main() { auto addr,args,end,locals,frame,firstArg,name,ret; for(addr = NextFunction(addr); addr != BADADDR; addr = NextFunction(addr)) { name = Name(addr); end = GetFunctionAttr(addr,FUNCATTR_END); locals = GetFunctionAttr(addr,FUNCATTR_FRSIZE); // 得到栈帧大小 frame = GetFrame(addr); // 栈中保存返回地址偏移量 ret = GetMemberOffset(frame," r"); if(ret == -1)continue; firstArg = ret +4; args = GetStrucSize(frame) - firstArg; Message("函数: %s 开始: 0x%x 结束: 0x%x 大小: %d bytes 栈帧: %d bytes (%d args) \n",name,addr,end,locals,args,args/4); } } 

检索交叉引用(全部):

#include <idc.idc> static main() { auto func,end,target,inst,name,flags,xref; flags = SEARCH_DOWN | SEARCH_NEXT; func = GetFunctionAttr(ScreenEA(),FUNCATTR_START); if(func != -1) { name =Name(func); end = GetFunctionAttr(func,FUNCATTR_END); for(inst = func;inst < end; inst = FindCode(inst,flags)) { for(target = Rfirst(inst);target != BADADDR; target = Rnext(inst,target)) { xref = XrefType(); if(xref == fl_CN || xref == fl_CF) { Message("%s call -> %sfrom --> %x \n",name,Name(target),inst); } } } } } 


if

#include <idc.idc> static main() { auto CurrAddress = ScreenEA(); if(CurrAddress == 0x401161) { Message("程序OEP => 0x%x \n",CurrAddress); } else { Message("没有扎到OEP \n"); } } 

for

#include <idc.idc> static main() { auto origEA,currEA,funcStart,funcEnd; origEA = ScreenEA(); // origEA = OEP 如果origEA 不在函数内则返回-1 funcStart = GetFunctionAttr(origEA,FUNCATTR_START); funcEnd = GetFunctionAttr(origEA,FUNCATTR_END); //Message("OEP: %x 起始地址: %x --> 结束地址: %x \n",origEA,funcStart,funcEnd); // NextHead 在currEA开始的位置寻找下一条指令的地址 for(currEA = funcStart; currEA != -1; currEA=NextHead(currEA,funcEnd)) { Message("--> %8x \n",currEA); } } 

while语句实现

#include <idc.idc> static main() { auto origEA,currEA,funcStart,funcEnd; origEA = ScreenEA(); // origEA = OEP 如果origEA 不在函数内则返回-1 funcStart = GetFunctionAttr(origEA,FUNCATTR_START); funcEnd = GetFunctionAttr(origEA,FUNCATTR_END); //Message("OEP: %x 起始地址: %x --> 结束地址: %x \n",origEA,funcStart,funcEnd); while(currEA != BADADDR) { Message("--> %x \n",currEA); currEA = NextHead(currEA,funcEnd); } } 

idc 函数

#include <idc.idc> // 定义一个函数 static OutPutAddress(MyString) { auto currAddress; currAddress = ScreenEA(); Message("%d \n",MyString); return currAddress; } static main() { auto ret = OutPutAddress(123); Message("%x \n",ret); } 

idc 获取函数名

#include <idc.idc> static main() { auto origEA,currEA,funcStart,funcEnd; origEA = ScreenEA(); // origEA = OEP 如果origEA 不在函数内则返回-1 funcStart = GetFunctionAttr(origEA,FUNCATTR_START); funcEnd = GetFunctionAttr(origEA,FUNCATTR_END); //Message("OEP: %x 起始地址: %x --> 结束地址: %x \n",origEA,funcStart,funcEnd); while(currEA != BADADDR) { Message("--> %x name: %s \n",currEA,GetFunctionName(currEA)); currEA = NextHead(currEA,funcEnd); } } 

idc 枚举所有函数

#include <idc.idc> static main() { auto currAddr,func,endSeg,funcName,counter; currAddr = ScreenEA(); func = SegStart(currAddr); endSeg = SegEnd(currAddr); Message("%x --> %x \n",func,endSeg); counter = 0; while(func != BADADDR && func < endSeg) { funcName = GetFunctionName(func); if(funcName != " ") { Message("%x --> %s \n",func,funcName); counter++; } func = NextFunction(func); } } 
#include <idc.idc> static main() { auto currAddr,func,endSeg,funcName,counter; currAddr = ScreenEA(); func = SegStart(currAddr); endSeg = SegEnd(currAddr); Message("%x --> %x \n",func,endSeg); counter = 0; while(func != BADADDR && func < endSeg) { funcName = GetFunctionName(func); if(funcName != " ") { if(funcName == "__lock") { Message("%x --> %s \n",func,funcName); } counter++; } func = NextFunction(func); } } 

寻找特殊指令,并高亮显示

#include <idc.idc> static main(void) { auto head, op; head = NextHead(0x00000000, 0xFFFFFFFF); while ( head != BADADDR ) { op = GetMnem(head); Message("%x %s \n",head,op); if ( op == "jmp" || op == "call" ) SetColor(head, CIC_ITEM, 0x010187); head = NextHead(head, 0xFFFFFFFF); } } 

ida dump

#include <idc.idc> static getFuncName(ea) { auto funcName = get_func_name(ea); auto dm = demangle_name(funcName, get_inf_attr(INF_LONG_DN)); if(dm != 0) { funcName = dm; } return funcName; } static functionDump(ea) { auto funcName = 0; auto end = 0x0; auto file_open = get_idb_path()[0:-4] + "_dump.log"; auto stream = fopen(file_open, "w"); auto peekAhead; while( ea != BADADDR ) { ea = NextFunction(ea); peekAhead = NextFunction(ea); end = FindFuncEnd(ea); funcName = getFuncName(ea); if(peekAhead == BADADDR) { fprintf(stream, "{ 0x%X, 0x%X, \"%s\" }\n", ea, end, funcName); ea = peekAhead; continue; } end = peekAhead - 1; fprintf(stream, "{ 0x%X, 0x%X, \"%s\" }\n", ea, end,funcName); } fclose(stream); } static main() { functionDump(0x40000); } 

查找特定指令片段

#include <idc.idc> static main() { auto currAddr,startSeg,endSeg; Jump(0x0401000); // 光标跳转到起始位置 currAddr = ScreenEA(); // 反回当前光标所在地址 startSeg = SegStart(currAddr); endSeg = SegEnd(currAddr); Message("OEP = %x 起始地址: %x 结束地址: %x \n",currAddr,startSeg,endSeg); while(startSeg < endSeg) { auto op = GetDisasm(startSeg); // 查找第一条指令 if(strstr(op,"push    esi")==0) { startSeg++; op = GetDisasm(startSeg); if(strstr(op,"push    edi")==0) { Message("特征: %x \n",startSeg-1); } } startSeg++; } } 

关键字段定位:

#include <idc.idc> static main() { auto currAddr,startSeg,endSeg; auto array_ptr = CreateArray("array"); auto ptr = GetArrayId("array"); SetArrayString(ptr,0,"push    ebp"); SetArrayString(ptr,1,"mov     ebp, esp"); Jump(0x0401000); // 光标跳转到起始位置 currAddr = ScreenEA(); // 反回当前光标所在地址 startSeg = SegStart(currAddr); endSeg = SegEnd(currAddr); Message("OEP = %x 起始地址: %x 结束地址: %x \n",currAddr,startSeg,endSeg); while(startSeg < endSeg) { auto x = 0; auto count=0; for(x=0;x<2;x++) { auto op = GetDisasm(startSeg); auto st = GetArrayElement(AR_STR,ptr,x); if(strstr(op,st) == 0) { count = count +1; if(count == 2) { msg("匹配地址: %x \n",startSeg--); } } startSeg++; } } DeleteArray(ptr); } 

全局数组操作: 数组是全局的,并写入数据库,白嫖完了,一定得释放。

#include <idc.idc> static main() { // 创建数组元素 auto array_ptr = CreateArray("array"); // 获取数组指针 auto ptr = GetArrayId("array"); Message("获取到的操作指针: %x \n",ptr); // 设置两个字符串变量 SetArrayString(ptr,0,"hello"); SetArrayString(ptr,1,"lyshark"); // 设置两个整数变量 SetArrayLong(ptr,2,100); SetArrayLong(ptr,3,200); // 如果提取字符串使用 AR_STR 标记 ,提取整数使用 AR_LONG auto st = GetArrayElement(AR_STR,ptr,0); auto st1 = GetArrayElement(AR_STR,ptr,1); Message("提取字符串变量: %s %s !\n",st,st1); auto lo = GetArrayElement(AR_LONG,ptr,2); Message("提取整数变量: %d \n",lo); // 删除数组的0号元素 DelArrayElement(AR_STR,ptr,0); // 注销整个数组 DeleteArray(ptr); } 

字符串处理函数:

#include <idc.idc> static main() { // 格式化字符串,类似于sprintf auto name = form("hello %s","lyshark"); Message("格式化后的内容: %s \n",name); Message("十六进制转为整数: %d \n",xtol("0x41")); Message("十进制100转为八进制: %d \n",ltoa(100,8)); Message("十进制100转换二进制: %d \n",ltoa(100,2)); Message("字符A的ASCII: %d \n",ord("A")); Message("计算字符串长度: %d \n",strlen("hello lyshark")); // 在著字符串中寻找子串 auto main = "hello lyshark"; auto sub = "lyshark"; Message("寻找子串: %d \n",strstr(main,sub)); } 

反汇编函数:

#include <idc.idc> static main() { // 索索特征码 auto code = FindBinary(0x401020,1,"55 8B EC"); Message("%x \n",code); // 反汇反汇编代码 code = GetDisasm(0x401000); Message("%s \n",code); // 反汇 位于地址处的指令 code = GetMnem(0x401000); Message("%s \n",code); // 反汇opcode code = GetOpnd(0x401070,0); Message("%s \n",code); } 

枚举函数:

#include <idc.idc> static main() { auto addr,args,end,locals,frame,firstArg,name,ret; for(addr = NextFunction(addr); addr != BADADDR; addr = NextFunction(addr)) { name = Name(addr); end = GetFunctionAttr(addr,FUNCATTR_END); locals = GetFunctionAttr(addr,FUNCATTR_FRSIZE); // 得到栈帧大小 frame = GetFrame(addr); // 栈中保存返回地址偏移量 ret = GetMemberOffset(frame," r"); if(ret == -1)continue; firstArg = ret +4; args = GetStrucSize(frame) - firstArg; Message("函数: %s 开始: 0x%x 结束: 0x%x 大小: %d bytes 栈帧: %d bytes (%d args) \n",name,addr,end,locals,args,args/4); } } 

枚举指令: 测试

#include <idc.idc> static main() { auto func,end,count,inst; func = GetFunctionAttr(ScreenEA(),FUNCATTR_START); if(func != -1) { end = GetFunctionAttr(func,FUNCATTR_END); count =0; inst = func; while(inst < end) { count ++; inst = FindCode(inst,SEARCH_DOWN | SEARCH_NEXT); } Message("%s --> %d \n",Name(func),count); } } 

检索交叉引用(全部):

#include <idc.idc> static main() { auto func,end,target,inst,name,flags,xref; flags = SEARCH_DOWN | SEARCH_NEXT; func = GetFunctionAttr(ScreenEA(),FUNCATTR_START); if(func != -1) { name =Name(func); end = GetFunctionAttr(func,FUNCATTR_END); for(inst = func;inst < end; inst = FindCode(inst,flags)) { for(target = Rfirst(inst);target != BADADDR; target = Rnext(inst,target)) { xref = XrefType(); if(xref == fl_CN || xref == fl_CF) { Message("%s call -> %sfrom --> %x \n",name,Name(target),inst); } } } } } 

枚举指定交叉引用函数:

#include <idc.idc> static FindFunction(bad_func) { auto func,addr,xref,source; func = LocByName(bad_func); if(func == BADADDR) { Message("error \n"); } else { for(addr = RfirstB(func);addr != BADADDR; addr = RnextB(func,addr)) { xref = XrefType(); if(xref == fl_CN || xref == fl_CF) { source = GetFunctionName(addr); Message("%s call => %0x in %s \n",bad_func,addr,source); } } } } static main() { FindFunction("LoadString"); } 
#include <idc.idc> static main() { auto inpt_count,i,ord,addr,name,purged,file,fd; file = AskFile(1,"*.idt","select idt save file"); fd = fopen(file,"w"); inpt_count = GetEntryPointQty(); fprintf(fd,"Name = %s \n",GetInputFile()); fprintf(fd,"inpt_count = %x \n",inpt_count); for(i=0;i<inpt_count;i++) { ord = GetEntryOrdinal(i); if(ord == 0) continue; addr = GetEntryPoint(ord); if(ord == addr) { continue; } name = Name(addr); fprintf(fd,"%d Name = %s \n",ord,name); purged = GetFunctionAttr(addr,FUNCATTR_ARGSIZE); if(purged > 0) { fprintf(fd,"pascal = %d ",purged); } fprintf(fd,"\n"); } }

评论

暂无
发表评论
 返回顶部 
热度(278)
 关注微信