JAVA
JADX
C
nm -D
(对动态库)或strings
解出来的函数声明,用c++filt
能还原参数类型。
静态用IDA,动态用frida,二者结合。
IDA 7.5
由于没有回退功能,多拍快照。
data_ | on 64bit device | bits |
---|---|---|
byte3 | 3 | |
byte | char | 8 |
word | short | 16 |
dword | int, float | 32 |
qword | long, long long, double, size_t, void* | 64 |
xmmword / oword=8words | 4 ints, 2 doubles | 128 |
ymmword | 256 |
IDA中的_OWORD
Fundamental types
32位机器和64位机器中int、char等数据类型所占字节长度对比
Porting C++ codes to the 64-bit platform
类
- 无虚函数及父类,与结构所占内存相同;静态成员不占其空间。浅析C++类的内存布局
- 有虚函数时,可使用medigate fork(其将原项目目录重整)(介绍)及HexRaysPyTools
- IDA Pro - 使用IDA Pro逆向C++程序
函数
- 用第一选项new或第一选项打开已有库或程序
- 左侧函数窗口.text的区段是函数定义,找到目标函数(可用^f搜索)双击,显示汇编代码
- 在汇编代码窗口F5显示C代码
- 双击伪代码中的函数进行跳转
- 在伪代码中按x,选XR或BL行,跳转到当前函数的调用处
- 在变量处右键选convert to structure*,或按y,修改变量类型(工具解析的可能有误)的显示
- 在变量处按n修改变量名的显示
- 在数字常量上按右键转换进制显示
插件:
将文件放到Plugin目录,在IDA->Edit->Plugins找到对应插件。重启失效。
IDA_FunctionStringAssociate_PlugIn 能在函数前面加一行显示原文件名等
结构
- 欲分析原代码中的结构,只能自己定义:Edit->Add struct type;或在View->Open subviews->Structures窗口(可见已有四个Elf32/64结构,这些是程序默认需要的)按[Insert]
- 建好空结构后,按d添加一个成员
- 右键,对这个为了填充所有内容的成员进行重命名
- 右键,Expand struct将此成员大小设置为整个结构大小-1
- 按g并输入大小跳转到结尾或开头
- 在无名成员处按d生成默认名称
- 在数字成员类型上按d切换其类型——byte, word=2bytes, d(-ouble)word, q(-uater)word
- 改好类型后,再对成员重命名为需要的内容
- 在末尾按d添加成员
- 回到伪代码页面,修改变量类型为建好的结构后,按F5刷新,就能更新为定义的成员名称了
- 有不同名称指向同一变量时,按=将其指代
在结构定义页,
- 在原有默认结构之间或之前定义结构,容易伤及无辜,造成无法识别JNI定义的结构(如JNIEnv, JavaVM)等
- 删除(u)最后一个定义的成员时,包括它之前连续的未定义成员的空间都会删除
在本地类型(local types)页,
- 按Insert添加类型时,可写结构的源代码
- 按^E可修改结构的源代码
REF
frida
动态查看有根权限手机上进程的内存
- 安装python3.8,3.9,conda均可
pip3 install Frida
pip3 install frida-tools
frida-ps –U
显示手机上所有进程- 安装node.js后,用
npm i @types/frida-gum
即可在VS CODE中编译脚本 - 下载手机对应的变种frida-server-16.1.7-android-arm64,并在手机上运行:
adb push frida-server-16.1.7-android-arm64 /data/local/tmp/
adb root
adb shell /data/local/tmp/frida-server-16.1.7-android-arm64
frida -U '进程名' -l 脚本名
下面是脚本示例
function callinitFun(base_address) {
var real_addr = base_address.add(0xXX)
var init_function = new NativeFunction(real_addr,"int",["pointer"] )
var input = "/system/etc/test_config.json";
var arg1= Memory.allocUtf8String(input);
init_function(arg1)
console.log("call init_function success");
}
function hook_native() {
var baseaddress = Module.findBaseAddress("libTest.so");
if (baseaddress) {
//从输入参数找到算法加密的过程
console.log("baseaddress: ", baseaddress);
let my_struct_length = 0xXX;
var initConfigAddr = baseaddress.add(0xXX);
Interceptor.attach(initConfigAddr, {
onEnter: function (args) {
this.arg0 = args[0];
console.log("initConfigAddr onEnter:", ptr(this.arg0).readCString());
console.log("initConfigAddr hexdump :", hexdump(args[0], { length: my_struct_length} ));
}, onLeave: function (retval) {
console.log("initConfigAddr onLeave:", ptr(retval));
console.log("initConfigAddr hexdump :", hexdump(this.arg0, { length: my_struct_length} ));
}
});
callinitFunc(baseaddress);
}
}
function main() {
hook_native();
}
setImmediate(main);
鸣谢
Chaohao为IDA & frida提供帮助