.so 文件的逆向工程并非易事。C 不像 java,你可以将 .class 文件转换成更易读的形式,比如 .smali。
您可以使用radare2检查.so 文件,但是要从r2 输出中获取任何内容,您需要一些有关处理器架构和正确操作码的基本知识。
你可以在这里开始你的教育:https : //azeria-labs.com/writing-arm-assembly-part-1/
或者您可以在下面找到一些基本说明:
假设你已经安装了radare2并且你已经解压了你的apk文件。
转到 apk 目录并列出lib目录abi docs:
$树库
库/
├── arm64-v8a
│ └── libnative-lib.so
├── armeabi-v7a
│ └── libnative-lib.so
├── x86
│ └── libnative-lib.so
└── x86_64
└── libnative-lib.so
4个目录,4个文件
选择您的平台(对于您的情况,它将是 armeabi-v7a 或 arm64-v8a)
用(-A选项运行aaa命令) 打开它
r2 -A lib/armeabi-v7a/libnative-lib.so
列出函数或搜索特定函数名称
[0x00006498]> afl
[0x00006498]> afl ~JNI
0x000064e4 9 256 -> 238 sym.Java_foo_com_bar_MainActivity_stringFromJNI
0x000065f0 1 44 sym._JNIEnv::NewStringUTF_charconst
0x00006724 1 28 sym.JNI_OnLoad
//跳转到函数:
$ [0x00006498]> s 0x00006724
//打印指令
$ [0x00006724]> pdf
/ (fcn) sym.JNI_OnLoad 28
| sym.JNI_OnLoad();
| ; var int local_0h @ sp+0x0
| ; var int local_4h @ sp+0x4
| ; var int local_8h @ sp+0x8
| ; var int local_ch @ sp+0xc
| ; var int local_10h @ sp+0x10
| ; 来自 0x00000234 的未知外部参照 (aav.0x00000224 + 16)
| 0x00006724 85b0 sub sp, 0x14
| 0x00006726 0a46 移动 r2,r1
| 0x00006728 0346 移动 r3,r0
| 0x0000672a 0490 str r0,[sp + local_10h]
| 0x0000672c 0391 str r1,[sp + local_ch]
| 0x0000672e 0620 movs r0, 6 ; aav.0x00000006
| 0x00006730 .dword 0x0001f2c0 ;aav.0x0001f2c0
| 0x00006734 0290 str r0,[sp + local_8h]
| 0x00006736 0298 ldr r0,[sp + local_8h]
| 0x00006738 0192 str r2,[sp + local_4h]
| 0x0000673a 0093 str r3,[sp]
| 0x0000673c 05b0 添加 sp,0x14
\ 0x0000673e 7047 bx lr
现在您必须解释radare2 输出,为此您需要带有描述的操作码列表,可以在此处或(对于arm64)在此处找到。
如您所见,没有简单的方法。
提示
您可以告诉radare2 在它们旁边写操作码描述。只需输入
e asm.describe=1
并且输出将更改为如下所示:
| 0x0000672e 0620 movs r0, 6 ; aav.0x00000006 ; 立即进入注册和更新标志
| 0x00006730 .dword 0x0001f2c0 ;aav.0x0001f2c0 ; 在半字的顶部写入 16 位值
| 0x00006734 0290 str r0,[sp + local_8h];将寄存器存储到内存中
| 0x00006736 0298 ldr r0,[sp + local_8h];从内存加载到寄存器
| 0x00006738 0192 str r2,[sp + local_4h];将寄存器存储到内存中
| 0x0000673a 0093 str r3, [sp]; 将寄存器存储到内存中
最后说明:
Arm 库有时会使用 Thumb 模式,这是另一个话题。您可以在azeria-labs 网站上找到有关拇指模式的一些信息