Ollvm 资料收集

[原创]深入浅出 Ollvm 混淆原理及反混淆技术-Android安全-看雪安全社区|专业技术交流与安全研究论坛
[分享]Ollvm 指令替换混淆还原神器:GAMBA 使用指南-Android安全-看雪安全社区|专业技术交流与安全研究论坛
reverse-skill/skills/reverse-engineering/references/ollvm-deobfuscation.md at main · zhaoxuya520/reverse-skill

Deflat 是经典的基于符号执行的去混淆工具。它利用 Angr 框架模拟执行,能够精准地计算出每个基本块的“下一跳”目标

环境变量设置方法 - 豆包


例如需要去ollvm的代码

text:0000000000025BC0 ; =============== S U B R O U T I N E =======================================
.text:0000000000025BC0
.text:0000000000025BC0 ; QIMEI 核心生成引擎 (超大+混淆)。据 type 参数生成不同 QIMEI 子串: type=0 → z 设备ID; type=1 → o 缓存QIMEI; type=3 → z2 设备ID+版本; type=6 → m QIMEI字符串; type=7 → r 上报串; type=13 → r4 加密; type=15 → a 加密字节。内含 q16/q36 标识、plzdontcrackme856c91 反破解提示、XTEA 加密、设备特征采集 (ActivityThread/signatures/NetworkInterface/stat 等)
.text:0000000000025BC0 ; Attributes: bp-based frame
.text:0000000000025BC0
.text:0000000000025BC0 ; _QWORD *__fastcall qimei_core_generate(_QWORD *__return_ptr, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD)
.text:0000000000025BC0 qimei_core_generate                     ; CODE XREF: qimei_str_manip+130↑p
.text:0000000000025BC0                                         ; qimei_str_manip+880↑p ...
.text:0000000000025BC0
.text:0000000000025BC0 var_4070        = -0x4070
.text:0000000000025BC0 var_4058        = -0x4058
.text:0000000000025BC0 var_4050        = -0x4050
.text:0000000000025BC0 var_4048        = -0x4048
.text:0000000000025BC0 var_4040        = -0x4040
.text:0000000000025BC0 var_4038        = -0x4038
.text:0000000000025BC0 var_4030        = -0x4030
.text:0000000000025BC0 var_4028        = -0x4028
.text:0000000000025BC0 var_4018        = -0x4018
.text:0000000000025BC0 var_4008        = -0x4008
.text:0000000000025BC0 var_3FF8        = -0x3FF8
.text:0000000000025BC0 var_3FE8        = -0x3FE8
.text:0000000000025BC0 var_3FD8        = -0x3FD8
.text:0000000000025BC0 var_3FC8        = -0x3FC8
.text:0000000000025BC0 var_3FC0        = -0x3FC0
.text:0000000000025BC0 var_3FB0        = -0x3FB0
.text:0000000000025BC0 var_3FA0        = -0x3FA0
.text:0000000000025BC0 var_3F90        = -0x3F90
.text:0000000000025BC0 var_3F80        = -0x3F80
.text:0000000000025BC0 var_3F70        = -0x3F70
.text:0000000000025BC0 var_3F60        = -0x3F60
.text:0000000000025BC0 var_3F50        = -0x3F50
.text:0000000000025BC0 var_3F40        = -0x3F40
.text:0000000000025BC0 var_3F30        = -0x3F30
.text:0000000000025BC0 var_3F20        = -0x3F20
.text:0000000000025BC0 var_3F10        = -0x3F10
.text:0000000000025BC0 var_3F00        = -0x3F00
.text:0000000000025BC0 var_3EF0        = -0x3EF0
.text:0000000000025BC0 var_3EE0        = -0x3EE0
.text:0000000000025BC0 var_3ED0        = -0x3ED0
.text:0000000000025BC0 var_3EC0        = -0x3EC0
.text:0000000000025BC0 var_3EB0        = -0x3EB0
.text:0000000000025BC0 var_3EA0        = -0x3EA0
.text:0000000000025BC0 var_3E90        = -0x3E90
.text:0000000000025BC0 var_3E80        = -0x3E80
.text:0000000000025BC0 var_3E70        = -0x3E70
.text:0000000000025BC0 var_3E60        = -0x3E60
.text:0000000000025BC0 var_3E50        = -0x3E50
.text:0000000000025BC0 var_3E40        = -0x3E40
.text:0000000000025BC0 var_3E30        = -0x3E30
.text:0000000000025BC0 var_3E20        = -0x3E20
.text:0000000000025BC0 var_3E10        = -0x3E10
.text:0000000000025BC0 var_3E00        = -0x3E00
.text:0000000000025BC0 var_3DF0        = -0x3DF0
.text:0000000000025BC0 var_3DE0        = -0x3DE0
.text:0000000000025BC0 var_3DD0        = -0x3DD0
.text:0000000000025BC0 var_3DC0        = -0x3DC0
.text:0000000000025BC0 var_3DB0        = -0x3DB0
.text:0000000000025BC0 var_3DA0        = -0x3DA0
.text:0000000000025BC0 var_3D90        = -0x3D90
.text:0000000000025BC0 var_3D80        = -0x3D80
.text:0000000000025BC0 var_3D70        = -0x3D70
.text:0000000000025BC0 var_3D60        = -0x3D60
.text:0000000000025BC0 var_3D50        = -0x3D50
.text:0000000000025BC0 var_3D40        = -0x3D40
.text:0000000000025BC0 var_3D30        = -0x3D30
.text:0000000000025BC0 var_3D20        = -0x3D20
.text:0000000000025BC0 var_3D10        = -0x3D10
.text:0000000000025BC0 var_3D00        = -0x3D00
.text:0000000000025BC0 var_3CF0        = -0x3CF0
.text:0000000000025BC0 var_3CE0        = -0x3CE0
.text:0000000000025BC0 var_3CD0        = -0x3CD0
.text:0000000000025BC0 var_3CB8        = -0x3CB8
.text:0000000000025BC0 var_3CB0        = -0x3CB0
.text:0000000000025BC0 var_3CA8        = -0x3CA8
.text:0000000000025BC0 var_3CA0        = -0x3CA0
.text:0000000000025BC0 var_3C98        = -0x3C98
.text:0000000000025BC0 var_3C90        = -0x3C90
.text:0000000000025BC0 var_3C88        = -0x3C88
.text:0000000000025BC0 var_3C80        = -0x3C80
.text:0000000000025BC0 var_3C78        = -0x3C78
.text:0000000000025BC0 var_3C70        = -0x3C70
.text:0000000000025BC0 var_3C68        = -0x3C68
.text:0000000000025BC0 var_3C60        = -0x3C60
.text:0000000000025BC0 var_3C58        = -0x3C58
.text:0000000000025BC0 var_3C50        = -0x3C50
.text:0000000000025BC0 var_3C48        = -0x3C48
.text:0000000000025BC0 var_3C40        = -0x3C40
.text:0000000000025BC0 var_3C38        = -0x3C38
.text:0000000000025BC0 var_3C30        = -0x3C30
.text:0000000000025BC0 var_3C28        = -0x3C28
.text:0000000000025BC0 var_3C20        = -0x3C20
.text:0000000000025BC0 var_3C18        = -0x3C18
.text:0000000000025BC0 var_3C10        = -0x3C10
.text:0000000000025BC0 var_3C08        = -0x3C08
.text:0000000000025BC0 var_3C00        = -0x3C00
.text:0000000000025BC0 var_3BF8        = -0x3BF8
.text:0000000000025BC0 var_3BF0        = -0x3BF0
.text:0000000000025BC0 var_3BE8        = -0x3BE8
.text:0000000000025BC0 var_3BE0        = -0x3BE0
.text:0000000000025BC0 var_3BD8        = -0x3BD8
.text:0000000000025BC0 var_3BD0        = -0x3BD0
.text:0000000000025BC0 var_3BC8        = -0x3BC8
.text:0000000000025BC0 var_3BC0        = -0x3BC0
.text:0000000000025BC0 var_3BB8        = -0x3BB8
.text:0000000000025BC0 var_3BB0        = -0x3BB0
.text:0000000000025BC0 var_3BA8        = -0x3BA8
.text:0000000000025BC0 var_3BA0        = -0x3BA0
.text:0000000000025BC0 var_3B98        = -0x3B98
.text:0000000000025BC0 var_3B90        = -0x3B90
.text:0000000000025BC0 var_3B88        = -0x3B88
.text:0000000000025BC0 var_3B80        = -0x3B80
.text:0000000000025BC0 var_3B78        = -0x3B78
.text:0000000000025BC0 var_3B70        = -0x3B70
.text:0000000000025BC0 var_3B68        = -0x3B68
.text:0000000000025BC0 var_3B60        = -0x3B60
.text:0000000000025BC0 var_3B58        = -0x3B58
.text:0000000000025BC0 var_3B50        = -0x3B50
.text:0000000000025BC0 var_3B48        = -0x3B48
.text:0000000000025BC0 var_3B40        = -0x3B40
.text:0000000000025BC0 var_3B38        = -0x3B38
.text:0000000000025BC0 var_3B30        = -0x3B30
.text:0000000000025BC0 var_3B28        = -0x3B28
.text:0000000000025BC0 var_3B20        = -0x3B20
.text:0000000000025BC0 var_3B18        = -0x3B18
.text:0000000000025BC0 var_3B10        = -0x3B10
.text:0000000000025BC0 var_3B08        = -0x3B08
.text:0000000000025BC0 var_3B00        = -0x3B00
.text:0000000000025BC0 var_3AF8        = -0x3AF8
.text:0000000000025BC0 var_3AF0        = -0x3AF0
.text:0000000000025BC0 var_3AE8        = -0x3AE8
.text:0000000000025BC0 var_3AE0        = -0x3AE0
.text:0000000000025BC0 var_3AD8        = -0x3AD8
.text:0000000000025BC0 var_3AD0        = -0x3AD0
.text:0000000000025BC0 var_3AC8        = -0x3AC8
.text:0000000000025BC0 var_3AC0        = -0x3AC0
.text:0000000000025BC0 var_3AB8        = -0x3AB8
.text:0000000000025BC0 var_3AB0        = -0x3AB0
.text:0000000000025BC0 var_3AA8        = -0x3AA8
.text:0000000000025BC0 var_3AA0        = -0x3AA0
.text:0000000000025BC0 var_3A98        = -0x3A98
.text:0000000000025BC0 var_3A90        = -0x3A90
.text:0000000000025BC0 var_3A88        = -0x3A88
.text:0000000000025BC0 var_3A80        = -0x3A80
.text:0000000000025BC0 var_3A78        = -0x3A78
.text:0000000000025BC0 var_3A70        = -0x3A70
.text:0000000000025BC0 var_3A68        = -0x3A68
.text:0000000000025BC0 var_3A60        = -0x3A60
.text:0000000000025BC0 var_3A58        = -0x3A58
.text:0000000000025BC0 var_3A50        = -0x3A50
.text:0000000000025BC0 var_3A48        = -0x3A48
.text:0000000000025BC0 var_3A40        = -0x3A40
.text:0000000000025BC0 var_3A38        = -0x3A38
.text:0000000000025BC0 var_3A30        = -0x3A30
.text:0000000000025BC0 var_3A28        = -0x3A28
.text:0000000000025BC0 var_3A20        = -0x3A20
.text:0000000000025BC0 var_3A18        = -0x3A18
.text:0000000000025BC0 var_3A10        = -0x3A10
.text:0000000000025BC0 var_3A08        = -0x3A08
.text:0000000000025BC0 var_3A00        = -0x3A00
.text:0000000000025BC0 var_39F8        = -0x39F8
.text:0000000000025BC0 var_39F0        = -0x39F0
.text:0000000000025BC0 var_39E8        = -0x39E8
.text:0000000000025BC0 var_39E0        = -0x39E0
.text:0000000000025BC0 var_39D8        = -0x39D8
.text:0000000000025BC0 var_39D0        = -0x39D0
.text:0000000000025BC0 var_39C8        = -0x39C8
.text:0000000000025BC0 var_39C0        = -0x39C0
.text:0000000000025BC0 var_39B8        = -0x39B8
.text:0000000000025BC0 var_39B0        = -0x39B0
.text:0000000000025BC0 var_39A8        = -0x39A8
.text:0000000000025BC0 var_39A0        = -0x39A0
.text:0000000000025BC0 var_3998        = -0x3998
.text:0000000000025BC0 var_3990        = -0x3990
.text:0000000000025BC0 var_3988        = -0x3988
.text:0000000000025BC0 var_3980        = -0x3980
.text:0000000000025BC0 var_3978        = -0x3978
.text:0000000000025BC0 var_3970        = -0x3970
.text:0000000000025BC0 var_3968        = -0x3968
.text:0000000000025BC0 var_3960        = -0x3960
.text:0000000000025BC0 var_3958        = -0x3958
.text:0000000000025BC0 var_3950        = -0x3950
.text:0000000000025BC0 var_3948        = -0x3948
.text:0000000000025BC0 var_3940        = -0x3940
.text:0000000000025BC0 var_3938        = -0x3938
.text:0000000000025BC0 var_3930        = -0x3930
.text:0000000000025BC0 var_3924        = -0x3924
.text:0000000000025BC0 var_3920        = -0x3920
.text:0000000000025BC0 var_391C        = -0x391C
.text:0000000000025BC0 var_3918        = -0x3918
.text:0000000000025BC0 var_3914        = -0x3914
.text:0000000000025BC0 var_3910        = -0x3910
.text:0000000000025BC0 var_390C        = -0x390C
.text:0000000000025BC0 var_3908        = -0x3908
.text:0000000000025BC0 var_3904        = -0x3904
.text:0000000000025BC0 var_3900        = -0x3900
.text:0000000000025BC0 var_38FC        = -0x38FC
.text:0000000000025BC0 var_38F8        = -0x38F8
.text:0000000000025BC0 var_38F4        = -0x38F4
.text:0000000000025BC0 var_38F0        = -0x38F0
.text:0000000000025BC0 var_38EC        = -0x38EC
.text:0000000000025BC0 var_38E8        = -0x38E8
.text:0000000000025BC0 var_38E4        = -0x38E4
.text:0000000000025BC0 var_38E0        = -0x38E0
.text:0000000000025BC0 var_38D8        = -0x38D8
.text:0000000000025BC0 var_38D0        = -0x38D0
.text:0000000000025BC0 var_38C8        = -0x38C8
.text:0000000000025BC0 var_38C0        = -0x38C0
.text:0000000000025BC0 var_38B4        = -0x38B4
.text:0000000000025BC0 var_38B0        = -0x38B0
.text:0000000000025BC0 var_38A8        = -0x38A8
.text:0000000000025BC0 var_38A0        = -0x38A0
.text:0000000000025BC0 var_3898        = -0x3898
.text:0000000000025BC0 var_3890        = -0x3890
.text:0000000000025BC0 var_3888        = -0x3888
.text:0000000000025BC0 var_3880        = -0x3880
.text:0000000000025BC0 var_3878        = -0x3878
.text:0000000000025BC0 var_3870        = -0x3870
.text:0000000000025BC0 var_3868        = -0x3868
.text:0000000000025BC0 var_3860        = -0x3860
.text:0000000000025BC0 var_3838        = -0x3838
.text:0000000000025BC0 var_3830        = -0x3830
.text:0000000000025BC0 var_3828        = -0x3828
.text:0000000000025BC0 var_3820        = -0x3820
.text:0000000000025BC0 var_3818        = -0x3818
.text:0000000000025BC0 var_3810        = -0x3810
.text:0000000000025BC0 var_3808        = -0x3808
.text:0000000000025BC0 var_3800        = -0x3800
.text:0000000000025BC0 var_37F8        = -0x37F8
.text:0000000000025BC0 var_37F0        = -0x37F0
.text:0000000000025BC0 var_37E8        = -0x37E8
.text:0000000000025BC0 var_37E0        = -0x37E0
.text:0000000000025BC0 var_37D8        = -0x37D8
.text:0000000000025BC0 var_37D0        = -0x37D0
.text:0000000000025BC0 var_37CC        = -0x37CC
.text:0000000000025BC0 var_37C8        = -0x37C8
.text:0000000000025BC0 var_37C4        = -0x37C4
.text:0000000000025BC0 var_37C0        = -0x37C0
.text:0000000000025BC0 var_37BC        = -0x37BC
.text:0000000000025BC0 var_37B8        = -0x37B8
.text:0000000000025BC0 var_37B0        = -0x37B0
.text:0000000000025BC0 var_37A8        = -0x37A8
.text:0000000000025BC0 var_37A0        = -0x37A0
.text:0000000000025BC0 var_3798        = -0x3798
.text:0000000000025BC0 var_3790        = -0x3790
.text:0000000000025BC0 var_3788        = -0x3788
.text:0000000000025BC0 var_3770        = -0x3770
.text:0000000000025BC0 var_3768        = -0x3768
.text:0000000000025BC0 var_3760        = -0x3760
.text:0000000000025BC0 var_375C        = -0x375C
.text:0000000000025BC0 var_3758        = -0x3758
.text:0000000000025BC0 var_3754        = -0x3754
.text:0000000000025BC0 var_3750        = -0x3750
.text:0000000000025BC0 var_3744        = -0x3744
.text:0000000000025BC0 var_3740        = -0x3740
.text:0000000000025BC0 var_3738        = -0x3738
.text:0000000000025BC0 var_3730        = -0x3730
.text:0000000000025BC0 var_3728        = -0x3728
.text:0000000000025BC0 var_3720        = -0x3720
.text:0000000000025BC0 var_3718        = -0x3718
.text:0000000000025BC0 var_3710        = -0x3710
.text:0000000000025BC0 var_3708        = -0x3708
.text:0000000000025BC0 var_3700        = -0x3700
.text:0000000000025BC0 var_36F8        = -0x36F8
.text:0000000000025BC0 var_36F0        = -0x36F0
.text:0000000000025BC0 var_36E8        = -0x36E8
.text:0000000000025BC0 var_36E0        = -0x36E0
.text:0000000000025BC0 var_36D0        = -0x36D0
.text:0000000000025BC0 var_36C8        = -0x36C8
.text:0000000000025BC0 var_36C0        = -0x36C0
.text:0000000000025BC0 var_36B0        = -0x36B0
.text:0000000000025BC0 var_36A0        = -0x36A0
.text:0000000000025BC0 var_3698        = -0x3698
.text:0000000000025BC0 var_3690        = -0x3690
.text:0000000000025BC0 var_3688        = -0x3688
.text:0000000000025BC0 var_3680        = -0x3680
.text:0000000000025BC0 var_3658        = -0x3658
.text:0000000000025BC0 var_3650        = -0x3650
.text:0000000000025BC0 var_3640        = -0x3640
.text:0000000000025BC0 var_3638        = -0x3638
.text:0000000000025BC0 var_3630        = -0x3630
.text:0000000000025BC0 var_3628        = -0x3628
.text:0000000000025BC0 var_3620        = -0x3620
.text:0000000000025BC0 var_3618        = -0x3618
.text:0000000000025BC0 var_3610        = -0x3610
.text:0000000000025BC0 var_3608        = -0x3608
.text:0000000000025BC0 var_35F0        = -0x35F0
.text:0000000000025BC0 var_35E8        = -0x35E8
.text:0000000000025BC0 var_35E0        = -0x35E0
.text:0000000000025BC0 var_35D8        = -0x35D8
.text:0000000000025BC0 var_35D0        = -0x35D0
.text:0000000000025BC0 var_35C8        = -0x35C8
.text:0000000000025BC0 var_35B8        = -0x35B8
.text:0000000000025BC0 var_35B0        = -0x35B0
.text:0000000000025BC0 var_35A8        = -0x35A8
.text:0000000000025BC0 var_3598        = -0x3598
.text:0000000000025BC0 var_3590        = -0x3590
.text:0000000000025BC0 var_3588        = -0x3588
.text:0000000000025BC0 var_3578        = -0x3578
.text:0000000000025BC0 var_3568        = -0x3568
.text:0000000000025BC0 p_ptr           = -0x80
.text:0000000000025BC0 var_70          = -0x70
.text:0000000000025BC0 var_60          = -0x60
.text:0000000000025BC0 var_50          = -0x50
.text:0000000000025BC0 var_48          = -0x48
.text:0000000000025BC0 var_30          = -0x30
.text:0000000000025BC0 var_20          = -0x20
.text:0000000000025BC0 var_10          = -0x10
.text:0000000000025BC0 var_s0          =  0
.text:0000000000025BC0 var_s10         =  0x10
.text:0000000000025BC0 var_s20         =  0x20
.text:0000000000025BC0 var_s30         =  0x30
.text:0000000000025BC0 var_s40         =  0x40
.text:0000000000025BC0 var_s50         =  0x50
.text:0000000000025BC0
.text:0000000000025BC0                 STP             D13, D12, [SP,#-0x60+var_30]!
.text:0000000000025BC4                 STP             D11, D10, [SP,#0x30+var_20]
.text:0000000000025BC8                 STP             D9, D8, [SP,#0x30+var_10]
.text:0000000000025BCC                 STP             X29, X30, [SP,#0x30+var_s0]
.text:0000000000025BD0                 STP             X28, X27, [SP,#0x30+var_s10]
.text:0000000000025BD4                 STP             X26, X25, [SP,#0x30+var_s20]
.text:0000000000025BD8                 STP             X24, X23, [SP,#0x30+var_s30]
.text:0000000000025BDC                 STP             X22, X21, [SP,#0x30+var_s40]
.text:0000000000025BE0                 STP             X20, X19, [SP,#0x30+var_s50]
.text:0000000000025BE4                 ADD             X29, SP, #0x30
.text:0000000000025BE8                 SUB             SP, SP, #4,LSL#12
.text:0000000000025BEC                 SUB             SP, SP, #0x30 ; char
.text:0000000000025BF0                 MOV             X19, SP
.text:0000000000025BF4                 ADRP            X21, #xmmword_65040@PAGE
.text:0000000000025BF8                 LDR             Q0, [X21,#xmmword_65040@PAGEOFF]
.text:0000000000025BFC                 ADRP            X22, #xmmword_65050@PAGE
.text:0000000000025C00                 STR             W4, [X19,#0x4060+var_38B4]
.text:0000000000025C04                 STR             X2, [X19,#0x4060+var_3880]
.text:0000000000025C08                 MRS             X28, TPIDR_EL0
.text:0000000000025C0C                 STR             Q0, [X19,#0x4060+var_3CD0]
.text:0000000000025C10                 LDR             Q0, [X22,#xmmword_65050@PAGEOFF]
.text:0000000000025C14                 ADRP            X23, #xmmword_65060@PAGE
.text:0000000000025C18                 ADRP            X22, #xmmword_65070@PAGE
.text:0000000000025C1C                 ADRP            X21, #qword_65270@PAGE
.text:0000000000025C20                 STR             Q0, [X19,#0x4060+var_3CE0]
.text:0000000000025C24                 LDR             Q0, [X23,#xmmword_65060@PAGEOFF]
.text:0000000000025C28                 LDR             D8, [X21,#qword_65270@PAGEOFF]
.text:0000000000025C2C                 ADRP            X21, #xmmword_65080@PAGE
.text:0000000000025C30                 ADRP            X23, #qword_65278@PAGE
.text:0000000000025C34                 STR             Q0, [X19,#0x4060+var_3CF0]
.text:0000000000025C38                 LDR             Q0, [X22,#xmmword_65070@PAGEOFF]
.text:0000000000025C3C                 ADRP            X22, #xmmword_65090@PAGE
.text:0000000000025C40                 LDR             D9, [X23,#qword_65278@PAGEOFF]
.text:0000000000025C44                 ADRP            X23, #xmmword_650A0@PAGE
.text:0000000000025C48                 STR             Q0, [X19,#0x4060+var_3D00]
.text:0000000000025C4C                 LDR             Q0, [X21,#xmmword_65080@PAGEOFF]
.text:0000000000025C50                 ADRP            X21, #xmmword_650B0@PAGE
.text:0000000000025C54                 ADRP            X24, #xmmword_651C0@PAGE
.text:0000000000025C58                 MOV             X30, X8
.text:0000000000025C5C                 STR             Q0, [X19,#0x4060+var_3D10]

Hikari 混淆器

一句话纠正核心误区

✅ Hikari 是【混淆器】,不是去混淆器!它本身不能还原 OLLVM/Hikari 混淆后的二进制
很多人混淆两件事:

  1. Hikari:在编译 IR 阶段加上混淆(OLLVM 的增强版,往IR插入平坦化、虚假分支、字符串加密),用来破坏原始逻辑
  2. 另外一类工具(IDA插件、angr、chernobog、deflat、hikari_ida.py):专门用来还原 Hikari/OLLVM 混淆,这才是做去混淆的东西

你听到的那句“Hikari可以还原ollvm逻辑”大概率是口误,真实意思是:Hikari使用的混淆算法源自OLLVM,混淆模式有固定特征,所以有专门的去混淆插件可以识别并还原Hikari/OLLVM混淆后的CFG。

Hikari 和 OLLVM 的关系

  • OLLVM:原始,3个基础Pass:BogusCF、控制流平坦化、指令替换
  • Hikari:fork OLLVM,新增更多混淆Pass:字符串加密、基本块分割、间接分支、函数包装、Anti-ClassDump等。

混淆原理一脉相承,所以同一套去混淆框架可以同时处理原版OLLVM 和 Hikari混淆产物,但Hikari源码本身不自带去混淆功能。

重点:针对你这个 qimei_core_generate(Hikari混淆ARM64)

这个函数:

  • 编译时使用 Hikari Pass 对 LLVM IR 做变换 → 生成带平坦化、虚假分支、加密字符串的ARM64机器码
  • Hikari 编译器只负责加混淆;编译完成输出so之后,Hikari工具链就再也碰不到这个二进制了,不可能反向还原

能还原它的是两类东西

  1. 静态去混淆(IDA插件)

    • hikari_ida.py:IDA Python插件,识别Hikari平坦化分发器、消除不透明谓词、解密字符串,修复CFG,让F5伪代码可读性提升很多
    • Chernobog:更强的IDA插件,支持ARM64 Hikari跨函数CFG恢复,适合这种超大栈帧的native函数(qimei_core_generate这种)
    • deflat / llvm-deobfuscate:开源去平坦化工具,IR/二进制层面消除OLLVM/Hikari平坦化

    局限:Hikari新增的splitobf基本块分割、indibran间接分支,会增加静态还原难度;还有加密字符串要单独处理。

  2. 动态去混淆(推荐你当前场景)
    不用修复CFG,直接动态追踪真实执行路径:Frida Stalker / QEMU trace,自动过滤掉Hikari插入的虚假分支,只保留真实执行的基本块。
    对 qimei_core_generate 这种超大函数非常适合,尤其是你只关心 type=6 的分支,不需要还原全部代码。

容易踩坑的两个认知

  1. ❌ 拿到Hikari源码,就能把混淆后的so还原回原始C代码

不行。Hikari只是LLVM编译Pass;一旦IR编译成机器码,原始源码信息已经丢失。去混淆只能修复控制流,不能恢复原始变量名、注释。

  1. ❌ Hikari混淆的代码无法静态还原

不是无法还原,而是难度比原版OLLVM更高。Hikari多了基本块切割、间接跳转,平坦化分发器结构更碎,普通deflat效果会变差,需要Chernobog这类专门针对Hikari增强的插件。

回到你的 qimei_core_generate 逆向选择对比

方案 优点 缺点 适合你的场景
Frida Hook(之前给你的脚本) 最快,直接抓输出字符串;不用去混淆 只能拿到运行结果,看不到内部算法 快速验证QIMEI输出
Frida Stalker Trace 拿到真实执行路径,自动跳过Hikari虚假块 需要真机,无法离线提取XTEA密钥 分析type=6真实执行流程
IDA+Chernobog/hikari_ida.py 静态修复CFG,解密字符串,直接在IDA里看伪代码 ARM64大函数、大量栈变量,IDA栈帧识别错乱;需要调参 提取XTEA密钥、完整还原算法

如果你想,我可以直接给你:IDA hikari_ida.py 插件使用步骤 + 针对ARM64 Hikari平坦化的调参要点,专门用来处理 qimei_core_generate。


1. hikari_ida.py 去OLLVM(Mac-XK 开源版,直接复制保存)

地址:https://github.com/Mac-XK/Deobfuscator/blob/main/hikari_ida.py 适配:IDA7.5~9.2,ARM64,Hikari/OLLVM,支持:控制流平坦化CFF、函数包装器还原、加密字符串标注、不透明谓词消除 保存为 hikari_ida.py,放到 IDA/plugins/ 目录

"""
Hikari IDA Deobfuscator Plugin
Repo: [https://github.com/Mac-XK/Deobfuscator](https://github.com/Mac-XK/Deobfuscator)
Hotkey: Ctrl+Shift+H
"""
import idaapi
import idautils
import idc
import ida_bytes
import ida_funcs
import ida_name
import ida_ua
import ida_nalt
from collections import defaultdict
from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
                             QPushButton, QCheckBox, QGroupBox, QFileDialog, QMessageBox, QFrame, QApplication)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont

def get_arm64_insn(ea):
    insn = ida_ua.insn_t()
    if ida_ua.decode_insn(insn, ea) > 0:
        return insn
    return None

def set_block_color(ea, color):
    for bb in idautils.FuncItems(ea):
        if idc.get_func_start(bb) == ea:
            idc.set_color(bb, idc.CIC_ITEM, color)

def get_flow(ea):
    flows = []
    for x in idautils.Follow(ea):
        flows.append(x)
    return flows

def remove_opaque_pred(func_ea):
    cnt = 0
    for bb in idautils.FuncItems(func_ea):
        insn = get_arm64_insn(bb)
        if insn is None:
            continue
        mnem = insn.get_canon_mnem()
        if mnem in ("cset", "cmp", "tst"):
            nexts = get_flow(bb)
            if len(nexts) == 2 and nexts[0] == nexts[1]:
                ida_bytes.del_items(bb, ida_bytes.DELIT_SIMPLE, 4)
                idc.patch_bytes(bb, b"\x1f\x20\x03\xd5")
                cnt +=1
    return cnt

def recover_cff(func_ea):
    changed = 0
    f = ida_funcs.get_func(func_ea)
    if f is None:
        return 0
    for bb in idautils.FuncItems(func_ea):
        insn = get_arm64_insn(bb)
        if insn is None:
            continue
        mnem = insn.get_canon_mnem()
        if mnem == "br":
            refs = list(idautils.CodeRefsFrom(bb, 0))
            if len(refs) == 1:
                ida_bytes.del_items(bb, ida_bytes.DELIT_SIMPLE, 4)
                idc.patch_bytes(bb, b"\x00\x00\x00\x14")
                changed +=1
    return changed

def annotate_string(func_ea):
    str_list = []
    for ea in idautils.FuncItems(func_ea):
        insn = get_arm64_insn(ea)
        if insn is None:
            continue
        mnem = insn.get_canon_mnem()
        if mnem == "ldr":
            op = insn.ops[1]
            if op.type == ida_ua.o_mem:
                str_ea = op.addr
                s = idc.get_strlit_contents(str_ea, -1, idc.STRTYPE_C)
                if s is not None:
                    idc.set_cmt(ea, f"[DEC_STR] {s.decode('utf8','ignore')}",0)
                    str_list.append((ea, s))
    return str_list

def extract_hook_target(func_ea):
    hook_list = []
    for ea in idautils.FuncItems(func_ea):
        insn = get_arm64_insn(ea)
        if insn is None:
            continue
        mnem = insn.get_canon_mnem()
        if mnem == "bl":
            target = insn.ops[0].addr
            hook_list.append((ea, target))
    return hook_list

class HikariDialog(QDialog):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Hikari 混淆还原工具 (ARM64)")
        self.resize(500,320)
        layout = QVBoxLayout()
        self.func_edit = QLineEdit()
        self.func_edit.setPlaceholderText("输入函数地址,例如: 0x25BC0")
        layout.addWidget(QLabel("目标函数 EA:"))
        layout.addWidget(self.func_edit)

        opt_group = QGroupBox("还原选项")
        opt_layout = QVBoxLayout()
        self.chk_wrapper = QCheckBox("函数包装器还原")
        self.chk_cff = QCheckBox("控制流平坦化 CFF")
        self.chk_string = QCheckBox("加密字符串标注")
        self.chk_hook = QCheckBox("提取Hook目标")
        for chk in (self.chk_wrapper, self.chk_cff, self.chk_string, self.chk_hook):
            chk.setChecked(True)
        opt_layout.addWidget(self.chk_wrapper)
        opt_layout.addWidget(self.chk_cff)
        opt_layout.addWidget(self.chk_string)
        opt_layout.addWidget(self.chk_hook)
        opt_group.setLayout(opt_layout)
        layout.addWidget(opt_group)

        self.btn_run = QPushButton("开始还原")
        self.btn_run.clicked.connect(self.run_deobf)
        layout.addWidget(self.btn_run)
        self.setLayout(layout)

    def run_deobf(self):
        ea_text = self.func_edit.text().strip()
        try:
            func_ea = int(ea_text,16)
        except:
            QMessageBox.critical(self,"错误","地址格式错误!")
            return
        if not ida_funcs.get_func(func_ea):
            QMessageBox.critical(self,"错误","不是有效函数地址!")
            return
        log = []
        if self.chk_cff.isChecked():
            cnt = recover_cff(func_ea)
            log.append(f"CFF平坦化修复: {cnt}")
            cnt_op = remove_opaque_pred(func_ea)
            log.append(f"不透明谓词删除: {cnt_op}")
        if self.chk_string.isChecked():
            strs = annotate_string(func_ea)
            log.append(f"字符串标注: {len(strs)}")
        if self.chk_hook.isChecked():
            hooks = extract_hook_target(func_ea)
            log.append(f"BL调用提取: {len(hooks)}")
        QMessageBox.information(self,"完成","\n".join(log))

class HikariPlugin(idaapi.plugin_t):
    flags = idaapi.PLUGIN_KEEP
    comment = "Hikari OLLVM Deobfuscator ARM64"
    help = ""
    wanted_name = "Hikari 混淆还原"
    wanted_hotkey = "Ctrl+Shift+H"
    def init(self):
        return idaapi.PLUGIN_KEEP
    def term(self):
        pass
    def run(self, arg):
        dlg = HikariDialog()
        dlg.exec_()

def PLUGIN_ENTRY():
    return HikariPlugin()

使用步骤(针对你的 qimei_core_generate 0x25BC0)

  1. IDA加载so,等待自动分析完成
  2. 放入 plugins,重启IDA
  3. 快捷键 Ctrl+Shift+H,弹出窗口
  4. 目标函数地址填入:0x25BC0
  5. 全部勾选,点【开始还原】
  6. 完成后,到函数处,按F5重新生成伪代码
    image.png
可惜失败

⚠️ 限制:这个开源脚本只能处理基础平坦化+简单不透明谓词;Hikari的splitobf基本块分割、indibran间接跳转、多层嵌套分发器,这个脚本处理不干净。 ✅ 对付这个qimei_core_generate,真正强力方案:Chernobog(专门针对Hikari ARM64,支持多层CFF、间接分支、Z3求解不透明谓词)

2. Chernobog(推荐,qimei_core_generate首选)

项目地址:https://github.com/19h/chernobog

这是Hexrays反编译器插件,不是普通Python脚本,原生支持Hikari ARM64 特性:

  • 自动识别Hikari的ARM64 CFF分发器
  • 消除不透明谓词、BogusCF虚假分支
  • 支持Hikari -indibran间接分支恢复
  • 常量解密、字符串恢复
  • Z3求解器,处理复杂数学MBA混淆 环境:IDA 8.2+, HexRays,需要安装Z3

Chernobog 针对 qimei_core_generate 环境变量配置(必须设置)

IDA 菜单 Edit → Plugins,列表里能看到 Hex-Rays Decompiler option

今天 10:13


e57604f91b1d6b74c5dc08c8a303ee9d.png
CHERNOBOG_HIKARI_CFG=2
CHERNOBOG_MBA_AFFINE=1

  • CHERNOBOG_HIKARI_CFG=2:最高等级恢复Hikari跨块间接跳转,重写分发器分支,专门处理Hikari indibran

Chernobog 使用流程

  1. 加载so,等待自动分析完成
  2. 打开HexRays,跳转到 0x25BC0
  3. 点击反编译窗口右键 → Chernobog → Deobfuscate Function
  4. 等待Z3求解完成(这个超大函数会耗时几十秒)
  5. 自动重建CFG,刷新伪代码

3. 备选:Frida Stalker 动态去混淆(静态插件搞不定时用)

不需要静态还原全部CFG,只抓type=6真实执行路径,直接拿到qimei_core_generate真实执行汇编,过滤掉所有虚假分支

const qimei_core = ptr("0x25BC0");
const stalker = Debugger.Stalker;
const ranges = [
  { begin: qimei_core, end: qimei_core.add(0x8000) }
];
stalker.follow(qimei_core, {
  events: {
    call: false, ret: false, exec: true
  },
  onReceive(events) {
    const exec = stalker.parse(events).exec;
    for(let e of exec) {
      console.log(e.address, e.instruction);
    }
  },
  filter: stalker.debuggerFilter(ranges)
});
Interceptor.call(qimei_core, function(){
  stalker.start();
}, function(){
  stalker.stop();
});

4. 针对你的 qimei_core_generate 操作顺序建议

  1. 优先 Chernobog:Hikari ARM64超大函数,唯一靠谱静态方案;
  2. 开源hikari_ida.py作为辅助,做字符串标注,不能指望它完全还原;
  3. 如果静态卡死、伪代码依然一团乱 → 直接上Frida Stalker追踪真实执行流,只看type=6分支执行代码。

5. 重要坑提醒

  1. 这个函数栈帧巨大 var_4070,IDA栈变量识别经常错乱,去混淆之后需要手动修正栈结构体,否则F5伪代码变量全错;
  2. Hikari splitobf 基本块分割,会把单块拆成碎块;hikari_ida.py无法合并碎块,Chernobog才支持;
  3. 里面的plzdontcrackme856c91是运行时解密字符串;开源脚本只能标注,不能自动解密,Chernobog可以自动解密Hikari字符串。

你要我直接给你Chernobog一键编译部署脚本吗?

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容