-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
1481 lines (1114 loc) · 168 KB
/
search.xml
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
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[wireshark抓不到某些udp包??]]></title>
<url>/2019/07/11/wireshark%E6%8A%93%E4%B8%8D%E5%88%B0%E6%9F%90%E4%BA%9Budp%E5%8C%85%EF%BC%9F%EF%BC%9F/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>场景如下: 无线网卡做ap,两台设备A,B都连接这个ap,在插着无线网卡的电脑上开wireshark抓包,某个时刻A应该给了B一个UDP包,,但是并没有抓到。</p>
<h3 id="u8BE6_u7EC6_u7684_u4E00_u70B9_u662F_uFF1A"><a href="#u8BE6_u7EC6_u7684_u4E00_u70B9_u662F_uFF1A" class="headerlink" title="详细的一点是:"></a>详细的一点是:</h3><p>能抓到 A广播的UDP报文,能抓到B广播的UDP报文,就是抓不到A给B的udp。</p>
<h3 id="u8FC7_u7A0B_uFF1A"><a href="#u8FC7_u7A0B_uFF1A" class="headerlink" title="过程:"></a>过程:</h3><p>在设备A上开TCPDUMP看到了这个包。但是wireshark还是看不见。</p>
<h3 id="u8BB2_u9053_u7406"><a href="#u8BB2_u9053_u7406" class="headerlink" title="讲道理"></a>讲道理</h3><p>我开了混杂模式,而且无线网卡还是AP,为什么抓不到???</p>
<h3 id="u771F_u7684_u662F_u672A_u89E3_u4E4B_u8C1C_u4E86"><a href="#u771F_u7684_u662F_u672A_u89E3_u4E4B_u8C1C_u4E86" class="headerlink" title="真的是未解之谜了"></a>真的是未解之谜了</h3><h3 id="u540E_u7EED_2C_u6362_u6210ubuntu_u4E0B_u7684wireshark_u5C31_u53EF_u4EE5_u4E86"><a href="#u540E_u7EED_2C_u6362_u6210ubuntu_u4E0B_u7684wireshark_u5C31_u53EF_u4EE5_u4E86" class="headerlink" title="后续,换成ubuntu下的wireshark就可以了"></a>后续,换成ubuntu下的wireshark就可以了</h3>]]></content>
</entry>
<entry>
<title><![CDATA[修改服务器返回的js]]></title>
<url>/2019/07/09/%E4%BF%AE%E6%94%B9%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%94%E5%9B%9E%E7%9A%84js/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u573A_u666F"><a href="#u95EE_u9898_u573A_u666F" class="headerlink" title="问题场景"></a>问题场景</h3><p> android app 里有一个webview,webview加载一个http页,页内加载了一个js,我想修改这个js的内容,往里边加些日志,让他把一些值输出来。</p>
<h3 id="u89E3_u51B3_u8FC7_u7A0B"><a href="#u89E3_u51B3_u8FC7_u7A0B" class="headerlink" title="解决过程"></a>解决过程</h3><p>我想了两种可能解决方案</p>
<ol>
<li>修改缓存在本地的js缓存。 </li>
<li>用mitm拦截返回的js进行修改。这个看起来是可以的。</li>
</ol>
<p>要修改本地的缓存就要知道js缓存在哪里,找了半天发现在 <code>/data/user/0/{package_name}/cache/org.chromium.android_webview</code>下边,但是里边的js名字已经变了,而且被压缩过了,都是二进制的没法改。<br><img src="\images\pasted-49.png" alt="upload successful"></p>
<p>换另一个方案,确实拦截到了返回的js,但是js太大了,有1000多kB,找起来太麻烦了。意外的发现可以<a href="https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews" target="_blank" rel="external">远程调试android webVew里边的js</a>,这个方案下需要<code>WebView.setWebContentsDebuggingEnabled(true);</code>,恰好这个应用确实把这一项设为true了,当然如果应用将这一项设为false,也可以用xposed模块来搞:<br>恰好有个现成的<a href="https://github.com/HIjack2015/Inspeckage" target="_blank" rel="external">xposed模块</a>里边有这个功能,起作用的代码如下:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">findAndHookMethod(WebView.class, "setWebContentsDebuggingEnabled", "boolean", new XC_MethodHook() {</div><div class="line"> @Override</div><div class="line"> protected void beforeHookedMethod(MethodHookParam param) throws Throwable {</div><div class="line"> boolean value = (boolean) param.args[0];</div><div class="line"> param.args[0]=true;</div><div class="line"> XposedBridge.log(TAG + "Web Contents Debugging Enabled: " + String.valueOf(value));</div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure>
]]></content>
</entry>
<entry>
<title><![CDATA[一些工具的破解版]]></title>
<url>/2019/07/07/%E4%B8%80%E4%BA%9B%E5%B7%A5%E5%85%B7%E7%9A%84%E7%A0%B4%E8%A7%A3%E7%89%88/</url>
<content type="html"><![CDATA[<h3 id="u8FD9_u6837_u4E0D_u597D"><a href="#u8FD9_u6837_u4E0D_u597D" class="headerlink" title="这样不好"></a>这样不好</h3><p>我知道这样不好,but…</p>
<h3 id="u5217_u8868"><a href="#u5217_u8868" class="headerlink" title="列表"></a>列表</h3><p><b>SecureCRT</b> 8.3 版(下载+破解)<br>百度网盘:<a href="https://pan.baidu.com/s/1YT2vo1cdLGhSW3ODOGXtGg" target="_blank" rel="external">https://pan.baidu.com/s/1YT2vo1cdLGhSW3ODOGXtGg</a><br>提取码:85y9</p>
<p><b>charles</b> license Registered Name: <a href="https://zhile.io" target="_blank" rel="external">https://zhile.io</a><br>License Key: 48891cf209c6d32bf4</p>
]]></content>
</entry>
<entry>
<title><![CDATA[android安装证书为系统证书]]></title>
<url>/2019/07/05/andrdoid%E5%AE%89%E8%A3%85%E8%AF%81%E4%B9%A6%E4%B8%BA%E7%B3%BB%E7%BB%9F%E8%AF%81%E4%B9%A6/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>最近在抓手机上的包,但是出现一个有意思的问题,即<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">@Override</div><div class="line">public void onReceivedSslError(WebView view, SslErrorHandler handler,</div><div class="line"> SslError error) {</div><div class="line"> Log.d("sslError",error.toString());</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>webviewClient 会接到 error code为 3,在官网上查到3 代表是不被信任</p>
<h3 id="u89E3_u51B3_u7ECF_u8FC7"><a href="#u89E3_u51B3_u7ECF_u8FC7" class="headerlink" title="解决经过"></a>解决经过</h3><p>在<a href="https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html" target="_blank" rel="external">官方博客</a>上发现从7.0开始应用就不信任用户的证书了,所以我的任务是把证书添加到系统里,找到解决方案如下:</p>
<ol>
<li>安装用户证书。</li>
<li>把证书从<code>/data/misc/user/0/cacerts-added</code> 移动到<code>/system/etc/security/cacerts</code></li>
<li>再次抓包试下</li>
</ol>
<p>诡异的事情出现了! 这次sslErrorCode 返回了5,invalid,因为我的证书是用burp导出的,而且在系统里可以看见是启用的,所以很困惑。然后折腾了半天用charles导出证书再试就可以了。所以问题可能出在burp的证书上。</p>
<h3 id="u6298_u817E_u3002"><a href="#u6298_u817E_u3002" class="headerlink" title="折腾。"></a>折腾。</h3><p>在试了半天还是不行后,我决定翻一翻源码,于是我在我的aosp根目录下<br><code>grep -inr 'new SslErrorHandler(</code> 结果没有找到调用!我觉得这太不可思议了。列入未解之谜吧。可能和chromium有关系</p>
]]></content>
</entry>
<entry>
<title><![CDATA[修改aosp中WebView实现]]></title>
<url>/2019/07/05/%E4%BF%AE%E6%94%B9aosp%E4%B8%ADWebView%E5%AE%9E%E7%8E%B0/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>有一个奇怪的现象,同样的一个程序,程序里仅仅是加载一个webview,在一台设备上能行,另一台却不行,我考虑可能和webview有关系,于是决定更新webview。</p>
<h3 id="u7ECF_u8FC7"><a href="#u7ECF_u8FC7" class="headerlink" title="经过"></a>经过</h3><p>我天真的以为只要下好新的webview安上就好了,结果并不是那么回事,在开发者选项-webview实现中,并没有找到安装好的新的webview.<br><img src="\images\pasted-47.png" alt="upload successful"><br>接着发现需要修改/system/framework/base/core 里边的<a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/xml/config_webview_packages.xml" target="_blank" rel="external">某个xml文件</a>,如果不同的版本位置可能不一样,grep -rni . “com.android.webview”就可以找到它,然后把它改成”com.google.android.webview”就好了。</p>
<h3 id="u4E00_u4E2A_u70B9"><a href="#u4E00_u4E2A_u70B9" class="headerlink" title="一个点"></a>一个点</h3><p>我想这里如果改成这个样子<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><webviewproviders></div><div class="line"> <!-- The default WebView implementation --></div><div class="line"> <webviewprovider description="Android WebView" packageName="com.android.webview" availableByDefault="true"></div><div class="line"> </webviewprovider></div><div class="line"> <!-- The default WebView implementation --></div><div class="line"> <webviewprovider description="Android WebView" packageName="com.google.android.webview" availableByDefault="false"></div><div class="line"> </webviewprovider></div><div class="line"></webviewproviders></div></pre></td></tr></table></figure></p>
<p>会不会就可以选了。</p>
<h3 id="u53C2_u8003"><a href="#u53C2_u8003" class="headerlink" title="参考"></a>参考</h3><p><a href="http://bbs.phoenixstudio.org/cn/read.php?tid=21359&fid=12&page=1" target="_blank" rel="external">http://bbs.phoenixstudio.org/cn/read.php?tid=21359&fid=12&page=1</a></p>
]]></content>
</entry>
<entry>
<title><![CDATA[双击windows的apk文件将应用安装到手机]]></title>
<url>/2019/07/01/%E5%8F%8C%E5%87%BBapk%E5%B0%86%E5%BA%94%E7%94%A8%E5%AE%89%E8%A3%85%E5%88%B0%E6%89%8B%E6%9C%BA/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>最近总要把下载在电脑上的apk文件通过adb安装到手机上.每次都要在命令行敲“adb insatll fileLocation”,敲的手疼。</p>
<h3 id="u89E3_u51B3_u7ECF_u8FC7"><a href="#u89E3_u51B3_u7ECF_u8FC7" class="headerlink" title="解决经过"></a>解决经过</h3><p>看了这个<a href="https://www.cr173.com/soft/925908.html" target="_blank" rel="external">教程</a>,试了不行。%1 每次都是空的。<br>然后干脆自己写个exe吧。<br>就凭借残存的c++语法写了这个东西:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">#include "pch.h"</div><div class="line">#include <iostream></div><div class="line"></div><div class="line">int main(int argc, char* args[])</div><div class="line">{</div><div class="line"> std::cout << args[0];</div><div class="line"> std::string str(args[1]);</div><div class="line"> std::string str0("adb install -r -g "); </div><div class="line"> //-r 替换已有应用 -g 默认给权限</div><div class="line"> str0.append(str);</div><div class="line"> system(str0.c_str());</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>(一共十来行,写了半小时。。)</p>
<p>然后在修改默认打开方式为生成的exe就可以啦。</p>
<h3 id="u7ED3_u8BBA"><a href="#u7ED3_u8BBA" class="headerlink" title="结论"></a>结论</h3><p>有上网搜的功夫不如自己写一个。以及我真的是懒惰。<br>(1)BUG 忘了加双引号,导致有空格时无法安装<br>(2)需要优化 根据返回值进行下一步操作。</p>
]]></content>
<tags>
<tag> 偷懒 </tag>
</tags>
</entry>
<entry>
<title><![CDATA[aosp系统时间不对]]></title>
<url>/2019/06/26/aosp%E7%B3%BB%E7%BB%9F%E6%97%B6%E9%97%B4/</url>
<content type="html"><![CDATA[<h3 id="u5237_u5165aosp_u540E_uFF0C_u6BCF_u6B21_u5F00_u673A_u65F6_u95F4_u90FD_u4E0D_u5BF9"><a href="#u5237_u5165aosp_u540E_uFF0C_u6BCF_u6B21_u5F00_u673A_u65F6_u95F4_u90FD_u4E0D_u5BF9" class="headerlink" title="刷入aosp后,每次开机时间都不对"></a>刷入aosp后,每次开机时间都不对</h3><p> 然后找到了这个地方<br> <a href="https://blog.csdn.net/SpHinner/article/details/84952260" target="_blank" rel="external">https://blog.csdn.net/SpHinner/article/details/84952260</a></p>
<p> 有空照着改了试试。</p>
<p> 发现不用重现编译,在adb里边改一下配置就好了</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">adb shell settings put global ntp_server asia.pool.ntp.org</div></pre></td></tr></table></figure>]]></content>
<tags>
<tag> aosp </tag>
</tags>
</entry>
<entry>
<title><![CDATA[ro.debuggable(2)]]></title>
<url>/2019/06/25/ro-debuggable2/</url>
<content type="html"><![CDATA[<h3 id="u4E00_u79CD_u7528xposed__u4FEE_u6539_debuggable_u65B9_u6848_uFF0C_u786E_u5B9E_u53EF_u7528"><a href="#u4E00_u79CD_u7528xposed__u4FEE_u6539_debuggable_u65B9_u6848_uFF0C_u786E_u5B9E_u53EF_u7528" class="headerlink" title="一种用xposed 修改 debuggable方案,确实可用"></a>一种用xposed 修改 debuggable方案,确实可用</h3><p><a href="https://blog.csdn.net/QQ1084283172/article/details/80963610" target="_blank" rel="external">https://blog.csdn.net/QQ1084283172/article/details/80963610</a></p>
<p>有空试一下</p>
]]></content>
</entry>
<entry>
<title><![CDATA[合并文件夹]]></title>
<url>/2019/06/24/%E5%90%88%E5%B9%B6%E6%96%87%E4%BB%B6%E5%A4%B9/</url>
<content type="html"><![CDATA[<p>需要合并多个以smali开头的文件夹到同一个文件夹中<br><img src="\images\pasted-46.png" alt="upload successful"><br>用python 或者powershell 写个脚本都可以。选择使用python<br>代码片段如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">from distutils.dir_util import copy_tree</div><div class="line">import glob</div><div class="line"></div><div class="line">fromDirectory = "C:\\Users\\jiakang\\Desktop\\huaweiLock\\smarthome"</div><div class="line">toDirectory = "C:\\Users\\jiakang\\Desktop\\huaweiLock\\smarthome\\all_smali"</div><div class="line">folders= glob.glob(fromDirectory+"\\smali*")</div><div class="line">for folder in folders:</div><div class="line"> copy_tree(folder, toDirectory)</div></pre></td></tr></table></figure></p>
]]></content>
<categories>
<category> 片段 </category>
</categories>
<tags>
<tag> 脚本 </tag>
</tags>
</entry>
<entry>
<title><![CDATA[模拟快速点击]]></title>
<url>/2019/04/29/%E6%A8%A1%E6%8B%9F%E5%BF%AB%E9%80%9F%E7%82%B9%E5%87%BB/</url>
<content type="html"><![CDATA[<h3 id="u6A21_u62DF_u70B9_u51FB_u53EF_u4EE5_u600E_u6837_u505A"><a href="#u6A21_u62DF_u70B9_u51FB_u53EF_u4EE5_u600E_u6837_u505A" class="headerlink" title="模拟点击可以怎样做"></a>模拟点击可以怎样做</h3><p>adb input tap…. 这样做的问题是太慢了。我想要每隔0.1s点一次。<br>然后看到了这个<br><a href="https://igor.mp/blog/2018/02/23/using-adb-simulate-touch-events.html" target="_blank" rel="external">https://igor.mp/blog/2018/02/23/using-adb-simulate-touch-events.html</a></p>
<ol>
<li>把点击事件从/dev/input/eventX 里边读出来,读入文件。</li>
<li>从文件读出来,写回去</li>
</ol>
<p>这样是可以的,问题是只能模拟简单的点击,如果要复杂的操作该怎么做呢?我想可以这样吧。</p>
<p>读入文件时同时记录当前时间,等重放时也按照相同的时间间隔重放。这里要看一下读出来的格式。完全是二进制的东西,可能有需求的话需要分析一下。。<br>此外,takser和 按键精灵他们是怎么做的?很好奇</p>
<p>ps. 当然如果是要测试自己的应用 用espresso就好了。</p>
]]></content>
</entry>
<entry>
<title><![CDATA[windows下的apkAnalyzer]]></title>
<url>/2019/04/18/windows%E4%B8%8B%E7%9A%84apkAnalyzer/</url>
<content type="html"><![CDATA[<h5 id="u95EE_u9898"><a href="#u95EE_u9898" class="headerlink" title="问题"></a>问题</h5><p>最近想用<a href="https://developer.android.com/studio/command-line/apkanalyzer" target="_blank" rel="external">apkanalyer</a>这个工具,但是发现sdk里边的没有在windows下的该工具。</p>
<h5 id="u65B9_u6848"><a href="#u65B9_u6848" class="headerlink" title="方案"></a>方案</h5><p>sdk/tools/bin下新建一个批处理,内容如下:<br><code><br>@echo off</code></p>
<p>::##############################################################################<br>::##<br>::## apkanalyzer start up script for Windows<br>::##<br>::## converted by ewwink<br>::##<br>::##############################################################################</p>
<p>::Attempt to set APP_HOME</p>
<p>SET SAVED=%cd%<br>SET APP_HOME=C:\Users\jiakang\AppData\Local\Android\Sdk\tools<br>SET APP_NAME=”apkanalyzer”</p>
<p>::Add default JVM options here. You can also use JAVA_OPTS and APKANALYZER_OPTS to pass JVM options to this script.<br>SET DEFAULT_JVM_OPTS=-Dcom.android.sdklib.toolsdir=%APP_HOME%</p>
<p>SET CLASSPATH=%APP_HOME%\lib\dvlib-26.0.0-dev.jar;%APP_HOME%\lib\util-2.2.1.jar;%APP_HOME%\lib\jimfs-1.1.jar;%APP_HOME%\lib\annotations-13.0.jar;%APP_HOME%\lib\ddmlib-26.0.0-dev.jar;%APP_HOME%\lib\repository-26.0.0-dev.jar;%APP_HOME%\lib\sdk-common-26.0.0-dev.jar;%APP_HOME%\lib\kotlin-stdlib-1.1.3-2.jar;%APP_HOME%\lib\protobuf-java-3.0.0.jar;%APP_HOME%\lib\apkanalyzer-cli.jar;%APP_HOME%\lib\gson-2.3.jar;%APP_HOME%\lib\httpcore-4.2.5.jar;%APP_HOME%\lib\dexlib2-2.2.1.jar;%APP_HOME%\lib\commons-compress-1.12.jar;%APP_HOME%\lib\generator.jar;%APP_HOME%\lib\error_prone_annotations-2.0.18.jar;%APP_HOME%\lib\commons-codec-1.6.jar;%APP_HOME%\lib\kxml2-2.3.0.jar;%APP_HOME%\lib\httpmime-4.1.jar;%APP_HOME%\lib\annotations-12.0.jar;%APP_HOME%\lib\bcpkix-jdk15on-1.56.jar;%APP_HOME%\lib\jsr305-3.0.0.jar;%APP_HOME%\lib\explainer.jar;%APP_HOME%\lib\builder-model-3.0.0-dev.jar;%APP_HOME%\lib\baksmali-2.2.1.jar;%APP_HOME%\lib\j2objc-annotations-1.1.jar;%APP_HOME%\lib\layoutlib-api-26.0.0-dev.jar;%APP_HOME%\lib\jcommander-1.64.jar;%APP_HOME%\lib\commons-logging-1.1.1.jar;%APP_HOME%\lib\annotations-26.0.0-dev.jar;%APP_HOME%\lib\builder-test-api-3.0.0-dev.jar;%APP_HOME%\lib\animal-sniffer-annotations-1.14.jar;%APP_HOME%\lib\bcprov-jdk15on-1.56.jar;%APP_HOME%\lib\httpclient-4.2.6.jar;%APP_HOME%\lib\common-26.0.0-dev.jar;%APP_HOME%\lib\jopt-simple-4.9.jar;%APP_HOME%\lib\sdklib-26.0.0-dev.jar;%APP_HOME%\lib\apkanalyzer.jar;%APP_HOME%\lib\shared.jar;%APP_HOME%\lib\binary-resources.jar;%APP_HOME%\lib\guava-22.0.jar</p>
<p>SET APP_ARGS=%*<br>::Collect all arguments for the java command, following the shell quoting and substitution rules<br>SET APKANALYZER_OPTS=%DEFAULT_JVM_OPTS% -classpath %CLASSPATH% com.android.tools.apk.analyzer.ApkAnalyzerCli %APP_ARGS%</p>
<p>::Determine the Java command to use to start the JVM.<br>SET JAVACMD=”java”<br>where %JAVACMD% >nul 2>nul<br>if %errorlevel%==1 (<br> echo ERROR: ‘java’ command could be found in your PATH.<br> echo Please set the ‘java’ variable in your environment to match the<br> echo location of your Java installation.<br> echo.<br> exit /b 0<br>)</p>
<p>:: execute apkanalyzer<br>%JAVACMD% %APKANALYZER_OPTS%<br></p>
]]></content>
</entry>
<entry>
<title><![CDATA[用monkey批量测试应用遇到的问题]]></title>
<url>/2019/04/18/%E7%94%A8monkey%E6%89%B9%E9%87%8F%E6%B5%8B%E8%AF%95%E5%BA%94%E7%94%A8%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/</url>
<content type="html"><![CDATA[<h5 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h5><p>需要批量测试应用(约2000个),执行如下步骤</p>
<ol>
<li>安装</li>
<li>用monkey随机点2000次。</li>
<li>卸载 </li>
</ol>
<p>代码还是很好写的,但是中间遇到了很多问题。</p>
<ol>
<li>跑一会了就会在主界面乱点。不会再自动打开相应的应用来点击。重启模拟器才行。<br> 解:设置了点击延迟<code>--throttle</code>之后就不再出这个情况了,不知道为什么。</li>
<li><p>半数应用安装不上。而且也没报错信息。</p>
<p> 解:用arm的模拟器就好了</p>
</li>
<li>但是arm模拟器很慢。。。 没什么好办法。</li>
<li>过一会adb会自己停掉。连不上。 写一个线程检测adb状态。死了就restart。</li>
<li>设备总是掉线。。这个是我自己蠢,代码adb用了两个版本的。所以总是不停的kill。。统一版本就好了。</li>
<li>跑一会之后系统冻屏。systemUI进程ANR, 暂无解决方案。</li>
</ol>
]]></content>
</entry>
<entry>
<title><![CDATA[起进程提示open file too much]]></title>
<url>/2019/04/18/%E8%B5%B7%E8%BF%9B%E7%A8%8B%E6%8F%90%E7%A4%BAopen-file-too-much/</url>
<content type="html"><![CDATA[<h5 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h5><p><b>ubuntu</b>下需要起很多进程,跑了一会提示open file too much.</p>
<h5 id="u89E3_u51B3_u8FC7_u7A0B"><a href="#u89E3_u51B3_u8FC7_u7A0B" class="headerlink" title="解决过程"></a>解决过程</h5><p>默认是1024,调大就好了。但是试了几个都无效。</p>
<p>最终在<a href="https://superuser.com/questions/1200539/cannot-increase-open-file-limit-past-4096-ubuntu" target="_blank" rel="external">这里</a>找到了解决方案。</p>
<ol>
<li><p>Modify /etc/systemd/user.conf and /etc/systemd/system.conf with the following line (this takes care of graphical login):</p>
<p> DefaultLimitNOFILE=65535</p>
</li>
<li><p>Modify /etc/security/limits.conf with the following lines (this takes care of non-GUI login):</p>
<p> username hard nofile 65535<br> username soft nofile 65535</p>
</li>
</ol>
<p><b>重启后生效</b></p>
]]></content>
</entry>
<entry>
<title><![CDATA[如何批量给应用授权?]]></title>
<url>/2019/04/09/%E5%A6%82%E4%BD%95%E8%AE%A9%E6%89%B9%E9%87%8F%E7%BB%99%E5%BA%94%E7%94%A8%E6%8E%88%E6%9D%83%EF%BC%9F/</url>
<content type="html"><![CDATA[<h5 id="u76EE_u7684_uFF1A_u6279_u91CF_u5B89_u88C5_u5E94_u7528_uFF0C_u5E76_u6388_u4E88_u6307_u5B9A_u6743_u9650"><a href="#u76EE_u7684_uFF1A_u6279_u91CF_u5B89_u88C5_u5E94_u7528_uFF0C_u5E76_u6388_u4E88_u6307_u5B9A_u6743_u9650" class="headerlink" title="目的:批量安装应用,并授予指定权限"></a>目的:批量安装应用,并授予指定权限</h5><h5 id="u77E5_u8BC6_uFF1A_u6743_u9650_u5206_u7C7B"><a href="#u77E5_u8BC6_uFF1A_u6743_u9650_u5206_u7C7B" class="headerlink" title="知识:权限分类"></a>知识:<a href="https://developer.android.com/guide/topics/permissions/overview#normal-dangerous" target="_blank" rel="external">权限分类</a></h5><p>权限分三种</p>
<ol>
<li>normal</li>
<li>dangerous</li>
<li>special</li>
</ol>
<h5 id="u7ECF_u8FC7"><a href="#u7ECF_u8FC7" class="headerlink" title="经过"></a>经过</h5><ol>
<li>查到可以用<code>adb shell pm grant <package_name> <permission_name></code>,我要授予的权限是<code>android.permission.SYSTEM_ALERT_WINDOW</code>,授权之后发现还是没有权限,试了几个权限发现这条命令只对normal和dangerous的权限有效,而SYSTEM_ALERT_WINDOW 是special 权限</li>
<li>查到可以用<code>adb shell appops set <package_name> SYSTEM_ALERT_WINDOW allow</code> ,发现确实可用。但是要执行一条命令</li>
<li>发现在安装应用时有一个选项<code>adb install -g</code> ,这个<code>g</code>的意思就是 grant all runtime permission。<h5 id="u7ED3_u8BBA"><a href="#u7ED3_u8BBA" class="headerlink" title="结论"></a>结论</h5>android里边真是乱七八糟</li>
</ol>
]]></content>
</entry>
<entry>
<title><![CDATA[monkeyRunner不能用]]></title>
<url>/2019/04/09/monkeyRunner%E4%B8%8D%E8%83%BD%E7%94%A8-1/</url>
<content type="html"><![CDATA[<h3 id="monkeyRunner_u4E0D_u80FD_u7528"><a href="#monkeyRunner_u4E0D_u80FD_u7528" class="headerlink" title="monkeyRunner不能用"></a>monkeyRunner不能用</h3><p>最近在学自动化测试。但是发现windows下自带的monkeyrunner不能用了,<br><img src="\images\pasted-45.png" alt="upload successful"><br>打开这个批处理文件看了看,发现里边的路径不太对。就挨个改了改,改完之后是这样的</p>
<p><code><br>setlocal</code></p>
<p>rem Set up prog to be the path of this script, including following symlinks,<br>rem and set up progdir to be the fully-qualified pathname of its directory.<br>set prog=%~f0</p>
<p>rem Change current directory and drive to where the script is, to avoid<br>rem issues with directories containing whitespaces.<br>cd /d %~dp0</p>
<p>rem Check we have a valid Java.exe in the path.<br>set java_exe=<br>set sdk=C:\Users\jiakang\AppData\Local\Android\Sdk\<br>call ..\lib\find_java.bat<br>if not defined java_exe goto :EOF</p>
<p> for /f %%a in (“%APP_HOME%\lib\monkeyrunner-26.0.0-dev.jar”) do set jarfile=%%~nxa</p>
<p>set frameworkdir=.<br>set libdir=</p>
<p>if exist %frameworkdir%\%jarfile% goto JarFileOk<br> set frameworkdir=%sdk%tools\lib</p>
<p>if exist %frameworkdir%\%jarfile% goto JarFileOk<br> rem set frameworkdir=..\lib</p>
<p>:JarFileOk</p>
<p>set jarpath=%frameworkdir%\%jarfile%</p>
<p>if not defined ANDROID_SWT goto QueryArch<br> set swt_path=%ANDROID_SWT%<br> goto SwtDone</p>
<p>:QueryArch</p>
<p>rem for /f “delims=” %%a in (‘%frameworkdir%..\bin\archquery’) do set swt_path=%frameworkdir%\%%a<br>set swt_path=..\lib\x86_64<br>:SwtDone</p>
<p>if exist “%swt_path%” goto SetPath<br> echo SWT folder ‘%swt_path%’ does not exist.<br> echo Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.<br> exit /B</p>
<p>:SetPath<br>echo %frameworkdir%<br>echo %jarpath%<br>call “%java_exe%” -Xmx512m “-Djava.ext.dirs=%frameworkdir%;%swt_path%” -Dcom.android.monkeyrunner.bindir=%sdk%platform-tools -jar %jarpath% %*<br><br>其中改了 </p>
<ol>
<li>swt_path</li>
<li>framework_dir</li>
<li>-Dcom.android.monkeyrunner.bindir=%sdk%platform-tools</li>
</ol>
<p>让我觉得诧异的是sdk里边的工具竟然会出这种问题,不知道谷歌是怎么想的。还是说这些功能其实根本没人用?(感觉是个坑)</p>
]]></content>
<categories>
<category> android </category>
</categories>
</entry>
<entry>
<title><![CDATA[android6.0 widget textview 不见了!]]></title>
<url>/2018/06/04/android6-0-widget-textview-%E4%B8%8D%E8%A7%81%E4%BA%86/</url>
<content type="html"><![CDATA[<h3 id="u8D77_u56E0"><a href="#u8D77_u56E0" class="headerlink" title="起因"></a>起因</h3><p>最近在开发android的widget.搞完以后想不如测测兼容性把.放到6.0 上,所有的textview都不显示了!如图:</p>
<p>7.0,8.0下效果.<br><img src="\images\pasted-43.png" alt="upload successful"><br>6.0 下效果</p>
<p><img src="\\images\pasted-44.png" alt="upload successful"><br>所有的文字都不见了…</p>
]]></content>
</entry>
<entry>
<title><![CDATA[完美世界面试经过]]></title>
<url>/2018/02/27/%E5%AE%8C%E7%BE%8E%E4%B8%96%E7%95%8C%E9%9D%A2%E8%AF%95%E7%BB%8F%E8%BF%87/</url>
<content type="html"><![CDATA[<h3 id="u7ECF_u8FC7"><a href="#u7ECF_u8FC7" class="headerlink" title="经过"></a>经过</h3><p>30分钟笔试.三道程序设计题.</p>
<ol>
<li>rand5 生成 rand7</li>
<li>检测链表是否存在环及环的位置.</li>
<li>排序选一种写出来.</li>
</ol>
<p>题不算难,但我愣是连快排都忘了怎么写,炸裂.估计面试官也挺无奈的.但是他还是认真的提示我.我还是没想到该怎么办…于是更加尴尬了. </p>
<p>然后开始面试,开始问我 动画,一直围绕ui问,其实这方面我是最不了解,也最不感兴趣的.然后双方都很无奈.估计他也在想:”这样一个彩笔是怎样经过简历筛选的”.于是他说:”那就这样吧”,我说:”抱歉浪费您时间了.”</p>
<p>就酱.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[搜狐视频面试经过]]></title>
<url>/2018/02/27/%E9%9D%A2%E8%AF%95%E8%AE%B0%E5%BD%95/</url>
<content type="html"><![CDATA[<h3 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a>前言</h3><p>又一次开始开始北漂,这里我们记录下所有我觉得有价值的面试题,怎么来说也是一笔财富.</p>
<h3 id="u9762_u8BD5_u5C97_u4F4D_3Aandroid_u5F00_u53D1"><a href="#u9762_u8BD5_u5C97_u4F4D_3Aandroid_u5F00_u53D1" class="headerlink" title="面试岗位:android开发."></a>面试岗位:android开发.</h3><h3 id="u7ECF_u8FC7_3A"><a href="#u7ECF_u8FC7_3A" class="headerlink" title="经过:"></a>经过:</h3><p>十点半开始,先做一个小时的笔试题,由于是两年来第一次笔试所以发挥的一般. 题目很侧重基础.也很常规.选择填空大题.选择填空记不清了.大概包括: </p>
<ol>
<li>intent可以传递的数据类型? </li>
<li>哪个是runtime exception?</li>
<li>android 动画分为几类? 4</li>
</ol>
<p>大题包括 </p>
<ol>
<li>手写观察者</li>
<li>如何避免anr.</li>
<li>gc过程<a href="http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html" target="_blank" rel="external">答案链接</a><br>剩下的忘了.</li>
</ol>
<p>然后是面试.基本就是对着简历面,面试官很nice,遇到不会的还会提示你,最后会给你讲一下.现在还能想起来的题目就剩下:</p>
<ol>
<li>泛型的局限性.</li>
<li>命令模式的用途.</li>
</ol>
<p>明天二面,待续…</p>
]]></content>
</entry>
<entry>
<title><![CDATA[安卓下一些好用的ui 库]]></title>
<url>/2018/01/20/%E5%AE%89%E5%8D%93%E4%B8%8B%E4%B8%80%E4%BA%9B%E5%A5%BD%E7%94%A8%E7%9A%84ui-%E5%BA%93/</url>
<content type="html"><![CDATA[<h3 id="u8BF4_u660E"><a href="#u8BF4_u660E" class="headerlink" title="说明"></a>说明</h3><p>一些我用过的好用的开源ui库,持续更新</p>
<h3 id="u5217_u8868"><a href="#u5217_u8868" class="headerlink" title="列表"></a>列表</h3><ol>
<li><a href="https://github.com/prolificinteractive/material-calendarview" target="_blank" rel="external">一个高度自定义的calendarView</a></li>
<li><a href="https://github.com/scwang90/SmartRefreshLayout" target="_blank" rel="external">好用的下拉刷新</a></li>
</ol>
]]></content>
</entry>
<entry>
<title><![CDATA[分享一个kotlin中很好用的工具类]]></title>
<url>/2018/01/15/%E5%88%86%E4%BA%AB%E4%B8%80%E4%B8%AAkotlin%E4%B8%AD%E5%BE%88%E5%A5%BD%E7%94%A8%E7%9A%84spgongjulei/</url>
<content type="html"><![CDATA[<h3 id="u6548_u679C"><a href="#u6548_u679C" class="headerlink" title="效果"></a>效果</h3><p><code><br> //get default prefs<br>val prefs = PreferenceHelper.defaultPrefs(this)<br>//set any type of value in prefs<br>prefs[Constants.PREF_NAME] = “name”<br>//get any value from prefs<br>val name: String? = prefs[Constants.PREF_NAME]<br>//get value from prefs (with default value)<br>val age: Int? = prefs[Constants.PREF_AGE, 23]<br></code></p>
<p>怎么样?读写sharedPreference 就像读写数组那样简单.</p>
<h3 id="u6E90_u7801"><a href="#u6E90_u7801" class="headerlink" title="源码"></a>源码</h3><p><code><br>object PreferenceHelper {</code></p>
<pre><code>fun defaultPrefs(context: Context): SharedPreferences
= PreferenceManager.getDefaultSharedPreferences(context)
fun customPrefs(context: Context, name: String): SharedPreferences
= context.getSharedPreferences(name, Context.MODE_PRIVATE)
inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
/**
* puts a key value pair in shared prefs if doesn't exists, otherwise updates value on given [key]
*/
operator fun SharedPreferences.set(key: String, value: Any?) {
when (value) {
is String? -> edit({ it.putString(key, value) })
is Int -> edit({ it.putInt(key, value) })
is Boolean -> edit({ it.putBoolean(key, value) })
is Float -> edit({ it.putFloat(key, value) })
is Long -> edit({ it.putLong(key, value) })
else -> throw UnsupportedOperationException("Not yet implemented")
}
}
/**
* finds value on given key.
* [T] is the type of value
* @param defaultValue optional default value - will take null for strings, false for bool and -1 for numeric values if [defaultValue] is not specified
*/
operator inline fun <reified T : Any> SharedPreferences.get(key: String, defaultValue: T? = null): T? {
return when (T::class) {
String::class -> getString(key, defaultValue as? String) as T?
Int::class -> getInt(key, defaultValue as? Int ?: -1) as T?
Boolean::class -> getBoolean(key, defaultValue as? Boolean ?: false) as T?
Float::class -> getFloat(key, defaultValue as? Float ?: -1f) as T?
Long::class -> getLong(key, defaultValue as? Long ?: -1) as T?
else -> throw UnsupportedOperationException("Not yet implemented")
}
}
</code></pre><p>}</p>
<p>格式有点差,凑活看…</p>
<h3 id="u6765_u6E90"><a href="#u6765_u6E90" class="headerlink" title="来源"></a><a href="https://myprogrammingexperiments.wordpress.com/2017/06/04/manipulating-shared-prefs-with-kotlin-just-two-lines-of-code/" target="_blank" rel="external">来源</a></h3><h3 id="u611F_u89E6"><a href="#u611F_u89E6" class="headerlink" title="感触"></a>感触</h3><p>kotlin真的比java好用多了.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[安卓源码编译刷入nexus6p]]></title>
<url>/2018/01/13/%E5%AE%89%E5%8D%93%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91%E5%88%B7%E5%85%A5nexus6p/</url>
<content type="html"><![CDATA[<h3 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a>前言</h3><p>为什么要做编译一份源码刷入真机这件事情?<br>通过准备编译环境,下源码,编译,刷入设备这些事情,可以使我们对aosp有更好的理解.此外,要想在逆向的路上走下去,不可避免的要读一读安卓的源码,然后修改源码以过掉一些反调试的手段.</p>
<h3 id="u8FC7_u7A0B"><a href="#u8FC7_u7A0B" class="headerlink" title="过程"></a>过程</h3><p>首先参考<a href="https://source.android.com/setup/requirements" target="_blank" rel="external">官网</a>得知大概是以下几步.</p>
<ol>
<li>搭建编译环境</li>
<li>下载源码</li>
<li>进行编译</li>
<li>编译源码</li>
<li>刷入设备 </li>
</ol>
<p>于是我在笔记本上安装了一个ubuntu14.04的系统,开始按照官网搭建编译系统,但是踩了很多坑,在搜集资料时,我意外的发现了<a href="http://weishu.me/2016/12/30/simple-way-to-compile-android-source/" target="_blank" rel="external">这篇博客</a>.我决定按照这个教程搞.于是按照顺序做了以下几件事</p>
<h5 id="1-__u5728ubuntu_u4E0A_u5B89_u88C5docker"><a href="#1-__u5728ubuntu_u4E0A_u5B89_u88C5docker" class="headerlink" title="1. 在ubuntu上安装docker"></a>1. <a href="https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#extra-steps-for-aufs" target="_blank" rel="external">在ubuntu上安装docker</a></h5><p>这里有一点需要注意,docker只能跑在64位的ubuntu上,而64位的ubuntu在<a href="http://releases.ubuntu.com/14.04/" target="_blank" rel="external">ubuntu官网</a>上显示的下载链接是这样的<code>64-bit PC (AMD64) desktop image</code>,经过实测在intel的cpu上也能跑.</p>
<h5 id="2-__u7B80_u5355_u4E86_u89E3docker"><a href="#2-__u7B80_u5355_u4E86_u89E3docker" class="headerlink" title="2. 简单了解docker"></a>2. 简单了解docker</h5><p>在这里我们可以将docker理解成一个很厉害的虚拟机,教程简单的在官网上看一下就好了,英文不好的可以看这本教程<a href="https://www.gitbook.com/book/yeasy/docker_practice/details" target="_blank" rel="external">Docker —— 从入门到实践</a>,其实如果不踩坑的话,根本不用了解docker的:)</p>
<h5 id="3-__u6309_u7167_u6559_u7A0B_u6267_u884C_u811A_u672C"><a href="#3-__u6309_u7167_u6559_u7A0B_u6267_u884C_u811A_u672C" class="headerlink" title="3. 按照教程执行脚本"></a>3. 按照教程执行脚本</h5><p>找一个合适的目录依次执行以下脚本<br><code><br>curl -O <a href="https://raw.githubusercontent.com/tiann/docker-aosp/master/tests/build-nougat.sh" target="_blank" rel="external">https://raw.githubusercontent.com/tiann/docker-aosp/master/tests/build-nougat.sh</a><br>bash ./build-nougat.sh<br></code><br>这里需要注意的是,down下来的脚本里边的版本不一定是你需要的版本,我们需要在<a href="https://source.android.com/setup/build-numbers#source-code-tags-and-builds" target="_blank" rel="external">这里</a>找到适合自己设备的版本然后替换脚本里边的版本.<br>此外如果将编出的系统刷入真机,我们还需要将脚本里边<code>lunch aosp_arm-eng</code>这一行里的<code>aosp_arm-eng</code>改成相应的<a href="https://source.android.com/setup/running" target="_blank" rel="external">设备号</a>.</p>
<p>正如教程里所说只要等待就好了,如果一切顺利的话,在下载两小时左右之后(50M带宽的网)就可以进行编译,编译需要大概两个小时(8g内存,i7 6700cpu),编完之后可以看到如下场景<br><img src="\images\pasted-41.png" alt="upload successful"></p>
<h5 id="4-__u641E_u5B9A_u9A71_u52A8"><a href="#4-__u641E_u5B9A_u9A71_u52A8" class="headerlink" title="4. 搞定驱动"></a>4. 搞定驱动</h5><p>到现在我们已经编译出可以在虚拟机上跑的安卓系统,但是如果想要刷入设备的话还要搞定相应的驱动.这里我在网上找到了两个办法,一个是下载相应脚本再编译(我没试).另一种是下载相应的<a href="https://developers.google.com/android/images" target="_blank" rel="external">factory image</a>然后解压.从里边取出vender.img这就是编好的驱动.</p>
<h5 id="5-__u5237_u5165_u8BBE_u5907"><a href="#5-__u5237_u5165_u8BBE_u5907" class="headerlink" title="5. 刷入设备"></a>5. 刷入设备</h5><p>按照官网的教程解了bl锁,进fastboot,然后<code>flash all</code>就好了.没啥说的.大概5分钟后就可以进系统了</p>
<p><img src="\images\pasted-42.png" alt="upload successful">,上车成功!</p>
<h5 id="6-__u5B58_u5728_u95EE_u9898"><a href="#6-__u5B58_u5728_u95EE_u9898" class="headerlink" title="6. 存在问题"></a>6. 存在问题</h5><ol>
<li>指纹识别模块不能用,原因未知.</li>
<li>在cpu忙的时候屏幕边缘会闪.</li>
<li>每次开机都需要手动关闭sellinux,要不然xposed不能用 </li>
</ol>
<h5 id="7-__u540E_u7EED"><a href="#7-__u540E_u7EED" class="headerlink" title="7. 后续"></a>7. 后续</h5><p>如果后续再需要编译指定模块的话,把之前down下来的脚本里边的关于初始化代码库的内容注释掉然后把<code>make -j $cpus</code>替换成自己要做的操作就好了. </p>
<h3 id="u53C2_u8003_u8D44_u6599"><a href="#u53C2_u8003_u8D44_u6599" class="headerlink" title="参考资料"></a>参考资料</h3><ol>
<li><a href="http://weishu.me/2016/12/30/simple-way-to-compile-android-source" target="_blank" rel="external">docker下编译的教程</a></li>
<li><a href="https://www.jianshu.com/p/367f0886e62b" target="_blank" rel="external">一篇不错的博客</a> </li>
<li><a href="https://source.android.com" target="_blank" rel="external">aosp网站</a></li>
<li><a href="https://www.jianshu.com/p/167a9f819a37" target="_blank" rel="external">怎么搞定驱动</a></li>
<li><a href="http://blog.csdn.net/luoshengyang/article/details/20501657" target="_blank" rel="external">编出来的img都起什么作用</a></li>
</ol>
]]></content>
<categories>
<category> android </category>
</categories>
</entry>
<entry>
<title><![CDATA[kotlin资料收集,持续更新]]></title>
<url>/2018/01/12/kotlin%E8%B5%84%E6%96%99%E6%94%B6%E9%9B%86-%E6%8C%81%E7%BB%AD%E6%9B%B4%E6%96%B0/</url>
<content type="html"><![CDATA[<h3 id="u4ECB_u7ECD"><a href="#u4ECB_u7ECD" class="headerlink" title="介绍"></a>介绍</h3><p>主要收集kotlin语言和它与安卓有关的知识 </p>
<h3 id="u8BED_u6CD5_u4E4B_u7C7B_u7684"><a href="#u8BED_u6CD5_u4E4B_u7C7B_u7684" class="headerlink" title="语法之类的"></a>语法之类的</h3><ol>
<li><a href="https://kotlinlang.org" target="_blank" rel="external">kotlin官网</a> 始终是最权威的地方.</li>
<li><a href="https://developer.android.com/kotlin/index.html" target="_blank" rel="external">kotlin+android谷歌官网</a> 看看就好.不要全信. </li>
<li><a href="https://github.com/dbacinski/Design-Patterns-In-Kotlin" target="_blank" rel="external">kotlin中的设计模式</a></li>
</ol>
<h3 id="u4E66_u7C4D"><a href="#u4E66_u7C4D" class="headerlink" title="书籍"></a>书籍</h3><ol>
<li><a href="https://pan.baidu.com/s/1nvqMkHj" target="_blank" rel="external">kotlin-for-android-developers英文版</a> 网盘密码 iyno. kotlin入门不错的一本书.</li>
<li><a href="https://github.com/wangjiegulu/kotlin-for-android-developers-zh" target="_blank" rel="external">kotlin-for-android-developers中文版</a>,英文不好的可以看这本 </li>
</ol>
<h3 id="u6846_u67B6"><a href="#u6846_u67B6" class="headerlink" title="框架"></a>框架</h3><ol>
<li><a href="https://www.raywenderlich.com/170233/reactive-programming-rxandroid-kotlin-introduction" target="_blank" rel="external">rxKotlin介绍</a></li>
<li><a href="https://github.com/ReactiveX/RxKotlin" target="_blank" rel="external">rxKotlin项目</a></li>
<li><a href="https://github.com/Kotlin/anko" target="_blank" rel="external">anko</a>强烈推荐. </li>
</ol>
<h3 id="u53C2_u8003_u9879_u76EE"><a href="#u53C2_u8003_u9879_u76EE" class="headerlink" title="参考项目"></a>参考项目</h3><ol>
<li><a href="https://github.com/Yalantis/kotlin-mvp-example" target="_blank" rel="external">一个mvp的简单demo</a></li>
</ol>
]]></content>
</entry>
<entry>
<title><![CDATA[保护自己的应用不被xposed Hook]]></title>
<url>/2018/01/07/%E4%BF%9D%E6%8A%A4%E8%87%AA%E5%B7%B1%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%8D%E8%A2%ABxposed-Hook/</url>
<content type="html"><![CDATA[<h3 id="u8D77_u56E0"><a href="#u8D77_u56E0" class="headerlink" title="起因"></a>起因</h3><p>今天写了个xposed模块,跑的好好的,但是对酷安怎么也不生效,搜索得知酷安可以设置自己不被xposedhook,<b>什么?</b>,他为什么这么叼.</p>
<h3 id="u53EF_u80FD_u539F_u56E0"><a href="#u53EF_u80FD_u539F_u56E0" class="headerlink" title="可能原因"></a>可能原因</h3><p>我的xposed是从酷安上下的,所以可能是因为酷安改包了,下载apk验了下签名,发现没改.那可能是因为我给了它root权限?去掉root权限发现还是不能hook…真的有这种黑科技?</p>
<h3 id="u62C6_u5305"><a href="#u62C6_u5305" class="headerlink" title="拆包"></a>拆包</h3><p>把最新的酷安放到jadx里边,搜xposed,看到一个这样的类<br><code><br>public class bj {<br> public static void a() {<br> try {<br> Field declaredField =ClassLoader.getSystemClassLoader(). loadClass(“de.robv.android.xposed.XposedBridge”).getDeclaredField(“disableHooks”);<br> declaredField.setAccessible(true);<br> declaredField.set(null, Boolean.valueOf(true));<br> } catch (Throwable th) {<br> }<br> }<br>}<br></code><br>再看一下<a href="https://github.com/rovo89/XposedBridge/blob/art/app/src/main/java/de/robv/android/xposed/XposedBridge.java" target="_blank" rel="external">这个类</a>.好的把,还以为是什么黑科技…原来是反射.真相大白</p>
<h3 id="u7ED3_u8BBA"><a href="#u7ED3_u8BBA" class="headerlink" title="结论"></a>结论</h3><p>这样做其实意义不是很大,直接hook bj.a()方法就好了,亦或者自己编一份xposed出来改个类名,都可以过掉这个保护,不过骗骗小白还是可以的~.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[ida调试so]]></title>
<url>/2018/01/06/ida%E8%B0%83%E8%AF%95so/</url>
<content type="html"><![CDATA[<h3 id="u4E3A_u4EC0_u4E48_u8981_u5B66_u8FD9_u4E2A_3F"><a href="#u4E3A_u4EC0_u4E48_u8981_u5B66_u8FD9_u4E2A_3F" class="headerlink" title="为什么要学这个?"></a>为什么要学这个?</h3><p>现在人们都喜欢把关键的核心逻辑写在<a href="https://developer.android.com/ndk/guides/prebuilts.html" target="_blank" rel="external">so</a>里边.如果想抄代码,爬服务器,破解的话就必须对so进行逆向.</p>
<h3 id="u51C6_u5907_u5DE5_u4F5C"><a href="#u51C6_u5907_u5DE5_u4F5C" class="headerlink" title="准备工作."></a>准备工作.</h3><ol>
<li>一台root的安卓机,或者5.0以下的虚拟机(我没试,理论可行.至于为什么是5.0以下的<a href="https://issuetracker.google.com/issues/37123176" target="_blank" rel="external">见这里</a>) </li>
<li><a href="https://down.52pojie.cn/Tools/Disassemblers/" target="_blank" rel="external">ida pro</a></li>
<li><a href="https://developer.android.com/ndk/guides/index.html" target="_blank" rel="external">一丢丢ndk的知识</a></li>
<li><a href="http://resources.infosecinstitute.com/basics-of-ida-pro-2/#gref" target="_blank" rel="external">一丢丢ida的知识</a></li>
</ol>
<h3 id="u8FC7_u7A0B"><a href="#u8FC7_u7A0B" class="headerlink" title="过程."></a>过程.</h3><ol>
<li>用android studio 建一个包含c++的工程.<br><img src="\images\pasted-32.png" alt="upload successful"><br>都使用默认项一直下一步,得到一个包含jni的项目.<br><img src="\images\pasted-33.png" alt="upload successful"></li>
<li>稍作修改.<br>为了调试方便我们写一个简单的click函数来触发调用so的事件.<br><code><br> public native String stringFromJNI();<br> public void dealClick(View view) {<pre><code>TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
</code></pre> }<br></code></li>
<li>编译出apk,解压拿到so文件.<br><img src="\images\pasted-34.png" alt="upload successful"></li>
<li>放到ida里边 ,搜函数名,找到代码,下断点.<br><img src="\images\pasted-35.png" alt="upload successful"></li>
<li>启动android_server.<br>在ida安装目录(\IDA 7.0\dbgsrv)下找到android_server拷贝到安卓手机的/data下,改权限<code>chmod 777 android_server</code>然后执行<code>./android_server</code>.<br><img src="\images\pasted-37.png" alt="upload successful"></li>
<li>设置ida pro调试选项 然后附加进程.<br>ip是同一局域网下手机的ip(不在同一局域网下需要端口转发).端口号固定23946<br><img src="\images\pasted-39.png" alt="upload successful"><br>选择附加进程<br><img src="\images\pasted-38.png" alt="upload successful"></li>
<li>点击手机按钮,断下来了!!<br><img src="\images\pasted-40.png" alt="upload successful"></li>
</ol>
<h3 id="u7ED3_u8BBA"><a href="#u7ED3_u8BBA" class="headerlink" title="结论."></a>结论.</h3><p>至此我们完成了ida调试so的全过程.有两点需要注意,一是真正调的时候绝对不会这么顺利的,肯定有各种反调试手段等着我们,二是1-3步在实战中是没有的. 下一步就是找个软点的柿子实战一下了.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[windows卸载docker ce后virtualbox不能使用]]></title>
<url>/2018/01/04/windows%E5%8D%B8%E8%BD%BDdocker-ce%E5%90%8Evirtualbox%E4%B8%8D%E8%83%BD%E4%BD%BF%E7%94%A8/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>今天在windows上安装了docker ce,安装的时候提示:安上virtualbox就不能用了.我点了确定.然后过了一会我卸载掉了docker ce,但是仍然不能打开virtualbox虚拟机.</p>
<h3 id="u5206_u6790_u95EE_u9898"><a href="#u5206_u6790_u95EE_u9898" class="headerlink" title="分析问题."></a>分析问题.</h3><p>去<a href="https://stackoverflow.com/questions/46907506/cant-start-my-virtual-box-machine-after-installing-docker-on-windows/48081059#48081059" target="_blank" rel="external">网上搜</a>,有人说要把hyper-v停掉.可是停掉以后还是打不开.. 要更新virtualbox.于是更新,更新后虚拟机又能打开了.</p>
<h3 id="u4E3A_u4EC0_u4E48_u5355_u72EC_u5199_u4E00_u7BC7"><a href="#u4E3A_u4EC0_u4E48_u5355_u72EC_u5199_u4E00_u7BC7" class="headerlink" title="为什么单独写一篇."></a>为什么单独写一篇.</h3><p>因为困扰了我很久.且国内的文章没找到解决方案.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[给微信写个xposed模块]]></title>
<url>/2018/01/03/%E7%BB%99%E5%BE%AE%E4%BF%A1%E5%86%99%E4%B8%AAxposed%E6%A8%A1%E5%9D%97/</url>
<content type="html"><![CDATA[<h3 id="u76EE_u6807"><a href="#u76EE_u6807" class="headerlink" title="目标"></a>目标</h3><p>之前的文里边说过了,要写一个微信的模块,功能是<code>完全屏蔽群消息.即有了新消息也不要出现在顶端.</code></p>
<h3 id="u51C6_u5907_u5DE5_u4F5C"><a href="#u51C6_u5907_u5DE5_u4F5C" class="headerlink" title="准备工作"></a>准备工作</h3><p>在前几天按照顺序进行了如下准备工作 </p>
<ol>
<li><a href="https://github.com/rovo89/XposedBridge/wiki/Development-tutorial" target="_blank" rel="external">xposed入门</a></li>
<li><a href="https://source.android.com/devices/tech/dalvik/dalvik-bytecode" target="_blank" rel="external">smali语法入门</a></li>
<li><a href="/2018/01/01/设置红米debugable-1">搞一台适合做调试的设备</a></li>
<li><a href="/2018/01/01/动态调试smali">通过反编译的smali来调试程序</a></li>
<li><a href="https://github.com/zhudongya123/WechatChatroomHelper" target="_blank" rel="external">找一份代码作为借鉴</a> </li>
<li>选最新的wx1200.apk下手.</li>
</ol>
<h3 id="u7528_u6237_u7684_u9700_u6C42"><a href="#u7528_u6237_u7684_u9700_u6C42" class="headerlink" title="用户的需求"></a>用户的需求</h3><p> 用户就有我自己.我的痛点就是每天都有很多垃圾信息出现在聊天列表的顶部,我每天都要花10s的时间来删掉这些消息.我的诉求就是这些烦人的消息不要出现在顶部.但是我偶尔也要去看一眼. </p>
<h3 id="u6536_u96C6_u4FE1_u606F"><a href="#u6536_u96C6_u4FE1_u606F" class="headerlink" title="收集信息."></a>收集信息.</h3><p> 通过读开源的代码,以及读微信的smali和java文件,动态调试微信smali…得知微信的聊天列表是个listView,Adapter的类为<code>com.tencent.mm.ui.conversation.g</code>这个类继承了<br> <code>com.tencent.mm.ui.g</code>,其中部分smali代码如下.<br> <code><br> //<b>conversation.g 开始代码</b><br> .class public final Lcom/tencent/mm/ui/conversation/g;<br>.super Lcom/tencent/mm/ui/g;<br>//<b>notifyDataSetChanged部分代码.</b><br> .method public final notifyDataSetChanged()V<br> .locals 2<br> .prologue<br> .line 1743<br> invoke-super {p0}, Lcom/tencent/mm/ui/g;->notifyDataSetChanged()V<br> .line 1744<br>//<b>ui.g的BO方法</b><br> .method public final BO(I)Lcom/tencent/mm/bw/a/a;<br> .locals 6<br> .annotation system Ldalvik/annotation/Signature;<br> value = {<br> “(I)TT;”<br> }<br> .end annotation<br> .prologue<br> const/4 v5, 0x0 //仅部分<br> </code></p>
<h3 id="u601D_u8DEF_2C_u8BBE_u8BA1"><a href="#u601D_u8DEF_2C_u8BBE_u8BA1" class="headerlink" title="思路,设计"></a>思路,设计</h3><p> 我需要hook尽可能少的函数,因为hook的越多模块越不稳定(对于我这样的初学者来说),于是我决定这样做: 首先收集所有聊天信息成一个list,然后根据是否为被屏蔽的群聊对这个list进行重新排列.将被屏蔽的群聊放在最底端.<br> 这样我们需要hook两个函数.一个是通过position获的view的函数,一个是列表数据变化被调用的函数.<br> 在<code>notifyDataSetChanged</code>上下断点发现无论是增删改这个listView该函数都会被调用.而<code>ui.g.BO</code>方法是通过位置获取view的函数.<br> 在notifyDataSetChange后得到原来位置和排序后的位置关系存到map中,在通过位置取view前将位置掉包成排序后的位置(说起来好别扭,看代码吧…).</p>
<h3 id="u5B9E_u73B0"><a href="#u5B9E_u73B0" class="headerlink" title="实现"></a>实现</h3><p> <a href="https://github.com/HIjack2015/EntireBlockWeChatGroup" target="_blank" rel="external">放到了github上</a></p>
<h3 id="u6548_u679C"><a href="#u6548_u679C" class="headerlink" title="效果"></a>效果</h3><p> 顶部被屏蔽的群不见了<br><img src="/images\pasted-30.png" alt="upload successful"><br> 全都到了最底部.<br><img src="/images\pasted-31.png" alt="upload successful"></p>
<h3 id="u7ED3_u8BBA"><a href="#u7ED3_u8BBA" class="headerlink" title="结论"></a>结论</h3><p> 能这么快搞定和微信这部分代码没加壳有很大关系.以及很多事情没想的那么难.一点一点搞就好了.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[设置测试机的ro.debuggable=1]]></title>
<url>/2018/01/01/%E8%AE%BE%E7%BD%AE%E7%BA%A2%E7%B1%B3debugable-1/</url>
<content type="html"><![CDATA[<h3 id="u80CC_u666F"><a href="#u80CC_u666F" class="headerlink" title="背景"></a>背景</h3><p>最近写微信的xposed插件需要动态调试微信.但是由于微信的build.config=false,所以无法调试.搜索得知需要将微信运行到ro.debuggable=1的安卓系统上.</p>
<h3 id="u8FC7_u7A0B"><a href="#u8FC7_u7A0B" class="headerlink" title="过程"></a>过程</h3><ol>
<li>首先想到的是更改虚拟机的启动参数,更改后调试确实可以看到各种进程,但是装不上微信,因为虚拟机是x86的.安装微信会提示<code>找不到*so</code>,<a href="https://www.zhihu.com/question/32137346" target="_blank" rel="external">据说</a>需要安装一个x86转arm的东西,搞了半天也没搞好. </li>
<li>于是我新建了一个arm的虚拟机,可是arm的虚拟机实在是太慢了.也没有什么<a href="http://delphi.org/2013/11/8-tips-to-speed-up-your-android-arm-emulator-avd/" target="_blank" rel="external">好办法</a><br>来优化虚拟机. 于是我决定拿自己的手机来搞一搞. </li>
<li>我在我的红米note4x根目录下搜索debuggable,找到了<code>default.prop</code>,听起来就像是要改的地方.把0改成1,然后重启,发现又变成了0,去网上<a href="https://android.stackexchange.com/questions/28653/obtaining-root-by-modifying-default-propro-secure" target="_blank" rel="external">查资料</a>发现自己太天真了.资料上说需要修改boot.img,然后刷回手机.</li>
<li>需要手机的boot.img,按照<a href="https://www.cnblogs.com/0xJDchen/p/6007938.html" target="_blank" rel="external">搜到的资料</a>提取出boot.img,觉得不太对,因为大小只有1kB,使用<a href="https://github.com/cofface/android_bootimg" target="_blank" rel="external">bootimg.exe</a>解开报错.再三尝试,也没有从手机中提取到合适的boot.img</li>
<li>于是起了刷机的念头,我的手机是<a href="http://www.miui.com/thread-8124484-1-1.html" target="_blank" rel="external">解了bl锁,root过的</a>,所以搞起来会方便一些.<br>正好最近<a href="http://www.miui.com/download-326.html" target="_blank" rel="external">miui9</a>发布了,把开发版下载下来.<a href="http://tieba.baidu.com/p/3912611042" target="_blank" rel="external">解压,修改boot.img.然后压回去</a>,我们修改的内容仅是ro.debuggable=1,照常规刷机流程把rom刷进去就好了.(贴吧真是个神奇的地方..)</li>
<li>成功!<br><img src="\images\pasted-28.png" alt="upload successful"> </li>
</ol>
<h3 id="u5199_u5728_u540E_u8FB9"><a href="#u5199_u5728_u540E_u8FB9" class="headerlink" title="写在后边."></a>写在后边.</h3><p>这样离调试微信的目标又近了一步,另外我决定去淘个nexus6p,自己编译一个系统灌进去,据说这样调试起来会方便许多.</p>
]]></content>
<categories>
<category> 安卓逆向 </category>
</categories>
</entry>
<entry>
<title><![CDATA[动态调试smali]]></title>
<url>/2018/01/01/%E5%8A%A8%E6%80%81%E8%B0%83%E8%AF%95smali/</url>
<content type="html"><![CDATA[<h3 id="u9700_u8981_u7684_u5DE5_u5177"><a href="#u9700_u8981_u7684_u5DE5_u5177" class="headerlink" title="需要的工具."></a>需要的工具.</h3><ol>
<li>android studio 或者 intellij IDEA(以AS为例)</li>
<li><a href="https://ibotpeaches.github.io/Apktool/" target="_blank" rel="external">APKTOOL</a></li>
<li><a href="https://bitbucket.org/JesusFreke/smali/downloads/smalidea-0.05.zip" target="_blank" rel="external">Smalidea 插件</a></li>
</ol>
<h3 id="u6B65_u9AA4"><a href="#u6B65_u9AA4" class="headerlink" title="步骤"></a>步骤</h3><ol>
<li>在ide中安装插件. </li>
<li>选一个没加固的apk(最好是自己编一个apk出来,也不要混淆什么的). </li>
<li>用apktool反编译apk,得到smali文件夹. </li>
<li>在android studio 中导入项目.</li>
<li>配置调试器</li>
<li>打断点,开始调试.(有空详说+补充图片)</li>
</ol>
<h3 id="u53C2_u8003_u8D44_u6599"><a href="#u53C2_u8003_u8D44_u6599" class="headerlink" title="参考资料"></a>参考资料</h3><p> <a href="https://github.com/JesusFreke/smali/wiki/smalidea" target="_blank" rel="external">smali wiki</a><br> <a href="https://crosp.net/blog/android/android-reverse-engineering-debugging-smali-using-smalidea/" target="_blank" rel="external">一份更为详细的教程</a></p>
]]></content>
</entry>
<entry>
<title><![CDATA[再见2017]]></title>
<url>/2017/12/29/%E5%86%8D%E8%A7%812017/</url>
<content type="html"><![CDATA[<h3 id="u6211_u53D1_u8A93_u8FD9_u662F_u6700_u540E_u4E00_u6B21_u6D6A_u4E86"><a href="#u6211_u53D1_u8A93_u8FD9_u662F_u6700_u540E_u4E00_u6B21_u6D6A_u4E86" class="headerlink" title="我发誓这是最后一次浪了."></a>我发誓这是最后一次浪了.</h3><p>说起来今天是2017年的最后一个工作日了,想来我是会有点小激动的,如果我还在上班的话,可惜我没有.因为我辞去工作浪了.</p>
<h3 id="u4E3A_u4EC0_u4E48_u8981_u6D6A"><a href="#u4E3A_u4EC0_u4E48_u8981_u6D6A" class="headerlink" title="为什么要浪"></a>为什么要浪</h3><p>谁又想写一辈子业务代码呢?做出的东西仅是为了完成任务,没有用户又有什么意思呢,所以今年5月决定辞职了,去做些更有趣的事情,比如考研,比如做一个独立开发者.</p>
<h3 id="u90A3_u4F60_u6210_u529F_u4E86_u5417_3F"><a href="#u90A3_u4F60_u6210_u529F_u4E86_u5417_3F" class="headerlink" title="那你成功了吗?"></a>那你成功了吗?</h3><p>想来是没有的,还被现实<b>狠狠地</b>删了一耳光.<br>半年开发了三个app,两个靠广告收入了一共不到10块(写出来都觉得丢人),一个靠捐款收入200,诶,,,,一声长叹.我本以为我解决了温饱问题,可以开始追求成就感了,其实看到好评的时候确实会开心一下.<br><img src="\images\pasted-27.png" alt="upload successful">但是我还是不能靠这个养活自己.不够租房,甚至不够吃饭,我总是要面对现实的,就当练手了吧.<br> 而且由于初期的盲目乐观,后期的动能不足,初试通过的可能性也就一两成吧,.而且今年数学还泄题了.也算给我上了一课吧,尤其是在背政治背的自己都要信了的情况下.</p>
<h3 id="u6240_u4EE5_u5462_3F"><a href="#u6240_u4EE5_u5462_3F" class="headerlink" title="所以呢?"></a>所以呢?</h3><p> 半年前辞职的时候想,就算荒废半年也没有什么不可以接受的.毕竟自己早上了一年学.半年过去了,再也没有资本浪了.从现在起,面对现实吧.</p>
]]></content>
<categories>
<category> 胡言乱语 </category>
</categories>
</entry>
<entry>
<title><![CDATA[安卓逆向入门]]></title>
<url>/2017/12/29/%E5%AE%89%E5%8D%93%E9%80%86%E5%90%91%E5%85%A5%E9%97%A8/</url>
<content type="html"><![CDATA[<h3 id="u4E3A_u4EC0_u4E48_u8981_u5B66_u8FD9_u4E2A"><a href="#u4E3A_u4EC0_u4E48_u8981_u5B66_u8FD9_u4E2A" class="headerlink" title="为什么要学这个."></a>为什么要学这个.</h3><p>因为最近加到了亲戚的群里,有个人每天都要发四条广告,实在受不了,即使是屏蔽了群消息,还是会有一个小红点,微信又没有提供完全屏蔽的功能,所以只能自己写个xposed模块来搞一搞了. </p>
<h3 id="u4E3A_u4EC0_u4E48_u662Fxposed"><a href="#u4E3A_u4EC0_u4E48_u662Fxposed" class="headerlink" title="为什么是xposed"></a>为什么是xposed</h3><p>能想到的方案就两种,1. 改包重新编译,这个有三点不好,微信一升级就得重新搞,签名不一样分享到微信功能就不好使了,而且据说容易封号,2. xposed,唯一的不好就是总得重启.</p>
<h3 id="u9047_u5230_u4EC0_u4E48_u95EE_u9898_3F"><a href="#u9047_u5230_u4EC0_u4E48_u95EE_u9898_3F" class="headerlink" title="遇到什么问题?"></a>遇到什么问题?</h3><p>我首先应该把apk反编译了,找到合适的类和方法来hook,但是第一步就难到了我,反编译出来了5个dex,用dex2jar 转jar包的时候报错,<br><img src="/images\pasted-22.png" alt="upload successful"><br>去<a href="https://stackoverflow.com/questions/1393486/error-java-lang-outofmemoryerror-gc-overhead-limit-exceeded" target="_blank" rel="external">网上</a>搜说是该加些jvm选项.可是加上后仍然报错,于是换jadx试,也是转到一半就进程就死掉了.我想这是微信为了防破解做了些什么事情.但是做了什么事情我就不知到了.所以还是先从基础学起吧.</p>
<h3 id="u5F00_u59CB_21"><a href="#u5F00_u59CB_21" class="headerlink" title="开始!"></a>开始!</h3><p>我决定先学下改apk,改一个别人的apk可以让我快速了解apk的结构和smali的语法.说干就干,柿子要捡软的捏,我看了一眼手机上的app,决定就挑这个<a href="https://www.coolapk.com/apk/com.plan.kot32.tomatotime" target="_blank" rel="external">软柿子</a>了.目标为破解vip后重新打包.</p>
<h3 id="u8FC7_u7A0B"><a href="#u8FC7_u7A0B" class="headerlink" title="过程"></a>过程</h3><p>先把包扔到apkstudio里边,按照以前在windows上的经验,找提示入口<br><img src="/images/pasted-23.png" alt="upload successful">.这个柿子果然很软,几乎没有什么保护手段.一路跟到这里<br><img src="/images\pasted-24.png" alt="upload successful">在smali把返回值中改成1.<br><img src="/images\pasted-25.png" alt="upload successful"><br>重新打包,签名,安装.<br><img src="/images\pasted-26.png" alt="upload successful"></p>
<h3 id="u7ED3_u8BBA"><a href="#u7ED3_u8BBA" class="headerlink" title="结论"></a>结论</h3><p>通过一次简单的逆向了解了安卓的逆向的过程,以及smali的语法.发现安卓端的逆向要比windows上简单很多.可能这就是汇编和字节码的区别吧.接下来就是调研微信究竟为了反调试做了哪些事情了.</p>
]]></content>
<categories>
<category> 安卓逆向 </category>
</categories>
<tags>
<tag> android </tag>
</tags>
</entry>
<entry>
<title><![CDATA[升级apk自带的db]]></title>
<url>/2017/09/13/%E5%8D%87%E7%BA%A7apk%E8%87%AA%E5%B8%A6%E7%9A%84db/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>有时候在开发app的时候,要在/assets下放一个sqlite的db文件.当版本升级的时候我们需要更新里边的数据.笔者使用了<a href="https://github.com/jgilfelt/android-sqlite-asset-helper" target="_blank" rel="external">sqliteassethelper</a>和 <a href="https://github.com/greenrobot/greenDAO" target="_blank" rel="external">greendao</a> 进行数据库管理和升级. </p>
<h3 id="u5347_u7EA7_u6B65_u9AA4"><a href="#u5347_u7EA7_u6B65_u9AA4" class="headerlink" title="升级步骤"></a>升级步骤</h3><ol>
<li>增加db文件中的userversion <code>pragma user_version=5</code>(根据自己设定的规则选一个新的version).</li>
<li>对应的改变build.gradle里边的userversion.<br><img src="/images/pasted-20.png" alt="upload successful"><br>这是greendao需要的配置项.</li>
<li>写出升级的sql并按照sqliteassethelper的要求创建相应的sql文件.<br><img src="/images/pasted-21.png" alt="upload successful"></li>
<li>在db中执行升级sql.</li>
<li>对应的helper里边也要改一下<br><code><br>public class WordDatabase extends SQLiteAssetHelper {<br> private static final int DATABASE_VERSION = 4;<br></code><h3 id="done_7E_21"><a href="#done_7E_21" class="headerlink" title="done~!"></a>done~!</h3>这样,在老用户升级的时候,升级sql就会自动执行.新用户则会直接将最新的db拷贝到相应目录.</li>
</ol>
]]></content>
</entry>
<entry>
<title><![CDATA[点评一下国内的应用市场]]></title>
<url>/2017/08/08/%E7%82%B9%E8%AF%84%E4%B8%80%E4%B8%8B%E5%9B%BD%E5%86%85%E7%9A%84%E5%BA%94%E7%94%A8%E5%B8%82%E5%9C%BA/</url>
<content type="html"><![CDATA[<h3 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a>前言</h3><p>和国内的应用市场们打交道也有一段时间了.那么让我以一个个人开发者的角度来点评一下国内的应用市场吧.</p>
<h3 id="u6328_u4E2A_u70B9_u8BC4"><a href="#u6328_u4E2A_u70B9_u8BC4" class="headerlink" title="挨个点评."></a>挨个点评.</h3><ol>
<li>最无语. 360.<br>360的工作人员态度挺好的.审核也很及时.但是就是不让上架.原因包括但不限于:需要以公司身份上架.缺少文件. </li>
<li>最差 腾讯应用宝<br>审核不及时,上线后根本看不到自己的应用.搜出来的全是广告.一点机会都不给.</li>
<li>一般 小米,百度<br>确实给机会了,但是审核的很慢.上架游戏没成功.应用上架后能搜的到.这就可以了.</li>
<li>还好 华为<br>华为好于小米百度是因为他的开发者控制台还不错.有各种测试工具.而且可以远程调用华为的各种真机.而且竟然可以调用很多谷歌的亲儿子.</li>
<li>给机会 酷安<br>酷安的用户和上边的比少很多,但是它会给独立开发者机会.至少新上架的应用会得到一次展示的机会,而且如果应用确实不错的话有机会上头条.(我的应用每次更新后都会在头条上待一天左右)</li>
<li>游戏开发者的乐园. taptap<br>taptap 在我看来是游戏开发者的乐园.没有之一.它有很多高素质玩家.而且上架不需要乱七八糟的证明什么的.(毕竟我的游戏只在taptap和酷安上架了…),此外它还有完善的付费机制(据说.)</li>
<li>顺便一提 google play<br>还没有试,先挖个坑,过几天来填.</li>
</ol>
]]></content>
</entry>
<entry>
<title><![CDATA[如何批量重命名文件]]></title>
<url>/2017/08/07/%E5%A6%82%E4%BD%95%E6%89%B9%E9%87%8F%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6/</url>
<content type="html"><![CDATA[<h3 id="u7B80_u5355_u7684_u8BB0_u4E00_u4E0B"><a href="#u7B80_u5355_u7684_u8BB0_u4E00_u4E0B" class="headerlink" title="简单的记一下"></a>简单的记一下</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">dir | rename-item -NewName {$_.name -replace "_weapon.png",".png"}</div></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title><![CDATA[若一去不回]]></title>
<url>/2017/08/03/%E8%8B%A5%E4%B8%80%E5%8E%BB%E4%B8%8D%E5%9B%9E/</url>
<content type="html"><![CDATA[<h3 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言."></a>前言.</h3><p>这一篇没什么营养,是个人的一些想法. </p>
<h3 id="u4E3A_u4EC0_u4E48_u7A81_u7136_u6709_u60F3_u6CD5_u4E86_3F"><a href="#u4E3A_u4EC0_u4E48_u7A81_u7136_u6709_u60F3_u6CD5_u4E86_3F" class="headerlink" title="为什么突然有想法了?"></a>为什么突然有想法了?</h3><p>今天跑了五个银行去办一张visa的卡.本来也不是什么难的事情.但是因为自己的尴尬身份没有办下来.一个大学毕业的人,没有社保没有正式工作.办不下信用卡来.唯一一个中行还要预存一万等额外币.最终花了大价钱(340)在淘宝上买了一个.感觉很亏.但也没什么办法.因为我打算将自己的app上架在google play.</p>
<p>其实最近过得不是很好,也可以说是很不好.顺心的事情很少,自从六月辞职以来,旅行花了十几天.剩下的时间用来复习考研和开发app.都不是很顺利.<br>复习遇到的最大困扰就是数学题不会做.并且对复习考研总是提不起兴趣来.<br>开发app最大的问题就是上架问题.</p>
<ol>
<li>被多家应用市场以各种各样的理由拒绝.我能记起来的不下10个.</li>
<li>而且适配系统,适配屏幕,适配厂商的深度定制.适配自己的历史版本.</li>
<li>开发之路也不是一帆风顺.总会踩到各种各样的坑.就很烦.有时候一个问题会困扰5个小时.就会觉得自己很废物.</li>
<li>上架之后偶尔有奇怪的bug出现,多出现在多线程上.因为没有接入崩溃统计的sdk.难以分析.</li>
<li>没有收入,接入广告的app收入大概在4美分每天.不带广告只有捐款的app平均每天三毛.虽然之前的公司工资不高,到手也有9k.而且还可以住公司宿舍.现在呢?身上的积蓄快完了.服务器一个月要80块,租房要1K,吃饭至少500.我到底想要什么呢? </li>
</ol>
<h3 id="u6211_u60F3_u8981_u4EC0_u4E48"><a href="#u6211_u60F3_u8981_u4EC0_u4E48" class="headerlink" title="我想要什么"></a>我想要什么</h3><ol>
<li>首先,我想要凭借自己的双手养活自己,这个目标只要2k就可以实现.</li>
<li>一套房.这个就难了些,暂时不考虑.</li>
<li>得到用户的认可,这个已经部分实现了.</li>
<li>稳定的收入,能养活家人,这个还不急,实现1再说.大概需要10k/m</li>
<li>帮助需要帮助的人,让世界因我存在而更好一点. 等实现了 1234 再说吧. </li>
</ol>
<h3 id="u60F3_u8981_u5C31_u53BB_u505A_u554A"><a href="#u60F3_u8981_u5C31_u53BB_u505A_u554A" class="headerlink" title="想要就去做啊."></a>想要就去做啊.</h3><p>想要和得到 ,中间还有两个字,就是做到.<br>最初的梦想,一定会实现.<br>敢想不敢为者,终困身牢笼.<br>如果梦想不曾坠落悬崖 千钧一发 又怎会晓得执着的人 拥有隐形翅膀.<br>不如再看一遍士兵突击吧.看看许三多,想一想什么算好好活.</p>
<p> “大圣,此去欲何?”<br> “踏南天,碎凌霄。”<br> “若一去不回……”<br> “便一去不回” </p>
]]></content>
<categories>
<category> 胡言乱语 </category>
</categories>
</entry>
<entry>
<title><![CDATA[python爬虫初体验]]></title>
<url>/2017/07/22/python%E7%88%AC%E8%99%AB%E5%88%9D%E4%BD%93%E9%AA%8C/</url>
<content type="html"><![CDATA[<h3 id="u5199_u5728_u524D_u8FB9"><a href="#u5199_u5728_u524D_u8FB9" class="headerlink" title="写在前边"></a>写在前边</h3><p>最近python爬虫大火,我这样一个java的忠实粉丝也忍不住去python官网看了看文档.搭环境写了几个demo.你还别说,真的给我一种很”锋利”的感觉,远比什么 c sharp 锋利的多.</p>
<h3 id="u7B80_u5355_u7684_u722C_u866B"><a href="#u7B80_u5355_u7684_u722C_u866B" class="headerlink" title="简单的爬虫."></a>简单的爬虫.</h3><p>出于某种需要,我要爬一本单词,网址如下<a href="https://www.shanbay.com/wordbook/115978/" target="_blank" rel="external">一本英文词典</a>.我的目标是爬下所有的英文单词.说干就干!<br>先分析一下,这个单词书有2000多单词,分为16个网页: <a href="https://www.shanbay.com/wordbook/115978/123" target="_blank" rel="external">https://www.shanbay.com/wordbook/115978/123</a>, 每个网页又分为10个page :<a href="https://www.shanbay.com/wordbook/115978/123?page=1" target="_blank" rel="external">https://www.shanbay.com/wordbook/115978/123?page=1</a>.<br>我觉得构建这10*16个网页url还是直接在浏览器控制台构建好了.回顾了一下jquery的语法,写出代码如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">urls=[]</div><div class="line">for( i=0;i<$(".wordbook-wordlist-name").length;i++) {</div><div class="line"> var url= $($(".wordbook-wordlist-name")[i].children[0]).attr('href')</div><div class="line"> urls.push('https://www.shanbay.com'+url)</div><div class="line">}</div><div class="line">for(i=0;i<urls.length;i++) {</div><div class="line"> for(j=1;j<11;j++) {</div><div class="line"> console.log(urls[i]+'?page='+j)</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>得到了所有的url.然后找一个python download函数<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">import urllib3</div><div class="line"></div><div class="line">http = urllib3.PoolManager()</div><div class="line">def download(urlToDown):</div><div class="line"> fp = http.request('GET',urlToDown)</div><div class="line"> return fp.data.decode('utf-8');</div></pre></td></tr></table></figure></p>
<p>下载一个html的content只需要4行!这里我不得不和java的对比一下(随手写的,不确定可以执行):<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"></div><div class="line">import java.nio.charset.Charset;</div><div class="line">import org.apache.http.client.methods.CloseableHttpResponse;</div><div class="line">import org.apache.http.client.methods.HttpGet;</div><div class="line">import org.apache.http.client.methods.HttpUriRequest;</div><div class="line">import org.apache.http.client.methods.RequestBuilder;</div><div class="line">import org.apache.http.impl.client.CloseableHttpClient;</div><div class="line">import org.apache.http.impl.client.HttpClients;</div><div class="line">import org.apache.http.util.EntityUtils;</div><div class="line"> private CloseableHttpClient httpclient = HttpClients.custom()</div><div class="line"> .setDefaultCookieStore(cookieStore).build();</div><div class="line"></div><div class="line"> public String download(String url) {</div><div class="line"> HttpGet httpget = new HttpGet(url);</div><div class="line"> try {</div><div class="line"> CloseableHttpResponse response3 = httpclient.execute(httpget);</div><div class="line"> String content = EntityUtils.toString(response3.getEntity(),</div><div class="line"> Charset.forName("utf8"));</div><div class="line"> return content;</div><div class="line"> } catch (Exception e) {</div><div class="line"> return e.toString();</div><div class="line"></div><div class="line"> }</div><div class="line"> }</div></pre></td></tr></table></figure></p>
<p>然后是取目标单词.考虑在html中单词元素有特征如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><td class="span2"><strong>wrapped</strong></td></code></div></pre></td></tr></table></figure></p>
<p>直接用正则就好了.<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">allWord=[]</div><div class="line">def getWordFromUrl(shanBeiUrl):</div><div class="line"> content= download(shanBeiUrl)</div><div class="line"> words= re.findall('<td class="span2"><strong>(.*?)</strong></td>', content)</div><div class="line"> allWord.extend(words)</div><div class="line"> return</div></pre></td></tr></table></figure></p>
<p>再加上循环和输出<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">for shanbeiUrl in shanBeiUrls:</div><div class="line"> getWordFromUrl(shanbeiUrl)</div><div class="line"> </div><div class="line">print(allWord)</div></pre></td></tr></table></figure></p>
<p>代码加一块不到20行!我的天!之前用java写类似的程序,花了半天的时间,定义了5个类,20几个方法.还美滋滋的认为自己面向对象了..以下是去年写的爬公司oa的java代码.<br><img src="/images/pasted-19.png" alt="upload successful"></p>
<h3 id="python_u548Cjava_u7684_u533A_u522B_3F"><a href="#python_u548Cjava_u7684_u533A_u522B_3F" class="headerlink" title="python和java的区别?"></a>python和java的区别?</h3><p>以我长达三小时的python学习来说.他们的区别有如下几点,</p>
<table>
<thead>
<tr>
<th>属性</th>
<th style="text-align:center">java</th>
<th style="text-align:right">python</th>
</tr>
</thead>
<tbody>
<tr>
<td>语法</td>
<td style="text-align:center">有些繁复.<br>另外为了命名清晰,函数和变量总是特别长.</td>
<td style="text-align:right">十分简单,没有花括号,不用加引号,使用缩进代替<br>各种命名都力求简洁</td>
</tr>
<tr>
<td>集合处理</td>
<td style="text-align:center">难之又难,(每个操作)</td>
<td style="text-align:right">简单得很</td>
</tr>
<tr>
<td>库</td>
<td style="text-align:center">很多很多,我从来没有遇到找不到想要的库找不到的情况</td>
<td style="text-align:right">据说python以库多著称</td>
</tr>
<tr>
<td>使用范围</td>
<td style="text-align:center">作为一个java的粉丝,我认为java适用范围很广,就算是写脚本也可以用groovy啊.</td>
<td style="text-align:right">这个比java还是差了点吧,至少2016毕业的时候以python为主的公司就遇到过3家</td>
</tr>
</tbody>
</table>
<h3 id="u611F_u89E6"><a href="#u611F_u89E6" class="headerlink" title="感触."></a>感触.</h3><ol>
<li>面向对象不是银弹,设计模式也不是.黑猫白猫.高效,稳定,快速,安全,可扩展的抓住老鼠的猫才是好猫.</li>
<li>估计某个项目会尝试使用python作为后台.请期待下一篇.</li>
</ol>
]]></content>
<categories>
<category> python </category>
</categories>
<tags>
<tag> 爬虫 </tag>
</tags>
</entry>
<entry>
<title><![CDATA[green dao 返回的结果都是相同的??]]></title>
<url>/2017/07/21/green-dao-%E8%BF%94%E5%9B%9E%E7%9A%84%E7%BB%93%E6%9E%9C%E9%83%BD%E6%98%AF%E7%9B%B8%E5%90%8C%E7%9A%84/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>今天写程序尝试从sqlite db中取出一个列表,orm用的是greendao,代码如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">List<SolveStep> solveSteps= solveStepDao.queryBuilder()</div><div class="line"> .where(SolveStepDao.Properties.PuzzleId.eq(puzzleId))</div><div class="line"> .orderAsc(SolveStepDao.Properties.Sequence)</div><div class="line"> .build().list();</div></pre></td></tr></table></figure></p>
<p>结果取出来的结果都是相同的,且都为数据库中的第一条记录:<br><img src="/images/pasted-18.png" alt="upload successful"></p>
<h3 id="u89E3_u51B3_u8FC7_u7A0B"><a href="#u89E3_u51B3_u8FC7_u7A0B" class="headerlink" title="解决过程"></a>解决过程</h3><p>按照我解决问题的思路,首先去google搜索如下关键字.<b>greendao result same error</b>,然后打开前几个结果.竟然都和我的问题没关系.我陷入了深深的沉思.</p>
<ol>
<li>莫不是数据库中的数据就是相同的?仔细查询发现并不是.</li>
<li>莫不是greendao的缓存机制出了问题?看了一会文档,觉得<code>list()</code>这个函数没什么问题.</li>
<li>莫不是android studio 或者设备出了问题? 全部重启,问题还在.</li>
<li>哪里写错了触发了隐藏bug? 没有啊…以前也是这么写的…</li>
<li>真的是灵异事件???</li>
</ol>
<p>我觉得这样下去是解决不了问题的.从头分析一下吧</p>
<ol>
<li>list中都是同一个对象的引用.</li>
<li>list中的那个对象是正确结果集中的第一个.<br>所以是由于某种原因导致greendao查询完第一个结果之后不再继续查询.转而从缓存中拿数据.<br>那么greendao是根据什么来判断缓存中已经有这个记录了呢?<b>ID</b>,我赶紧打开model来看.<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">@Entity</div><div class="line">public class SolveStep {</div><div class="line"> @Id</div><div class="line"> private Integer puzzleId;</div><div class="line"></div><div class="line"> private Integer stepNo;</div><div class="line"></div><div class="line"> private String pointToMove;</div><div class="line"></div><div class="line"> private Integer direction;</div><div class="line"></div><div class="line"> </div><div class="line"> private Integer id;</div></pre></td></tr></table></figure>
</li>
</ol>
<p>这里的 puzzleId并不是主键,而是外键.也是查询的条件.真正的主键是 Id,<code>@Id</code>这个注解标错了位置.才导致了这个问题的出现.</p>
<h3 id="u611F_u609F"><a href="#u611F_u609F" class="headerlink" title="感悟"></a>感悟</h3><p>谷歌不是万能的.它拯救不了一个傻逼,遇到问题还是要从蛛丝马迹推断,以及不细心的话不仅考不了高分.写代码效率也会特别低.</p>
]]></content>
<categories>
<category> 编程 </category>
</categories>
<tags>
<tag> orm </tag>
</tags>
</entry>
<entry>
<title><![CDATA[一份正确的mybatis gen xml for sqlite db]]></title>
<url>/2017/07/19/%E4%B8%80%E4%BB%BD%E6%AD%A3%E7%A1%AE%E7%9A%84mybatis-gen-xml-for-sqlite-db/</url>
<content type="html"><![CDATA[<h3 id="u5199_u5728_u524D_u9762"><a href="#u5199_u5728_u524D_u9762" class="headerlink" title="写在前面."></a>写在前面.</h3><p>每次给sqlite db 中的表生成model时都要折腾半天 mybatis generator.这东西唯一的好处就是大表不用写很长的java bean.现在备份一份完整可用的.以后都按照这份配置就好了.</p>
<h3 id="u914D_u7F6E_u6587_u4EF6"><a href="#u914D_u7F6E_u6587_u4EF6" class="headerlink" title="配置文件"></a>配置文件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><?xml version="1.0" encoding="UTF-8"?></div><div class="line"><!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"></div><div class="line"><generatorConfiguration></div><div class="line"></div><div class="line"> <classPathEntry location="L:\jar\sqlite-jdbc-3.7.2.jar"></classPathEntry></div><div class="line"></div><div class="line"> <context id="context1"></div><div class="line"> <!-- 不需要注释 --></div><div class="line"> <commentGenerator></div><div class="line"> <property name="suppressAllComments" value="true" /></div><div class="line"> </commentGenerator></div><div class="line"> <jdbcConnection driverClass="org.sqlite.JDBC"</div><div class="line"> connectionURL="jdbc:sqlite:K:\dbName.db"</div><div class="line"> userId="" password=""></div><div class="line"> </jdbcConnection></div><div class="line"> <javaModelGenerator targetPackage="model"</div><div class="line"> targetProject="myBatisGen2"></javaModelGenerator></div><div class="line"> <sqlMapGenerator targetPackage="model" targetProject="myBatisGen2"></sqlMapGenerator></div><div class="line"> <javaClientGenerator targetPackage="model"</div><div class="line"> targetProject="myBatisGen2" type="XMLMAPPER"></javaClientGenerator></div><div class="line"></div><div class="line"> <table tableName="puzzle"></div><div class="line"></div><div class="line"> </table></div><div class="line"> </context></div><div class="line"></generatorConfiguration></div></pre></td></tr></table></figure>
<p>只要以后照着这份配置应该就没什么问题了.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[上架一个app前需要做什么]]></title>
<url>/2017/07/14/%E4%B8%8A%E6%9E%B6%E4%B8%80%E4%B8%AAapp%E5%89%8D%E9%9C%80%E8%A6%81%E5%81%9A%E4%BB%80%E4%B9%88/</url>
<content type="html"><![CDATA[<h3 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a>前言</h3><p>如果你是一个安卓独立应用开发者,如果你从来没有上架过应用,那么这篇文章可能会帮到你.</p>
<h3 id="u6B65_u9AA4"><a href="#u6B65_u9AA4" class="headerlink" title="步骤"></a>步骤</h3><ol>
<li>新建密钥库,新建密钥,签名的时候要用. </li>
<li>找一份适合自己的混淆文件.混淆文件可以帮助你混淆你的源码,如果不混淆和开源没什么区别,就算你打算开源,也应该配置混淆以减小压缩包的体积.</li>
<li>第三方加固,再次加大反编译的难度,且有些应用市场不再次加固无法上架.</li>
<li>决定上架在哪些市场.根据查到的资料我决定在用户量最大的 360和应用宝上架,此外还有小米,华为和酷安.</li>
<li>通过开发者认证,你需要一个邮箱,手机号,身份证号,身份证照片,手持证件照,来通过开发者认证.</li>
<li>准备上架应用的材料. <ul>
<li>一句话介绍你的app.</li>
<li>100字的应用介绍.</li>
<li>至少四张的app截图.</li>
<li>推荐页的图片(可选).</li>
<li>各个尺寸的图标 16*16,216*216,512*512.</li>
<li>已经签名加固的apk.</li>
</ul>
</li>
<li>上传应用等待审核通过. </li>
</ol>
<h3 id="u80E1_u8BF4_u516B_u9053"><a href="#u80E1_u8BF4_u516B_u9053" class="headerlink" title="胡说八道"></a>胡说八道</h3><p>至少从现在看来,成为一个独立开发者并不是一个很好的选择,经济来源无非是 捐赠,广告.除非自己注册一个公司,否则无法引入付费应用和会员机制.广告有人喷,捐款没人捐.可能我还是该找个地方去上班吧.继续去写不想写的代码.但是在那之前还是坚持一下吧.</p>
]]></content>
<categories>
<category> 安卓 </category>
</categories>
</entry>
<entry>
<title><![CDATA[java中的NULL和null]]></title>
<url>/2017/07/12/java%E4%B8%AD%E7%9A%84NULL%E5%92%8Cnull/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>众所周知,java的语法中是没有NULL的,那我为什么要起一个骇人听闻的标题呢?昨天code的时候,我给一个Integer赋值为空,但是debug发现它的值为0.</p>
<h3 id="u89E3_u51B3_u8FC7_u7A0B"><a href="#u89E3_u51B3_u8FC7_u7A0B" class="headerlink" title="解决过程"></a>解决过程</h3><p>我很恐慌,觉得自己的认知受到了颠覆,开始看Integer的自动装箱.开始四处查资料,两个小时过去了,我发现我的赋值语句是这样的.<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Integer i=NULL;</div></pre></td></tr></table></figure></p>
<p>我发现了有哪里不对,我点到NULL的声明里边去.发现这个变量位于java.sql,类名为Types<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">/**</div><div class="line"> * <P>The constant in the Java programming language</div><div class="line"> * that identifies the generic SQL value</div><div class="line"> * <code>NULL</code>.</div><div class="line"> */</div><div class="line"> public final static int NULL = 0;</div></pre></td></tr></table></figure></p>
<p>额,原来是手残拼错了.我的两个小时啊….</p>
<h3 id="u611F_u609F"><a href="#u611F_u609F" class="headerlink" title="感悟"></a>感悟</h3><p> 最近换了新的ide,intellja 会自动加入静态引用,而eclipse不会,也许之前也拼错过,但是eclipse会报错吧.<br>感悟就是:关注语法,注意保留关键字.注意代码中不同单词在ide中颜色不一样.<br>以及google和stackoverflow也不是全能的,它们拯救不了一个傻逼.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[代码整洁之道笔记]]></title>
<url>/2017/07/08/%E4%BB%A3%E7%A0%81%E6%95%B4%E6%B4%81%E4%B9%8B%E9%81%93%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<h3 id="u5199_u5728_u524D_u8FB9"><a href="#u5199_u5728_u524D_u8FB9" class="headerlink" title="写在前边"></a>写在前边</h3><p>随着我的项目功能点越来越多,项目持续时间也越来越长.我开始看着以前的代码发呆:</p>
<ul>
<li>这个变量,这个方法,这个类是干什么用的?</li>
<li>为什么已经在努力,仍然有一些重复的代码?</li>
<li>怎么javadoc写了跟没写一个样?</li>
<li>这种垃圾注释真的是我写的?</li>
<li>这个类如何与其他类交互?</li>
<li>为什么当时要这么分包?</li>
<li>为什么svn上的提交日志和实际更改不完全一致? </li>
<li>为什么我不像是写代码,而是像写bug? </li>
</ul>
<p>我越来越力不从心,我需要一个银弹.于是我决定找出以前草草读过的<代码整洁之道>,再认真的结合项目读一遍,并做一些笔记.(我始终认为每个java程序员都应该读一读这本书,这既是为自己好,也是对同事的仁慈).</p>
<h3 id="u7410_u788E_u7684_u7B14_u8BB0_u548C_u611F_u609F"><a href="#u7410_u788E_u7684_u7B14_u8BB0_u548C_u611F_u609F" class="headerlink" title="琐碎的笔记和感悟"></a>琐碎的笔记和感悟</h3><h4 id="u7AE5_u5B50_u519B_u519B_u89C4"><a href="#u7AE5_u5B50_u519B_u519B_u89C4" class="headerlink" title="童子军军规"></a>童子军军规</h4><pre><code>让营地比你来的时候更干净.
</code></pre><p>如果每次签入时,代码都比签出时干净,那么代码就不会腐坏,清理并一定要花多少时间,也许只是改好一个变量名,拆分一个有点过长的函数,消除一点点重复的代码,清理一个嵌套的if.<br><small>感悟:也许我该看一看svn的提交记录,并且每次提交前先运行两遍code inspect. 此外 .</small></p>
]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> 代码 </tag>
<tag> 笔记 </tag>
</tags>
</entry>
<entry>
<title><![CDATA[关于设计的笔记]]></title>
<url>/2017/07/08/%E5%85%B3%E4%BA%8E%E8%AE%BE%E8%AE%A1%E7%9A%84%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<h3 id="u5199_u5728_u524D_u8FB9"><a href="#u5199_u5728_u524D_u8FB9" class="headerlink" title="写在前边"></a>写在前边</h3><p>最近在尝试成为一个可以养活自己的独立开发者,虽然会有些难,但我仍想试一下.做一个好的app,设计必不可少.但这可难到了我,从ui,到ue,我都是一窍不通.所以开始看书看视频提高自己的设计水平. 并做了一些笔记.同时也希望能对你有所帮助. </p>
<h5 id="u5173_u4E8E_u521B_u65B0"><a href="#u5173_u4E8E_u521B_u65B0" class="headerlink" title="关于创新"></a>关于创新</h5><p>世间没有无缘无故的爱恨情愁,更没有空中阁楼而来的灵动设计。每一个曾经瞬间探触过你内心深处的设计,背后必有缘由。问渠哪得清如许,为有源头活水来。再说创新,对这个永恒的话题,我们发现,创新从来都不刻意苛求而来的,我们的做法就是彻底忘掉这个词。设身处地地研究和理解用户,然后以挑剔和挑战的态度不断迭代并尝试更好的解决方案。直到有一天,开始有人惊呼,于是,所谓的创新就出现了。<br>来自 <em>在你身边,为你设计-腾讯的用户体验设计之道</em><br><small>感悟: 大家都喜欢黑腾讯靠抄起家,但是很多被’抄’的产品都死了,而腾讯的产品垄断了市场.也许在做产品的时候,我们缺的不是一个好的想法,而是一个<b>设身处地的研究和理解用户,以挑剔和挑战的态度不断迭代和尝试更好的解决方案</b>的做事态度吧.</small></p>
<h5 id="u5173_u4E8E_u6CE8_u518C_u548C_u767B_u5F55"><a href="#u5173_u4E8E_u6CE8_u518C_u548C_u767B_u5F55" class="headerlink" title="关于注册和登录"></a>关于注册和登录</h5><p>也许十年前我们需要精心设计一个适合用户的注册和登录表单,但是现在最好的方式是使用微信和微博登录(并提供可选的表单注册).<br>来自<a href="https://classroom.udacity.com/courses/ud849" target="_blank" rel="external">优达学城-UE设计</a><br><small>感悟:他说的很对,用户其实不想输入任何东西,这也算是一种创新了.</small></p>
]]></content>
<categories>
<category> 设计 </category>
</categories>
<tags>
<tag> 笔记 </tag>
</tags>
</entry>
<entry>
<title><![CDATA[如何调试已签名的release包]]></title>
<url>/2017/07/04/%E5%A6%82%E4%BD%95%E8%B0%83%E8%AF%95%E5%B7%B2%E7%AD%BE%E5%90%8D%E7%9A%84release%E5%8C%85/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>最近调试android应用时遇到了一个问题,在debug模式下应用跑的很好,但是安装签了名的release包就出现奇怪的错误.此外有些sdk必须在签名后才能调用,所以调试签名后的release包是很有必要的.</p>
<h3 id="u89E3_u51B3_u8FC7_u7A0B"><a href="#u89E3_u51B3_u8FC7_u7A0B" class="headerlink" title="解决过程"></a>解决过程</h3><p>首先去搜资料,发现大都很旧了,找了半天找到了这个.<br>首先 在build variant 中调整模式为release.<br><img src="/images/pasted-15.png" alt="upload successful"><br>然后File-project structure 进行签名配置.<br><img src="/images/pasted-17.png" alt="upload successful"><br><img src="/images/pasted-16.png" alt="upload successful"><br>这样就可以调试签名过的app了.但是调试时发现了另一个问题.</p>
<h3 id="u53E6_u4E00_u4E2A_u95EE_u9898"><a href="#u53E6_u4E00_u4E2A_u95EE_u9898" class="headerlink" title="另一个问题"></a>另一个问题</h3><p>无法下断点,下断点后不跑断点处.上网搜索发现是因为proguard.pro没有配置这个</p>
<pre><code>-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
</code></pre><p>加入配置后可以正常调试.最终发现问题是 proguard.pro不该混淆内容少配置了,导致混淆了不该混淆的内容.</p>
<h3 id="u6211_u7684_u611F_u609F"><a href="#u6211_u7684_u611F_u609F" class="headerlink" title="我的感悟"></a>我的感悟</h3><p>什么面向对象编程,面向函数编程.分明是面向google和面向stack over flow 编程.</p>
]]></content>
</entry>
<entry>
<title><![CDATA[换手机号引发的血案]]></title>
<url>/2017/06/29/%E6%8D%A2%E6%89%8B%E6%9C%BA%E5%8F%B7%E5%BC%95%E5%8F%91%E7%9A%84%E8%A1%80%E6%A1%88/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>最近我换了一次手机号.用新手机号注册支付宝的时候,发现这个手机号已经有人注册过了,称之为A.<br><img src="/images/pasted-5.png" alt="upload successful">我突然好奇,我可以通过这个手机号,通过合法的手段,挖出这个有缘人A的哪些信息呢?</p>
<h3 id="u641E_u4E8B_u60C5"><a href="#u641E_u4E8B_u60C5" class="headerlink" title="搞事情"></a>搞事情</h3><p>既然注册过支付宝,就从支付宝下手把<br><img src="/images/pasted-7.png" alt="upload successful"><br><img src="/images/pasted-8.png" alt="upload successful">通过手机号重置密码成功.相同的方式重置了淘宝密码.查看历史订单<br><img src="/images/pasted-9.png" alt="upload successful"><br>大多是吉他篮球和电子产品.顺势找到了收货地址.<br><img src="/images/pasted-10.png" alt="upload successful"><br>上边一条收过护腰的东西,大概是A的长辈吧,下边两个是天津的同一个住址.而且姓名还是明显的一男一女,估计是A和A的女友了.<br>已经有了姓名(从收货地址)接下来就是找到身份证号了.<br><img src="/images/pasted-6.png" alt="upload successful"> </p>
<p>登录支付宝发现需要验证信息,得到前4位后两位.根据倒数第二位是0还是1确认了性别.根据身份证构建规则6+8+2+1+1(详情百度).考虑长辈的收货地址.构建前6位,但是出生日期怎么办?开始百度 A的名字,结果很多.于是尝试百度手机号,发现并没有什么痕迹.于是百度A名字+A女友名字.<br><img src="/images/pasted-11.png" alt="upload successful"><br>找到了人人的空间.看了一眼相册.多是吉他,耳机….确认是同一个人.看个人信息.出生年月日.</p>
<p><img src="/images/pasted-12.png" alt="upload successful"><br>现在只差中间两位了.生成100个身份证号校验,其中大概有15个符合规则.越小的约有可能性是A的身份证号.现在已经有了可能的身份证号,怎么验证对不对呢? 诚然之前工作中做过调用公安部的接口,但现在用它不太合适.不如试试实名认证吧,任意找一个防沉迷的系统,进行实名认证.成功.<br>之后翻看A的人人相册发现了这个:<br><img src="/images/pasted-13.png" alt="upload successful"><br>额,早知道就不这么麻烦了…<br>此外还有他的经历<br><img src="/images/pasted-14.png" alt="upload successful"><br>大概就这么多了,后续陆续有某个银行给我发交易的短信,我通过真实姓名+身份证号+银行预留手机号走到了重置密码这一步.但是为了避免给远在米国的A造成麻烦.并没有重置密码. </p>
<h3 id="u4E0D_u5B8C_u7F8E_u4E4B_u5904"><a href="#u4E0D_u5B8C_u7F8E_u4E4B_u5904" class="headerlink" title="不完美之处"></a>不完美之处</h3><p>支付宝使用时被告知需要重新认证,只能通过验证银行卡或是刷脸.我对着人人中A的照片试了试,结果并不能行,在网上找了很久图片建模工具找到.也没有也没有什么好办法搞到他的银行卡号(也许重置密码后可以?)</p>
<h3 id="u7ED3_u8BBA"><a href="#u7ED3_u8BBA" class="headerlink" title="结论."></a>结论.</h3><p>换手机号前一定要解绑所有帐号,尤其是涉及到敏感信息的.</p>
]]></content>
<categories>
<category> 安全 </category>
</categories>
<tags>
<tag> 社会工程 </tag>
<tag> 闲的无聊 </tag>
</tags>
</entry>
<entry>
<title><![CDATA[一个有趣的java控制台]]></title>
<url>/2017/06/26/%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84java%E6%8E%A7%E5%88%B6%E5%8F%B0/</url>
<content type="html"><![CDATA[<p><iframe src="http://www.javarepl.com/embed.html" style="width: 720px; height: 350px; border: 0px"></iframe><br><a href="http://blog.csdn.net/renfufei/article/details/48481439" target="_blank" rel="external">csdn介绍</a></p>
]]></content>
</entry>
<entry>
<title><![CDATA[kali+virtualbox调节屏幕分辨率]]></title>
<url>/2017/06/25/kali-virtualbox%E8%B0%83%E8%8A%82%E5%B1%8F%E5%B9%95%E5%88%86%E8%BE%A8%E7%8E%87/</url>
<content type="html"><![CDATA[<h3 id="u95EE_u9898_u6765_u6E90"><a href="#u95EE_u9898_u6765_u6E90" class="headerlink" title="问题来源"></a>问题来源</h3><p>今天安装在virtualbox上安装了kali linux,安装好以后发现屏幕分辨率为1024<em>768,看起来特别小. 于是打开kali中显示器设置,发现只有1024</em>768和更低的分辨率可选.<br><img src="/images/pasted-2.png" alt="upload successful"></p>
<h3 id="u89E3_u51B3_u8FC7_u7A0B"><a href="#u89E3_u51B3_u8FC7_u7A0B" class="headerlink" title="解决过程"></a>解决过程</h3><p>上网搜解决方案,通过<a href="https://docs.kali.org/general-use/kali-linux-virtual-box-guest" target="_blank" rel="external">官方文档</a>了解到需要安装增强工具.照做之后仍然无法调整屏幕分辨率.<br> 于是尝试使用官网上旧的方案安装,按照<a href="http://jingyan.baidu.com/article/73c3ce28e6b899e50343d92f.html" target="_blank" rel="external">百度经验</a><br>尝试安装.报错.被告知先要执行<br><code>apt-get install gcc make linux-headers-$(uname -r)</code><br>执行报错.报错为:<br><code>Unable to locate package 'linux-headers-4.9.0-kali3-amd64'</code><br> 然后我在<br><a href="https://unix.stackexchange.com/questions/266871/cannot-find-linux-headers-4-3-0-kali-amd64" target="_blank" rel="external">某个外国论坛</a><br>按照教程更新了内核,重新尝试,仍然报错.<br>继续寻找解决方案.翻遍了互联网,仍然不行.<br>无奈之下考虑版本冲突.原来的virtualbox 版本为5.024 .更新到当前最新的5.1.22后重启虚拟机安装直接成功,重启后分辨率可调节:<br><img src="/images/pasted-4.png" alt="upload successful"> </p>
<h3 id="u611F_u609F"><a href="#u611F_u609F" class="headerlink" title="感悟"></a>感悟</h3><p>官网文档一般不会出错,出错后考虑版本环境问题.<br>还是自己太菜了,此外kali的图标真的帅,甩出ubuntu,红帽,centos20条街.</p>
]]></content>
<categories>
<category> linux </category>
</categories>
<tags>
<tag> 难以解决 </tag>
<tag> kali </tag>
</tags>