APK逆向經驗:取回正點工具箱程式鎖密碼

過程中使用到的工具:

第一步:把apk抓出來

  Microsoft Windows [版本 6.1.7601]
  Copyright (c) 2009 Microsoft Corporation. All rights reserved.

  C:\Users\Inndy>adb shell
  shell@android:/ $ su
  su
  root@android:/ # cd data/app
  cd data/app
  root@android:/data/app # ls | busybox grep -e 'zd'
  ls | busybox grep -e 'zd'
  com.zdworks.android.toolbox-1.apk
  root@android:/data/app # exit
  exit
  shell@android:/ $ exit
  exit

  C:\Users\Inndy>adb pull /data/app/com.zdworks.android.toolbox-1.apk
  2875 KB/s (6326169 bytes in 2.148s)

  C:\Users\Inndy>

第二步:分別丟進兩種工具反編譯

第三步:找出關鍵字串和參考點

從 APK multi-tool 解出來的東西裡面找,String Resource在 res\values-zh-rTW\strings.xml 裡面,搜尋 "密碼錯誤" 後找到...

Line 309: <string name="input_fail">密碼錯誤請重新輸入!</string>" 然後我寫了一個Python Script去找含有 "input_fail" 的檔案,藉此挖出Resource ID

import os

for root, dirs, files in os.walk("./smali"):
    for f in files:
        f = os.path.realpath("%s/%s" % (root, f))
        if os.path.isfile(f):
            content = open(f, "r").read()
            if content.find("input_fail") > -1:
                print(f)
                for (i, line) in enumerate(content.split("\n")):
                    if line.find("input_fail") > -1:
                        print("Line %5d:%s" % (i + 1, line))

"""
=== Result ===

C:\Users\Inndy\Desktop\APK Multi-Tool V1.0.11\projects\zdbox.apk\smali\com\zdworks\android\toolbox\R$string.smali
Line  1966:.field public static final input_fail:I = 0x7f090342
"""

接著在onekey-decompile-apk解出來的source裡面尋找檔名:applock 會找到很多檔案,全部丟進Notepad++打開 搜索所有檔案 -> "2131297090"  (2131297090 = 0x7f090342) 接著找到了...

  C:\Users\Inndy\Desktop\zdbox.apk.src\com\zdworks\android\toolbox\ui\applock\AppLockPasswordActivity.java (1 hit)
 Line 109:       Toast.makeText(this, getString(2131297090), 0).show();
  C:\Users\Inndy\Desktop\zdbox.apk.src\com\zdworks\android\toolbox\ui\applock\ApplockPatternActivity.java (1 hit)
 Line 348:           Toast.makeText(ApplockPatternActivity.this, 2131297090, 0).show();

接下來就是Code Review找來源

// com\zdworks\android\toolbox\ui\applock\AppLockPasswordActivity.java
// Line 340
public void onPatternDetected(List<LockPatternView.Cell> paramList)
{
  String str = PasswordUtils.patternToString(paramList);
  ApplockPatternActivity.this.mHandler.postDelayed(new ApplockPatternActivity.AutoClearThread(ApplockPatternActivity.this, null), 1000L);
  if (this.crtPattern.equals(str))
 if ((!ApplockPatternActivity.this.checkpattern(str)) && (ApplockPatternActivity.this.calledIntent != 0) && (ApplockPatternActivity.this.calledIntent != 4))
 {
   ApplockPatternActivity.this.setPatternState(false);
   Toast.makeText(ApplockPatternActivity.this, 2131297090, 0).show();
   ApplockPatternActivity.this.initTitle();
 }
  while (true)
  {
 return;
 ApplockPatternActivity.this.setPatternState(true);
 ApplockPatternActivity.this.finishInputPassword(str);
 continue;
 this.crtPattern = str;
  }
}
// com\zdworks\android\toolbox\ui\applock\ApplockPatternActivity.java
// Line 199
public boolean checkpattern(String paramString)
{
  return paramString.equals(this.patternPassword);
}


// Line 181
private void initView()
{
  initRecommendZDLockView();
  this.patternPassword = this.mConfig.getApplockPasswordPattern();
  this.mLockView = ((LockPatternView)findViewById(2131427460));
  this.mForgetPassword = ((LinearLayout)findViewById(2131427459));
  this.mLockView.setOnPatternListener(new ApplockPatternListener(null));
  if ((-1 != this.mConfig.getSecurityQuestionIndex()) && (this.calledIntent != 0) && (this.calledIntent != 4))
  {
    this.mForgetPassword.setVisibility(0);
    ((TextView)findViewById(2131427799)).getPaint().setFlags(9);
    this.mForgetPassword.setOnClickListener(this);
  }
  this.mLockView.enableInput();
  this.mLockView.setInStealthMode(this.mConfig.isHideTrace());
  this.mLockView.setInVibrateMode(this.mConfig.isVibrateTracelessUnlock());
}


// Line 54
private ConfigManager mConfigManager;
// com\zdworks\android\toolbox\global\ConfigManager.java
// Line 377
public String getApplockPasswordPattern()
{
  return this.mSharedPre.getString("applock_pw_pattern", "");
}


// Line 219
private ConfigManager(Context paramContext)
{
  this.mContext = paramContext;
  this.mSharedPre = PreferenceManager.getDefaultSharedPreferences(paramContext);
}

跟到最上面發現原來是PreferenceManager,可以去把我的密碼找出來了!

Microsoft Windows [版本 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Inndy>adb shell
shell@android:/ $ su
su
root@android:/ # cd data/data
cd data/data
root@android:/data/data # ls | busybox grep -e 'zd'
ls | busybox grep -e 'zd'
com.zdworks.android.toolbox
root@android:/data/data # cd com.zd*
cd com.zd*
root@android:/data/data/com.zdworks.android.toolbox # ls
ls
cache
databases
files
lib
shared_prefs
root@android:/data/data/com.zdworks.android.toolbox # cd sh*
cd sh*
root@android:/data/data/com.zdworks.android.toolbox/shared_prefs # ls
ls
GetJarClientPrefs.xml
com.zdworks.android.toolbox_preferences.xml
com.zdworks.android.toolboxsession.xml
lastUsageCheckFile.xml
splash_hash.xml
splash_pref.xml
timestamp.xml
zda_agent_online_setting_com.zdworks.android.toolbox.xml
root@android:/data/data/com.zdworks.android.toolbox/shared_prefs # cat com.zdwor
ks.android.toolbox_preferences.xml | busybox grep -e 'applock_pw_pattern'
<string name="applock_pw_pattern">*******</string>
root@android:/data/data/com.zdworks.android.toolbox/shared_prefs #

搞定了,結案。

最後小提醒:保護手機安全,請隨手關閉adb,並且把adb shell的 root 權限設定為每次詢問。