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

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

2023-3-27 16:35
9844

前阵子分析某团,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脚本反混淆系列文章真心赞!


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

上传的附件:
收藏
点赞8
打赏
分享
最新回复 (18)
雪    币: 52
活跃值: (506)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
万里星河 2023-3-27 17:58
2
0
支持一下
雪    币: 490
活跃值: (1500)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
黑龙lilad 2023-3-28 10:02
3
0
支持一下
雪    币: 2944
活跃值: (3921)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
0xEA 2023-3-28 10:20
4
0
龙哥yyds
雪    币: 1030
活跃值: (334)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ForrestV 2023-3-30 10:29
5
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 52
活跃值: (3274)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DirtyAngle 2023-3-30 13:31
6
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 772
活跃值: (1309)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_ixzqfdot 2023-3-31 00:22
7
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 2938
活跃值: (1353)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
MsScotch 2023-5-3 21:45
8
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 603
活跃值: (6342)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
704088 2023-5-3 23:45
9
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 19124
活跃值: (28707)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-5-4 09:07
10
1
怀念
雪    币: 229
活跃值: (213252)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
shinratensei 1 2023-5-4 09:47
11
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 3125
活跃值: (1162)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
小堆 1 2023-5-4 09:57
12
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 2842
活跃值: (2842)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
安和桥南 2023-5-4 11:48
13
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 603
活跃值: (6342)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
704088 2023-5-4 13:22
14
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 690
活跃值: (187)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Azhan_ 2023-5-8 14:49
15
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 2674
活跃值: (4443)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 2023-5-8 15:23
16
0
什么风气?看雪自己都搞课程,没有互联网共享的大环境了。
雪    币: 8270
活跃值: (4786)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
v0id_ 2023-5-8 16:19
17
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
雪    币: 447
活跃值: (1438)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Mrack 2023-5-8 16:21
18
0
看雪现在什么风气~引流一下,卖课去了~无比怀念五年前、十年前~
游客
登录 | 注册 方可回帖
返回