首页
社区
课程
招聘
[分享]某团间接跳转混淆还原
发表于: 2023-3-27 16:35 11313

[分享]某团间接跳转混淆还原

2023-3-27 16:35
11313

前阵子分析某团,so层有比较重的混淆,除了一些简单的可整体nop的花指令以外,还有大量的间接跳转混淆(原理参考https://github.com/amimo/goron),刚好前阵子在龙哥那学了几招,三下五除二,就把间接跳转处理干净了,这里做个脚本分享:

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
104
105
import keystone
import ida_bytes
import ida_ida
import ida_segment
import ida_ua
import idaapi
import idautils
import idc
 
# 初始化汇编器的架构和模式
ks = keystone.Ks(keystone.KS_ARCH_ARM64, keystone.KS_MODE_LITTLE_ENDIAN)
 
 
def getAddrRange():
    start = ida_ida.inf_get_min_ea()
    size = ida_ida.inf_get_max_ea() - start
    # 将地址范围限定于text节
    for seg in idautils.Segments():
        seg = idaapi.getseg(seg)
        segName = ida_segment.get_segm_name(seg)
        if segName == ".text":
            start = seg.start_ea
            size = seg.size()
    return start, size
 
 
def binSearch(start, end, pattern):
    matches = []
    addr = start
    if end == 0:
        end = idc.BADADDR
    if end != idc.BADADDR:
        end = end + 1
    while True:
        addr = ida_bytes.bin_search(addr, end, bytes.fromhex(pattern), None, idaapi.BIN_SEARCH_FORWARD,
                                    idaapi.BIN_SEARCH_NOCASE)
        if addr == idc.BADADDR:
            break
        else:
            matches.append(addr)
            addr = addr + 1
    return matches
 
 
def generate(code, addr):
    encoding, _ = ks.asm(code, addr)
    return encoding
 
# 不一定全,可以碰到再处理
full_nop_list = [
    "FF0301D1E0FB00A90100009480000010FE0300AAFF030191C0035FD6E0FB7CA9",
    "FFC300D1E07B01A90100009480000010FE0300AAFFC30091C0035FD6E07B7EA9",
    "FF4301D1E07B02A90100009480000010FE0300AAFF430191C0035FD6E07B7DA9",
    "FF4301D1E0FB00A90100009480000010FE0300AAFF430191C0035FD6E0FB7BA9",
    "FF4301D1E0FB01A90100009480000010FE0300AAFF430191C0035FD6E0FB7CA9",
    "E0FB3EA90100009460000010FE0300AAC0035FD6E0FB7EA9",
    "E07B3EA90100009460000010FE0300AAC0035FD6E07B7EA9",
    "E07B3FA90100009460000010FE0300AAC0035FD6E07B7FA9"
]
 
for i in range(len(full_nop_list)):
    matches = binSearch(0, 0, full_nop_list[i])
    for matche in matches:
        print("flower" + str(i) + ":", hex(matche))
        nopCode = generate("nop", 0)
        ida_bytes.patch_bytes(matche, bytes(nopCode) * int(len(full_nop_list[i]) / 8))
 
 
# 获取代码段的起始地址和长度
start, size = getAddrRange()
insn = ida_ua.insn_t()
 
indirect_jump_addr = []
for i in range(0, size, 4):
    addr = start + i
    # decode_insn 返回长度,ARM64即4,无法解析则返回0
    if idaapi.decode_insn(insn, addr):
        mnemonic = insn.get_canon_mnem()
        if mnemonic == "BL" and insn.Op1.addr == 0x14DFC:
            indirect_jump_addr.append(addr)
            # print(hex(addr))
 
for i in range(0, size, 4):
    addr = start + i
    # decode_insn 返回长度,ARM64即4,无法解析则返回0
    if idaapi.decode_insn(insn, addr):
        mnemonic = insn.get_canon_mnem()
        local_addr = insn.Op1.addr
        if mnemonic == "B" and local_addr in indirect_jump_addr:
            firstinsn = ida_ua.insn_t()
            idaapi.decode_insn(firstinsn, addr - 4)
            if firstinsn.get_canon_mnem() == 'MOV':
                value = firstinsn.Op2.value
            elif firstinsn.get_canon_mnem() == 'LDR':
                value = ida_bytes.get_dword(firstinsn.Op2.addr)           
            else:
                print("需要额外处理")
 
            offset_addr = local_addr + 4 + 4 * value
            target_addr = local_addr + 4 + ida_bytes.get_dword(offset_addr)
            print("flower_indirect local_addr",hex(addr),"target_addr",hex(target_addr))
 
            code = f"B {hex(target_addr)}"
            bCode = generate(code, addr)
            ida_bytes.patch_bytes(addr, bytes(bCode))

最后放一下龙哥星球的邀请链接~IDA脚本反混淆系列文章真心赞!


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 8
支持
分享
最新回复 (18)
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持一下
2023-3-27 17:58
0
雪    币: 2313
活跃值: (1950)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
支持一下
2023-3-28 10:02
0
雪    币: 3098
活跃值: (4222)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
龙哥yyds
2023-3-28 10:20
0
雪    币: 1030
活跃值: (344)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-3-30 10:29
0
雪    币: 562
活跃值: (4190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-3-30 13:31
0
雪    币: 1523
活跃值: (2270)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-3-31 00:22
0
雪    币: 3237
活跃值: (1886)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-3 21:45
0
雪    币: 637
活跃值: (6493)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-3 23:45
0
雪    币: 3525
活跃值: (31011)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
怀念
2023-5-4 09:07
1
雪    币: 1671
活跃值: (215852)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
11
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-4 09:47
0
雪    币: 3134
活跃值: (1227)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
12
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-4 09:57
0
雪    币: 3373
活跃值: (3403)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-4 11:48
0
雪    币: 637
活跃值: (6493)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-4 13:22
0
雪    币: 1053
活跃值: (667)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-8 14:49
0
雪    币: 4118
活跃值: (5810)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
什么风气?看雪自己都搞课程,没有互联网共享的大环境了。
2023-5-8 15:23
0
雪    币: 8447
活跃值: (5041)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
17
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-8 16:19
0
雪    币: 440
活跃值: (1918)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
2023-5-8 16:21
0
游客
登录 | 注册 方可回帖
返回
//