sha1中的zhaoboy就是输入明文=7a68616f626f79
zhaoboy+9ddcbd818e1eb3a1c9792a70b406eb622f92cccad1454ac612751d7451360006
定位9ddcbd818e1eb3a1c9792a70b406eb622f92cccad1454ac612751d7451360006 怎么来
[memcpy] [LR]:RX@0x40022c88[libgdwg.so]0x22c88 [arg1]: RW@0x404145c7 [arg2]: RW@0x40420b80 [len]: 32 [memcpy] [sourceBar] [-99, -36, -67, -127, -114, 30, -77, -95, -55, 121, 42, 112, -76, 6, -21, 98, 47, -110, -52, -54, -47, 69, 74, -58, 18, 117, 29, 116, 81, 54, 0, 6] [memcpy] [sourceHex] 9ddcbd818e1eb3a1c9792a70b406eb622f92cccad1454ac612751d7451360006
tracewrite(0x40420b80)
[20:06:17 931] Memory WRITE at 0x40420b80, data size = 1, data value = 0x9d, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608 [20:06:17 931] Memory WRITE at 0x40420b81, data size = 1, data value = 0x4c, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608 [20:06:17 932] Memory WRITE at 0x40420b81, data size = 1, data value = 0xdc, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608 [20:06:17 932] Memory WRITE at 0x40420b82, data size = 1, data value = 0xc7, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608 [20:06:17 932] Memory WRITE at 0x40420b82, data size = 1, data value = 0xbd, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608 [20:06:17 932] Memory WRITE at 0x40420b83, data size = 1, data value = 0x97, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608 [20:06:17 932] Memory WRITE at 0x40420b83, data size = 1, data value = 0x81, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608 [20:06:17 933] Memory WRITE at 0x40420b84, data size = 1, data value = 0x95, PC=RX@0x40024674[libgdwg.so]0x24674, LR=RX@0x40024608[libgdwg.so]0x24608
隔一行 取一个值,这里看过去是vmp
0x249f4] [4925c91a] 0x400249f4: "lsr w9, w10, w9" w10=0x71200879 w9=0x7 => w9=0xe24010 0x249f4] [4925c91a] 0x400249f4: "lsr w9, w10, w9" w10=0x71200879 w9=0x12 => w9=0x1c480x249f4] [4925c91a] 0x400249f4: "lsr w9, w10, w9" w10=0x71200879 w9=0x3 => w9=0xe24010f根据这个来,sha256的明文编排,明文编排的第二个分组,分别右移7、18、3 rot7 = right_rotate(W[i - 15], 7) rot18 = right_rotate(W[i - 15], 18) shr3 = W[i - 15] >> 3 0xe25c58fed81d57这个是s1的结果 0x6959d44c这个就是第一个明文[libgdwg.so 0x24704] [4901098b] 0x40024704: "add x9, x10, x9" x10=0xe25c58fed81d57 x9=0x6959d44c => x9=0xe25c596831f1a3
0x71200879+0x6831f1a3 这个有点难推,得仔细找,
看看其他明文的编排 这里很快就找到了
# "eor w9, w10, w9" w10=0x1104400c w9=0xe818980 => w9=0x1f85c98c# x10=0x14e1883b2ae1883 x9=0x2887293fa8 => x9=0x14e18ab3587272b# x10=0x5be0cd19 x9=0x14e18ab3587272b => x9=0x14e18ab9167f444 H+S1+** # "add x9, x10, x9" x10=0x14e18ab9167f444 x9=0x1f85c98c => x9=0x14e18abb0edbdd0 temp1 = (h + S1 + ch + K[i] + W[i]) & 0xffffffff # 0x24704] [4901098b] 0x40024704: "add x9, x10, x9" x10=0x14e18abb0edbdd0 x9=0x428a2f98 => x9=0x14e18abf377ed68跟k表相加的地方就是明文 直接找,其实就是数据大小k表第15个# W[ 0]: 0x6959d44c | W[ 1]: 0x71200879 | W[ 2]: 0x7fc8738a | W[ 3]: 0x557ec398# W[ 4]: 0x80000000 | W[ 5]: 0x00000000 | W[ 6]: 0x000000 | W[ 7]: 0x00000000# W[ 8]: 0x00000000 | W[ 9]: 0x00000000 | W[10]: 0x00000000 | W[11]: 0x00000000# W[12]: 0x00000000 | W[13]: 0x00000000 | W[14]: 0x00000000 | W[15]: 0x00000080
6959d44c712008797fc8738a557ec398800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080
明文=6959d44c712008797fc8738a557ec398
59c2c38ef09f068f13638e434ff007870d1cca21480e7ca3e64fb39f9190a421 为sha256的密文
如下为AI生成,仅供参考。
本指南专注于ARM64架构下的VMP逆向技术,完全排除x86相关内容,提供针对ARM64架构的深度逆向方法。
1. ARM64架构下VMP的核心特点
1.1 ARM64特有保护机制
• AArch64指令集虚拟化:将ARM64指令转换为自定义字节码 • PAC(指针认证)滥用:利用ARMv8.3+的指针认证特性增强保护 • SVC调用混淆:通过系统调用实现控制流转移 • NEON指令虚拟化:对SIMD指令的特殊处理
1.2 ARM64 VMP二进制特征
• .vmpa64
专用段标识 • 使用x16/x17
寄存器作为虚拟IP(指令指针) • 频繁的brk #0x1
指令用于反调试 • 基于msr/mrs
的系统寄存器操作
2. ARM64专用工具链
2.1 静态分析工具
• IDA Pro with ARM64处理器模块• **Ghidra 10.3+**:改进的ARM64反编译器 • Binary Ninja:支持ARM64控制流图分析 • VMArm64Analyzer:专用插件
2.2 动态分析工具
• Frida-gum:ARM64内联hook框架 • Qiling Framework:ARM64模拟器 • ARM64 GDB with GEF:增强调试功能 • ADBI:安卓ARM64动态二进制插桩工具
3. ARM64静态分析技术
3.1 入口点识别
# 使用readelf定位.init_arrayreadelf -d libtarget.so | grep INIT_ARRAY# 检查JNI_OnLoad变形objdump -D libtarget.so | grep -A 20 "JNI_OnLoad"
3.2 IDA Pro专项分析
# IDAPython定位ARM64虚拟入口deffind_vm_entry():for seg in Segments():if SegName(seg) == ".vmpa64": print(f"Found VMP segment at 0x{seg:x}")for func in Functions(seg, GetSegmentAttr(seg, SEGATTR_END)):if"vm_start"in GetFunctionName(func):return funcreturn BADADDR
4. ARM64动态调试方案
4.1 Frida ARM64专用脚本
// 拦截ARM64寄存器访问Interceptor.attach(Module.findExportByName(null, "mprotect"), {onEnter: function(args) {console.log(`mprotect(${args[0]}, ${args[1]}, ${args[2]})`);console.log("X0-X3:", this.context.x0, this.context.x1, this.context.x2, this.context.x3); }});// 绕过ARM64反调试const svc_handler = new NativeFunction( Module.findExportByName(null, "svc#0"),'void', ['uint32']);Interceptor.replace(svc_handler, new NativeCallback(function(num) {if(num === 0x1) return; // 忽略brk #0x1return svc_handler(num);}, 'void', ['uint32']));
4.2 Qiling模拟框架配置
from qiling import Qilingfrom qiling.const import QL_ARCH, QL_OSdefarm64_vmp_sandbox(): ql = Qiling(["libtarget.so"], rootfs="/android_rootfs", arch=QL_ARCH.ARM64, ostype=QL_OS.LINUX)# 设置ARM64特定hookdefsyscall_hook(ql, *args): print(f"SVC #{ql.reg.x8} called") ql.set_syscall(0x1337, syscall_hook) ql.run()
5. ARM64虚拟机逆向
5.1 虚拟寄存器映射
structARM64_VRegs {uint64_t vX[31]; // 对应X0-X30uint64_t vIP; // 虚拟指令指针(X16)uint64_t vSP; // 虚拟堆栈指针(X17)uint32_t vNZCV; // 虚拟条件标志uint64_t vFP[32]; // 虚拟浮点寄存器};
5.2 关键handler识别表
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
6. ARM64控制流分析
6.1 虚拟跳转解析
defanalyze_vm_jump(uc, address):# 读取ARM64虚拟跳转指令 opcode = uc.mem_read(address, 4)if (opcode[0] & 0xF0) == 0x80:# 解析相对跳转偏移 offset = (opcode[1] << 16) | (opcode[2] << 8) | opcode[3]return address + (offset * 4)return address + 4
6.2 基本块划分算法
defsplit_basic_blocks(start, end): blocks = [] current = startwhile current < end: size = get_instr_size(current)if is_branch_instr(current): blocks.append((current, current+size)) current += sizeifnot is_terminator(current-size): next_block = get_branch_target(current-size) blocks += split_basic_blocks(next_block, end)break current += sizereturn blocks
7. ARM64反反调试技术
7.1 绕过ptrace检测
# 使用ADBI注入绕过adb push adbi /data/local/tmpadb shell chmod +x /data/local/tmp/adbiadb shell /data/local/tmp/adbi -p `pidof target` -l libbypass.so
7.2 处理内存校验
// Frida脚本绕过内存校验const mprotect = Module.findExportByName(null, "mprotect");Interceptor.attach(mprotect, {onLeave: function(retval) {if(this.returnAddress.toString().includes("libvmp.so")) { Memory.protect(ptr(this.context.x0), this.context.x1.toInt32(),'rwx'); } }});
8. ARM64性能优化
8.1 并行模拟技术
from multiprocessing import Pooldefparallel_emulate(blocks):with Pool(4) as p: results = p.map(emulate_block, blocks)return merge_results(results)
8.2 缓存机制实现
classVMCache:def__init__(self): self.block_cache = {}defget(self, address):if address in self.block_cache:return self.block_cache[address] block = self._analyze_block(address) self.block_cache[address] = blockreturn block
9. ARM64实战案例
9.1 算法还原流程
-
定位加密函数在so中的位置 -
识别ARM64虚拟化指令模式 -
重建虚拟寄存器流转 -
转换为标准ARM64汇编
9.2 协议逆向方法
-
拦截SSL_write/read调用 -
追踪ARM64寄存器中的缓冲区 -
分析加密前/后的数据变化 -
重建协议加解密流程
10. 法律合规建议
-
仅针对自己拥有版权的应用进行分析 -
避免绕过DRM或付费验证机制 -
研究结果仅用于安全防御目的 -
遵守《计算机软件保护条例》相关规定
本指南提供的技术需要专业的ARM64架构知识,建议在合法授权的环境下使用。ARM64逆向通常需要200-500小时的专业训练才能熟练掌握。
原文始发于微信公众号(小白技术社):广东的vmp大致分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论