背景:
漆黑夜晚的海滩上,发现一个遗落很久的木箱,箱子很重,边角用钢板缝合,尝试用普通的石块工具根本砸不开,
潮水有节奏的拍打着沙滩,饥肠辘辘的漂泊者望着箱子发呆,里面一定有水果罐头或是金币皇冠...
挣扎许久忽然在箱子一角发现印有模糊的PIPEOR,他思索片刻嘴角露出久违的笑容
题目信息:
本题是安卓平台规则2的crackme
文件名:KCTF2022-sprint-android-crackme.apk
公开序列号如下:
name:KCTF
serial:3432356538383237303738386163323436323438663964343063393831366663
第二组序列号:
name:C8EB85C90E69EDC8
serial:3638386461396366623135623535353361323862656630656561326334303931
(通过命令shasum -a 256 KCTF2022-sprint-android-crackme.apk计算apk得文件hash:
c8eb85c90e69edc8ee85e7233c6cb91aa633f6ff5dc4882ca3fc3ba45225d8c1)
设计思路:
本题算法延续了KCTF2021-秋季赛-第八题群狼环伺的设计方法:
增加防护技巧:
解题思路:
主要是去除防调试功能及调试检测功能
跟踪管道通信时,子进程read读数据操作,读取到value值后会进行校验,重点关注eor指令对数据进行的运算操作
vm保护原理:
正常编译后的代码通过反编译工具,逻辑结构很清晰,门槛低的小白都可以拿来用f5分析,所以代码防护很重要,最起码能防部分小白。最初级的加壳保护运行后会解密所以动态调试和dump内存也能获取到原代码,这时保护后勿需还原最终以保护态运行就会提高分析门槛。X86时期辉煌无数的vmprotect技术令大部分人闻风丧胆。该技术放到arm架构同样适用。原理也大同小异:
保护流程主要由三部分组成:反汇编器,解释器vmachine和链接器。
反汇编器取汇编指令列表中的指令根据指令类型生成对应的模拟代码,
如push/pop, ldr/str, bl, add, mov等,由于对指令进行了重新编码故称为指令模拟
原始代码开始替换为一条b 指令跳转到新生成的模拟代码运行,这样做可以避免其
他函数调用该函数时能正常工作。其余位置可以填充随机字段或者清空。
解释器工作原理:
针对ARM平台ELF格式的二进制程序的代码保护,兼容Arm&Thumb指令集,
首先反编译被保护的函数获取指令流 其次对指令流类型分别处理进行重定位
和需要模拟的指令进行编码生成vmdata最后通过链接7⃣️将解释器和原二进制
文件进行patch生成新二进制
由于编译后的汇编指令地址相关性,当把指令放到到千里之外,且不影响运行首要任务就是对地址相关指令做重定位
.text:000016C2 19 4C LDR R4, =(__stack_chk_guard_ptr - 0x16CC)
.text:000016C4 C3 B0 SUB SP, SP, #0x10C
.text:000016C6 01 AE ADD R6, SP, #0x120+var_11C
.text:000016C8 7C 44 ADD R4, PC
.text:000016CA 24 68 LDR R4, [R4]
…
.text:00001728 A0 38 00 00 off_1728 DCD __stack_chk_guard_ptr - 0x16CC
Thumb指令16C2处指令为ldr r4, [pc, #0x64],
访问的数据地址为 (16C2&0xFFF4) + (PC+4) + 0x64 = 0x1728
意思是从0x1728中获取数据即0x38A0赋值给R4寄存器
R4寄存器在0x16C8地址处会跟PC寄存器相加即0x38A0+(PC+4)=0x4F6C
结合0x16CA指令读内存操作,也就是说程序是在读取0x4F6C地址处的数据
这段代码当移动到其他地址运行时PC寄存器会变为移动后的地址
例如这段代码移动到
.text:00006000 19 4C LDR R4, =(__stack_chk_guard_ptr - 0x16CC)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-5-28 10:46
被kanxue编辑
,原因: