APP 逆向 --- du APP 逆向


APP 逆向 --- du APP 逆向

第一步就是抓包

根據抓到的包,可以看出需要破解的參數 newSign 、password、uuid 還有 headers 中的參數 shumeiid/x-auth-token/duuid/duimei/shumengid 。也就是有這么多的參數是不知道的,需要去 app 中找的。

第二步 使用 jadx 打開 app

直接搜索 api,

點進去后直接查找用例,就會跳轉到下圖。

走到這再去點的時候,發現一些參數而且調用了 newParams, 參數 userName、type、sourcePage、countryCode 都是沒有加密的,所以重點就是看看這個 password。hook 這個方法發現里面密碼是已經加密過的,直接查找用例

點進去就找到 password 的加密位置。

從這個方法中可以看到密碼是 MD5Util 的加密。為了驗證我的判斷,直接 Hook MD5Util.a方法

md5_js_code = """

Java.perform(function () {
var MainActivity = Java.use('com.shizhuang.duapp.framework.util.encrypt.MD5Util');
MainActivity.a.overload('java.lang.String').implementation = function () {
console.log("password: #################" + arguments[0]);
var str2 = "12345678du";
Java.openClassFile("/data/local/tmp/r0gson.dex").load();
const gson = Java.use("com.r0ysue.gson.Gson");
console.log("11111111111111111111111111111111111111111+++++++++++++++++++++")
console.log(gson.$new().toJson(this.a(str2)));
console("------------------------------");
};
});
"""

打印的結果

然后點擊 LoginFacade.c ,發現到了最開始的發起請求,拼接參數的地方。到這里 password 的就完事了。

然后又重新搜索參數 newSign

這里看看 OkHttp https://blog.csdn.net/qq_38851536/article/details/100146115

點進去后,發現基本參數,以及請求頭這些東西都可以找到。剩下的就是這些具體的實現以及加密。

繼續找到 RequestUtils.b 方法,這個方法最后就是該參數的加密位置以及加密方法。從名字看就是個 AES 加密。加密的內容就是請求參數轉為字符串,然后拼接后加密。

繼續進入這個 b 方法, 可以看到返回的是一個執行encodeByte 方法后的返回值。而這個方法是 native, 加載的 so 文件為 JNIEncrypt

剩下的就是關於這個加密參數的 Hook.

第三步直接 HOOK 這個方法,查看具體都加密了哪些東西

可以看到 java 層加密的就是這么多的東西,剩下的就是 native 層

參考文章

爬蟲工程師的unidbg入門教程

通過 unidbg 直接調用 so 文件

直接去 github上下載 https://github.com/zhkl0228/unidbg

參考上面大佬文章中的代碼,進行簡單的修改。我逆向的版本中 encodeByte 方法有更新,簡單修改一下,就可以了

public class du extends AbstractJni {
//ARM模擬器
private final AndroidEmulator emulator;
//vm
private final VM vm;
//載入的模塊
private final Module module;

private final DvmClass TTEncryptUtils;

//初始化
public du() throws IOException {
//創建毒進程,這里其實可以不用寫的,我這里是隨便寫的,使用app本身的進程就可以繞過進程檢測
emulator = new AndroidARMEmulator("com.shizhuang.duapp");
final Memory memory = emulator.getMemory();
//作者支持19和23兩個sdk
memory.setLibraryResolver(new AndroidResolver(23));
// memory.setCallInitFunction();
//創建DalvikVM,利用apk本身,可以為null
//如果用apk文件加載so的話,會自動處理簽名方面的jni,具體可看AbstractJni,這就是利用apk加載的好處
vm = emulator.createDalvikVM(null);
vm.setVerbose(true);
vm.setJni(this);
// vm = emulator.createDalvikVM(null);
//加載so,使用armv8-64速度會快很多
DalvikModule dm = vm.loadLibrary(new File("src/test/resources/xiaohongshu/libJNIEncrypt.so"), false);
//調用jni
dm.callJNI_OnLoad(emulator);
module = dm.getModule();
//Jni調用的類,加載so
TTEncryptUtils = vm.resolveClass("com/duapp/aesjni/AESEncrypt");
}


//關閉模擬器
private void destroy() throws IOException {
emulator.close();
System.out.println("destroy");
}

public static void main(String[] args) throws IOException {
du t = new du();
t.encodeByte("123456");
t.destroy();

}

private String encodeByte(String strs) {
//調試
// 這里還支持gdb調試,
//emulator.attach(DebuggerType.GDB_SERVER);
//附加調試器
// emulator.attach(DebuggerType.SIMPLE);
// emulator.traceCode();
//這里是打斷點,原地址0x00005028->新地址0x40005028 新地址需要改成0x4
// emulator.attach().addBreakPoint(null, 0x40001188);//encode地址
// emulator.attach().addBreakPoint(null, 0x40000D10);
Number ret = TTEncryptUtils.callStaticJniMethod(emulator, "getByteValues()Ljava/lang/String;");
System.out.println(ret);
System.out.println("-----------------------");
long hash = ret.intValue() & 0xffffffffL;
StringObject st1 = vm.getObject(hash);
//*這里要處理下字符串
String byteString = st1.getValue();
StringBuilder builder = new StringBuilder(byteString.length());
for (int i = 0; i < byteString.length(); i++) {
if (byteString.charAt(i) == '0') {
builder.append('1');
} else {
builder.append('0');
}
}
byte[] strs_byte = strs.getBytes();
//獲取encodeByte地址
ret = TTEncryptUtils.callStaticJniMethod(emulator, "encodeByte([BLjava/lang/String;)Ljava/lang/String;", vm.addLocalObject(new ByteArray(strs_byte)),

//傳參,這里需要兩個字符串,所以就傳入兩個參數
// vm.addLocalObject(new StringObject(vm, strs)),
vm.addLocalObject(new StringObject(vm, builder.toString()))

);
//ret 返回的是地址,
hash = ret.intValue() & 0xffffffffL;
//獲得其值
StringObject str = vm.getObject(hash);
System.out.println(str);
System.out.println("----------------------");
System.out.println(str.getValue());
return str.getValue();
}
}

這個執行完之后在進行 md5 . 就 OK 了

第四步:使用 python 調用 jar

關注微信公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM