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 函数数据库

posted @   穷到底  阅读(204)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示