Master Frida: Hook Android Apps to Reveal Encryption and Debugging Secrets
This guide demonstrates how to use Frida for Android reverse engineering, covering essential commands, stack tracing, and practical hook scripts for common methods such as HashMap.put, Base64.encodeToString, and UI event listeners, enabling developers to locate and analyze encryption logic within apps.
Hello, I am "Code Farmer Saturday Eight". This tutorial is for learning and discussion only; any illegal use of the techniques is prohibited.
Preface
When an app encrypts strings, variable names become obfuscated, making the code hard to read. Even system‑level functions like Toast cannot be obfuscated, so by tracing clues you can eventually find a cracking point.
Common Frida Commands
frida
-U Connect USB device
-F Attach to the frontmost app
-l Inject JS script
-o Output to file
-f Restart app
--no-pause Execute immediately without pausePrinting Stack Traces
The essence of printing a stack trace is throwing an exception; the result is read from bottom to top.
Code
function printStacks() {
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.lang.Throwable").$new()
)
);
}Common Hook Snippets
Hook HashMap.put
var hashMap = Java.use("java.util.HashMap");
hashMap.put.implementation = function(a, b) {
// a == "username" or a.equals("username") usually works
if (a == "username") {
console.log("hashMap.put: ", a, b);
printStacks();
}
return this.put(a, b);
};Hook ArrayList.add
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();
}
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);
};Hook TextUtils.isEmpty
var textUtils = Java.use("android.text.TextUtils");
textUtils.isEmpty.implementation = function(a) {
if (a == "TURJNk1EQTZNREE2TURBNk1EQTZNREE9") {
console.log("textUtils.isEmpty: ", a);
printStacks();
}
return this.isEmpty(a);
};Hook String.trim
var str = Java.use("java.lang.String");
str.trim.implementation = function() {
console.log("str.trim: ", this);
printStacks();
return this.trim();
};Hook Log.w
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);
};Hook EditText.getText
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;
};Hook Collections.sort
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);
};Hook JSONObject.put & getString
var jSONObject = Java.use("org.json.JSONObject");
jSONObject.put.overload('java.lang.String', 'java.lang.Object').implementation = function(a, b) {
console.log("jSONObject.put: ", a, b);
printStacks();
return this.put(a, b);
};
jSONObject.getString.implementation = function(a) {
console.log("jSONObject.getString: ", a);
var result = this.getString(a);
console.log("jSONObject.getString result: ", result);
printStacks();
return result;
};Hook Toast.show
var toast = Java.use("android.widget.Toast");
toast.show.implementation = function() {
console.log("toast.show: ");
printStacks();
return this.show();
};Hook Base64.encodeToString
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;
};Hook String.getBytes
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;
};Finding View IDs
Use the Android SDK tool uiautomatorviewer.bat (located in <SDK directory>\tools\bin) to inspect UI components and obtain IDs such as btn_login.
Hooking the Login Button
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);
};Simple Usage Example
In the "DuduCow" app, the final encryption uses DES and the result is displayed as Base64. Hooking the Base64 method reveals the encrypted payload.
Hook Result
Conclusion
The snippets above are common hooks used during Android reverse engineering. Depending on the target app, you may need additional hooks, but the presented examples form a solid foundation for analyzing encryption, data handling, and UI interactions.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Crawling & Data Mining
Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
