hook的作用hook,译为“钩子”,是指将方法/函数勾住,勾住后我们可以做一些我们想做的事情。实际上我们可以通过一些工具,可以把我们java、native层面的方法/函数调用给“勾住了”,或者直接理解为监听,我们可以监听到调用方法,方法的传参,以及修改方法的返回值等等
了解这些工具,可以帮助我们更好的去定位问题、进行debug,甚至可以对一些app进行破解修改
常见的逆向工具工具/方法 | 作用 | java层 | native层 | SDK集成 | 是否需要root | 备注 | 其他 |
---|---|---|---|---|---|---|---|
JADX | 反编译查看源码 | 支持 | 不支持 | 无 | 无 | 加固的apk需要先脱壳 | |
apktool | 反编译/回编 APK | 无 | 无 | 无 | 无 | 修改smail码 | |
epic/sandhook | app集成SDK进行代码hook | 支持 | 支持 | 需要 | 不需要 | xposed框架,不同的系统API不一致需要适配 | |
xposed插件 | 在集成了xposed框架的安卓环境上进行hook | 支持 | 不支持 | 不需要 | 需要 | 需要root,其他同上 | |
frida | 在root的安卓环境下,对java/native 直接进行二进制hook | 支持 | 支持 | 需要 | 需要 | 需要root环境,python环境 |
frida是一款二进制hook框架,支持java/native层hook,需要root环境,因为是二进制内存hook,可以实现直接hook当前进程,无需集成SDK甚至不需要重启进程
// 安装特定版本 pip install frida==版本号
pip install frida
pip install frida-tools
// 网络不好使用镜像库
pip install firda -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
// 查看当前frida版本
frida --version
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
# 这里放于 /data/local/tmp
adb push E:\frida-server /data/local/tmp/frida-server
# 进入adb shell
adb shell
# 以管理员权限访问
su
# 进入frida-server目录
cd /data/local/tmp
# 提供权限
chmod 777 frida-server
# 运行frida-server
./frida-server
# 命令成功输出进程列表
frida-ps -U
# 根据包名连接目标进程
frida -U -f com.xxx.xxx
执行hookimport frida, sys
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
jscode = """
Java.perform(() =>{
// Function to hook is defined here
const MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
// Whenever button is clicked
const onClick = MainActivity.onClick;
onClick.implementation = function (v) {
// Show a message to know that the function got called
send('onClick');
// Call the original onClick handler
onClick.call(this, v);
// Set our values after running the original onClick handler
this.m.value = 0;
this.n.value = 1;
this.cnt.value = 999;
// Log to the console that it's done, and we should have the flag!
console.log('Done:' + JSON.stringify(this.cnt));
};
});
"""
# pid or package name
process = frida.get_usb_device().attach(13347)
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read())
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()
frida -U [pid|packagename] -l test.js
常用hook脚本/APIpublic class TestStaticClass {public static int count = 0;
private static String TAG = "TestStaticClass";
public static String getCountString(){Log.i(TAG, "call testMethod");
return "count:" + count;
}
public static void addCount(){count++;
}
public static String getCountString(int input){return "getCountString:" + input;
}
public static String getCountString(int[] input){return "getCountString:" + Arrays.toString(input);
}
public void testStack(){Log.i(TAG, "call testStack");
}
}
方法 | 含义 | 其他 |
---|---|---|
$new | 新建对象 | |
$init | 构造函数 |
const JavaString = Java.use('java.lang.String');
var exampleString1 = JavaString.$new('Hello World, this is an example string in Java.');
获取类与静态函数方法调用
Java.perform(() =>{const TestStaticClass = Java.use("com.hjl.nativetest.TestStaticClass");
TestStaticClass.count.value = 1; //访问静态变量
TestStaticClass.addCount(); //hook静态函数直接调用
});
hook方法打印方法值并修改返回值
Java.perform(() =>{// 获取类
const TestStaticClass = Java.use("com.hjl.nativetest.TestStaticClass");
// 获取方法
const getCountString = TestStaticClass.getCountString;
// hook方法
getCountString.implementation = function () {// 当方法调用时
send('call getCountString');
// 调用原方法获取结果
var result = getCountString.call(this);
console.log("getCountString:" + result);
// 返回自定义的结果
return "hook return String";
};
// 获取重载方法
// 基础类型直接填,数组以类似JNI的签名形式如[I ,类型填完整类
const getCountString2 = TestStaticClass.getCountString.overload('int')
getCountString2.implementation = function (data) {// 打印原始输入参数
send('call getCountString:' + data);
// 调用原方法获取结果
var result = getCountString2.call(this,data);
console.log("getCountString:" + result);
// 返回自定义的结果
return "hook return String";
};
});
获取调用栈
Java.perform(() =>{const TestStaticClass = Java.use("com.hjl.nativetest.TestStaticClass");
const Exception = Java.use('java.lang.Exception');
const Log = Java.use('android.util.Log');
const testStack = TestStaticClass.testStack
testStack.implementation = function () {console.log(stackTraceHere());
};
function stackTraceHere() {return Log.getStackTraceString(Exception.$new());
}
});
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享标题:【安卓逆向】Frida入门与常用备忘-创新互联
路径分享:https://www.cdcxhl.com/article44/cddoee.html
成都网站建设公司_创新互联,为您提供品牌网站设计、标签优化、外贸建站、做网站、响应式网站、App设计
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联