Patching iOS binaries
Alex Soler
(murphy)
@as0ler
Mach-0 File Layout
Mach-0 Header
Load Commands
Data
FatMach-O File Layout
FAT Header
FAT Arch
Mach-0 File
struct fat_header {
uint32_t magic;
uint32_t nfat_arch; //Bin number
};
struct fat_arch {
uint32_t cputype; //Arch
uint32_t cpusubtype;
uint32_t offset; //Bin offset
uint32_t size; //BIn size
uint32_t alighn;
};
FAT Arch
Mach-0 File
pf Command
$pf obj=xxdz prev next size name #Define an "obj" struct (hexflag hexflag hex string)
$pf.obj @ <addr> #Apply "obj" struct to addr
$pf. #List all formats
[0x00000100]> pf??
|pf: pf[.k[.f[=v]]|[ v]]|[n]|[0][ [sz] fmt] [a0 a1 ...]
| Format:
| b byte (unsigned)
| B resolve enum bitfield (see t?)
| c char (signed byte)
| d 0x%%08x hexadecimal value (4 bytes)
| D disassemble one opcode
| e temporally swap endian
| E resolve enum name (see t?)
| f float value (4 bytes)
| i %%i integer value (4 bytes)
| n next char specifies size of signed value (1, 2, 4 or 8 byte(s))
| N next char specifies size of unsigned value (1, 2, 4 or 8 byte(s))
| o 0x%%08o octal value (4 byte)FatMach-0 Header
struct fat_header {
uint32_t magic;
uint32_t nfat_arch; //numBin
};FAT Struct is in big endian!
struct fat_arch {
uint32_t cputype; //Arch
uint32_t cpusubtype;
uint32_t offset; //Bin offset
uint32_t size; //BIn size
uint32_t align;
};Mach-0 Header
struct mach_header {
uint32_t magic;
uint32_t cputype;
uint32_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
};Load Commands
struct lc {
uint32_t cmd;
uint32_t cmdsize;
//Custom fields
};Interesting sections
Classdump
0x00c96248 class 0 IGAlbumCameraPermissionView
0x0011e3b0 method 0 initWithFrame:_8
0x0011ea2a method 1 layoutSubviews_15
0x0011ed48 method 2 refreshViewStateAnimated:
0x0011ef8c method 3 didTapCameraEnable
0x0011efca method 4 didTapMicrophoneEnable
0x0011f07a method 5 .cxx_destruct_42
0x0011f008 method 6 delegate_27
0x0011f026 method 7 setDelegate:_25
0x0011f03a method 8 cameraBlurOverlay
0x0011f04a method 9 textLabel_2
0x0011f05a method 10 cameraButton
0x0011f06a method 11 microphoneButton$rabin2 -c Instagram.arm_32.0[0x100000de0]> iCLC_ENCRYPTION_INFO
struct encryption_info_command {
uint32_t cmd; /* LC_ENCRYPTION_INFO */
uint32_t cmdsize; /* sizeof(struct encryption_info_command) */
uint32_t cryptoff; /* file offset of encrypted range */
uint32_t cryptsize; /* file size of encrypted range */
uint32_t cryptid; /* which enryption system,
0 means not-encrypted yet */
};The binary is decrypted in memory
Can't decrypt some binaries
Decrypt everything all the time (=slow)
Lots of lines of code (difficult to fix)
$git clone http://github.com/radare/radare2
$sys/ios-cydia.shiphone$ dpkg -i radare2_0.10.6-git_iphoneos-arm.debCompile Radare2 in local.
Copy .deb file into the iphone.
radare2/sys/cydia/radare2/radare2_0.10.6-git_iphoneos-arm.debInstalling deb
Check version
Default
Debug
Remember to add the correct Entitlements
iPhone:~ root# cat radare.xml
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>app-identifier</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
</dict>
</plist>
<!--
This file must be used to 'sign' the 'radare' binary
after compiling to permit debugging on the iphone-os
$ ldid -Sradare.xml radare
-->
iPhone:~ root# ldid -Sradare.xml /usr/bin/radare2And of course, you can check it with R2...
1. Extract mach0 bin from FatMach0 (if needed)
Mach-o file
Mach-o file
FatMach-o Header
Fat Arch
0x00000000
struct fat_arch {
uint32_t cputype;
uint32_t cpusubtype;
uint32_t offset; //fat_arch + 8
uint32_t size; //fat_arch + 12
uint32_t alighn;
};
Fat Arch
8 bytes
rabin2
Custom
2. Identify whether PIE is enabled or not.
3. Identify encryption information
00121 LC_ENCRYPTION_INFO = 0x00000021u,
00133 LC_ENCRYPTION_INFO_64 = 0x0000002Cu,4. Identify process address space.
PIE
non-PIE
5. Dump decrypted process into a file
Mach-0 Header
Encrypted Data
cryptoff
baseaddr
dump.bin
Mach-o Header
6. Overwrite original binary with the decrypted one
iPhone:~ root# cat bin.r2
f cryptoff=0x4000
f cryptsize=0x48000
f binoff=0x4000
iPhone:~ root#Mach-0 Header
Encrypted Data
cryptoff
binoff
dump.bin
Mach-o Header
FatMach-o Header
Fat Arch
0x00000000
7. Patch binary structure as a decrypted one.
struct encryption_info_command {
uint32_t cmd;
uint32_t cmdsize;
uint32_t cryptoff;
uint32_t cryptsize;
uint32_t cryptid;
};R2Clutch
https://github.com/as0ler/r2clutch