android 逆向 11 / 38
- app OAuth api_sign 分析
- app sig 参数加密分析 unidbg 模拟黑盒调用
- app sign so 加密参数破解|unidbg
- sgmain x-sign 分析 - unidbg
- androidAsync fridaManager sgmain 70102 rpc 远程调用
- app edata 参数 so aes 加密分析破解|unidbg
- frida 加载 sekiro dex 文件 实现与服务端交互
- frida sekiro 实现 sgmain 70102 远程 rpc 调用
- xposed sekiro hook 获取 wx 万能 key
- unidbg console debugger 使用
- unidbg hook inline hook 使用
- app 公众号文章列表 so 加解密算法分析还原 | 简单分析
- app 公众号文章列表 so 加解密算法分析还原 | 加密 rsa base64 分析
- app 公众号文章列表 so 加解密算法分析还原 | 加密 zip aes 分析
- app 公众号文章列表 so 加解密算法分析还原 | response 内容解密分析
- app sign so 加密算法分析还原|简单分析
- app sign so 加密算法分析还原|so 算法分析
- app sign so 加密算法分析还原|so sub_126AC 函数算法还原
- app so signkeyV1 参数分析
- ida 动态调试 android so 文件|基础入门环境搭建
- app so newSign 参数分析破解
- app tzRgz52a 参数分析破解
- app sign-v2 签名算法 aes 加解密分析
- app so 加密参数分析|protocbuf 分析
- mxtakatak android app 加解密分析
- android app so 加密算法分析破解|mtgsig unidbg
- android app so 加密算法分析破解|siua unidbg
- android app nsign so 加密算法分析
- android app sig 参数 so 加密逻辑逆向分析
- android app so sig 加密参数 unidbg
- 狗狗音乐登陆协议加密参数逆向分析
- android sign so 加密参数分析|unidbg
- android app X-SS-QUERIES 参数分析
- unidbg android app xgorgon 加密参数 leviathan
- sgmain 6.4.x xsign 加密算法分析研究
- sgmain 6.4.x xminiwua 加密算法分析研究
- 某 app mas 算法分析还原 cms so
- 某东登陆协议 tlv 逻辑分析
const 龙哥 = Function() {}
const a = 全能的傻宝,每天都会换一种姿势来分享各种操作,最近 10 月在分享密码学;
const b = 点击加入星球;
return "无敌的龙哥";
前言
unidbg
是个非常好用的工具,可以模拟手机运行环境执行so
文件,同时也非常适合算法还原
得益于它强大的hook debugger
功能,我们今天的主角是hook
,简单介绍使用一下
想学习unidbg
的小伙伴,可以call 龙哥 ();
demo
这篇文章的样本是 搜狗搜索 app,不了解的同学,可以参考一下文章
sougou搜索 app weixin公众号文章列表 so 加解密算法分析还原 | 简单分析
推荐阅读
unidbg console debugger 使用 推荐先阅读此文章对样本有个大概的了解
start
0x1
使用
IHookZz hook
一下此函数,看看参数跟返回值
public void hookSCEncryptWallEncode() {
// 获取 HookZz 对象
IHookZz hookZz = HookZz.getInstance(emulator);
// enable hook
hookZz.enable_arm_arm64_b_branch();
hookZz.wrap(module.base + 0xA284 + 1, new WrapCallback<RegisterContext>() {
Pointer buffer;
@Override
public void preCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo info) {
System.out.println("HookZz hook Sc_EncryptWallEncode");
Pointer input1 = ctx.getPointerArg(0);
Pointer input2 = ctx.getPointerArg(1);
Pointer input3 = ctx.getPointerArg(2);
// getString 的参数 i 代表 index, 即 input[i:]
System.out.println("参数1:" + input1.getString(0));
System.out.println("参数2:" + input2.getString(0));
System.out.println("参数3:" + input3.getString(0));
// 先保存 参数四的 内存地址
buffer = ctx.getPointerArg(3);
}
@Override
public void postCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo info) {
// getByteArray 参数1是起始index,参数2是长度,我们不知道结果多长,就先设置0x100吧
byte[] outputhex = buffer.getByteArray(0, 0x100);
Inspector.inspect(outputhex, " Sc_EncryptWallEncode output");
}
});
hookZz.disable_arm_arm64_b_branch();
}
代码跑起来
参数 123 刚好是我们传进去的
参数 4 是个 buffer
返回的数据存到了这个地址里面,函数执行完后,直接取出来即可
0x2
使用
IHookZz 的 inline hook
一下此函数,看看参数跟返回值
public void inlineHookSCEncryptWallEncode() {
// 查看 Sc_EncryptWallEncode 执行前后 buffer 变化
IHookZz hookZz = HookZz.getInstance(emulator);
hookZz.enable_arm_arm64_b_branch();
hookZz.instrument(module.base + 0x9D24 + 1, new InstrumentCallback<Arm32RegisterContext>() {
@Override
public void dbiCall(Emulator<?> emulator, Arm32RegisterContext ctx, HookEntryInfo info) {
System.out.println("HookZz inline hook Sc_EncryptWallEncode");
Pointer input1 = ctx.getPointerArg(0);
Pointer input2 = ctx.getPointerArg(1);
Pointer input3 = ctx.getPointerArg(2);
// getString 的参数 i 代表 index, 即 input[i:]
System.out.println("参数1:" + input1.getString(0));
System.out.println("参数2:" + input2.getString(0));
System.out.println("参数3:" + input3.getString(0));
buffer = ctx.getPointerArg(3);
}
});
hookZz.instrument(module.base + 0x9d28 + 1, new InstrumentCallback<Arm32RegisterContext>() {
@Override
public void dbiCall(Emulator<?> emulator, Arm32RegisterContext ctx, HookEntryInfo info) {
Inspector.inspect(buffer.getByteArray(0, 0x100), " inline hook Sc_EncryptWallEncode");
}
});
}
执行代码结果都是一样的
在有些时候,一个函数可能会运行,但我们只想查看当前的运行情况,这时可能会使用到 inline hook需要注意,inline hook 的时机是目标指令执行前
0x3
使用 unicorn inline hook
public void hookUnicornBase64Encode() {
// 使用 unicorn 进行 hook
emulator.getBackend().hook_add_new(new CodeHook() {
@Override
public void onAttach(Unicorn.UnHook unHook) {
}
@Override
public void detach() {
}
@Override
public void hook(Backend backend, long address, int size, Object user) {
if (address == (module.base + 0xB372)) {
System.out.println("Hook By Unicorn Base64Encode");
RegisterContext ctx = emulator.getContext();
Pointer input1 = ctx.getPointerArg(0);
Inspector.inspect(input1.getByteArray(0, 0x100), " 参数1");
}
if (address == (module.base + 0xB376)) {
RegisterContext ctx = emulator.getContext();
Inspector.inspect(ctx.getPointerArg(0).getByteArray(0, 0x100), " Unicorn hook Base64Encode");
}
}
}, module.base + 0xB372, module.base + 0xB376, null);
}
代码里是 hook Base64Encode
的执行前跟执行后,分别打印输入跟输出
结果也全部出来了,参数一就是上面 rsa
的加密结果,在使用 base64Encode