1

Hello reverse engineers,

I am reverse engineering a Mach-O executable for iOS. File says: Mach-O universal binary with 2 architectures: [arm_v7: Mach-O arm_v7 executable] [64-bit architecture=12]. I need to convert a virtual address to a file offset in a Mach-O file. In IDA, I see some data in the data segment with the virtual address 0x0000000100366720, which I want to read with a C program.

Using hexdump -C -v, I saw that the virtual address corresponds with the file offset 0xa9a720:

00a9a720  89 00 00 00 00 00 00 00  50 b7 39 00 01 00 00 00  |........P.9.....|
00a9a730  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a740  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a750  70 22 12 00 01 00 00 00  50 53 12 00 01 00 00 00  |p"......PS......|
00a9a760  58 53 12 00 01 00 00 00  00 00 00 00 00 00 00 00  |XS..............|
00a9a770  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a780  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a790  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a7a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a7b0  00 00 00 00 00 00 00 00  80 57 12 00 01 00 00 00  |.........W......|
00a9a7c0  98 cf 32 00 01 00 00 00  94 cf 32 00 01 00 00 00  |..2.......2.....|
00a9a7d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a7e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a7f0  00 67 36 00 01 00 00 00  c0 cf 32 00 01 00 00 00  |.g6.......2.....|
00a9a800  20 54 12 00 01 00 00 00  7c 57 12 00 01 00 00 00  | T......|W......|
00a9a810  38 ce 32 00 01 00 00 00  10 ce 32 00 01 00 00 00  |8.2.......2.....|
00a9a820  34 ce 32 00 01 00 00 00  f0 53 12 00 01 00 00 00  |4.2......S......|
00a9a830  51 00 00 00 e8 03 00 00  2c 00 00 00 25 00 00 00  |Q.......,...%...|
00a9a840  46 00 00 00 ff 29 11 17  00 00 00 00 4b 17 00 00  |F....)......K...|
00a9a850  80 00 00 00 08 00 00 00  08 00 00 00 0a 00 00 00  |................|
00a9a860  00 00 00 00 0f 00 00 00  28 1b 00 00 d0 03 00 00  |........(.......|
00a9a870  c8 02 00 00 a0 01 00 00  00 00 00 00 58 02 00 00  |............X...|
00a9a880  a8 02 00 00 d8 01 00 00  00 00 00 00 50 01 00 00  |............P...|
00a9a890  48 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |H...............|
00a9a8a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a8b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a8c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00a9a8d0  00 00 00 00 29 da f5 21  a1 b5 7a bf e9 7a d7 5b  |....)..!..z..z.[|
00a9a8e0  3a 97 49 72 00 00 00 00  20 67 36 00 01 00 00 00  |:.Ir.... g6.....|
00a9a8f0  f0 e2 32 00 01 00 00 00  20 e3 32 00 01 00 00 00  |..2..... .2.....|

Using IDA:

0000000100366720  89 00 00 00 00 00 00 00  50 B7 39 00 01 00 00 00  ........P.9.....
0000000100366730  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000000100366740  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000000100366750  70 22 12 00 01 00 00 00  50 53 12 00 01 00 00 00  p"......PS......
0000000100366760  58 53 12 00 01 00 00 00  00 00 00 00 00 00 00 00  XS..............
0000000100366770  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000000100366780  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000000100366790  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000001003667A0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000001003667B0  00 00 00 00 00 00 00 00  80 57 12 00 01 00 00 00  .........W......
00000001003667C0  98 CF 32 00 01 00 00 00  94 CF 32 00 01 00 00 00  ..2.......2.....
00000001003667D0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000001003667E0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000001003667F0  00 67 36 00 01 00 00 00  C0 CF 32 00 01 00 00 00  .g6.......2.....
0000000100366800  20 54 12 00 01 00 00 00  7C 57 12 00 01 00 00 00   T......|W......
0000000100366810  38 CE 32 00 01 00 00 00  10 CE 32 00 01 00 00 00  8.2.......2.....
0000000100366820  34 CE 32 00 01 00 00 00  F0 53 12 00 01 00 00 00  4.2......S......
0000000100366830  51 00 00 00 E8 03 00 00  2C 00 00 00 25 00 00 00  Q.......,...%...
0000000100366840  46 00 00 00 FF 29 11 17  00 00 00 00 4B 17 00 00  F....)......K...
0000000100366850  80 00 00 00 08 00 00 00  08 00 00 00 0A 00 00 00  ................
0000000100366860  00 00 00 00 0F 00 00 00  28 1B 00 00 D0 03 00 00  ........(.......
0000000100366870  C8 02 00 00 A0 01 00 00  00 00 00 00 58 02 00 00  ............X...
0000000100366880  A8 02 00 00 D8 01 00 00  00 00 00 00 50 01 00 00  ............P...
0000000100366890  48 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  H...............
00000001003668A0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000001003668B0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000001003668C0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000001003668D0  00 00 00 00 29 DA F5 21  A1 B5 7A BF E9 7A D7 5B  ....)..!..z..z.[
00000001003668E0  3A 97 49 72 00 00 00 00  20 67 36 00 01 00 00 00  :.Ir.... g6.....
00000001003668F0  F0 E2 32 00 01 00 00 00  20 E3 32 00 01 00 00 00  ..2..... .2.....

In the post Convert Mach-O VM Address To File Offset this formula is mentioned:

you need to find the segment (LC_SEGMENT) load command which covers the address, then do something like this:

fle_off = (address-seg.address)+ seg.offset

I have this load command in my Mach-O header:

HEADER:0000000100000380 ; LC_SEGMENT_64 - 64-bit segment of this file to be mapped
HEADER:0000000100000380                 segment_command_64 <0x19, 0x5E8, "__DATA", 0x100360000, 0x50000, \
HEADER:0000000100000380                                     0x360000, 0xC000, 3, 3, 0x12, 0>

If I fill in the formula: fle_off = (0x0000000100366720 - 0x100360000) + 0x360000 = 0x366720

The result is not the same file offset as 0xa9a720, which I found out using hexdump. It seems like I just calculated the offset from the base address. What am I doing wrong?

  • 1
    is it a fat (multi-architecture) file? – Igor Skochinsky Apr 26 '17 at 9:46
  • jup, file says Mach-O universal binary with 2 architectures: [arm_v7: Mach-O arm_v7 executable] [64-bit architecture=12] – exploiter Apr 26 '17 at 11:09
1

The offsets in the LC_SEGMENT command are counted from the beginning of the Mach-O header in the file. Normally the Mach-O header is at file offset 0, however OS X and iOS support so-called "fat" files which can contain several Mach-O files (usually for different architectures). You need to account for that and add a corresponding delta to the file offset, or, alternatively, extract the subfile you're interested in (e.g. using lipo) and work on a single file directly.

  • Thanks Igor, we identified the problem. When you asked that question I already started thinking about fat :) – exploiter Apr 26 '17 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.