刚才写入Section之后,虽然是成功运行,没有任何报错,但是我还没有解释清楚那个谜之数据是怎么来的。
虽然在注释里写出了ASM,但是里面其实是有坑的。
解密之后的数据:
unsignedint sectionData[] = {0xA0E1000E,0xE0800001,0xE12FFF30}; // Encrypt Decrypt ASM // 0xCB927360 0xA0E1000E mov r0, lr // 0x8BF3736F 0xE0800001 add r0, r0, r1 // 0x8A5C8C5E 0xE12FFF30 blx r0
让我们用之前所讲的第一种创建Section的方法写一下吧:
__declspec(allocate("__[data deleted],__code")) void func() { printf(""); } int main(int argc, const char * agrv[]) { // 确保func()被编译 if (ULLONG_MAX == argc) func(); Dl_info info; if (dladdr((const void *)main, &info)){ const struct SEGMENT_COMMAND * myseg = getsegbyname("__[data deleted]"); vm_address_t addr = myseg->vmaddr + reinterpret_cast<unsigned long>(info.dli_fbase) - FILE_BASE_ADDR; (*((void (*)())(addr)))(); } }
在MachOView中设置好段属性之后,通过debugserver调试:(在设备上)
debugserver -x backboard *:1234 /segment
在lldb里下一个断点在dladdr上,
b dladdr
之后一路按'n',等执行到
(*((void (*)())(addr)))();
其实用'dis -A thumb'就和Hopper里看见的一样了:
但是!请注意!
lldb之所以默认从thumb变到ARM的反汇编模式,是因为设备上的CPU模式发生了变化,不信你可以在单步跟进func()之前输入'dis'和'dis -A thumb',你看到的反汇编结果会是一样的!
于是这就要求我们嵌入在Section的指令必须是ARM的!
那么要怎么生成ARM指令的程序呢,在Xcode上还没找到。。。
thumb指令被当成ARM指令之后,不是可能正常执行的:
- 生成ARM指令的程序
不过借助LLVM框架还是可以完成的:
nico.m文件:
#import <stdio.h> void nico() { printf("Nico~Nico~Ni\n"); }
编译:
$ llc -march arm -mcpu generic nico.ll -o nico.s $ clang nico.s -x assembler -arch armv7 -e _nico -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -o nico