常见找加密点思路:
objeciton
andorid hooking watch class_method java.lang.String.getBytes
会发现一些堆栈
找到地方 如下
package com.sichuanol.cbgc.util;
/* loaded from: 5382408_artMethod_out.dex */
public class SignManager implements cn.thecover.lib.common.a.b {
static {
System.loadLibrary("wtf");
}
public static native String getSign(String str, String str2, String str3);
@Override // cn.thecover.lib.common.a.b
public String a(String str, String str2, String str3) {
return getSign(cn.thecover.lib.third.b.c.h().k() ? String.valueOf(cn.thecover.lib.third.b.c.h().i().getUser_id()) : "", str2, str3);
}
@Override // cn.thecover.lib.common.a.b
public String b(String str) {
return str;
}
}
在上层函数,用objection hook一下 确定了这个函数
接下来直接看so
拖进去打开一下 ,是导出函数、 f5 反编译一下
int __fastcall Java_com_sichuanol_cbgc_util_SignManager_getSign(int a1, int a2, int a3, int a4, int a5)
第一个是jnienv 第二个是jclass 或者jobject ,第三个参数是时间戳
修改jnienv 类型 : 右键 set lvar type ,输入 JNIEnv* a1
某热点
先抓个包:
https://api.taozuiredian.com/api/v1/auth/login/sms
{
"app_ver": "100",
"sign": "cfe2d759e2cc1fbc5511180e6adcb327a82beec3",
"nonce": "ui4jf11705903613902",
"tzrd": "BwzXzSGFyiPstMIVuzTZb3+J7q683AZCxxxxxxxx“
"timestamp": "1705903613"
}
先去hook一下常见加密:
======================================
模式填充:AES/CBC/PKCS5Padding
======================================
算法名:AES|Dec密钥:PeMBjWOVbrMgElXO
算法名:AES|Hex密钥:50654d426a574f5662724d67456c584f
======================================
iv向量:VTToNCiifIJ9c2co
iv向量:5654546f4e43696966494a396332636f
java.lang.Exception
at javax.crypto.Cipher.doFinal(Native Method)
at com.maihan.tredian.util.AesUtil.b(AesUtil.java:5)
at com.maihan.tredian.net.MhRequestUtil.a(MhRequestUtil.java:19)
at com.maihan.tredian.net.MhRequestUtil.b(MhRequestUtil.java:1)
at com.maihan.tredian.net.MhNetworkUtil$2.run(MhNetworkUtil.java:36)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
======================================
doFinal参数:{"imei2":"null","device_name":"Xiaomi M2002J9E","code":"7849","imei1":"null","phone":"1569xxxxxx","getui_push_id":"c4fd627e5e3e743b3f3e133a9d1a3093","device_udid":"77fb71caeaa086a24ae45xxx4c","device_id":"6904ef1483403e03b4c331b6fcc41444","channel":"official","system":"1","from":"app","mac":"02:00:00:00:00:00","os_ver_code":"31","android_id":"90c79d4b6bb04ab9","oaid":"36742ffd17e32c35"}
doFinal结果:070cd7cd2185ca23ecb4c215bb34d96f7f89eeaebcdc0642e6ef70cc025044abb8d37b276aceb8f0ce67513a7cecc65d01fed9368cb884e7ec7dbb32b7e0107bd39304c4ec433b6119410e0dda8aa2f29e88def61053f1ff44f7029124850574a1263cc1a978f27916ff79187c2528a7f0d6259fae4d1527892c2a9648f3e95376b26c5a09a79fec21761c448fbbbb1b87608d54cb4a052ea5927e8652b4129a67ea88f29acc853a38d0850588eb8cf183fa77f3a57edddcaee1ac0481eae843485df2806dd392d3cf4502a22e32bac896549ca9f092c56a979cf8181848d8ba38423ac8e8efaefdcc733cf0009a8b8f76732f6f9c4ec0f357d7f4592640ced646f78610527914cda63d4a295a769e483d79e2911c9885c7de584c372f3217b0352fa1a054869196455e68d5d34bb88aea0e605d02e4bd375f7cd8ad5124f27dd99140e06051deb153d23609f519a12242ab5f8d6bc60842ebe2632652f5db2660b1c1f9cc524b9c086b6727f30ad031e6681f76cc1a96bc816d0cd32952bc23a911f00cfe8b753f84c020d7b34ee55b
doFinal结果:BwzXzSGFyiPstMIVuzTZb3+J7q683AZC5u9wzAJQRKu403snas648M5nUTp87MZdAf7ZNoy4hOfsfbsyt+AQe9OTBMTsQzthGUEODdqKovKeiN72EFPx/0T3ApEkhQV0oSY8wal48nkW/3kYfCUop/DWJZ+uTRUniSwqlkjz6VN2smxaCaef7CF2HESPu7sbh2CNVMtKBS6lkn6GUrQSmmfqiPKazIU6ONCFBYjrjPGD+nfzpX7d3K7hrASB6uhDSF3ygG3TktPPRQKiLjK6yJZUnKnwksVql5z4GBhI2Lo4QjrI6O+u/cxzPPAAmouPdnMvb5xOwPNX1/RZJkDO1kb3hhBSeRTNpj1KKVp2nkg9eeKRHJiFx95YTDcvMhewNS+hoFSGkZZFXmjV00u4iuoOYF0C5L03X3zYrVEk8n3ZkUDgYFHesVPSNgn1GaEiQqtfjWvGCELr4mMmUvXbJmCxwfnMUkucCGtnJ/MK0DHmaB92zBqWvIFtDNMpUrwjqRHwDP6LdT+EwCDXs07lWw==
来自抓包: "BwzXzSGFyiPstMIVuzTZb3+J7q683AZC5u9wzAJQRKu403snas648M5nUTp87MZdAf7ZNoy4hOfsfbsyt+AQe9OTBMTsQzthGUEODdqKovKeiN72EFPx\/0T3ApEkhQV0oSY8wal48nkW\/3kYfCUop\/DWJZ+uTRUniSwqlkjz6VN2smxaCaef7CF2HESPu7sbh2CNVMtKBS6lkn6GUrQSmmfqiPKazIU6ONCFBYjrjPGD+nfzpX7d3K7hrASB6uhDSF3ygG3TktPPRQKiLjK6yJZUnKnwksVql5z4GBhI2Lo4QjrI6O+u\/cxzPPAAmouPdnMvb5xOwPNX1\/RZJkDO1kb3hhBSeRTNpj1KKVp2nkg9eeKRHJiFx95YTDcvMhewNS+hoFSGkZZFXmjV00u4iuoOYF0C5L03X3zYrVEk8n3ZkUDgYFHesVPSNgn1GaEiQqtfjWvGCELr4mMmUvXbJmCxwfnMUkucCGtnJ\/MK0DHmaB92zBqWvIFtDNMpUrwjqRHwDP6LdT+EwCDXs07lWw==",
说明 tzrd 是java 层的加密,账密iv都有了
剩下看下其他两个参数 sign 和noice
看一下堆栈 在jadx中,直接看 at com.maihan.tredian.net.MhRequestUtil.a(MhRequestUtil.java:19)
private static String a() {
Random random = new Random();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 6; i++) {
stringBuffer.append("abcdefghijklmnopqrstuvwxyz0123456789".charAt(random.nextInt(36)));
}
return stringBuffer.toString() + System.currentTimeMillis();
}
sign:
/* loaded from: classes2.dex */
public class TreUtil {
static {
try {
System.loadLibrary("tre");
} catch (Throwable th) {
th.printStackTrace();
}
}
public static native byte[] iv();
public static native byte[] key();
public static native String sign(String str);
}
分析so :
n strcpy(v31, "b2qKgtaW4,9z9D`Fmst?K5JZbLYOY]NP6ssGf2U~;zk9oCNgoytV!}wW7ia+`w9g");
v5 = (*a1)->GetStringUTFChars(a1, a3, &v22);
v6 = 0;
if ( v5 )
{
v21 = &_stack_chk_guard;
v7 = v5;
v19[0] = a3;
v8 = strlen(v31);
v19[1] = (int)v19;
v9 = (char *)v19 - ((strlen(v7) + v8 + 8) & 0xFFFFFFF8);
strcpy(v9, v7);
strcat(v9, v31); //拼接
v10 = *a1;
v20 = a1;
v10->ReleaseStringUTFChars(a1, (jstring)v19[0], v7);
v11 = strlen(v9);
v12 = (const char *)&v19[-2 * v11];
j_base64_encode_new(v9, v12, v11);
v28 = 0;
v27[0] = 1732584193;
v27[1] = -271733879;
v27[2] = -1732584194;
v27[3] = 271733878;
v27[4] = -1009589776;
v27[5] = 0;
v27[6] = 0;
v29 = 0;
v30 = 0;
memset(v25, 0, sizeof(v25));
v13 = strlen(v12);
v14 = j_SHA1Input(v27, v12, v13);
if ( v14 )
fprintf((FILE *)((char *)&_sF + 168), "SHA1Input Error %d.\n", v14);
v15 = j_SHA1Result(v27, v26);
if ( v15 )
{
fprintf((FILE *)((char *)&_sF + 168), "SHA1Result Error %d, could not compute message digest.\n", v15);
}
按h转十六进制
var soAddr = Module.findBaseAddress("libtre.so");
var funcAddr = soAddr.add(0x15BE+1);
// hook_native_addr(funcAddr, 3);
Interceptor.attach(funcAddr, {
onEnter: function(args){
// console.log(args[1].readCstring());
console.log(args[0].readCString());
this.args1 = args[1];
},
onLeave: function(retval){
console.log(this.args1.readCString());
}
});
把这个参数解密一下: base64
app_ver=100&nonce=oj1k5s1705908313273×tamp=1705908313&tzrd=BwzXzSGFyiPstMIVuzTZb3+J7q683AZC5u9wzAJQRKu403snas648M5nUTp87MZdAf7ZNoy4hOfsfbsyt+AQe9OTBMTsQzthGUEODdqKovKeiN72EFPx/0T3ApEkhQV0oSY8wal48nkW/3kYfCUop/DWJZ+uTRUniSwqlkjz6VN2smxaCaef7CF2HESPu7sbh2CNVMtKBS6lkn6GUrQSmmfqiPKazIU6ONCFBYjrjPGD+nfzpX7d3K7hrASB6uhDSF3ygG3TktPPRQKiLjK6yJZUnKnwksVql5z4GBhI2Lo4QjrI6O+u/cxzPPAAmouPdnMvb5xOwPNX1/RZJkDO1kb3hhBSeRTNpj1KKVp2nkg9eeKRHJiFx95YTDcvMhewNS+hoFSGkZZFXmjV00u4iuoOYF0C5L03X3zYrVEk8n3ZkUDgYFHesVPSNgn1GaEiQqtfjWvGCELr4mMmUvXbJmCxwfnMUkucCGtnJ/MK0DHmaB92zBqWvIFtDNMpUrwjqRHwDP6LdT+EwCDXs07lWw==b2qKgtaW4,9z9DFmst?K5JZbLYOY]NP6ssGf2U~;zk9oCNgoytV!}wW7ia+
w9g
实际上就是最后加了一串这个参数
去hook一下 这个 base64
13B4
在输出的时候
function print_log1(addr) {
var module = Process.findRangeByAddress(addr);
if(module != null)
{
// var str = Memory.readUtf8String(ptr(addr));
// console.log("String at address " + ptr(addr) + ": " + str);
console.log('=====================')
console.log(addr.readCString())
return hexdump(addr) + "\n";
}
return ptr(addr) + "\n";
}
// readCString 和 hexdump 如果为了获取字符串 都可以用
// var SHA1Input = soAddr.add(0x15BE + 1);
// //hook_native_addr(SHA1Input, 3);
// Interceptor.attach(SHA1Input, {
// onEnter: function (args) {
// //console.log(args[1].readCString());
// console.log(hexdump(args[1], {
// offset: 0,
// length: args[2].toInt32(), //这里只能接收十进制的
// header: true,
// ansi: false
// }));
// }, onLeave: function (retval) {
//
// }
// });
这个可以把hexdump 多打印几个参数
// so hook
function print_log1(addr) {
var module = Process.findRangeByAddress(addr);
if(module != null)
{
// var str = Memory.readUtf8String(ptr(addr));
// console.log("String at address " + ptr(addr) + ": " + str);
// return str+"\n"
return hexdump(addr) + "\n";
}
return ptr(addr) + "\n";
}
function print_arg_2(addr){
rse=Memory.readUtf8String(addr);
return rse
}
function print_arg(addr){
return print_arg_2(addr);
}
function hook_native_addr(funcPtr, paramsNum){
var module = Process.findModuleByAddress(funcPtr);
Interceptor.attach(funcPtr, {
onEnter: function(args){
this.logs = [];
this.params = [];
this.logs.push("call " + module.name + "!" + ptr(funcPtr).sub(module.base) + "\n");
for(let i = 0; i < paramsNum; i++){
this.params.push(args[i]);
this.logs.push("this.args" + i + " onEnter: " + print_arg(args[i]));
}
}, onLeave: function(retval){
for(let i = 0; i < paramsNum; i++){
this.logs.push("this.args" + i + " onLeave: " + print_arg(this.params[i]));
}
this.logs.push("retval onLeave: " + print_arg(retval) + "\n");
console.log(this.logs);
}
});
}
var soAddr = Module.findBaseAddress("libtre.so");
var funcAddr = soAddr.add(0x15BE+1);
// hook_native_addr(funcAddr, 3);
Interceptor.attach(funcAddr, {
onEnter: function(args){
// console.log(args[1].readCstring());
console.log(args[0].readCString());
this.args1 = args[1];
},
onLeave: function(retval){
console.log(this.args1.readCString());
}
});
更多内容请移步公众号一起学习,同篇笔记可能会有更新喔