IDA 逆 WDF 驱动时的函数识别插件
快一年没更新了,累,工作累,各种累,想换个工作,突然发现找不到合适的工作了,哎,自己往火坑里跳,怪不得别人。
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import idautils import idaapi import idc print ( "new ------------------------------------------" ) #ea = idc.get_curline() #print(ea) # def GetWdfVersionBindObject(addr): for x in XrefsTo(addr,flags = 0 ): cur_addr = x.frm cur_asm = GetDisasm(cur_addr) if (cur_asm.startswith( "call" )): pass else : continue func_addr = idc.get_func_attr(cur_addr,FUNCATTR_START) pre_addr = cur_addr while True : if pre_addr < = func_addr: break pre_addr = idc.prev_head(pre_addr) pre_asm = GetDisasm(pre_addr) if (pre_asm.startswith( "lea" )): t = idc.get_operand_type(pre_addr, 0 ) # 寄存器 if (t = = 1 ): pass else : break data = idc.get_operand_value(pre_addr, 0 ) # r8 if (data = = 8 ): t = idc.get_operand_type(pre_addr, 1 ) data = idc.get_operand_value(pre_addr, 1 ) return data return 0 # 从模块中找到对应符号地址 fpWdfVersionBind = idc.get_name_ea( 0x140000000 , "WdfVersionBind" ) print ( 'Address : WdfVersionBind : %#x' % fpWdfVersionBind) # 根据对应符号地址,找到其第三个参数地址 pObject = GetWdfVersionBindObject(fpWdfVersionBind) print ( 'Address : Wdf Object : %#x' % pObject) # 获取的版本号 verBig = idaapi.get_dword(pObject + 0x10 ) verMin = idaapi.get_dword(pObject + 0x14 ) print ( "version :" , verBig, verMin) # 根据函数索引取函数名字 def GetNameByID( id ): return "" def MakeWdfFunctionInfo(addr): for x in XrefsTo(addr,flags = 0 ): cur_addr = x.frm cur_asm = GetDisasm(cur_addr) if (cur_asm.startswith( "mov" )): pass else : continue #print("cur", cur_addr, cur_asm) pre_addr = idc.prev_head(cur_addr) pre_asm = GetDisasm(pre_addr) #print("pre", pre_addr, pre_asm) if (pre_asm.startswith( "imul" )): # 第 0 个参数类型是1,所以是寄存器 type0 = idc.get_operand_type(pre_addr, 0 ) if (type0 = = 1 ): pass else : break # 寄存器参数索引是 0,是rax data = idc.get_operand_value(pre_addr, 0 ) if (data = = 0 ): pass else : break # 按理说应该是取操作数1,但是这里1里面没值,所以取的是 2 # 取出来的就是函数索引 data = idc.get_operand_value(pre_addr, 2 ) # 根据函数索引 func_name = GetNameByID(data) fun_addr = idc.get_func_attr(pre_addr,FUNCATTR_START) if (func_name ! = ""): ida_name.set_name(fun_addr, func_name) # 寻找所有使用到的地方,并且修正对应函数名,编程索引对应函数名 MakeWdfFunctionInfo(get_qword(pObject + 0x20 )) |
几十行代码,有注释,一些地方用的是硬编码,需要改一改,但是目前至少能用了,还缺少一个东西,就是数据库,
这个数据库是根据不同版本的 WDF 函数数据库
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」