京公网安备 11010802034615号
经营许可证编号:京B2-20210330
作者:Python进阶者
来源:Python爬虫与数据挖掘
有时候可能会对APP进行字符串加密等操作,这样的话你的变量名等一些都被混淆了,看代码就可能无从下手
不管没关系,像系统级别的东西,Toast了等函数,是不能混淆的,所以可以根据蛛丝马迹,终究找到破解的点
frida -U 连接USB设备
-F 附加到最前面的app
-l 注入的js
-o 输出到文件
-f 重新启动
--no-pause 立马执行,中间不停顿
打印堆栈的本质就是抛异常,他的结果是从下往上看的!
function printStacks() { console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.lang.Throwable").$new()
)
);
}
hashMap,,那就很常用了,懂的都懂,但是一定要做好筛选,要不然app容易崩溃!
var hashMap = Java.use("java.util.HashMap");
hashMap.put.implementation = function (a, b) { //a=="username"和a.equals("username")一般都可以 //如果不行换一下即可 if (a=="username") { console.log("hashMap.put: ", a, b);
printStacks();
} return this.put(a, b);
}
Array似乎也很常用
var arrayList = Java.use("java.util.ArrayList");
arrayList.add.overload('java.lang.Object').implementation = function (a) { if (a == "username=18903916120") { console.log("arrayList.add: ", a);
printStacks();
} //console.log("arrayList.add: ", a); return this.add(a);
}
arrayList.add.overload('int', 'java.lang.Object').implementation = function (a, b) { console.log("arrayList.add: ", a, b); return this.add(a, b);
}
这个方法通常是安卓判断输入框是否为空必经的方法!
var textUtils = Java.use("android.text.TextUtils");
textUtils.isEmpty.implementation = function (a) { if (a == "TURJNk1EQTZNREE2TURBNk1EQTZNREE9") { console.log("textUtils.isEmpty: ", a);
printStacks();
} //console.log("textUtils.isEmpty: ", a); return this.isEmpty(a);
}
这个方法似乎也挺多,去掉开头和结尾的空格,防止脏数据
var str = Java.use("java.lang.String");
str.trim.implementation = function () { console.log("str.trim: ", this);
printStacks(); return this.trim();
}
var log = Java.use("android.util.Log");
log.w.overload('java.lang.String', 'java.lang.String').implementation = function (tag, message) { console.log("log.w: ", tag, message);
printStacks(); return this.w(tag, message);
}
这个应该就多了,但是这个一般在加密的上层,可以考虑使用。
var editText = Java.use("android.widget.EditText");
editText.getText.overload().implementation = function () { var result = this.getText();
result = Java.cast(result, Java.use("java.lang.CharSequence")); console.log("editText.getText: ", result.toString());
printStacks(); return result;
}
排序方法,频率还凑合
var collections = Java.use("java.util.Collections");
collections.sort.overload('java.util.List').implementation = function (a) {
var result = Java.cast(a, Java.use("java.util.ArrayList"));
console.log("collections.sort List: ", result.toString());
printStacks(); return this.sort(a);
}
collections.sort.overload('java.util.List', 'java.util.Comparator').implementation = function (a, b) {
var result = Java.cast(a, Java.use("java.util.ArrayList"));
console.log("collections.sort List Comparator: ", result.toString());
printStacks(); return this.sort(a, b);
}
// .overload('java.lang.String', 'double')
// .overload('java.lang.String', 'int')
// .overload('java.lang.String', 'long')
// .overload('java.lang.String', 'boolean')
一般在转成json时用的听过的,可以考虑
var jSONObject = Java.use("org.json.JSONObject");
jSONObject.put.overload('java.lang.String', 'java.lang.Object').implementation = function (a, b) { //var result = Java.cast(a, Java.use("java.util.ArrayList")); console.log("jSONObject.put: ", a, b);
printStacks(); return this.put(a, b);
}
jSONObject.getString.implementation = function (a) { //var result = Java.cast(a, Java.use("java.util.ArrayList")); console.log("jSONObject.getString: ", a); var result = this.getString(a); console.log("jSONObject.getString result: ", result);
printStacks(); return result;
}
这个就很多了,基本上每个app都有,但是hook这个位置又偏加密下层,因为肯定是处理完才弹窗
但是可以考虑不输入账号密码直接提交,这样位置大概在加密的上层,可以顺着往下走
var toast = Java.use("android.widget.Toast");
toast.show.implementation = function () { console.log("toast.show: ");
printStacks(); return this.show();
}
base64就很多了吧,除了消息摘要算法其他最后的形式都是base64格式,很有必要。
var base64 = Java.use("android.util.Base64");
base64.encodeToString.overload('[B', 'int').implementation = function (a, b) { console.log("base64.encodeToString: ", JSON.stringify(a)); var result = this.encodeToString(a, b); console.log("base64.encodeToString result: ", result)
printStacks(); return result;
}
var str = Java.use("java.lang.String");
str.getBytes.overload().implementation = function () { var result = this.getBytes(); var newStr = str.$new(result); console.log("str.getBytes result: ", newStr);
printStacks(); return result;
}
str.getBytes.overload('java.lang.String').implementation = function (a) { var result = this.getBytes(a); var newStr = str.$new(result, a); console.log("str.getBytes result: ", newStr);
printStacks(); return result;
}
这种方式hook代码,需要frida帮助我们启动app。
所以本次启动的命令为
frida -U -f com.dodonew.online -l g_关键代码快速定位.js -o 1.txt --no-pause
因为可能一开始就绑定了很多控件,所以一开始就要开始hook。
控件id可以通过<SDK目录>toolsbin下的uiautomatorviewer.bat来进行查看
查看登录按钮id
所以这个登录按钮的id就是btn_login
// 找id var btn_login_id = Java.use("com.dodonew.online.R$id").btn_login.value; console.log("btn_login_id:", btn_login_id); var view = Java.use("android.view.View");
view.setOnClickListener.implementation = function (a) { if(this.getId() == btn_login_id){ console.log("view.id: " + this.getId()); console.log("view.setOnClickListener is called");
printStacks();
} return this.setOnClickListener(a);
}
在嘟嘟牛这个app中,最后使用的是DES算法,并且base64结果展示加密的内容。
所以就hook一下base64试试
Java.perform(function () { //打印堆栈 function printStacks() { console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.lang.Throwable").$new()
)
);
} //base64 var base64 = Java.use("android.util.Base64");
base64.encodeToString.overload('[B', 'int').implementation = function (a, b) { console.log("base64.encodeToString: ", JSON.stringify(a)); var result = this.encodeToString(a, b); console.log("base64.encodeToString result: ", result)
printStacks(); return result;
}
})
所以如果说,你如果看结果像是base或者md5或者hex等,直接就使用这些常用的hook代码试一下,并且抛出堆栈。
就可以很好分析代码了。
虽然写的是关键代码定位,其实只不过是常用的代码罢了,上面这些使用在逆向app时总结的hook代码。
当然,实际肯定不止这么少,根据需求来,经验越多,轮子就越多。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
“2026年考什么证含金量高”这个问题,很难用一张榜单回答。同一本证书,对想进会计师事务所的人有价值,对想做行政的人可能用处 ...
2026-10-29一、Tableau 做地图的优势 在所有 BI 工具里,Tableau 的地图能力是第一梯队的。它内置了全球行政区划地理数据库,只要你的数据 ...
2026-10-29一、问题场景:为什么 Excel 自带直方图不支持多组 做数据分析时,经常需要把两组数据的分布放在同一张图里对比——比如"实验组 ...
2026-10-29当下,我们已然步入数据要素价值全面释放的智能时代。数据不再只是零散的数字记录,更是驱动新质生产力运转的核心动能、滋养人工 ...
2026-10-29一、RFM模型概述 RFM模型是由 George Cullinan 提出、营销领域公认的经典客户价值细分模型,依托客户交易行为数据,从三个核心维 ...
2026-10-28“不用学历可以考的资格证”这个说法,实际混着两类情况:一类是证书本身对学历没有硬性要求,报名时只看年龄、身份或培训经历; ...
2026-10-2837岁考什么证,先别急着看“女生适合考什么”的榜单。这个年龄处在职业中期,优势是已有工作经验和行业理解,约束是时间精力有限 ...
2026-10-28一、卡方分布是什么 卡方分布(Chi-square Distribution,χ²分布)是统计学中一种常用的概率分布,它和正态分布、t分布一样, ...
2026-10-28职业证书的作用不能一概而论。它既不是“考了就能找到好工作”的通行证,也不是“花钱买张纸”的摆设。真正决定一张证书有多大用 ...
2026-10-28产品岗没有统一的法定准入证书,招聘时也很少把某张证书写成硬性门槛。所以“真正有用”不能看广告里的名头,而要看三件事:它对 ...
2026-10-28“一般可以考什么证书”很难给出一份通用榜单。同为“证书”,有的是法律规定的准入资格,无证不能上岗;有的是职称评聘参考;有 ...
2026-10-28“现在大学生要什么证书好”,这个问题没有统一答案。同一张证书,对想进银行的学生可能是加分项,对准备考公的学生可能完全用不 ...
2026-10-28“十大证书含金量最高”这类榜单,最大的问题不是排名不准,而是没有交代排名依据。准入类和加分类混在一起排,高壁垒的和低门槛 ...
2026-10-28“什么证容易考且有用”,这个问题本身藏着一个容易踩的坑:把“容易考”和“有用”当成两个独立打分项,各找几个高分证书拼在一 ...
2026-10-28想考一个证书,第一步不是买教材,而是先确认它属于哪一类证书、由谁发证、在哪里报名。考取证书的通用流程可以概括为六步:确定 ...
2026-10-28“女生考什么证”这个问题,网上常见的答案是“教师资格证、会计证、普通话证”,理由往往是“稳定”“适合女孩子”。这类回答的 ...
2026-10-28“女的考什么证书比较实用”这个问题,本身藏着一个容易走偏的前提:把性别当成筛选证书的依据。证书不认性别,岗位也不按性别分 ...
2026-10-28“哪些考试含金量高”这个问题,很难有一张适合所有人的总榜。同一个考试,对想进医院的人和对想做运营的人,价值完全不同。含金 ...
2026-10-28“国家认可的技能证书”日常被用得很宽:有人指职业资格,有人指职业技能等级,也有人把培训结业证、企业认证一并算入。口径不统 ...
2026-10-28工作后考市场营销证书,容易陷入两种极端:要么被“高薪就业”“行业必备”的宣传推着走,要么觉得证书都没用、不如攒经验。更实 ...
2026-10-28