依星源码资源网,依星资源网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

限时开通VIP永久会员,可免费下载所有附件
查看: 19|回复: 0

某易手游反外挂产品原理浅析

[复制链接] 主动推送

1万

主题

1万

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11646
发表于 5 天前 | 显示全部楼层 |阅读模式
某易手游反外挂产品原理浅析
环境 :      ida7.2 jeb3 android4.4.4  dnSpy (5.0.9.0)
由于时间和水平有限,本文会存在诸多不足,希望得到您的及时反馈与指正,多谢!
0x01:反外挂系统基本架构
1.  该反外挂系统主要在U3D、反调试器、代码检验方面,反静态方面做了防护,主要技术用到混淆,内联、字符串加密、SMC等技术,大致框架如图1所示。

某易手游反外挂产品原理浅析

某易手游反外挂产品原理浅析


                                                                图1
0x02:反外挂技术细节分析
1.反外挂系统主要是通过对libmono.so加壳来启动反外挂功能,当游戏启动后加载libmono.so时会先执行initarray中的初始化函数,有三个函数,第三个函数是主要的。

2.反调试:主要通过svc 0指令来获取进程状态,找到所有svc指令,找到open函数,patch掉就过了,让它返回失败.,代码如下:

1
2
3
4
5
6
7
8
9
10
11
"/proc/self/status"
LOAD:003E11D4             NR_openat                               ; CODE XREF: sub_3D2630+1E↑p
LOAD:003E11D4             ; __unwind {
LOAD:003E11D4 07 C0 A0 E1                 MOV             R12, R7
LOAD:003E11D8 14 70 9F E5                 LDR             R7, =322
LOAD:003E11DC 00 00 00 EF                 SVC             0
LOAD:003E11E0 0C 70 A0 E1                 MOV             R7, R12
LOAD:003E11E4 01 0A 70 E3                 CMN             R0, #0x1000
LOAD:003E11E8 1E FF 2F 91                 BXLS            LR
LOAD:003E11EC 00 00 60 E2                 RSB             R0, R0, #0
LOAD:003E11F0 00 04 00 EA                 B               sub_3E21F8


3.第一次解密代码,计算crc值、判断crc、再次解密其它函数。
解密函数指令(前32字节),解密后指令计算crc、比较crc,相同后再解密其它函数指令,代码如下:
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
LOAD:762CB7B8
LOAD:762CB7B8             ; 指令加解密
LOAD:762CB7B8
LOAD:762CB7B8             DecCode
LOAD:762CB7B8             ; __unwind {
LOAD:762CB7B8 2D E9 F0 41 PUSH.W          {R4-R8,LR}
LOAD:762CB7BC 01 EB 02 08 ADD.W           R8, R1, R2
LOAD:762CB7C0 0D 46       MOV             R5, R1
LOAD:762CB7C2 21 F4 7F 64 BIC.W           R4, R1, #0xFF0
LOAD:762CB7C6 08 F6 FF 71 ADDW            R1, R8, #0xFFF
LOAD:762CB7CA 83 68       LDR             R3, [R0,#8]
LOAD:762CB7CC 21 F4 7F 61 BIC.W           R1, R1, #0xFF0
LOAD:762CB7D0 24 F0 0F 04 BIC.W           R4, R4, #0xF
LOAD:762CB7D4 21 F0 0F 01 BIC.W           R1, R1, #0xF
LOAD:762CB7D8 06 46       MOV             R6, R0
LOAD:762CB7DA 0F 1B       SUBS            R7, R1, R4
LOAD:762CB7DC 9B 68       LDR             R3, [R3,#8]
LOAD:762CB7DE 20 46       MOV             R0, R4
LOAD:762CB7E0 07 22       MOVS            R2, #7
LOAD:762CB7E2 39 46       MOV             R1, R7
LOAD:762CB7E4 98 47       BLX             R3
LOAD:762CB7E6 2B 46       MOV             R3, R5
LOAD:762CB7E8
LOAD:762CB7E8             loc_762CB7E8
LOAD:762CB7E8 43 45       CMP             R3, R8                  ; 解密指令
LOAD:762CB7EA 03 F1 01 01 ADD.W           R1, R3, #1
LOAD:762CB7EE 06 D0       BEQ             loc_762CB7FE
LOAD:762CB7F0 1A 78       LDRB            R2, [R3]                ; 加密后的指令
LOAD:762CB7F2 0B 46       MOV             R3, R1
LOAD:762CB7F4 82 F0 58 02 EOR.W           R2, R2, #0x58
LOAD:762CB7F8 01 F8 01 2C STRB.W          R2, [R1,#-1]
LOAD:762CB7FC F4 E7       B               loc_762CB7E8            ; 解密指令
LOAD:762CB7FE            
LOAD:762CB7FE
LOAD:762CB7FE             loc_762CB7FE
LOAD:762CB7FE B3 68       LDR             R3, [R6,#8]
LOAD:762CB800 28 46       MOV             R0, R5
LOAD:762CB802 00 22       MOVS            R2, #0
LOAD:762CB804 D3 F8 D8 30 LDR.W           R3, [R3,#0xD8]
LOAD:762CB808 98 47       BLX             R3
LOAD:762CB80A B3 68       LDR             R3, [R6,#8]
LOAD:762CB80C 20 46       MOV             R0, R4
LOAD:762CB80E 39 46       MOV             R1, R7
LOAD:762CB810 05 22       MOVS            R2, #5
LOAD:762CB812 5B 68       LDR             R3, [R3,#4]
LOAD:762CB814 98 47       BLX             R3
LOAD:762CB816 BD E8 F0 81 POP.W           {R4-R8,PC}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


4.下面是解密后代码,计算并比较代码crc值,直接nop掉,因为该指令是被加密存放的,如果要文件pathc,须先将nop指令加密再进行patch。代码如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
LOAD:762CB8F4             sub_762CB8F4
LOAD:762CB8F4
LOAD:762CB8F4             arg_140=  0x140
LOAD:762CB8F4             arg_160=  0x160
LOAD:762CB8F4
LOAD:762CB8F4 00 F0 9A FD BL              sub_762CC42C
LOAD:762CB8F8 20 46       MOV             R0, R4
LOAD:762CB8FA 29 46       MOV             R1, R5
LOAD:762CB8FC 00 F0 EE FB BL              crc22                   ; 计算并比较代码crc值,直接nop掉
LOAD:762CB900 C0 46       NOP //如果crc值不一样就不走解密函数流程
LOAD:762CB900             ; End of function sub_762CB8F4
LOAD:762CB900
LOAD:762CB902 01 AE       ADD             R6, SP, #4
LOAD:762CB904 29 46       MOV             R1, R5
LOAD:762CB906 01 22       MOVS            R2, #1
LOAD:762CB908 30 46       MOV             R0, R6
LOAD:762CB90A 00 F0 9D F8 BL              DecFunc
LOAD:762CB90E 30 46       MOV             R0, R6
LOAD:762CB910 00 F0 5C FA BL              sub_762CBDCC
LOAD:762CB914 20 46       MOV             R0, R4
LOAD:762CB916 00 F0 AB FD BL              sub_762CC470
LOAD:762CB91A 0D F5 84 6D ADD.W           SP, SP, #0x420
LOAD:762CB91E 70 BD       POP             {R4-R6,PC}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


5.计算代码crc值,代码如下:


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
LOAD:762CBF94
LOAD:762CBF94             ; 计算crc A2E12890
LOAD:762CBF94
LOAD:762CBF94             GetCodeCrc
LOAD:762CBF94             ; __unwind {
LOAD:762CBF94 70 B5       PUSH            {R4-R6,LR}
LOAD:762CBF96 4F F0 FF 33 MOV.W           R3, #0xFFFFFFFF
LOAD:762CBF9A 00 24       MOVS            R4, #0
LOAD:762CBF9C
LOAD:762CBF9C             loc_762CBF9C
LOAD:762CBF9C 94 42       CMP             R4, R2
LOAD:762CBF9E 09 D0       BEQ             loc_762CBFB4
LOAD:762CBFA0 0E 5D       LDRB            R6, [R1,R4]             ; 取代码字节
LOAD:762CBFA2 DD B2       UXTB            R5, R3
LOAD:762CBFA4 01 34       ADDS            R4, #1
LOAD:762CBFA6 75 40       EORS            R5, R6
LOAD:762CBFA8 02 35       ADDS            R5, #2
LOAD:762CBFAA 50 F8 25 50 LDR.W           R5, [R0,R5,LSL#2]       ; 查表
LOAD:762CBFAE 85 EA 13 23 EOR.W           R3, R5, R3,LSR#8
LOAD:762CBFB2 F3 E7       B               loc_762CBF9C
LOAD:762CBFB4
LOAD:762CBFB4
LOAD:762CBFB4             loc_762CBFB4
LOAD:762CBFB4 D8 43       MVNS            R0, R3
LOAD:762CBFB6 70 BD       POP             {R4-R6,PC}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


6.比较crc值,相同返回0,代码如下:


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
LOAD:762CB67A             ; 比较crc值
LOAD:762CB67A
LOAD:762CB67A             cmpcrc
LOAD:762CB67A 02 44       ADD             R2, R0
LOAD:762CB67C 03 46       MOV             R3, R0
LOAD:762CB67E 10 B5       PUSH            {R4,LR}
LOAD:762CB680
LOAD:762CB680             loc_762CB680
LOAD:762CB680 93 42       CMP             R3, R2
LOAD:762CB682 1C D2       BCS             loc_762CB6BE
LOAD:762CB684 1C 78       LDRB            R4, [R3]
LOAD:762CB686 08 78       LDRB            R0, [R1]
LOAD:762CB688 20 1A       SUBS            R0, R4, R0
LOAD:762CB68A 19 D1       BNE             locret_762CB6C0
LOAD:762CB68C 5C 1C       ADDS            R4, R3, #1
LOAD:762CB68E A2 42       CMP             R2, R4
LOAD:762CB690 16 D9       BLS             locret_762CB6C0
LOAD:762CB692 5C 78       LDRB            R4, [R3,#1]
LOAD:762CB694 48 78       LDRB            R0, [R1,#1]
LOAD:762CB696 20 1A       SUBS            R0, R4, R0
LOAD:762CB698 12 D1       BNE             locret_762CB6C0
LOAD:762CB69A 9C 1C       ADDS            R4, R3, #2
LOAD:762CB69C A2 42       CMP             R2, R4
LOAD:762CB69E 0F D9       BLS             locret_762CB6C0
LOAD:762CB6A0 9C 78       LDRB            R4, [R3,#2]
LOAD:762CB6A2 88 78       LDRB            R0, [R1,#2]
LOAD:762CB6A4 20 1A       SUBS            R0, R4, R0
LOAD:762CB6A6 0B D1       BNE             locret_762CB6C0
LOAD:762CB6A8 DC 1C       ADDS            R4, R3, #3
LOAD:762CB6AA A2 42       CMP             R2, R4
LOAD:762CB6AC 08 D9       BLS             locret_762CB6C0
LOAD:762CB6AE DC 78       LDRB            R4, [R3,#3]
LOAD:762CB6B0 04 31       ADDS            R1, #4
LOAD:762CB6B2 11 F8 01 0C LDRB.W          R0, [R1,#-1]
LOAD:762CB6B6 04 33       ADDS            R3, #4
LOAD:762CB6B8 20 1A       SUBS            R0, R4, R0
LOAD:762CB6BA E1 D0       BEQ             loc_762CB680
LOAD:762CB6BC 10 BD       POP             {R4,PC}
LOAD:762CB6BE            
LOAD:762CB6BE
LOAD:762CB6BE             loc_762CB6BE
LOAD:762CB6BE 00 20       MOVS            R0, #0
LOAD:762CB6C0
LOAD:762CB6C0             locret_762CB6C0
LOAD:762CB6C0                          
LOAD:762CB6C0 10 BD       POP             {R4,PC}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


7.如果crc值一样,就解密其它8个函数,并修复mono导出、hook函数mono_image_open_from_data_with_name、加载libNetHTProtect.so,调用libNetHTProtect.so中函数,反函数指令加密回去,代码如下:


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
解密8个函数(解密前32字节)
LOAD:762CB9C8             loc_762CB9C8
LOAD:762CB9C8 55 F8 04 1F LDR.W           R1, [R5,#4]!
LOAD:762CB9CC 29 B1       CBZ             R1, loc_762CB9DA        ; 比较是否解密结束
LOAD:762CB9CE 23 68       LDR             R3, [R4]
LOAD:762CB9D0 20 46       MOV             R0, R4
LOAD:762CB9D2 39 44       ADD             R1, R7
LOAD:762CB9D4 EA 69       LDR             R2, [R5,#0x1C]
LOAD:762CB9D6 5B 68       LDR             R3, [R3,#4]
LOAD:762CB9D8 98 47       BLX             R3                      ; 解密函数前32字节,R1要解密的函数,R2大小,R3解密函数
LOAD:762CB9DA
LOAD:762CB9DA             loc_762CB9DA
LOAD:762CB9DA B5 42       CMP             R5, R6                  ; 比较是否解密结束
LOAD:762CB9DC F4 D1       BNE             loc_762CB9C8
LOAD:762CB9DE BD E8 F0 41 POP.W           {R4-R8,LR}
LOAD:762CB9E2 04 B0       ADD             SP, SP, #0x10
LOAD:762CB9E4 70 47       BX              LR
//解密函数
LOAD:762CB9E6             DecCode_0
LOAD:762CB9E6             ; __unwind {
LOAD:762CB9E6 2D E9 F0 41 PUSH.W          {R4-R8,LR}
LOAD:762CB9EA 01 EB 02 08 ADD.W           R8, R1, R2
LOAD:762CB9EE 0D 46       MOV             R5, R1
LOAD:762CB9F0 21 F4 7F 64 BIC.W           R4, R1, #0xFF0
LOAD:762CB9F4 08 F6 FF 71 ADDW            R1, R8, #0xFFF
LOAD:762CB9F8 43 68       LDR             R3, [R0,#4]
LOAD:762CB9FA 21 F4 7F 61 BIC.W           R1, R1, #0xFF0
LOAD:762CB9FE 24 F0 0F 04 BIC.W           R4, R4, #0xF
LOAD:762CBA02 21 F0 0F 01 BIC.W           R1, R1, #0xF
LOAD:762CBA06 06 46       MOV             R6, R0
LOAD:762CBA08 0F 1B       SUBS            R7, R1, R4
LOAD:762CBA0A 5B 68       LDR             R3, [R3,#4]
LOAD:762CBA0C 20 46       MOV             R0, R4
LOAD:762CBA0E 07 22       MOVS            R2, #7
LOAD:762CBA10 39 46       MOV             R1, R7
LOAD:762CBA12 98 47       BLX             R3
LOAD:762CBA14 29 46       MOV             R1, R5
LOAD:762CBA16
LOAD:762CBA16             loc_762CBA16
LOAD:762CBA16 41 45       CMP             R1, R8
LOAD:762CBA18 05 D0       BEQ             loc_762CBA26
LOAD:762CBA1A 0A 78       LDRB            R2, [R1]
LOAD:762CBA1C 82 F0 58 02 EOR.W           R2, R2, #0x58           ; 解密代码
LOAD:762CBA20 01 F8 01 2B STRB.W          R2, [R1],#1
LOAD:762CBA24 F7 E7       B               loc_762CBA16
LOAD:762CBA26        
LOAD:762CBA26
LOAD:762CBA26             loc_762CBA26
LOAD:762CBA26 72 68       LDR             R2, [R6,#4]
LOAD:762CBA28 A5 F1 10 00 SUB.W           R0, R5, #0x10
LOAD:762CBA2C 20 31       ADDS            R1, #0x20 ; ' '
LOAD:762CBA2E D2 F8 D8 C0 LDR.W           R12, [R2,#0xD8]
LOAD:762CBA32 00 22       MOVS            R2, #0
LOAD:762CBA34 E0 47       BLX             R12
LOAD:762CBA36 73 68       LDR             R3, [R6,#4]
LOAD:762CBA38 20 46       MOV             R0, R4
LOAD:762CBA3A 39 46       MOV             R1, R7
LOAD:762CBA3C 05 22       MOVS            R2, #5
LOAD:762CBA3E 5B 68       LDR             R3, [R3,#4]
LOAD:762CBA40 98 47       BLX             R3
LOAD:762CBA42 BD E8 F0 81 POP.W           {R4-R8,PC}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


8.把比较crc与解密其它8个函数的指令加密回去,代码如下:


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
加密函数指令(32字节)
LOAD:762CB7B8
LOAD:762CB7B8             ; 指令加密
LOAD:762CB7B8
LOAD:762CB7B8             DecCode
LOAD:762CB7B8             ; __unwind {
LOAD:762CB7B8 2D E9 F0 41 PUSH.W          {R4-R8,LR}
LOAD:762CB7BC 01 EB 02 08 ADD.W           R8, R1, R2
LOAD:762CB7C0 0D 46       MOV             R5, R1
LOAD:762CB7C2 21 F4 7F 64 BIC.W           R4, R1, #0xFF0
LOAD:762CB7C6 08 F6 FF 71 ADDW            R1, R8, #0xFFF
LOAD:762CB7CA 83 68       LDR             R3, [R0,#8]
LOAD:762CB7CC 21 F4 7F 61 BIC.W           R1, R1, #0xFF0
LOAD:762CB7D0 24 F0 0F 04 BIC.W           R4, R4, #0xF
LOAD:762CB7D4 21 F0 0F 01 BIC.W           R1, R1, #0xF
LOAD:762CB7D8 06 46       MOV             R6, R0
LOAD:762CB7DA 0F 1B       SUBS            R7, R1, R4
LOAD:762CB7DC 9B 68       LDR             R3, [R3,#8]
LOAD:762CB7DE 20 46       MOV             R0, R4
LOAD:762CB7E0 07 22       MOVS            R2, #7
LOAD:762CB7E2 39 46       MOV             R1, R7
LOAD:762CB7E4 98 47       BLX             R3
LOAD:762CB7E6 2B 46       MOV             R3, R5
LOAD:762CB7E8
LOAD:762CB7E8             loc_762CB7E8
LOAD:762CB7E8 43 45       CMP             R3, R8                  ; 加密指令
LOAD:762CB7EA 03 F1 01 01 ADD.W           R1, R3, #1
LOAD:762CB7EE 06 D0       BEQ             loc_762CB7FE
LOAD:762CB7F0 1A 78       LDRB            R2, [R3]                ; 加密后的指令
LOAD:762CB7F2 0B 46       MOV             R3, R1
LOAD:762CB7F4 82 F0 58 02 EOR.W           R2, R2, #0x58
LOAD:762CB7F8 01 F8 01 2C STRB.W          R2, [R1,#-1]
LOAD:762CB7FC F4 E7       B               loc_762CB7E8            ; 加密指令
LOAD:762CB7FE            
LOAD:762CB7FE
LOAD:762CB7FE             loc_762CB7FE
LOAD:762CB7FE B3 68       LDR             R3, [R6,#8]
LOAD:762CB800 28 46       MOV             R0, R5
LOAD:762CB802 00 22       MOVS            R2, #0
LOAD:762CB804 D3 F8 D8 30 LDR.W           R3, [R3,#0xD8]
LOAD:762CB808 98 47       BLX             R3
LOAD:762CB80A B3 68       LDR             R3, [R6,#8]
LOAD:762CB80C 20 46       MOV             R0, R4
LOAD:762CB80E 39 46       MOV             R1, R7
LOAD:762CB810 05 22       MOVS            R2, #5
LOAD:762CB812 5B 68       LDR             R3, [R3,#4]
LOAD:762CB814 98 47       BLX             R3
LOAD:762CB816 BD E8 F0 81 POP.W           {R4-R8,PC}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


9.解密so字符串还原导出表,代码如下:


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
LOAD:762B4EEE             arg_4C=  0x4C
LOAD:762B4EEE
LOAD:762B4EEE 70 B5       PUSH            {R4-R6,LR}
LOAD:762B4EF0
LOAD:762B4EF0 04 46       MOV             R4, R0
LOAD:762B4EF2 43 68       LDR             R3, [R0,#4]
LOAD:762B4EF4 13 B9       CBNZ            R3, loc_762B4EFC
LOAD:762B4EF6
LOAD:762B4EF6
LOAD:762B4EF6             loc_762B4EF6
LOAD:762B4EF6 4F F0 FF 30 MOV.W           R0, #0xFFFFFFFF
LOAD:762B4EFA 70 BD       POP             {R4-R6,PC}
LOAD:762B4EFC
LOAD:762B4EFC
LOAD:762B4EFC             loc_762B4EFC
LOAD:762B4EFC C0 68       LDR             R0, [R0,#0xC]
LOAD:762B4EFE 03 68       LDR             R3, [R0]
LOAD:762B4F00 1B 68       LDR             R3, [R3]
LOAD:762B4F02 98 47       BLX             R3
LOAD:762B4F04 01 46       MOV             R1, R0
LOAD:762B4F06 00 28       CMP             R0, #0
LOAD:762B4F08 F5 D0       BEQ             loc_762B4EF6
LOAD:762B4F0A 23 68       LDR             R3, [R4]
LOAD:762B4F0C 20 46       MOV             R0, R4
LOAD:762B4F0E 62 68       LDR             R2, [R4,#4]
LOAD:762B4F10 5B 68       LDR             R3, [R3,#4]
LOAD:762B4F12 98 47       BLX             R3
LOAD:762B4F14 23 68       LDR             R3, [R4]
LOAD:762B4F16 E0 68       LDR             R0, [R4,#0xC]
LOAD:762B4F18 5D 69       LDR             R5, [R3,#0x14]
LOAD:762B4F1A 03 68       LDR             R3, [R0]
LOAD:762B4F1C 9B 68       LDR             R3, [R3,#8]
LOAD:762B4F1E 98 47       BLX             R3
LOAD:762B4F20 06 46       MOV             R6, R0
LOAD:762B4F22 E0 68       LDR             R0, [R4,#0xC]
LOAD:762B4F24 02 68       LDR             R2, [R0]
LOAD:762B4F26 D2 68       LDR             R2, [R2,#0xC]
LOAD:762B4F28 90 47       BLX             R2
LOAD:762B4F2A 31 46       MOV             R1, R6
LOAD:762B4F2C 63 68       LDR             R3, [R4,#4]
LOAD:762B4F2E 02 46       MOV             R2, R0
LOAD:762B4F30 20 46       MOV             R0, R4
LOAD:762B4F32 A8 47       BLX             R5                      ; 解密字符串表
LOAD:762B4F34 23 68       LDR             R3, [R4]
LOAD:762B4F36 E1 69       LDR             R1, [R4,#0x1C]
LOAD:762B4F38 20 46       MOV             R0, R4
LOAD:762B4F3A DB 6A       LDR             R3, [R3,#0x2C]
LOAD:762B4F3C 98 47       BLX             R3
LOAD:762B4F3E 23 69       LDR             R3, [R4,#0x10]
LOAD:762B4F40 E0 68       LDR             R0, [R4,#0xC]
LOAD:762B4F42 5D 6F       LDR             R5, [R3,#0x74]
LOAD:762B4F44 03 68       LDR             R3, [R0]
LOAD:762B4F46 9B 68       LDR             R3, [R3,#8]
LOAD:762B4F48 98 47       BLX             R3
LOAD:762B4F4A 63 68       LDR             R3, [R4,#4]
LOAD:762B4F4C D3 F8 8C 10 LDR.W           R1, [R3,#0x8C]
LOAD:762B4F50 A8 47       BLX             R5                      ; 解密so数据,还原导出
LOAD:762B4F52 23 68       LDR             R3, [R4]
LOAD:762B4F54 20 46       MOV             R0, R4
LOAD:762B4F56 61 68       LDR             R1, [R4,#4]
LOAD:762B4F58 9B 68       LDR             R3, [R3,#8]
LOAD:762B4F5A 98 47       BLX             R3
LOAD:762B4F5C 00 20       MOVS            R0, #0
LOAD:762B4F5E 70 BD       POP             {R4-R6,PC}


此时将libmono.so从内存中dump出来可以看到导出了。
10.获取libNetHTProtect.so中的函数(反调试),代码如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LOAD:762B7856             loc_762B7856
LOAD:762B7856 09 9E       LDR             R6, [SP,#0x24]          ; dlopenso
LOAD:762B7858 0F 98       LDR             R0, [SP,#0x3C]
LOAD:762B785A 33 68       LDR             R3, [R6]
LOAD:762B785C 5B 6D       LDR             R3, [R3,#0x54]
LOAD:762B785E 98 47       BLX             R3
LOAD:762B7860 AD B1       CBZ             R5, loc_762B788E
LOAD:762B7862 33 68       LDR             R3, [R6]
LOAD:762B7864 0D F2 EC 40 ADDW            R0, SP, #0x4EC
LOAD:762B7868 00 21       MOVS            R1, #0
LOAD:762B786A 5B 6A       LDR             R3, [R3,#0x24]
LOAD:762B786C 98 47       BLX             R3                      ; dlopen libNetHTProtect.so
LOAD:762B786E 00 28       CMP             R0, #0
LOAD:762B7870 00 F0 12 81 BEQ.W           loc_762B7A98<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


11.hook函数mono_image_open_from_data_with_name,代码如下:


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
LOAD:762B8DF2             loc_762B8DF2
LOAD:762B8DF2 21 68       LDR             R1, [R4]                ; hook
LOAD:762B8DF4 53 00       LSLS            R3, R2, #1
LOAD:762B8DF6 4F F6 DF 00 MOVW            R0, #0xF8DF
LOAD:762B8DFA 21 F0 01 01 BIC.W           R1, R1, #1
LOAD:762B8DFE 21 F8 12 00 STRH.W          R0, [R1,R2,LSL#1]
LOAD:762B8E02 4F F4 70 41 MOV.W           R1, #0xF000
LOAD:762B8E06 22 68       LDR             R2, [R4]
LOAD:762B8E08 22 F0 01 02 BIC.W           R2, R2, #1
LOAD:762B8E0C 1A 44       ADD             R2, R3
LOAD:762B8E0E 51 80       STRH            R1, [R2,#2]
LOAD:762B8E10 22 68       LDR             R2, [R4]
LOAD:762B8E12 22 F0 01 02 BIC.W           R2, R2, #1
LOAD:762B8E16 99 18       ADDS            R1, R3, R2
LOAD:762B8E18 62 68       LDR             R2, [R4,#4]
LOAD:762B8E1A 8A 80       STRH            R2, [R1,#arg_4]
LOAD:762B8E1C 22 68       LDR             R2, [R4,#(loc_762B8EF0 - 0x762B8EF0)]
LOAD:762B8E1E 22 F0 01 02 BIC.W           R2, R2, #1
LOAD:762B8E22 13 44       ADD             R3, R2
LOAD:762B8E24 E2 88       LDRH            R2, [R4,#6]
LOAD:762B8E26 DA 80       STRH            R2, [R3,#6]
LOAD:762B8E28 04 E0       B               loc_762B8E34
LOAD:762B8E2A
LOAD:762B8E2A
LOAD:762B8E2A             loc_762B8E2A
LOAD:762B8E2A 60 4A       LDR             R2, =0xE51FF004
LOAD:762B8E2C 1A 60       STR             R2, [R3]
LOAD:762B8E2E 62 68       LDR             R2, [R4,#4]
LOAD:762B8E30
LOAD:762B8E30             loc_762B8E30
LOAD:762B8E30 23 68       LDR             R3, [R4]
LOAD:762B8E32 5A 60       STR             R2, [R3,#4]
LOAD:762B8E34
LOAD:762B8E34             loc_762B8E34
LOAD:762B8E34 A3 68       LDR             R3, [R4,#8]
LOAD:762B8E36 3B B1       CBZ             R3, loc_762B8E48
LOAD:762B8E38 22 68       LDR             R2, [R4]
LOAD:762B8E3A 12 F0 01 0F TST.W           R2, #1
LOAD:762B8E3E 62 6F       LDR             R2, [R4,#0x74]
LOAD:762B8E40 18 BF       IT NE
LOAD:762B8E42 42 F0 01 02 ORRNE.W         R2, R2, #1
LOAD:762B8E46 1A 60       STR             R2, [R3]
LOAD:762B8E48
LOAD:762B8E48             loc_762B8E48
LOAD:762B8E48                  
LOAD:762B8E48 02 9E       LDR             R6, [SP,#8]
LOAD:762B8E4A 00 22       MOVS            R2, #0
LOAD:762B8E4C 20 68       LDR             R0, [R4,#arg_0]
LOAD:762B8E4E A1 6F       LDR             R1, [R4,#0x78]
LOAD:762B8E50
LOAD:762B8E50             loc_762B8E50
LOAD:762B8E50 33 68       LDR             R3, [R6]
LOAD:762B8E52 20 F0 01 00 BIC.W           R0, R0, #1
LOAD:762B8E56 01 44       ADD             R1, R0
LOAD:762B8E58 D3 F8 D8 30 LDR.W           R3, [R3,#arg_D8]
LOAD:762B8E5C 98 47       BLX             R3                      ; cacheflush<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


12.再将解密的so数据加密加回去,代码如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
LOAD:762B7B2A             loc_762B7B2A
LOAD:762B7B2A A1 42       CMP             R1, R4
LOAD:762B7B2C 17 D0       BEQ             loc_762B7B5E
LOAD:762B7B2E 01 33       ADDS            R3, #(loc_762B7CA8+1 - 0x762B7CA8)
LOAD:762B7B30 0D F6 EC 07 ADDW            R7, SP, #0x8EC
LOAD:762B7B34 DB B2       UXTB            R3, R3
LOAD:762B7B36 F8 5C       LDRB            R0, [R7,R3]
LOAD:762B7B38 02 44       ADD             R2, R0
LOAD:762B7B3A D2 B2       UXTB            R2, R2
LOAD:762B7B3C BD 5C       LDRB            R5, [R7,R2]
LOAD:762B7B3E FD 54       STRB            R5, [R7,R3]
LOAD:762B7B40 B8 54       STRB            R0, [R7,R2]
LOAD:762B7B42 FD 5C       LDRB            R5, [R7,R3]
LOAD:762B7B44 28 44       ADD             R0, R5
LOAD:762B7B46 C0 B2       UXTB            R0, R0
LOAD:762B7B48 38 5C       LDRB            R0, [R7,R0]
LOAD:762B7B4A 05 11       ASRS            R5, R0, #arg_4
LOAD:762B7B4C 45 EA 00 10 ORR.W           R0, R5, R0,LSL#4
LOAD:762B7B50 4D 78       LDRB            R5, [R1,#1]
LOAD:762B7B52 C0 B2       UXTB            R0, R0
LOAD:762B7B54 5C 38       SUBS            R0, #0x5C ; '\'
LOAD:762B7B56 68 40       EORS            R0, R5
LOAD:762B7B58 01 F8 01 0F STRB.W          R0, [R1,#1]!<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


13.调用libNetHTProtect.so中的函数(反调试)



1
2
3
4
直接patch让它返回
libNetHTProtect.so:764DFA84 2D E9 F0 4F PUSH.W          {R4-R11,LR}
libNetHTProtect.so:764DFA88 BD E8 F0 8F POP.W           {R4-R11,PC}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


14.再将解密的8个函数再加密回去,代码如下:


1
2
3
4
5
6
7
8
9
10
11
12
LOAD:762B5BDA             loc_762B5BDA
LOAD:762B5BDA 01 AD       ADD             R5, SP, #0x20+var_1C
LOAD:762B5BDC 00 21       MOVS            R1, #0
LOAD:762B5BDE 0A 46       MOV             R2, R1
LOAD:762B5BE0 28 46       MOV             R0, R5
LOAD:762B5BE2 00 F0 31 FF BL              encFunc
LOAD:762B5BE6 20 69       LDR             R0, [R4,#0x10]
LOAD:762B5BE8 03 68       LDR             R3, [R0]
LOAD:762B5BEA DB 68       LDR             R3, [R3,#0xC]
LOAD:762B5BEC 98 47       BLX             R3
LOAD:762B5BEE 28 46       MOV             R0, R5<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


15.libmono.so壳大致分析完成, 当加载dll时通过hook函数mono_image_open_from_data_with_name是走到libNetHTProtect.so中去。接下来就是分析hook函数,dump dll。
16.在游戏目assets\bin\Data\Managed中没有发现Assembly-CSharp.dll,只有Assembly-CSharp-firstpass.dll,反编译Assembly-CSharp-firstpass.dll时看不到代码,如图2所示。应该是做保护处理了。

某易手游反外挂产品原理浅析

某易手游反外挂产品原理浅析
                         图2

17.分析libNetHTProtect.so中hook函数dump Assembly-CSharp-firstpass.dll,当dll加载走到hook函数中时会判断标记是否须要修复处理,代码如下:

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
判断标记并做出相应处理
.text:762EF534             loc_762EF534
.text:762EF534 1B 9E       LDR             R6, [SP,#0x2E80+bufer]  ; 判断32位是否为0
.text:762EF536 31 6A       LDR             R1, [R6,#0x20]
.text:762EF538 00 29       CMP             R1, #0
.text:762EF53A 00 F0 BA 82 BEQ.W           loc_762EFAB2
.text:762EF53E 9A 42       CMP             R2, R3
//如果有标记就开始修复dll
.text:762EF984             loc_762EF984
.text:762EF984 DD F8 18 90 LDR.W           R9, [SP,#0x2E80+src]    ; 修复dll
.text:762EF988 1B 9E       LDR             R6, [SP,#0x2E80+bufer]
.text:762EF98A C7 EB 09 03 RSB.W           R3, R7, R9
.text:762EF98E 16 F8 0B 20 LDRB.W          R2, [R6,R11]
.text:762EF992 F1 5C       LDRB            R1, [R6,R3]
.text:762EF994 4A 40       EORS            R2, R1
.text:762EF996 F2 54       STRB            R2, [R6,R3]
.text:762EF998 DB 1B       SUBS            R3, R3, R7
.text:762EF99A 37 44       ADD             R7, R6
.text:762EF99C
.text:762EF99C             loc_762EF99C
.text:762EF99C 5B 45       CMP             R3, R11
.text:762EF99E 09 D3       BCC             loc_762EF9B4
.text:762EF9A0 DD F8 6C 80 LDR.W           R8, [SP,#0x2E80+bufer]
.text:762EF9A4 FA 5C       LDRB            R2, [R7,R3]
.text:762EF9A6 13 F8 08 10 LDRB.W          R1, [R3,R8]
.text:762EF9AA 4A 40       EORS            R2, R1
.text:762EF9AC 03 F8 08 20 STRB.W          R2, [R3,R8]
.text:762EF9B0 01 3B       SUBS            R3, #1
.text:762EF9B2 F3 E7       B               loc_762EF99C
.text:762EF9B4、
.text:762EF9B4
.text:762EF9B4             loc_762EF9B4
.text:762EF9B4 4F F0 01 09 MOV.W           R9, #1
.text:762EF9B8
.text:762EF9B8             loc_762EF9B8
.text:762EF9B8 A4 F1 20 08 SUB.W           R8, R4, #0x20
.text:762EF9BC A5 F1 30 01 SUB.W           R1, R5, #0x30
.text:762EF9C0 0D F6 08 02 ADDW            R2, SP, #0x2E80+var_2678<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


18.将修复完后的dll dump出来进行反编译,如图3所示。


某易手游反外挂产品原理浅析

某易手游反外挂产品原理浅析


                                      图3
从上图可以看到主要是读到资源目录下的code.bytes.assetbundle文件,传给libUnityHelper.so中的LoadGame函数解密加载,代码如下:

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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
signed int __fastcall sub_82BAE570(size_t *codedata, signed int codelen, int (*JNI_OnLoad)(void), int constsize1, int constsize2)
{
  int v5; // r7
  signed int v6; // r6
  size_t *v7; // r5
  int v8; // r0
  int v9; // r7
  int v10; // r1
  int v11; // r3
  bool v12; // cf
  int v13; // r1
  int v14; // r1
  int v15; // r4
  int v16; // r2
  int v17; // r3
  signed int result; // r0
  int v19; // r6
  int v20; // r3
  int v21; // r5
  _DWORD *v22; // r0
  int v23; // r1
  int v24; // r2
  _DWORD *v25; // r8
  int v26; // r11
  unsigned int **v27; // r0
  unsigned int v28; // r5
  int v29; // r6
  int (**v30)(void); // r10
  _DWORD *v31; // r9
  _DWORD *v32; // r8
  int (*v33)(void); // r7
  int (*v34)(void); // t1
  _DWORD *v35; // r0
  _DWORD *v36; // r4
  _DWORD *v37; // r2
  int v38; // r3
  _DWORD *v39; // t1
  unsigned int **v40; // r2
  unsigned int v41; // r3
  _DWORD *v42; // r0
  unsigned int *v43; // r10
  int v44; // r4
  _DWORD *v45; // r8
  int v46; // r9
  int v47; // r3
  int v48; // lr
  int v49; // r4
  int v50; // r6
  bool v51; // zf
  bool v52; // nf
  unsigned __int8 v53; // vf
  int v54; // r2
  int v55; // t1
  int v56; // r1
  unsigned int *v57; // r2
  int v58; // r1
  unsigned int v59; // r3
  unsigned int *v60; // r0
  unsigned int *v61; // lr
  int v62; // r1
  int v63; // r2
  _DWORD *v64; // r0
  _DWORD *v65; // r11
  unsigned int *v66; // r2
  int v67; // r3
  _DWORD *v68; // t1
  unsigned int v69; // r3
  int v70; // lr
  int v71; // r0
  int v72; // r2
  int v73; // r3
  _DWORD *v74; // r1
  int v75; // r12
  _DWORD *v76; // r6
  signed int v77; // r6
  int v78; // r6
  size_t v79; // r7
  int v80; // r6
  unsigned int *v81; // r12
  int v82; // r3
  _DWORD *v83; // r0
  int v84; // r2
  _DWORD *v85; // r0
  int v86; // [sp+0h] [bp-50h]
  unsigned int **v87; // [sp+4h] [bp-4Ch]
  _BYTE *dllbuffer; // [sp+8h] [bp-48h]
  void *handle; // [sp+Ch] [bp-44h]
  int (__fastcall *mono_image_open_from_data)(_BYTE *, size_t, signed int, int *); // [sp+10h] [bp-40h]
  int (__fastcall *mono_assembly_load_from)(int, const char *, int *); // [sp+14h] [bp-3Ch]
  int v92; // [sp+1Ch] [bp-34h]
  size_t size; // [sp+20h] [bp-30h]
  int v94; // [sp+24h] [bp-2Ch]

  v5 = constsize1;
  v6 = codelen;
  v7 = codedata;
  v8 = JNI_OnLoad();
  v9 = *(_DWORD *)(v8 + v5);
  v86 = *(_DWORD *)(v8 + constsize2);
  v10 = *(_DWORD *)(v8 + constsize2 + 4) - v86;
  v11 = v10 + 3;
  v12 = v10 < 0;
  v13 = v10 & ~(v10 >> 32);
  if ( v12 )
    v13 = v11;
  v14 = v13 >> 2;
  if ( v14 <= 0 )
    return 0;
  v15 = 0;
  while ( 1 )
  {
    v16 = *(_DWORD *)(v9 + 8 * v15 + 4);
    if ( *(_DWORD *)(v16 - 12) == 19 )
      break;
LABEL_5:
    if ( ++v15 == v14 )
      return 0;
  }
  v17 = 0;
  do
  {
    result = *(unsigned __int8 *)(v16 + v17++);
    if ( result )
      goto LABEL_5;
  }
  while ( v17 != 19 );
  if ( *(_DWORD *)(v86 + 4 * v15) )
    return result;
  handle = dlopen("libmono.so", 0);
  mono_image_open_from_data = (int (__fastcall *)(_BYTE *, size_t, signed int, int *))dlsym(
                                                                                        handle,
                                                                                        "mono_image_open_from_data");
  v92 = 0;
  mono_assembly_load_from = (int (__fastcall *)(int, const char *, int *))dlsym(handle, "mono_assembly_load_from");
  memcpy(&g_codedata, v7, 0x400u);
  size = v7[256];
  if ( v6 < 1032 )
    goto LABEL_89;
  v19 = v6 - 1032;
  v94 = v7[257];
  v20 = v94 + 7;
  if ( v94 + 7 < 0 )
    v20 = v94 + 14;
  if ( v19 != v20 >> 3 )
  {
LABEL_89:
    v25 = 0;
  }
  else
  {
    v21 = (int)(v7 + 258);
    v22 = malloc(0x14u);
    v23 = (v94 + 7) & (v94 >> 32);
    if ( v94 >= 0 )
      v23 = v94;
    v24 = v94 % 8;
    v25 = v22;
    v22[3] = 0;
    *((_BYTE *)v22 + 16) = 0;
    *v22 = v21;
    v22[1] = v23 >> 3;
    v22[2] = v24;
  }
  v26 = v15;
  dllbuffer = malloc(size);
  v27 = (unsigned int **)malloc(0xCu);
  v28 = 0;
  v29 = 0;
  v30 = &dword_82C72024;
  v31 = v25;
  v32 = 0;
  *v27 = 0;
  v27[1] = 0;
  v27[2] = 0;
  v87 = v27;
  do
  {
    v34 = v30[1];
    ++v30;
    v33 = v34;
    if ( !v34 )
      goto LABEL_21;
    v35 = malloc(0x10u);
    v36 = v35;
    v35[1] = 0;
    *v35 = 0;
    v35[3] = v33;
    v35[2] = v29;
    if ( v28 )
    {
      if ( v35 == (_DWORD *)*v32 )
        goto LABEL_21;
      v37 = v32;
      v38 = 0;
      while ( ++v38 != v28 )
      {
        v39 = (_DWORD *)v37[1];
        ++v37;
        if ( v35 == v39 )
          goto LABEL_21;
      }
    }
    v40 = v87;
    v41 = (unsigned int)v87[1];
    if ( v41 <= v28 )
    {
      v87[1] = (unsigned int *)(v41 + 128);
      v42 = realloc(v32, 4 * (v41 + 128));
      v40 = v87;
      v32 = v42;
      *v87 = v42;
    }
    v32[v28] = v36;
    v40[2] = (unsigned int *)(v28++ + 1);
LABEL_21:
    ++v29;
  }
  while ( v29 != 256 );
  v43 = v32;
  v44 = v26;
  v45 = v31;
  memset(&g_codedata, 0, 0x400u);
  if ( !v28 )
    goto LABEL_66;
  if ( v28 == 1 )
  {
    v28 = *v43;
    free(v43);
    free(v87);
    goto LABEL_67;
  }
  v46 = v26;
  while ( 2 )
  {
    v47 = 0;
    v48 = (int)(v43 - 1);
    v49 = 0;
    v50 = 0;
    while ( 1 )
    {
      v53 = __OFSUB__(v28, v47);
      v51 = v28 == v47;
      v52 = (signed int)(v28 - v47++) < 0;
      if ( (unsigned __int8)(v52 ^ v53) | v51 )
        break;
      v55 = *(_DWORD *)(v48 + 4);
      v48 += 4;
      v54 = v55;
      if ( !v55 )
        break;
      if ( v50 && (v56 = *(_DWORD *)(v54 + 12), v56 >= *(_DWORD *)(v50 + 12)) )
      {
        if ( v49 )
        {
          if ( v56 < *(_DWORD *)(v49 + 12) )
            v49 = v54;
        }
        else
        {
          v49 = v54;
        }
        if ( v47 < 0 )
          break;
      }
      else
      {
        v49 = v50;
        v50 = v54;
        if ( v47 < 0 )
          break;
      }
    }
    v57 = v43;
    v58 = 0;
    while ( 1 )
    {
      v59 = *v57;
      v60 = v57;
      ++v58;
      ++v57;
      if ( v50 == v59 )
        break;
      if ( v58 == v28 )
      {
        v61 = *v87;
        goto LABEL_50;
      }
    }
    v84 = v28 + 0x3FFFFFFF;
    v61 = *v87;
    v28 = (unsigned int)v87[2] - 1;
    v87[2] = (unsigned int *)v28;
    *v60 = v43[v84];
    if ( !v28 )
    {
      v85 = malloc(0x10u);
      *v85 = v50;
      v65 = v85;
      v85[1] = v49;
      v85[3] = *(_DWORD *)(v49 + 12) + *(_DWORD *)(v50 + 12);
      goto LABEL_60;
    }
LABEL_50:
    if ( v49 != *v61 )
    {
      v62 = (int)(v61 + 1);
      v63 = 0;
      while ( 1 )
      {
        ++v63;
        v81 = (unsigned int *)v62;
        v62 += 4;
        if ( v63 == v28 )
          break;
        if ( v49 == *v81 )
          goto LABEL_81;
      }
      v64 = malloc(0x10u);
      *v64 = v50;
      v65 = v64;
      v64[1] = v49;
      v64[3] = *(_DWORD *)(v49 + 12) + *(_DWORD *)(v50 + 12);
      goto LABEL_56;
    }
    v81 = v61;
LABEL_81:
    v82 = v28-- + 0x3FFFFFFF;
    v87[2] = (unsigned int *)v28;
    *v81 = v61[v82];
    v83 = malloc(0x10u);
    *v83 = v50;
    v65 = v83;
    v83[1] = v49;
    v83[3] = *(_DWORD *)(v49 + 12) + *(_DWORD *)(v50 + 12);
    if ( v28 )
    {
LABEL_56:
      if ( v65 == (_DWORD *)*v43 )
        goto LABEL_63;
      v66 = v43;
      v67 = 0;
      while ( ++v67 != v28 )
      {
        v68 = (_DWORD *)v66[1];
        ++v66;
        if ( v65 == v68 )
          goto LABEL_63;
      }
    }
LABEL_60:
    v69 = (unsigned int)v87[1];
    if ( v69 <= v28 )
    {
      v87[1] = (unsigned int *)(v69 + 128);
      v43 = (unsigned int *)realloc(v43, 4 * (v69 + 128));
      *v87 = v43;
    }
    v43[v28] = (unsigned int)v65;
    v87[2] = (unsigned int *)(v28++ + 1);
LABEL_63:
    if ( v28 > 1 )
      continue;
    break;
  }
  v44 = v46;
  if ( v28 )
    v28 = *v43;
LABEL_66:
  free(v43);
  free(v87);
LABEL_67:
  v70 = 0;
  v71 = v45[1];
  v72 = v45[3];
  v73 = *((unsigned __int8 *)v45 + 16);
  v74 = (_DWORD *)v28;
  v75 = v45[2];
LABEL_70:
  if ( v71 == v72 )
    goto LABEL_76;
  do
  {
    do
    {
      v77 = (signed int)*(unsigned __int8 *)(*v45 + v72) >> v73;
      v73 = (unsigned __int8)(v73 + 1);
      v78 = v77 & 1;
      *((_BYTE *)v45 + 16) = v73;
      if ( v73 == 8 )
      {
        ++v72;
        v73 = 0;
        *((_BYTE *)v45 + 16) = 0;
        v45[3] = v72;
      }
      if ( !v78 )
      {
        v76 = (_DWORD *)*v74;
        if ( *v74 )
          goto LABEL_69;
        dllbuffer[v70++] = v74[2];
        v74 = *(_DWORD **)v28;
        goto LABEL_70;
      }
      v76 = (_DWORD *)v74[1];
      if ( v76 )
      {
LABEL_69:
        v74 = v76;
        goto LABEL_70;
      }
      dllbuffer[v70++] = v74[2];
      v74 = *(_DWORD **)(v28 + 4);
    }
    while ( v71 != v72 );
LABEL_76:
    ;
  }
  while ( v73 != v75 );
  dllbuffer[v70] = v74[2];
  sub_82BADFA0((void **)v28);
  free(v45);
  v79 = size;
  v80 = mono_image_open_from_data(dllbuffer, size, 1, &v92);// 解密后dll
  memset(dllbuffer, 0, v79);
  free(dllbuffer);
  if ( v80 && mono_assembly_load_from(v80, "Assembly-CSharp.dll", &v92) )
  {
    *(_DWORD *)(v86 + 4 * v44) = v80;
    dlclose(handle);
    result = 1;
  }
  else
  {
    dlclose(handle);
    result = 0;
  }
  return result;
}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>


从上面代码可以看到调用mono_image_open_from_data获取MonoImage,再调用mono_assembly_load_from完成对dll的加载,所以LoadGame最终也会走到libNetHTProtect.so中hook函数,判断是否须要修复,函数走完后直dump Assembly-CSharp.dll.dll就可以了,将dump出来的dll反编译后正常,如图4、5所示。

某易手游反外挂产品原理浅析

某易手游反外挂产品原理浅析


                                         图4

某易手游反外挂产品原理浅析

某易手游反外挂产品原理浅析


                              图5
整个反外挂流程到这里基本分析完成。
0x03:总结
1.该反外挂系统主要用到了svc 0系统调用做反调试,再加上动态加密解,内联、混淆,在一定程度给调试分析上加大了些难度。至于是否安全,个人觉得仁者见仁,智者见智,一个安全商业产品要做到产品易用性与绝对安全兼得基本上是不太可能的。


扫码关注微信公众号,及时获取最新资源信息!下载附件优惠VIP会员5折;永久VIP免费
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明:
1、本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
2、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,请勿任何商业目的与商业用途。
3、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4、论坛的所有内容都不保证其准确性,完整性,有效性,由于源码具有复制性,一经售出,概不退换。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
5、用户使用本网站必须遵守适用的法律法规,对于用户违法使用本站非法运营而引起的一切责任,由用户自行承担
6、本站所有资源来自互联网转载,版权归原著所有,用户访问和使用本站的条件是必须接受本站“免责声明”,如果不遵守,请勿访问或使用本网站
7、本站使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,本站不承担任何责任。
8、凡以任何方式登陆本网站或直接、间接使用本网站资料者,视为自愿接受本网站声明的约束。
9、本站以《2013 中华人民共和国计算机软件保护条例》第二章 “软件著作权” 第十七条为原则:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。若有学员需要商用本站资源,请务必联系版权方购买正版授权!
10、本网站如无意中侵犯了某个企业或个人的知识产权,请来信【站长信箱312337667@qq.com】告之,本站将立即删除。
郑重声明:
本站所有资源仅供用户本地电脑学习源代码的内含设计思想和原理,禁止任何其他用途!
本站所有资源、教程来自互联网转载,仅供学习交流,不得商业运营资源,不确保资源完整性,图片和资源仅供参考,不提供任何技术服务。
本站资源仅供本地编辑研究学习参考,禁止未经资源商正版授权参与任何商业行为,违法行为!如需商业请购买各资源商正版授权
本站仅收集资源,提供用户自学研究使用,本站不存在私自接受协助用户架设游戏或资源,非法运营资源行为。
 
在线客服
点击这里给我发消息 点击这里给我发消息 点击这里给我发消息
售前咨询热线
312337667

微信扫一扫,私享最新原创实用干货

QQ|免责声明|小黑屋|依星资源网 ( 鲁ICP备2021043233号-3 )|网站地图

GMT+8, 2024-10-28 18:21

Powered by Net188.com X3.4

邮箱:312337667@qq.com 客服QQ:312337667(工作时间:9:00~21:00)

快速回复 返回顶部 返回列表