同步家教王及其升级版的破解
一朋友让我来破解下一软件,我拿来一看是这玩意。我以为很难,结果发现没壳。兴趣就来了,弄了一天,就弄出来了。这里把过程和思路分享一下。其实很简单,大神一看就知道。因为这个没加壳,只是加了混淆的。
这算是我第一次破解玩玩整整的apk了。
我觉得授人以鱼不如授人以渔,就把它写出来了,需要的童鞋就看看吧,然后去动手试试,真心的,多动手。
然后我们就开始吧
一、工具
这次我用的是Androidkiller,感觉很不错的样子
然后就是我每次都要用的蓝叠
二、同步家教王
1.看情况
老规矩,还是先拖蓝叠看看情况
操作方法
- 01
随便输了123,出现了激活码错误。我们记下来
- 02
2.反编译 这个就不多说了,前面说的够多了。直接拖进去,反编译就OK。
- 03
3.修改 我们先去string.xml中没有信息,然后转码搜索激活码错误
- 04
我们跳过去,看看源码。右键,查看-查看源码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package com.school.app.activity.login; import android.os.Handler; import android.os.Message; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.school.app.utils.SharedPreHandler; class LoginActivity$3 extends Handler { LoginActivity$3(LoginActivity paramLoginActivity, String paramString) {} public void handleMessage(Message paramMessage) { try { if (paramMessage.obj != null) { paramMessage = ((String)paramMessage.obj).split("&"); if (paramMessage[0].equals("yes")) { SharedPreHandler.getShared().setSharedPreKey("activation_code", this.val$text); SharedPreHandler.getShared().setSharedPreKey("activation_deviceId", LoginActivity.access$1(this.this$0)); SharedPreHandler.getShared().setSharedPreKey("activation_model", LoginActivity.access$2(this.this$0)); if (paramMessage[1].equals("-1")) {} for (paramMessage = "激活成功";; paramMessage = String.format(LoginActivity.access$3(this.this$0), new Object[] { paramMessage[1], paramMessage[2] })) { SharedPreHandler.getShared().setSharedPreKey("activation_msg", paramMessage); LoginActivity.access$4(this.this$0); this.this$0.finish(); return; } } } return; } catch (Exception paramMessage) { paramMessage.printStackTrace(); this.this$0.title.setText("激活码错误"); this.this$0.back.setVisibility(0); this.this$0.exit.setVisibility(0); this.this$0.yes.setVisibility(8); this.this$0.clear.setVisibility(8); this.this$0.edit.setVisibility(8); } } }
- 05
我们可以很容易的看到激活码出错的字样。再来分析一下java代码。 我们发现激活码错误并没有跳转到这里,但是之前的代码却有个 :cond_1跳转这里来。所以我们明显知道是加了混淆的。 那我们只有从激活成功去看看下手了。 再次搜索
- 06
发现有两处 刚刚这出看过了,我们去看看另一处的源码 发现有两处 刚刚这出看过了,我们去看看另一处的源 package com.school.app.service; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.widget.Toast; import com.school.app.activity.login.LoginActivity; import com.school.app.utils.CommTool; import com.school.app.utils.SharedPreHandler; public class TimeCountService extends Service { private static final long sMinute = 1L; private Handler mHandler = new Handler() { public void handleMessage(Message paramAnonymousMessage) { try { if ((paramAnonymousMessage.obj != null) && (((String)paramAnonymousMessage.obj).contains("stop"))) { SharedPreHandler.getShared().setSharedPreKey("activation_code", ""); SharedPreHandler.getShared().setSharedPreKey("activation_msg", ""); paramAnonymousMessage = new Intent(); paramAnonymousMessage.setFlags(268435456); paramAnonymousMessage.setClass(TimeCountService.this, LoginActivity.class); TimeCountService.this.startActivity(paramAnonymousMessage); } return; } catch (Exception paramAnonymousMessage) { paramAnonymousMessage.printStackTrace(); } } }; private MyReceiver myReceiver; private long time; private void requestLoginInfo() { if (CommTool.isNetworkAvailable(this)) { String str = SharedPreHandler.getShared().getSharedStrPreKey("activation_code", ""); CommTool.getActivationCode(SharedPreHandler.getShared().getSharedStrPreKey("activation_deviceId", ""), SharedPreHandler.getShared().getSharedStrPreKey("activation_model", ""), str, this.mHandler); } } private void stopTimeCountService() { Intent localIntent = new Intent(); localIntent.setClass(this, TimeCountService.class); stopService(localIntent); } public IBinder onBind(Intent paramIntent) { return null; } public void onCreate() { super.onCreate(); } public void onDestroy() { super.onDestroy(); if (this.myReceiver != null) { unregisterReceiver(this.myReceiver); } } public int onStartCommand(Intent paramIntent, int paramInt1, int paramInt2) { String str = SharedPreHandler.getShared().getSharedStrPreKey("activation_msg", ""); if ((!str.equals("")) && (!str.equals("激活成功"))) { Toast.makeText(this, str, 1).show(); } requestLoginInfo(); return super.onStartCommand(paramIntent, paramInt1, paramInt2); } class MyReceiver extends BroadcastReceiver { MyReceiver() {} public void onReceive(Context paramContext, Intent paramIntent) {} } }
- 07
这里的话,我们还可以清晰看到激活的只是一个判断,然后Toast出来的,那我们去修改前面那一处的跳转试试。 在研究一下之前的源码,发现很混乱。但是明确知道,有个地方会跳转来验证。 的确很混乱,我研究了半天,才在这个地方破解出来。这个不写出出来这个方法,因为我自己也不是太清楚。我是自己不清楚,就绝不误人子弟的,这里大家可以自行尝试。