nProtect APPGuard安卓反外挂分析

最后编辑时间: 2017-11-08

工具与环境:

IDA7.0

JEB2.2.5

Nexus 5

Android 4.4

目录:

一:app简单分析与java层反编译

二: compatible.so反调试与反反调试

三: compatible.so注册jni函数分析

四: stub.so反调试与反反调试

五: stub.so注册jni函数分析

六: Assembly-CSharp.dll解密分析

七: libengine模块分析

八:总结

一:app简单分析与java层反编译

整体图:

1.最近在学习手游保护方面的技术,本文是学习过程中分析某反外挂的一点记录,高手莫要见笑,有不对的地方还请指教,首先简单通过资源目录中文件名做基本了解,

在lib目录中有libmono.so、libunity.so,资源目录中存在(assets\bin\Data\Managed\Assembly-CSharp.dll),应该是unity 3D编写,通过反编译发现该文件己被加密,在资源目录下armeabi文件夹中还存放着libengine.sox与libstub.sox文件,看名字猜测很可能这两个文件就是反外挂其中的一些模块了,在看看lib目录下只有libcompatible.so模块比较可疑。如下图所示:

当我们用调试器附加游戏程进时会有如下提示:

被发现有调试器附加,下节我们将分析它的反调试机制。

2.通过JEB反编译来看看大致流程,反编译后先找到application类,代码如下图:

主要是加载so模块,so名称字符串被加密了,解密出来后so名称"compatible",将compatible.so放到IDA中反编译发现函数名被混淆了,字符串己加密,如下图:

通过以上简单分析,我们主要关注的重点关注的模块主要有lib目录下的libcompatible.so与资源目录中的libengine.sox与libstub.sox,还有就是发现java层的字符串与函数名都被混淆,so模块中的字符串也函数名也被混淆。

3.拷贝资源,解密libstub.sox并加载 。

在Lcom/inca/security/Core/AppGuardEngine初始函数<init>(Landroid/content/Context;Lcom/inca/security/AppGuard/AppGuardEventListener;Z)V中将判断X86或ARM平台并将对应的\assets\appguard中的libengine.sox、libstub.sox、update.dat拷贝到程序安装目录。JEB未能正常反编译出java代码,看smali代码。

复制代码
 1 :1946
 2 00001946  const/4             v9, 3
 3 00001948  if-ge               v6, v9, :1C16
 4 :194C
 5 0000194C  invoke-static       Binder->getABI()I
 6 00001952  move-result         v6
 7 00001954  move-object/from16  v0, p0
 8 00001958  move-object/from16  v1, p1
 9 0000195C  invoke-virtual      AppGuardEngine->iiIIIiiiIi(Context, I)Z, v0, v1, v6  # 拷贝资源
10 00001962  move-result         v6
11 00001964  if-eqz              v6, :1BE0
12 :1968
13 00001968  new-instance        v6, qb
14 0000196C  invoke-static       JNISoxProxy->getContext()Context
15 00001972  move-result-object  v9
16 00001974  invoke-direct       qb-><init>(Context)V, v6, v9
17 0000197A  const-string        v9, "fChY~_h\u0004yEr"  # libstub.sox
18 0000197E  invoke-virtual      qb->iiIIIiiiIi([B)V, v6, v8
19 00001984  invoke-static       b->iiIIIiiiIi(String)String, v9
20 0000198A  move-result-object  v9
21 0000198C  const-string        v10, "j\u000Fd\u0015r\u0013dHu\t"  # libstub.so
22 00001990  invoke-static       yb->iiIIIiiiIi(String)String, v10
23 00001996  move-result-object  v10
24 00001998  const/4             v11, 0
25 0000199A  invoke-virtual      qb->iiIIIiiiIi(String, String, [B)Z, v6, v9, v10, v11  # 解密libstub.sox((最终传入so层解密private static native byte[] iIiIIIiIiI(byte[] arg0, int arg1)))
26 000019A0  move-result         v6
27 000019A2  if-eqz              v6, :1BE0
28 :19A6
29 000019A6  new-instance        v6, File
30 000019AA  new-instance        v9, StringBuilder
31 000019AE  invoke-direct       StringBuilder-><init>()V, v9
32 000019B4  const/4             v10, 0
33 000019B6  invoke-static       JNISoxProxy->getContext()Context
34 000019BC  move-result-object  v11
35 000019BE  invoke-virtual      Context->getFilesDir()File, v11
36 000019C4  move-result-object  v11
37 000019C6  invoke-virtual      File->getAbsolutePath()String, v11
38 000019CC  move-result-object  v11
39 000019CE  invoke-virtual      StringBuilder->insert(I, String)StringBuilder, v9, v10, v11
40 000019D4  move-result-object  v9
41 000019D6  const-string        v10, "%FcHy^\u007FH$Ye"  # /libstub.so
42 000019DA  invoke-static       b->iiIIIiiiIi(String)String, v10
43 000019E0  move-result-object  v10
44 000019E2  invoke-virtual      StringBuilder->append(String)StringBuilder, v9, v10
45 000019E8  move-result-object  v9
46 000019EA  invoke-virtual      StringBuilder->toString()String, v9
47 000019F0  move-result-object  v9
48 000019F2  invoke-direct       File-><init>(String)V, v6, v9
49 000019F8  invoke-virtual      File->exists()Z, v6
50 :19FE
51 000019FE  move-result         v9
52 00001A00  if-eqz              v9, :1BE0
53 :1A04
54 00001A04  invoke-virtual      File->getAbsolutePath()String, v6
55 00001A0A  move-result-object  v9
56 00001A0C  invoke-static       System->load(String)V, v9  # 加载指定路径的SO
57 00001A12  invoke-direct/range AppGuardEngine->lllIIIlllI(Context)V, p0 .. p1  # 调用Native
58 :1A18
59 00001A18  invoke-virtual      File->delete()Z, v6
60 00001A1E  new-instance        v6, File
61 00001A22  new-instance        v9, StringBuilder
62 00001A26  invoke-direct       StringBuilder-><init>()V, v9
63 00001A2C  const/4             v10, 0
64 00001A2E  invoke-static       JNISoxProxy->getContext()Context
65 00001A34  move-result-object  v11
66 00001A36  invoke-virtual      Context->getFilesDir()File, v11
67 00001A3C  move-result-object  v11
68 00001A3E  invoke-virtual      File->getAbsolutePath()String, v11
69 00001A44  move-result-object  v11
70 00001A46  invoke-virtual      StringBuilder->insert(I, String)StringBuilder, v9, v10, v11
71 00001A4C  move-result-object  v9
72 00001A4E  const-string        v10, ")\no\u0004u\u0012s\u0004(\u0015i\u001E"  # /libstub.sox
73 00001A52  invoke-static       yb->iiIIIiiiIi(String)String, v10
74 00001A58  move-result-object  v10
75 00001A5A  invoke-virtual      StringBuilder->append(String)StringBuilder, v9, v10
76 00001A60  move-result-object  v9
77 00001A62  invoke-virtual      StringBuilder->toString()String, v9
78 00001A68  move-result-object  v9
79 00001A6A  invoke-direct       File-><init>(String)V, v6, v9
80 00001A70  invoke-virtual      File->delete()Z, v6
复制代码

4. 解密libstub.sox模块。

解密函数在类com/inca/security/qb中iiIIIiiiIi函数,代码如下:

复制代码
  1    @SuppressLint(value={"SdCardPath"}) public boolean iiIIIiiiIi(String arg25, String arg26, byte[] arg27) throws IOException, InvalidKeyException {

2 Object v18;
3 Object v5_2;
4 long v16_1;
5 Method v8_3;
6 Class v11_2;
7 Object v7_2;
8 Object v4_7;
9 Method v15; // doFinal
10 Method v14_1; // init java.security.Key
11 Object v13_1; // RSA/ECB/PKCS1Padding
12 int v8_1;
13 int v7;
14 FileInputStream v13;
15 Method v4_6;
16 byte[] v7_1;
17 boolean v4_2;
18 Method v5_1; // read
19 byte[] v12;
20 byte[] v11;
21 Object v10; // /
22 Class v9; // java.io.FileInputStream
23 try {
24 v9 = Class.forName(vb.iiIIIiiiIi("&3:3b;#|\n; 7\u0005<<\'8\u00018 )3!")); // java.io.FileInputStream
25 Constructor v4_1 = v9.getConstructor(String.class);
26 v10 = v4_1.newInstance(arg25.indexOf(yb.iiIIIiiiIi("I")) == 0 ? arg25 : new StringBuilder().insert(0, this.iiIiiiIIIi).append(arg25).toString()); // /
27 v11 = new byte[16];
28 v12 = new byte[4];
29 v5_1 = v9.getMethod(vb.iiIIIiiiIi(" )3("), byte[].class, Integer.TYPE, Integer.TYPE); // read
30 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(3));
31 if(v11[0] == 83 && v11[1] == 79 && v11[2] == 88) { // 判断开头是否为SOX
32 goto label_82;
33 }
34
35 v4_2 = false;
36 return v4_2;
37 }
38 catch(Exception v4) {
39 goto label_78;
40 }
41
42 label_82:
43 int v4_3 = 3;
44 try {
45 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(2));
46 if((((short)((((short)v11[0])) | (((short)v11[1])) << 8))) != 1) {
47 return false;
48 }
49
50 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(1));
51 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(2));
52 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(2));
53 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(4));
54 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(4));
55 v5_1.invoke(v10, v12, Integer.valueOf(0), Integer.valueOf(4));
56 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(12));
57 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(16));
58 v5_1.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(16));
59 byte[] v4_5 = null;
60 if(v11[0] == 0 || v11[1] == 0 || v11[14] == 0 || v11[15] == 0) {
61 v7_1 = v4_5;
62 v4_6 = v5_1;
63 goto label_291;
64 label_276:
65 while(v7 < 64) {
66 v13.read(v11);
67 if(v8_1 == v14) {
68 v4_5 = new byte[16];
69 System.arraycopy(v11, 0, v4_5, 0, 16);
70 }
71
72 v7 = v8_1 + 1;
73 v8_1 = v7;
74 }
75
76 v13.close();
77 v7_1 = v4_5;
78 v4_6 = v5_1;
79 }
80 else {
81 File v8 = new File(String.format(yb.iiIIIiiiIi("CuI#\u0015(\u0012v\r"), arg25.substring(0, arg25.lastIndexOf(47)), qb.iiIIIiiiIi(v11))); // %s/%s.tpk
82 if(v8.exists()) {
83 v13 = new FileInputStream(v8);
84 v13.read(v11);
85 int v14 = (Math.abs(v11[0] << 24 | v11[4] << 16 | v11[8] << 8 | v11[12]) + 1) % 64;
86 v7 = 1;
87 v8_1 = 1;
88 goto label_276;
89 }
90 else {
91 return false;
92 }
93 }
94
95 label_291:
96 v4_6.invoke(v10, v11, Integer.valueOf(0), Integer.valueOf(4));
97 v4_5 = new byte[(v11[3] & 255) << 24 | 0 | (v11[2] & 255) << 16 | (v11[1] & 255) << 8 | v11[0] & 255];
98 v5_1 = v9.getMethod(vb.iiIIIiiiIi(" )3("), byte[].class); // read
99 v5_1.invoke(v10, v4_5);
100 Class v8_2 = Class.forName(yb.iiIIIiiiIi("\fg\u0010g\u001E(\u0005t\u001Fv\u0012iHE\u000Fv\u000Ec\u0014")); // javax.crypto.Cipher
101 Method v11_1 = v8_2.getMethod(vb.iiIIIiiiIi("+78\u001B\"!83\"1)"), String.class); // getInstance
102 v13_1 = v11_1.invoke(null, yb.iiIIIiiiIi("T5GIC%DIV-E576g\u0002b\u000Fh\u0001")); // RSA/ECB/PKCS1Padding
103 v14_1 = v8_2.getMethod(vb.iiIIIiiiIi(";\";8"), Integer.TYPE, Class.forName(yb.iiIIIiiiIi("\fg\u0010gHu\u0003e\u0013t\u000Fr\u001F(-c\u001F"))); // init java.security.Key
104 v14_1.invoke(v13_1, Integer.valueOf(2), this.iIiIIiIiIi);
105 v15 = v8_2.getMethod(vb.iiIIIiiiIi("(=\n;\"3 "), byte[].class); // doFinal
106 v4_7 = v15.invoke(v13_1, v4_5);
107 if(v7_1 != null) {
108 v13_1 = v11_1.invoke(null, yb.iiIIIiiiIi("\'C5")); // AES
109 v14_1.invoke(v13_1, Integer.valueOf(2), Class.forName(vb.iiIIIiiiIi("&3:34|/ 5\"8=b!<7/|\u001F7/ )&\u000775\u0001<7/")).getConstructor(byte[].class, String.class).newInstance(v7_1, yb.iiIIIiiiIi("\'C5"))); // javax.crypto.spec.SecretKeySpec AES
110 v4_7 = v15.invoke(v13_1, v4_7);
111 }
112
113 v7_2 = null;
114 v7_2 = v11_1.invoke(v7_2, vb.iiIIIiiiIi("\r\u0017\u001F"));
115 v14_1.invoke(v7_2, Integer.valueOf(2), Class.forName(yb.iiIIIiiiIi("\fg\u0010g\u001E(\u0005t\u001Fv\u0012iHu\u0016c\u0005(5c\u0005t\u0003r-c\u001FU\u0016c\u0005")).getConstructor(byte[].class, String.class).newInstance(v4_7, vb.iiIIIiiiIi("\r\u0017\u001F")));
116 v11_2 = Class.forName(yb.iiIIIiiiIi("\fg\u0010gHo\t($\u007F\u0012c\'t\u0014g\u001FI\u0013r\u0016s\u0012U\u0012t\u0003g\u000B"));
117 v13_1 = v11_2.getConstructor(null).newInstance(null);
118 byte[] v14_2 = new byte[1024];
119 v15 = v8_2.getMethod(vb.iiIIIiiiIi("\'<6-&)"), byte[].class, Integer.TYPE, Integer.TYPE);
120 Method v16 = v11_2.getMethod(yb.iiIIIiiiIi("\u0011t\u000Fr\u0003"), byte[].class);
121 for(v4_6 = v5_1; true; v4_6 = v5_1) {
122 v4_3 = v4_6.invoke(v10, v14_2).intValue();
123 if(v4_3 == -1) {
124 break;
125 }
126
127 v16.invoke(v13_1, v15.invoke(v7_2, v14_2, Integer.valueOf(0), Integer.valueOf(v4_3)));
128 }
129
130 v16.invoke(v13_1, v8_2.getMethod(vb.iiIIIiiiIi("(=\n;\"3 "), null).invoke(v7_2, null));
131 v4_7 = v11_2.getMethod(yb.iiIIIiiiIi("\u0012i$\u007F\u0012c\'t\u0014g\u001F"), null).invoke(v13_1, null);
132 if(arg25.indexOf(vb.iiIIIiiiIi("c")) != 0) {
133 arg26 = new StringBuilder().insert(0, this.iiIiiiIIIi).append(arg26).toString();
134 }
135
136 Class v7_3 = Class.forName(yb.iiIIIiiiIi("l\u0007p\u0007(\u000FiH@\u000Fj\u0003I\u0013r\u0016s\u0012U\u0012t\u0003g\u000B"));
137 v8_3 = v7_3.getMethod(vb.iiIIIiiiIi("; %&)"), byte[].class);
138 v14_1 = v7_3.getMethod(yb.iiIIIiiiIi("\u0005j\tu\u0003"), null);
139 v15 = v7_3.getMethod(vb.iiIIIiiiIi("*>9!$"), null);
140 v7_2 = v7_3.getConstructor(String.class).newInstance(arg26);
141 v16_1 = na.iIIIiiiIII(((byte[])v4_7), 5);
142 v5_2 = null;
143 }
144 catch(Exception v4) {
145 goto label_78;
146 }
147
148 try {
149 v18 = Binder.getReserved1();
150 if(v18 == null) {
151 goto label_761;
152 }
153 }
154 catch(Exception v4) {
155 goto label_760;
156 }
157
158 try {
159 v5_2 = v18.getClass().getMethod(yb.iiIIIiiiIi("o/o/O\u000Fo/o/"), byte[].class, Integer.TYPE).invoke(v18, v4_7, Integer.valueOf(((int)v16_1)));
160 }
161 catch(Exception v4) {
162 try {
163 v4.printStackTrace();
164 goto label_659;
165 label_761:
166 byte[] v5_3 = AppGuardEngine.iiIIIiiiIi(((byte[])v4_7), ((int)v16_1)); // 传入SO层解密 (该Native函数在compatible.so进行动态注册)
167 label_760:
168 }
169 catch(Exception v4) {
170 goto label_760;
171 }
172 }
173
174 label_659:
175 v4_3 = 3;
176 try {
177 int v12_1 = v12[0] & 255 | ((v12[v4_3] & 255) << 24 | 0 | (v12[2] & 255) << 16 | (v12[1] & 255) << 8);
178 Class v16_2 = Class.forName(vb.iiIIIiiiIi("&3:3b\'8; |6;<|\r6 7>a~"));
179 Object v17 = v16_2.getConstructor(null).newInstance(null);
180 v16_2.getMethod(yb.iiIIIiiiIi("s\u0016b\u0007r\u0003"), byte[].class, Integer.TYPE, Integer.TYPE).invoke(v17, v5_2, Integer.valueOf(0), Integer.valueOf(v5_2.length));
181 v16_1 = v16_2.getMethod(vb.iiIIIiiiIi("5)&\u001A3 \')"), null).invoke(v17, null).longValue();
182 if(v12_1 != 0 && v12_1 != (((int)v16_1))) {
183 v14_1.invoke(v7_2, null);
184 v4_2 = false;
185 }
186 else {
187 v8_3.invoke(v7_2, v5_2);
188 v15.invoke(v7_2, null);
189 v14_1.invoke(v7_2, null);
190 v9.getMethod(yb.iiIIIiiiIi("\u0005j\tu\u0003"), null).invoke(v10, null);
191 v11_2.getMethod(vb.iiIIIiiiIi("/>#!)"), null).invoke(v13_1, null);
192 v9.getMethod(yb.iiIIIiiiIi("\u0005j\tu\u0003"), null).invoke(v10, null);
193 v4_2 = true;
194 }
195
196 return v4_2;
197 }
198 catch(Exception v4) {
199 label_78:
200 Exception v5_4 = v4;
201 v4_2 = false;
202 v5_4.printStackTrace();
203 return v4_2;
204 }
205 }

复制代码

java层AES解密再传入传入so层解密private static native byte[] iIiIIIiIiI(byte[] arg0, int arg1)。

5. 解密libengine.sox模块

在Lcom/inca/security/Core/AppGuardEngine;->iiIIIiiiIi([B)Z生成一个随机数后SHA1后字会串做为解密后的文件名存放在/data/data/包名/files/目录下,解密函数与上一步相同。

生成随机数代码:

复制代码
 1 .method private synthetic iiIIIiiiIi([B)Z
2 .registers 12
3 .annotation build SuppressLint
4 value = {
5 "TrulyRandom"
6 }
7 .end annotation
8 .annotation system Throws
9 value = {
10 AppGuardException
11 }
12 .end annotation
13 00000000 const/4 v9, 2
14 00000002 const/16 v8, -0x007E
15 00000006 const/16 v7, 0x0030
16 0000000A const/4 v2, 0
17 0000000C const/4 v3, 1
18 :E
19 0000000E const-string v1, "U.GW" # SHA1
20 00000012 invoke-static yb->iiIIIiiiIi(String)String, v1
21 00000018 move-result-object v1
22 0000001A invoke-static MessageDigest->getInstance(String)MessageDigest, v1
23 :20
24 00000020 move-result-object v1
25 :22
26 00000022 new-instance v4, SecureRandom
27 00000026 invoke-direct SecureRandom-><init>()V, v4
28 0000002C const/16 v5, 0x0100
29 00000030 new-array v5, v5, [B
30 00000034 const/16 v6, 0x0126
31 00000038 invoke-virtual SecureRandom->nextBytes([B)V, v4, v5
32 0000003E invoke-virtual MessageDigest->update([B)V, v1, v5
33 00000044 invoke-virtual SecureRandom->nextBytes([B)V, v4, v5
34 0000004A invoke-virtual MessageDigest->update([B)V, v1, v5
35 00000050 new-instance v4, BigInteger
36 00000054 invoke-virtual MessageDigest->digest()[B, v1
37 0000005A move-result-object v1
38 0000005C invoke-direct BigInteger-><init>(I, [B)V, v4, v3, v1
39 00000062 const/16 v1, 0x0010
40 00000066 invoke-virtual BigInteger->toString(I)String, v4, v1 # 随机数后SHA1值
41 0000006C move-result-object v1
42 0000006E iput-object v1, p0, AppGuardEngine->IiIIiiiiii_Random_SHA1:String # 解密后文件名
43 //解密并调用
44 00000D7A new-instance v4, qb
45 00000D7E invoke-static JNISoxProxy->getContext()Context
46 00000D84 move-result-object v5
47 00000D86 invoke-direct qb-><init>(Context)V, v4, v5
48 00000D8C const-string v5, "fChOdMcDo\u0004yEr" # libengine.sox
49 00000D90 invoke-virtual qb->iiIIIiiiIi([B)V, v4, v1
50 00000D96 invoke-static b->iiIIIiiiIi(String)String, v5
51 00000D9C move-result-object v1
52 00000D9E iget-object v5, p0, AppGuardEngine->IiIIiiiiii_Random_SHA1:String
53 00000DA2 const/4 v6, 0
54 00000DA4 invoke-virtual qb->iiIIIiiiIi(String, String, [B)Z, v4, v1, v5, v6 # 解密libengine.sox(最终传入so层解密private static native byte[] iIiIIIiIiI(byte[] arg0, int arg1))
55 :DAA
56 00000DAA move-object v0, p0
57 :DAC
58 00000DAC invoke-static JNISoxProxy->getContext()Context
59 00000DB2 move-result-object v1
60 00000DB4 new-instance v4, StringBuilder
61 00000DB8 invoke-direct StringBuilder-><init>()V, v4
62 00000DBE invoke-static JNISoxProxy->getContext()Context
63 00000DC4 move-result-object v5
64 00000DC6 invoke-virtual Context->getFilesDir()File, v5
65 00000DCC move-result-object v5
66 00000DCE invoke-virtual File->getAbsolutePath()String, v5
67 00000DD4 move-result-object v5
68 00000DD6 invoke-virtual StringBuilder->insert(I, String)StringBuilder, v4, v2, v5
69 00000DDC move-result-object v4
70 00000DDE const-string v5, "%" # /
71 00000DE2 invoke-static b->iiIIIiiiIi(String)String, v5
72 00000DE8 move-result-object v5
73 00000DEA invoke-virtual StringBuilder->append(String)StringBuilder, v4, v5
74 00000DF0 move-result-object v4
75 00000DF2 iget-object v5, p0, AppGuardEngine->IiIIiiiiii_Random_SHA1:String
76 00000DF6 invoke-virtual StringBuilder->append(String)StringBuilder, v4, v5
77 00000DFC move-result-object v4
78 00000DFE invoke-virtual StringBuilder->toString()String, v4
79 00000E04 move-result-object v4
80 00000E06 invoke-direct AppGuardEngine->IIIIIIIlIl(Context, String, [B)I, v0, v1, v4, p1 # 将解密后将libengine文件路径传入该Native函数中调用
81 00000E0C move-result v1
82 00000E0E if-gez v1, :E9A
复制代码

解密后的so会在Native函数中通过dlopen、dlsym来调用。

二: compatible.so反调试与反反调试

1. 反调试 (文件偏移 13284)

复制代码
 1 /data/app-lib/com.digitalsky.girlsfrontline.cn-1/libcompatible.so    757C8000    0005F000
2 .text:757DB284 loc_757DB284 ; CODE XREF: JNI_OnLoad+254↑j
3 .text:757DB284 00 00 5C E3 CMP R12, #0
4 .text:757DB288 18 00 00 BA BLT loc_757DB2F0
5 .text:757DB28C 00 30 68 E2 RSB R3, R8, #0
6 .text:757DB290 03 00 20 E0 EOR R0, R0, R3
7 .text:757DB294 08 80 80 E0 ADD R8, R0, R8
8 .text:757DB298 0D 00 58 E3 CMP R8, #0xD ; 判断SDK版本
9 .text:757DB29C 9F FF FF DA BLE loc_757DB120
10 .text:757DB2A0
11 .text:757DB2A0 loc_757DB2A0 ; CODE XREF: JNI_OnLoad+2E4↓j
12 .text:757DB2A0 7D 2B 00 EB BL _Z11lIlIlIIIIIIv ; 创建3进程和多线程反调试
13 .text:757DB2A4 00 20 50 E2 SUBS R2, R0, #0 ; char *
复制代码

如果SDK大于0XD时就创建3进程与多线程反调试:

复制代码
  1 .text:756F84B0             EXPORT _Z11IIIIIIIllllv
2 .text:756F84B0 _Z11IIIIIIIllllv ; CODE XREF: JNI_OnLoad:loc_756EE6E4↑p
3 .text:756F84B0
4 .text:756F84B0 var_2C= -0x2C
5 .text:756F84B0 var_28= -0x28
6 .text:756F84B0 var_24= -0x24
7 .text:756F84B0 var_20= -0x20
8 .text:756F84B0
9 .text:756F84B0 ; __unwind {
10 .text:756F84B0 F0 43 2D E9 STMFD SP!, {R4-R9,LR}
11 .text:756F84B4 C0 43 9F E5 LDR R4, =(_GLOBAL_OFFSET_TABLE_ - 0x756F84C8)
12 .text:756F84B8 C0 23 9F E5 LDR R2, =(__stack_chk_guard_ptr - 0x7572FED0)
13 .text:756F84BC C0 33 9F E5 LDR R3, =(_ZN6Global10lIlIIllIIlE_ptr - 0x7572FED0)
14 .text:756F84C0 04 40 8F E0 ADD R4, PC, R4 ; GLOBAL_OFFSET_TABLE
15 .text:756F84C4 02 70 94 E7 LDR R7, [R4,R2]
16 .text:756F84C8 14 D0 4D E2 SUB SP, SP, #0x14
17 .text:756F84CC 00 20 97 E5 LDR R2, [R7]
18 .text:756F84D0 0C 20 8D E5 STR R2, [SP,#0x30+var_24]
19 .text:756F84D4 03 60 94 E7 LDR R6, [R4,R3]
20 .text:756F84D8 06 00 A0 E1 MOV R0, R6 ; int *
21 .text:756F84DC 72 F2 FF EB BL pipi
22 .text:756F84E0 00 00 50 E3 CMP R0, #0
23 .text:756F84E4 13 00 00 BA BLT loc_756F8538
24 .text:756F84E8 08 00 86 E2 ADD R0, R6, #8 ; int *
25 .text:756F84EC 6E F2 FF EB BL pipi
26 .text:756F84F0 00 00 50 E3 CMP R0, #0
27 .text:756F84F4 0F 00 00 BA BLT loc_756F8538
28 .text:756F84F8 48 00 86 E2 ADD R0, R6, #0x48 ; int *
29 .text:756F84FC 6A F2 FF EB BL pipi
30 .text:756F8500 00 00 50 E3 CMP R0, #0
31 .text:756F8504 0B 00 00 BA BLT loc_756F8538
32 .text:756F8508 30 00 86 E2 ADD R0, R6, #0x30 ; int *
33 .text:756F850C 66 F2 FF EB BL pipi
34 .text:756F8510 00 00 50 E3 CMP R0, #0
35 .text:756F8514 07 00 00 BA BLT loc_756F8538
36 .text:756F8518 38 00 86 E2 ADD R0, R6, #0x38 ; int *
37 .text:756F851C 62 F2 FF EB BL pipi
38 .text:756F8520 00 00 50 E3 CMP R0, #0
39 .text:756F8524 03 00 00 BA BLT loc_756F8538
40 .text:756F8528 40 00 86 E2 ADD R0, R6, #0x40 ; int *
41 .text:756F852C 5E F2 FF EB BL pipi
42 .text:756F8530 00 00 50 E3 CMP R0, #0
43 .text:756F8534 01 00 00 AA BGE loc_756F8540
44 .text:756F8538
45 .text:756F8538 loc_756F8538 ; CODE XREF: IIIIIIIllll(void)+34↑j
46 .text:756F8538 ; IIIIIIIllll(void)+44↑j ...
47 .text:756F8538 00 00 A0 E3 MOV R0, #0 ; int
48 .text:756F853C 4E F2 FF EB BL _Z10llIIlIIIlli ; llIIlIIIll(int)
49 .text:756F8540
50 .text:756F8540 loc_756F8540 ; CODE XREF: IIIIIIIllll(void)+84↑j
51 .text:756F8540 01 10 A0 E3 MOV R1, #1
52 .text:756F8544 04 00 A0 E3 MOV R0, #4 ; option
53 .text:756F8548 AF CB FF EB BL prctl
54 .text:756F854C 72 F2 FF EB BL getpid_0
55 .text:756F8550 30 33 9F E5 LDR R3, =(_ZN6Global10lIllllIllIE_ptr - 0x7572FED0)
56 .text:756F8554 03 50 94 E7 LDR R5, [R4,R3]
57 .text:756F8558 00 00 85 E5 STR R0, [R5] ; Global::lIllllIllI
58 .text:756F855C 60 F2 FF EB BL fork
59 .text:756F8560 01 00 70 E3 CMN R0, #1
60 .text:756F8564 04 00 85 E5 STR R0, [R5,#(dword_757309F4 - 0x757309F0)]
61 .text:756F8568 92 00 00 0A BEQ loc_756F87B8
62 .text:756F856C
63 .text:756F856C loc_756F856C ; CODE XREF: IIIIIIIllll(void)+314↓j
64 .text:756F856C 00 00 50 E3 CMP R0, #0
65 .text:756F8570 34 00 00 DA BLE loc_756F8648
66 .text:756F8574 00 80 A0 E3 MOV R8, #0
67 .text:756F8578 01 90 A0 E3 MOV R9, #1
68 .text:756F857C 08 33 9F E5 LDR R3, =(_ZN6Global10IIlIIlIIlIE_ptr - 0x7572FED0)
69 .text:756F8580 10 10 8D E2 ADD R1, SP, #0x30+var_20
70 .text:756F8584 38 00 96 E5 LDR R0, [R6,#(dword_75730EBC - 0x75730E84)] ; int
71 .text:756F8588 03 30 94 E7 LDR R3, [R4,R3]
72 .text:756F858C 04 20 A0 E3 MOV R2, #4 ; unsigned int
73 .text:756F8590 10 80 21 E5 STR R8, [R1,#-0x10]!
74 .text:756F8594 00 90 C3 E5 STRB R9, [R3] ; Global::IIlIIlIIlI
75 .text:756F8598 7B F2 FF EB BL read
76 .text:756F859C EC 12 9F E5 LDR R1, =(_ZN6Global6ThreadE_ptr - 0x7572FED0)
77 .text:756F85A0 EC 22 9F E5 LDR R2, =(_Z10IlIIlllIIlPv_ptr - 0x7572FED0)
78 .text:756F85A4 04 30 85 E2 ADD R3, R5, #4 ; void *
79 .text:756F85A8 01 60 94 E7 LDR R6, [R4,R1]
80 .text:756F85AC 02 20 94 E7 LDR R2, [R4,R2] ; void (__cdecl )(void *)
81 .text:756F85B0 08 10 A0 E1 MOV R1, R8 ; pthread_attr_t *
82 .text:756F85B4 06 00 A0 E1 MOV R0, R6 ; int *
83 .text:756F85B8 6D F1 FF EB BL pthread_create_0
84 .text:756F85BC 08 00 50 E1 CMP R0, R8
85 .text:756F85C0 80 00 00 BA BLT loc_756F87C8
86 .text:756F85C4
87 .text:756F85C4 loc_756F85C4 ; CODE XREF: IIIIIIIllll(void)+334↓j
88 .text:756F85C4 CC 32 9F E5 LDR R3, =(_Z10IIlIlllllIPv_ptr - 0x7572FED0)
89 .text:756F85C8 04 00 86 E2 ADD R0, R6, #4 ; int *
90 .text:756F85CC 00 10 A0 E3 MOV R1, #0 ; pthread_attr_t *
91 .text:756F85D0 03 20 94 E7 LDR R2, [R4,R3] ; void (__cdecl )(void *)
92 .text:756F85D4 09 30 A0 E3 MOV R3, #9 ; void *
93 .text:756F85D8 65 F1 FF EB BL pthread_create_0
94 .text:756F85DC 00 00 50 E3 CMP R0, #0
95 .text:756F85E0 6C 00 00 BA BLT loc_756F8798
96 .text:756F85E4
97 .text:756F85E4 loc_756F85E4 ; CODE XREF: IIIIIIIllll(void)+304↓j
98 .text:756F85E4 00 10 A0 E3 MOV R1, #0 ; pthread_attr_t *
99 .text:756F85E8 AC 22 9F E5 LDR R2, =(_Z11IIIlllIIIIIPv_ptr - 0x7572FED0)
100 .text:756F85EC 01 30 A0 E1 MOV R3, R1 ; void *
101 .text:756F85F0 02 20 94 E7 LDR R2, [R4,R2] ; void (__cdecl )(void *)
102 .text:756F85F4 10 00 86 E2 ADD R0, R6, #0x10 ; int *
103 .text:756F85F8 5D F1 FF EB BL pthread_create_0
104 .text:756F85FC 00 10 A0 E3 MOV R1, #0 ; pthread_attr_t *
105 .text:756F8600 98 22 9F E5 LDR R2, =(_Z11IIIlIIlIllIPv_ptr - 0x7572FED0)
106 .text:756F8604 01 30 A0 E1 MOV R3, R1 ; void *
107 .text:756F8608 02 20 94 E7 LDR R2, [R4,R2] ; void (__cdecl )(void *)
108 .text:756F860C 04 00 8D E2 ADD R0, SP, #0x30+var_2C ; int *
109 .text:756F8610 57 F1 FF EB BL pthread_create_0
110 .text:756F8614 88 32 9F E5 LDR R3, =(_Z10IIllIIlIlIPv_ptr - 0x7572FED0)
111 .text:756F8618 08 00 8D E2 ADD R0, SP, #0x30+var_28 ; int *
112 .text:756F861C 00 10 A0 E3 MOV R1, #0 ; pthread_attr_t *
113 .text:756F8620 03 20 94 E7 LDR R2, [R4,R3] ; void (__cdecl )(void *)
114 .text:756F8624 01 30 A0 E3 MOV R3, #1 ; void *
115 .text:756F8628 51 F1 FF EB BL pthread_create_0
116 .text:756F862C
117 .text:756F862C loc_756F862C ; CODE XREF: IIIIIIIllll(void)+250↓j
118 .text:756F862C 0C 20 9D E5 LDR R2, [SP,#0x30+var_24]
119 .text:756F8630 00 30 97 E5 LDR R3, [R7]
120 .text:756F8634 01 00 A0 E3 MOV R0, #1
121 .text:756F8638 03 00 52 E1 CMP R2, R3
122 .text:756F863C 8D 00 00 1A BNE loc_756F8878
123 .text:756F8640 14 D0 8D E2 ADD SP, SP, #0x14
124 .text:756F8644 F0 83 BD E8 LDMFD SP!, {R4-R9,PC}
125 .text:756F8648 ; ---------------------------------------------------------------------------
126 .text:756F8648
127 .text:756F8648 loc_756F8648 ; CODE XREF: IIIIIIIllll(void)+C0↑j
128 .text:756F8648 72 CB FF EB BL getpid
129 .text:756F864C 04 00 85 E5 STR R0, [R5,#(dword_757309F4 - 0x757309F0)]
130 .text:756F8650 23 F2 FF EB BL fork
131 .text:756F8654 04 10 85 E2 ADD R1, R5, #4 ; void *
132 .text:756F8658 08 00 85 E5 STR R0, [R5,#(dword_757309F8 - 0x757309F0)]
133 .text:756F865C 04 20 A0 E3 MOV R2, #4 ; unsigned int
134 .text:756F8660 3C 00 96 E5 LDR R0, [R6,#(dword_75730EC0 - 0x75730E84)] ; int
135 .text:756F8664 56 F2 FF EB BL write_0
136 .text:756F8668 08 30 95 E5 LDR R3, [R5,#(dword_757309F8 - 0x757309F0)]
137 .text:756F866C 01 00 73 E3 CMN R3, #1
138 .text:756F8670 64 00 00 0A BEQ loc_756F8808
139 .text:756F8674
140 .text:756F8674 loc_756F8674 ; CODE XREF: IIIIIIIllll(void)+364↓j
141 .text:756F8674 00 00 53 E3 CMP R3, #0
142 .text:756F8678 01 00 A0 E3 MOV R0, #1 ; option
143 .text:756F867C 09 10 A0 E3 MOV R1, #9
144 .text:756F8680 1F 00 00 DA BLE loc_756F8704
145 .text:756F8684 60 CB FF EB BL prctl
146 .text:756F8688 00 12 9F E5 LDR R1, =(_ZN6Global6ThreadE_ptr - 0x7572FED0)
147 .text:756F868C 00 22 9F E5 LDR R2, =(_Z10IlIIlllIIlPv_ptr - 0x7572FED0)
148 .text:756F8690 08 30 85 E2 ADD R3, R5, #8 ; void *
149 .text:756F8694 01 60 94 E7 LDR R6, [R4,R1]
150 .text:756F8698 02 20 94 E7 LDR R2, [R4,R2] ; void (__cdecl )(void *)
151 .text:756F869C 00 10 A0 E3 MOV R1, #0 ; pthread_attr_t *
152 .text:756F86A0 06 00 A0 E1 MOV R0, R6 ; int *
153 .text:756F86A4 32 F1 FF EB BL pthread_create_0
154 .text:756F86A8 00 00 50 E3 CMP R0, #0
155 .text:756F86AC 59 00 00 BA BLT loc_756F8818
156 .text:756F86B0
157 .text:756F86B0 loc_756F86B0 ; CODE XREF: IIIIIIIllll(void)+384↓j
158 .text:756F86B0 E0 31 9F E5 LDR R3, =(_Z10IIlIlllllIPv_ptr - 0x7572FED0)
159 .text:756F86B4 04 00 86 E2 ADD R0, R6, #4 ; int *
160 .text:756F86B8 00 10 A0 E3 MOV R1, #0 ; pthread_attr_t *
161 .text:756F86BC 03 20 94 E7 LDR R2, [R4,R3] ; void (__cdecl )(void *)
162 .text:756F86C0 01 30 A0 E3 MOV R3, #1 ; void *
163 .text:756F86C4 2A F1 FF EB BL pthread_create_0
164 .text:756F86C8 00 00 50 E3 CMP R0, #0
165 .text:756F86CC 45 00 00 BA BLT loc_756F87E8
166 .text:756F86D0
167 .text:756F86D0 loc_756F86D0 ; CODE XREF: IIIIIIIllll(void)+354↓j
168 .text:756F86D0 CC 31 9F E5 LDR R3, =(_Z10IIllIIlIlIPv_ptr - 0x7572FED0)
169 .text:756F86D4 00 10 A0 E3 MOV R1, #0 ; pthread_attr_t *
170 .text:756F86D8 03 20 94 E7 LDR R2, [R4,R3] ; void (__cdecl )(void *)
171 .text:756F86DC 02 30 A0 E3 MOV R3, #2 ; void *
172 .text:756F86E0 08 00 8D E2 ADD R0, SP, #0x30+var_28 ; int *
173 .text:756F86E4
174 .text:756F86E4 loc_756F86E4 ; CODE XREF: IIIIIIIllll(void)+2E4↓j
175 .text:756F86E4 22 F1 FF EB BL pthread_create_0
176 .text:756F86E8 08 00 9D E5 LDR R0, [SP,#0x30+var_28] ; int
177 .text:756F86EC 00 10 A0 E3 MOV R1, #0 ; void **
178 .text:756F86F0 A9 F1 FF EB BL pthread_join
179 .text:756F86F4 00 00 96 E5 LDR R0, [R6] ; int
180 .text:756F86F8 00 10 A0 E3 MOV R1, #0 ; void **
181 .text:756F86FC A6 F1 FF EB BL pthread_join
182 .text:756F8700 C9 FF FF EA B loc_756F862C
183 .text:756F8704 ; ---------------------------------------------------------------------------
184 .text:756F8704
185 .text:756F8704 loc_756F8704 ; CODE XREF: IIIIIIIllll(void)+1D0↑j
186 .text:756F8704 40 CB FF EB BL prctl
187 .text:756F8708 03 F2 FF EB BL getpid_0
188 .text:756F870C 05 10 A0 E1 MOV R1, R5
189 .text:756F8710 04 20 A0 E3 MOV R2, #4 ; unsigned int
190 .text:756F8714 08 00 A1 E5 STR R0, [R1,#(dword_757309F8 - 0x757309F0)]!
191 .text:756F8718 34 00 96 E5 LDR

请在下方留下您的评论.加入TG吹水群