Android逆向之路---Faceu的登录功能真的只提交了用户名和密码吗

问题

几乎99%的软件都有登录功能,而登录这一个动作真的将我们的用户名和密码上传到了服务器吗,会不会有个人隐私呢。根据我们这个问题,我们用FaceU这个软件,逆向来看看他的登录功能到底都传了什么数据。

准备工作

首先下载faceu的APK,具体下载地址大家可以去各大应用市场,我下载的版本是v2.2.6。

需要的工具

  • apktool (拆包APK用)
  • dex2jar (反编译dex文件用)

需要的工具下载地址:https://github.com/hanhan12312/android_reverse_practice/tree/master/tools

拆包

首先,我们利用apktool拆包apk,执行命令

1
apktool d faceu.apk

这样在当前文件夹就得到了一个faceu的文件夹。

定位代码

我们打开Faceu软件,点击下面的已有账号在此登录,然后弹出来登录界面,如图所示

我们利用字符串搜索法,这个页面的注册的EditText的hint字为”Faceu号/手机号”,我们搜索res文件夹内所有文件的内容,搜索此关键字找到两处,位置都在res/values/strings.xml文件内

strings.xml

1
2
<string name="str_account_hint">Faceu号 / 手机号</string>
<string name="str_search_user">Faceu号/手机号</string>

根据name我们也能知道,account_hint是账号的输入框,而另一个是用于搜索的。
我们知道一个布局文件肯定有用到过这个值。所以我们在工程内搜索”str_account_hint”,可是结果却发现只有两处引用到,如图
这里写图片描述
看来faceu的程序员们是没有在布局中引用,那就有可能在java代码内引用到,那就去看看”str_account_hint”在代码对应的值是多少。
紧接着我们顺着str_account_hint这个名字在res/values/public.xml文件内搜索”str_account_hint”,public.xml是在编译期间生成的文字对应编译后资源的id。
public.xml

1
<public type="string" name="str_account_hint" id="0x7f070047" />

由此我们可以看出在java代码内对应的是0x7f070047。因此我们再次在代码里面搜索0x7f070047试试。
找到了引用到这个常量的地方。

在文件com/lemon/faceu/login/b内

1
2
3
4
5
6
7
const v2, 0x7f070047
invoke-virtual {v1, v2}, Landroid/content/res/Resources;->getString(I)Ljava/lang/String;
move-result-object v1
invoke-virtual {v0, v1}, Lcom/lemon/faceu/uimodule/view/AccountEditText->setHintText(Ljava/lang/String;)V

熟悉smali语法的话,我们能够读懂,这个翻译成Java代码其实就是

1
2
String v1 = context.getString(0x7f070047);
editText.setHintText(v1);

目的是找到到这个字符串。

到此为止我们分析一下当前的类是个什么类,是个Activity?Fragment?还是自定义View。

我们找到当前页面网上翻几行,看看还有没有用到什么别的资源id,找到了如下代码

1
2
3
4
5
6
7
8
9
10
const v0, 0x7f0e026e
invoke-virtual {p1, v0}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Lcom/lemon/faceu/uimodule/view/PasswordEditText;
iput-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText;

很明显,这个凭借PasswordEditText名称我们也能发现他就是密码输入的EditText
翻译成java代码

1
2
PasswordEditText v0 = (PasswordEditText)this.findViewById(0x7f0e026e);
this.bpP = v0;

根据这一句话我们在public.xml里面找到对应的xml

1
<public type="id" name="cet_login_password" id="0x7f0e026e" />

然后我们再看看有没有布局文件引用到了cet_login_password,于是找到了4处
cet_login_password

我们进入fragment_login.xml发现他只有登录页面的上半部分。却没有下面的取消和确认按钮。可以猜测他并不是Activity,Fragment,因为没有标志性的onCreate方法,父类最终也没有找到Activity,Fragment等。很可能是一个负责处理业务的类。

但是我们知道了当前的成员变量bpP就是对应的密码的EditText了,那么看看都哪里调用这个bpP了。
通过对当前类分析,我最终找到了Lu方法里面对应到了登录按钮的。

逆向登录代码,查看传递参数

经过一番努力总算找到了登录界面,登录代码,现在我们进行分析,并且加入一段我们自己的代码,进行二次打包。
下面是分析详解

Lcom/lemon/faceu/login/b;

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
.method Lu()V
.locals 4
.prologue
.line 216
invoke-virtual {p0}, Lcom/lemon/faceu/login/b;->Ls()Z
#检测用户名是否合法
move-result v0
#如果不合法就返回
if-eqz v0, :cond_0
invoke-virtual {p0}, Lcom/lemon/faceu/login/b;->Lt()Z
#检测密码是否合法
move-result v0
#如果不合法就返回
if-nez v0, :cond_1
.line 241
:cond_0
:goto_0
return-void
.line 220
:cond_1
invoke-virtual {p0}, Lcom/lemon/faceu/login/b;->Uv()V
.line 222
const-string v0, "LoginFragment"
const-string v1, "startLogin"
invoke-static {v0, v1}, Lcom/lemon/faceu/sdk/utils/c;->i(Ljava/lang/String;Ljava/lang/String;)V
#调用Faceu自己的统计打点方法
.line 223
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText;
invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->getAccount()Ljava/lang/String;
move-result-object v0
#调用AccountEditText的getAccount方法,并将用户户名存入v0
iput-object v0, p0, Lcom/lemon/faceu/login/b;->aAS:Ljava/lang/String;
#将aAs赋值为用户名
.line 224
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText;
invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/PasswordEditText;->getEditText()Landroid/widget/EditText;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String;
move-result-object v0
#将密码从bpP取出来,并取出String类型的密码复制给v0
.line 227
invoke-static {}, Lcom/lemon/faceu/common/e/a;->xJ()Lcom/lemon/faceu/common/e/a;
move-result-object v1
iget-object v2, p0, Lcom/lemon/faceu/login/b;->aAS:Ljava/lang/String;
invoke-virtual {v1, v2}, Lcom/lemon/faceu/common/e/a;->setAccount(Ljava/lang/String;)V
#将现在的用户名存入sharedprefence,以便于记住用户名下次直接显示
.line 229
new-instance v1, Ljava/util/HashMap;
#new一个HashMap存储进v1
invoke-direct {v1}, Ljava/util/HashMap;-><init>()V
#初始化v1
.line 230
const-string v2, "account"
iget-object v3, p0, Lcom/lemon/faceu/login/b;->aAS:Ljava/lang/String;
invoke-interface {v1, v2, v3}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#将用户名存入HashMap
.line 231
const-string v2, "pwd"
invoke-static {v0}, Lcom/lemon/faceu/common/i/g;->bS(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
invoke-interface {v1, v2, v0}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#将密码调用bS方法加密并且存入map
.line 232
const-string v0, "councode"
const-string v2, "86"
invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#国家编号86,存入map
.line 233
const-string v0, "manufacture"
sget-object v2, Landroid/os/Build;->MANUFACTURER:Ljava/lang/String;
invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#将厂商信息存入map
.line 234
const-string v0, "model"
sget-object v2, Landroid/os/Build;->MODEL:Ljava/lang/String;
invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#将model信息存入map
.line 235
const-string v0, "version"
sget v2, Lcom/lemon/faceu/common/d/b;->aAL:I
invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v2
invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#将软件版本信息存入map
.line 236
const-string v0, "deviceinfo"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xt()Lorg/json/JSONObject;
move-result-object v2
#将调用com.lemon.faceu.common.b.a->xt()方法,取回JsonObject并且赋值给v2
invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#将JSONObject存入map
.line 238
new-instance v0, Lcom/lemon/faceu/common/t/a;
sget-object v2, Lcom/lemon/faceu/common/d/a;->azO:Ljava/lang/String;
invoke-static {}, Landroid/os/Looper;->getMainLooper()Landroid/os/Looper;
move-result-object v3
invoke-direct {v0, v2, v1, v3}, Lcom/lemon/faceu/common/t/a;-><init>(Ljava/lang/String;Ljava/util/Map;Landroid/os/Looper;)V
.line 239
iget-object v1, p0, Lcom/lemon/faceu/login/b;->aKe:Lcom/lemon/faceu/common/t/a$a;
invoke-virtual {v0, v1}, Lcom/lemon/faceu/common/t/a;->a(Lcom/lemon/faceu/common/t/a$a;)V
.line 240
const-string v1, "login"
invoke-static {v0, v1}, Lcom/lemon/faceu/sdk/i/b;->a(Ljava/lang/Runnable;Ljava/lang/String;)V
goto :goto_0
.end method
#此方法主要校验用户名是否合法,错误的话输出错误信息,返回值为boolean
.method Ls()Z
.locals 5
.prologue
const/4 v1, 0x0
#使v0寄存器为0
.line 177
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText;
#将成员变量bpO赋值给v0,此时v0就是用户名
invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->getAccount()Ljava/lang/String;
move-result-object v2
#调用AccountEditText的getAccount方法,并将返回值存入v2
.line 178
invoke-virtual {v2}, Ljava/lang/String;->length()I
#取出用户名长度
move-result v0
#v0 = 用户名长度
if-lez v0, :cond_0
invoke-virtual {v2, v1}, Ljava/lang/String;->charAt(I)C
move-result v0
invoke-static {v0}, Ljava/lang/Character;->isDigit(C)Z
move-result v0
if-eqz v0, :cond_0
.line 180
invoke-static {v2}, Lcom/lemon/faceu/common/u/t;->dz(Ljava/lang/String;)Z
move-result v0
if-nez v0, :cond_4
.line 181
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText;
const v2, 0x7f0700ae
invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String;
move-result-object v2
invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V
.line 202
:goto_0
return v1
.line 185
:cond_0
invoke-virtual {v2}, Ljava/lang/String;->length()I
move-result v0
const/16 v3, 0x14
if-le v0, v3, :cond_1
.line 186
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText;
const v2, 0x7f070087
invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String;
move-result-object v2
invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V
goto :goto_0
.line 188
:cond_1
invoke-virtual {v2}, Ljava/lang/String;->length()I
move-result v0
if-lez v0, :cond_2
invoke-virtual {v2, v1}, Ljava/lang/String;->charAt(I)C
move-result v0
invoke-static {v0}, Lcom/lemon/faceu/sdk/utils/h;->u(C)Z
move-result v0
if-nez v0, :cond_2
.line 189
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText;
const v2, 0x7f070086
invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String;
move-result-object v2
invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V
goto :goto_0
:cond_2
move v0, v1
.line 192
:goto_1
invoke-virtual {v2}, Ljava/lang/String;->length()I
move-result v3
if-ge v0, v3, :cond_4
.line 193
invoke-virtual {v2, v0}, Ljava/lang/String;->charAt(I)C
move-result v3
.line 194
const/16 v4, 0x5f
if-eq v3, v4, :cond_3
invoke-static {v3}, Ljava/lang/Character;->isDigit(C)Z
move-result v4
if-nez v4, :cond_3
invoke-static {v3}, Lcom/lemon/faceu/sdk/utils/h;->u(C)Z
move-result v3
if-nez v3, :cond_3
.line 195
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText;
const v2, 0x7f070085
invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String;
move-result-object v2
invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V
goto :goto_0
.line 192
:cond_3
add-int/lit8 v0, v0, 0x1
goto :goto_1
.line 202
:cond_4
const/4 v1, 0x1
goto :goto_0
.end method
#此方法主要校验密码是否合法,错误的话输出错误信息,做一些动画之类,正确返回true
.method Lt()Z
.locals 2
.prologue
.line 206
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText;
invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/PasswordEditText;->getEditText()Landroid/widget/EditText;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/String;->length()I
move-result v0
.line 207
const/4 v1, 0x6
if-lt v0, v1, :cond_0
const/16 v1, 0x10
if-le v0, v1, :cond_1
.line 208
:cond_0
iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText;
const v1, 0x7f0700b5
invoke-virtual {p0, v1}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String;
move-result-object v1
invoke-virtual {v0, v1}, Lcom/lemon/faceu/uimodule/view/PasswordEditText;->setTips(Ljava/lang/String;)V
.line 209
const/4 v0, 0x0
.line 211
:goto_0
return v0
:cond_1
const/4 v0, 0x1
goto :goto_0
.end method

我们主要看Lu方法里面的以下几行,他调用了com.lemon.faceu.common.b.a->xt()方法,这个主要是用于窃取我们的手机型号,系统,厂商等信息,我们进入方法看看

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
const-string v0, "deviceinfo"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xt()Lorg/json/JSONObject;
move-result-object v2
#将调用com.lemon.faceu.common.b.a->xt()方法,取回JsonObject并且赋值给v2
```
我们进入方法看看
```smali
.method public static xt()Lorg/json/JSONObject;
.locals 5
.prologue
.line 34
new-instance v1, Lorg/json/JSONObject;
invoke-direct {v1}, Lorg/json/JSONObject;-><init>()V
.line 36
:try_start_0
const-string v0, "cpu"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xv()Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
#取出你的cpu信息放入json
.line 37
const-string v0, "radio"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xx()Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
#机型的RADIO信息存入json
.line 38
const-string v0, "os_version"
sget v2, Landroid/os/Build$VERSION;->SDK_INT:I
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;I)Lorg/json/JSONObject;
#取出你系统版本
.line 39
const-string v0, "imei"
invoke-static {}, Lcom/lemon/faceu/common/e/a;->xJ()Lcom/lemon/faceu/common/e/a;
move-result-object v2
#取出IMEI号
invoke-virtual {v2}, Lcom/lemon/faceu/common/e/a;->getContext()Landroid/content/Context;
move-result-object v2
invoke-static {v2}, Lcom/lemon/faceu/common/b/a;->bd(Landroid/content/Context;)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
.line 40
const-string v0, "imsi"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xy()Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
.line 41
const-string v0, "iccid"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xz()Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
.line 42
const-string v0, "android_id"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xw()Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
.line 43
const-string v0, "model"
sget-object v2, Landroid/os/Build;->MODEL:Ljava/lang/String;
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
.line 44
const-string v0, "core_count"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xA()I
move-result v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;I)Lorg/json/JSONObject;
.line 45
const-string v0, "wifi"
invoke-static {}, Lcom/lemon/faceu/common/b/a;->xu()Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
:try_end_0
.catch Lorg/json/JSONException; {:try_start_0 .. :try_end_0} :catch_0
.line 49
:goto_0
return-object v1
.line 46
:catch_0
move-exception v0
.line 47
const-string v2, "DeviceInfo"
new-instance v3, Ljava/lang/StringBuilder;
invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V
const-string v4, "jsonexception, "
invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v3
invoke-virtual {v0}, Lorg/json/JSONException;->getMessage()Ljava/lang/String;
move-result-object v0
invoke-virtual {v3, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v0
invoke-static {v2, v0}, Lcom/lemon/faceu/sdk/utils/c;->e(Ljava/lang/String;Ljava/lang/String;)V
goto :goto_0
.end method

我们能看到他获取了我们的cpu,radio,os_version(系统版本),imei,MODEL,cpu_count,mac地址。
看了半天代码,我们加入一些我们的代码,让程序自己把提交的信息打印出来吧。

1
2
3
4
5
6
7
8
const-string v0, "MartinHan--map"
invoke-virtual {v1}, Ljava/util/HashMap;->toString()Ljava/lang/String;
move-result-object v3
invoke-static {v0, v3}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
const-string v3, "MartinHan---url"
invoke-static {v3, v2}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I

然后我们执行代码

1
2
3
4
5
6
7
apktool d faceu
cd faceu/disk
#签名 生成文件明为_signed.apk
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore "MartinHan.jks" -signedjar "_signed.apk" "faceu.apk" "111111" << EOF
111111
adb install _signed.apk

这样的流程走下来,我们的二次打包apk就安装到手机上啦,看看我们输入我们帐号,点击登录。会打印出log信息。
如下所示

1
2
3
03-13 14:17:15.269 10240-10240/com.lemon.faceu V/MartinHan--map: {account=159xxxxxxxx, deviceinfo={"android_id":"62fjdhu42d070400","wifi":"08:33:61:cc:b9:fc","model":"HUAWEI G630-U00","imei":"81338398767854654","iccid":"","cpu":"ARMv7 Processor rev 3 (v7l) ","radio":"203040,203040","imsi":"","core_count":4,"os_version":18}, model=HUAWEI G630-U00, pwd=4d259481d57ffc1c6b4b68cd73dbd301, councode=86, manufacture=HUAWEI, version=270540806}
03-13 14:17:15.269 10240-10240/com.lemon.faceu V/MartinHan---url: https://api2.faceu.mobi/faceu/v3/login.php

如上诉代码所示,我们在faceu登录一次,faceu会上传我们的很多个人信息
mac地址,手机型号,imei,cpu信息,radio,系统版本,国家代码,
并且找到了faceu登录的地址是https://api2.faceu.mobi/faceu/v3/login.php

以上就是我的所有思路,从问题开始,一直找代码,最后动态的打log实现在https加密前就让app自己吐出数据。

写在最后

其实我想不仅faceu,像是其他的厂商也会手机我们的个人信息,完成统计。并且通过大数据分析使用软件的人群,手机型号。
希望所有喜欢逆向的朋友们一起探讨,多多交流。

注:如有侵权,请联系我