ARM32 Binary Mangling


[:  :]

Here are some notes on experimenting with small ARM32 binaries. I edited binaries directly instead of assembling them on each modification to the binary.

Creating The Initial Binary

This is the source

$ cat hello.s
.data
msg: .ascii "[^-^] [^0^]\n"
len = . - msg

.text
.global _start

_start:
  mov     r0, #1    /* fd 1 = stdout */
  ldr     r1, =msg  /* message */
  ldr     r2, =len  /* length of message */
  mov     r7, $4    /* write */
  swi     #0        /* syscall */
  mov     r0, $0    /* status */
  mov     r7, $1    /* exit */
  swi     #0        /* syscall */

Output in raw hex - You can use objdump or this handy converter!

0100a0e3 MOV R0, #1
14109fe5 LDR R1, [PC, #0x14]
0c20a0e3 MOV R2, #0xC
0470a0e3 MOV R7, #4
000000ef SVC #0
0000a0e3 MOV R0, #0
0170a0e3 MOV R7, #1
000000ef SVC #0
90000200 MULEQ R2, R0, R0

Analyzing The Sections

Objdump

pi@pai:~/asm $ objdump -d hello
  hello:     file format elf32-littlearm
  
  Disassembly of section .text:
  
  00010074 <_start>:
     10074:       e3a00001        mov     r0, #1
     10078:       e59f1014        ldr     r1, [pc, #20]   ; 10094 <_start+0x20>
     1007c:       e3a0200c        mov     r2, #12
     10080:       e3a07004        mov     r7, #4
     10084:       ef000000        svc     0x00000000
     10088:       e3a00000        mov     r0, #0
     1008c:       e3a07001        mov     r7, #1
     10090:       ef000000        svc     0x00000000
     10094:       00020098        .word   0x00020098

Hexdump

pi@pai:~/asm $ hd hello
headers ----------------------------------------------------------------------
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 28 00 01 00 00 00  74 00 01 00 34 00 00 00  |..(.....t...4...|
00000020  60 02 00 00 00 02 00 05  34 00 20 00 02 00 28 00  |`.......4. ...(.|
00000030  07 00 06 00 01 00 00 00  00 00 00 00 00 00 01 00  |................|
00000040  00 00 01 00 98 00 00 00  98 00 00 00 05 00 00 00  |................|
00000050  00 00 01 00 01 00 00 00  98 00 00 00 98 00 02 00  |................|
00000060  98 00 02 00 0c 00 00 00  0c 00 00 00 06 00 00 00  |................|
00000070  00 00 01 00 

.text 0x74 | 0x24 ------------------------------------------------------------
00000074              01 00 a0 e3  14 10 9f e5 0c 20 a0 e3  |............. ..|
00000080  04 70 a0 e3 00 00 00 ef  00 00 a0 e3 01 70 a0 e3  |.p...........p..|
00000090  00 00 00 ef 98 00 02 00  

.data 0x98 | 0xc -------------------------------------------------------------
00000098                           5b 5e 2d 5e 5d 20 5b 5e  |........[^-^] [^|
000000a0  30 5e 5d 0a                                       |0^].

.ARM_attributes 0xa4 | 0x14 --------------------------------------------------
000000a4              41 13 00 00  00 61 65 61 62 69 00 01       A....aeabi..|
000000b0  09 00 00 00 06 01 08 01  

.symtab 0xb8 | 0x120 ---------------------------------------------------------
000000b8                           00 00 00 00 00 00 00 00  |................|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 74 00 01 00  |............t...|
000000d0  00 00 00 00 03 00 01 00  00 00 00 00 98 00 02 00  |................|
000000e0  00 00 00 00 03 00 02 00  00 00 00 00 00 00 00 00  |................|
000000f0  00 00 00 00 03 00 03 00  01 00 00 00 00 00 00 00  |................|
00000100  00 00 00 00 04 00 f1 ff  09 00 00 00 98 00 02 00  |................|
00000110  00 00 00 00 00 00 02 00  0d 00 00 00 0c 00 00 00  |................|
00000120  00 00 00 00 00 00 f1 ff  11 00 00 00 74 00 01 00  |............t...|
00000130  00 00 00 00 00 00 01 00  14 00 00 00 94 00 01 00  |................|
00000140  00 00 00 00 00 00 01 00  14 00 00 00 98 00 02 00  |................|
00000150  00 00 00 00 00 00 02 00  26 00 00 00 a4 00 02 00  |........&.......|
00000160  00 00 00 00 10 00 02 00  17 00 00 00 a4 00 02 00  |................|
00000170  00 00 00 00 10 00 02 00  25 00 00 00 a4 00 02 00  |........%.......|
00000180  00 00 00 00 10 00 02 00  36 00 00 00 74 00 01 00  |........6...t...|
00000190  00 00 00 00 10 00 01 00  31 00 00 00 a4 00 02 00  |........1.......|
000001a0  00 00 00 00 10 00 02 00  3d 00 00 00 a4 00 02 00  |........=.......|
000001b0  00 00 00 00 10 00 02 00  45 00 00 00 a4 00 02 00  |........E.......|
000001c0  00 00 00 00 10 00 02 00  4c 00 00 00 a4 00 02 00  |........L.......|
000001d0  00 00 00 00 10 00 02 00  

.strtab 0x1d8 | 0x51 ---------------------------------------------------------
000001d8                           00 68 65 6c 6c 6f 2e 6f  |.........hello.o|
000001e0  00 6d 73 67 00 6c 65 6e  00 24 61 00 24 64 00 5f  |.msg.len.$a.$d._|
000001f0  5f 62 73 73 5f 73 74 61  72 74 5f 5f 00 5f 5f 62  |_bss_start__.__b|
00000200  73 73 5f 65 6e 64 5f 5f  00 5f 5f 62 73 73 5f 73  |ss_end__.__bss_s|
00000210  74 61 72 74 00 5f 5f 65  6e 64 5f 5f 00 5f 65 64  |tart.__end__._ed|
00000220  61 74 61 00 5f 65 6e 64  00                       |ata._end.

.shstrtab 0x229 | 0x37 -------------------------------------------------------
00000229                              00 2e 73 79 6d 74 61            ..symta|
00000230  62 00 2e 73 74 72 74 61  62 00 2e 73 68 73 74 72  |b..strtab..shstr|
00000240  74 61 62 00 2e 74 65 78  74 00 2e 64 61 74 61 00  |tab..text..data.|
00000250  2e 41 52 4d 2e 61 74 74  72 69 62 75 74 65 73 00  |.ARM.attributes.|

Then a bunch of other stuff

00000260  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000280  00 00 00 00 00 00 00 00  1b 00 00 00 01 00 00 00  |................|
00000290  06 00 00 00 74 00 01 00  74 00 00 00 24 00 00 00  |....t...t...$...|
000002a0  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
000002b0  21 00 00 00 01 00 00 00  03 00 00 00 98 00 02 00  |!...............|
000002c0  98 00 00 00 0c 00 00 00  00 00 00 00 00 00 00 00  |................|
000002d0  01 00 00 00 00 00 00 00  27 00 00 00 03 00 00 70  |........'......p|
000002e0  00 00 00 00 00 00 00 00  a4 00 00 00 14 00 00 00  |................|
000002f0  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00000300  01 00 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|
00000310  b8 00 00 00 20 01 00 00  05 00 00 00 0a 00 00 00  |.... ...........|
00000320  04 00 00 00 10 00 00 00  09 00 00 00 03 00 00 00  |................|
00000330  00 00 00 00 00 00 00 00  d8 01 00 00 51 00 00 00  |............Q...|
00000340  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00000350  11 00 00 00 03 00 00 00  00 00 00 00 00 00 00 00  |................|
00000360  29 02 00 00 37 00 00 00  00 00 00 00 00 00 00 00  |)...7...........|
00000370  01 00 00 00 00 00 00 00                           |........|
00000378

Stripped Hexdump

pi@pai:~/asm $ strip hello
pi@pai:~/asm $ hd hello
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 28 00 01 00 00 00  74 00 01 00 34 00 00 00  |..(.....t...4...|
00000020  e0 00 00 00 00 02 00 05  34 00 20 00 02 00 28 00  |........4. ...(.|
00000030  05 00 04 00 01 00 00 00  00 00 00 00 00 00 01 00  |................|
00000040  00 00 01 00 98 00 00 00  98 00 00 00 05 00 00 00  |................|
00000050  00 00 01 00 01 00 00 00  98 00 00 00 98 00 02 00  |................|
00000060  98 00 02 00 0c 00 00 00  0c 00 00 00 06 00 00 00  |................|
00000070  00 00 01 00 01 00 a0 e3  14 10 9f e5 0c 20 a0 e3  |............. ..|
00000080  04 70 a0 e3 00 00 00 ef  00 00 a0 e3 01 70 a0 e3  |.p...........p..|
00000090  00 00 00 ef 98 00 02 00  5b 5e 2d 5e 5d 20 5b 5e  |........[^-^] [^|
000000a0  30 5e 5d 0a 41 13 00 00  00 61 65 61 62 69 00 01  |0^].A....aeabi..|
000000b0  09 00 00 00 06 01 08 01  00 2e 73 68 73 74 72 74  |..........shstrt|
000000c0  61 62 00 2e 74 65 78 74  00 2e 64 61 74 61 00 2e  |ab..text..data..|
000000d0  41 52 4d 2e 61 74 74 72  69 62 75 74 65 73 00 00  |ARM.attributes..|
000000e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000100  00 00 00 00 00 00 00 00  0b 00 00 00 01 00 00 00  |................|
00000110  06 00 00 00 74 00 01 00  74 00 00 00 24 00 00 00  |....t...t...$...|
00000120  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00000130  11 00 00 00 01 00 00 00  03 00 00 00 98 00 02 00  |................|
00000140  98 00 00 00 0c 00 00 00  00 00 00 00 00 00 00 00  |................|
00000150  01 00 00 00 00 00 00 00  17 00 00 00 03 00 00 70  |...............p|
00000160  00 00 00 00 00 00 00 00  a4 00 00 00 14 00 00 00  |................|
00000170  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00000180  01 00 00 00 03 00 00 00  00 00 00 00 00 00 00 00  |................|
00000190  b8 00 00 00 27 00 00 00  00 00 00 00 00 00 00 00  |....'...........|
000001a0  01 00 00 00 00 00 00 00                           |........|
000001a8

Readelf

pi@pai:~/asm $ readelf -a hello
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x10074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          608 (bytes into file)
  Flags:                             0x5000200, Version5 EABI, soft-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         7
  Section header string table index: 6

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00010074 000074 000024 00  AX  0   0  4
  [ 2] .data             PROGBITS        00020098 000098 00000c 00  WA  0   0  1
  [ 3] .ARM.attributes   ARM_ATTRIBUTES  00000000 0000a4 000014 00      0   0  1
  [ 4] .symtab           SYMTAB          00000000 0000b8 000120 10      5  10  4
  [ 5] .strtab           STRTAB          00000000 0001d8 000051 00      0   0  1
  [ 6] .shstrtab         STRTAB          00000000 000229 000037 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00010000 0x00010000 0x00098 0x00098 R E 0x10000
  LOAD           0x000098 0x00020098 0x00020098 0x0000c 0x0000c RW  0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text
   01     .data
There is no dynamic section in this file.

There are no relocations in this file.

There are no unwind sections in this file.

Symbol table '.symtab' contains 18 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00010074     0 SECTION LOCAL  DEFAULT    1
     2: 00020098     0 SECTION LOCAL  DEFAULT    2
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 FILE    LOCAL  DEFAULT  ABS hello.o
     5: 00020098     0 NOTYPE  LOCAL  DEFAULT    2 msg
     6: 0000000c     0 NOTYPE  LOCAL  DEFAULT  ABS len
     7: 00010074     0 NOTYPE  LOCAL  DEFAULT    1 $a
     8: 00010094     0 NOTYPE  LOCAL  DEFAULT    1 $d
     9: 00020098     0 NOTYPE  LOCAL  DEFAULT    2 $d
    10: 000200a4     0 NOTYPE  GLOBAL DEFAULT    2 _bss_end__
    11: 000200a4     0 NOTYPE  GLOBAL DEFAULT    2 __bss_start__
    12: 000200a4     0 NOTYPE  GLOBAL DEFAULT    2 __bss_end__
    13: 00010074     0 NOTYPE  GLOBAL DEFAULT    1 _start
    14: 000200a4     0 NOTYPE  GLOBAL DEFAULT    2 __bss_start
    15: 000200a4     0 NOTYPE  GLOBAL DEFAULT    2 __end__
    16: 000200a4     0 NOTYPE  GLOBAL DEFAULT    2 _edata
    17: 000200a4     0 NOTYPE  GLOBAL DEFAULT    2 _end

No version information found in this file.
Attribute Section: aeabi
File Attributes
  Tag_CPU_arch: v4
  Tag_ARM_ISA_use: Yes
  ARM ABI is version 5 

Can Delete up to .text and .data !

  pi@pai:~ $ hd hello_pi_no_armattr
  00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
  00000010  02 00 28 00 01 00 00 00  74 00 01 00 34 00 00 00  |..(.....t...4...|
  00000020  e0 00 00 00 00 02 00 05  34 00 20 00 02 00 28 00  |........4. ...(.|
  00000030  05 00 04 00 01 00 00 00  00 00 00 00 00 00 01 00  |................|
  00000040  00 00 01 00 98 00 00 00  98 00 00 00 05 00 00 00  |................|
  00000050  00 00 01 00 01 00 00 00  98 00 00 00 98 00 02 00  |................|
  00000060  98 00 02 00 0c 00 00 00  0c 00 00 00 06 00 00 00  |................|
  00000070  00 00 01 00 01 00 a0 e3  14 10 9f e5 0c 20 a0 e3  |............. ..|
  00000080  04 70 a0 e3 00 00 00 ef  00 00 a0 e3 01 70 a0 e3  |.p...........p..|
  00000090  00 00 00 ef 98 00 02 00  5b 5e 2d 5e 5d 20 5b 5e  |........[^-^] [^|
  000000a0  30 5e 5d 0a                                       |0^].|

Read elf again

pi@pai:~ $ readelf -a hello_pi_no_armattr
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x10074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          224 (bytes into file)
  Flags:                             0x5000200, Version5 EABI, soft-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         5
  Section header string table index: 4
readelf: Error: Reading 0xc8 bytes extends past end of file for section header
readelf: Error: Section headers are not available!

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00010000 0x00010000 0x00098 0x00098 R E 0x10000
  LOAD           0x000098 0x00020098 0x00020098 0x0000c 0x0000c RW  0x10000

There is no dynamic section in this file.

ELF Header

Here’s another look at the ELF Header with Index Letters to help see where stuff actually is:

Position  I    Value
----------------------------------------------------------------------
0-3       A    Magic number - 0x7F, then 'ELF' in ASCII
4         B    1 = 32 bit, 2 = 64 bit
5         C    1 = little endian, 2 = big endian
6         D    ELF Version
7         E    OS ABI - usually 0 for System V
8-15      F    Unused/padding
16-17     G    1 = relocatable, 2 = executable, 3 = shared, 4 = core
18-19     H    Instruction set 
20-23     I    ELF Version
24-27     J    Program entry position
28-31     K    Program header table position
32-35     L    Section header table position
36-39     M    Flags - architecture dependent; see note below
40-41     N    Header size
42-43     O    Size of an entry in the program header table
44-45     P    Number of entries in the program header table
46-47     Q    Size of an entry in the section header table
48-49     R    Number of entries in the section header table
50-51     S    Index in section header table with the section name

NOTE: 0x28 is the instruction set flag number for ARM.

Take a look at how these values are actually laid out in an ARM binary.

          A---------- B- C- D- E-  F----------------------
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
          G---- H---- I----------  J---------- K----------
00000010  02 00 28 00 01 00 00 00  74 00 01 00 34 00 00 00  |..(.....t...4...|
          L---------- M----------  N---- O---- P---- Q----
00000020  e0 00 00 00 00 02 00 05  34 00 20 00 02 00 28 00  |........4. ...(.|
          R---- S---- 
00000030  05 00 04 00

Program Headers [32 bit]

Position I  Value
----------------------------------------------------------------------
0-3      A  Type of segment
4-7      B  The offset in the file that the data for this segment can 
            be found (p_offset)
8-11     C  Where you should start to put this segment in virtual 
            memory (p_vaddr)
12-15    D  Undefined for the System V ABI
16-19    E  Size of the segment in the file (p_filesz)
20-23    F  Size of the segment in memory (p_memsz)
24-27    G  Flags 
         1 = x
         2 = w
         3 = wx
         4 = r
         5 = rx - code segment
         6 = rw - data segment
         7 = rwx
28-31    H  The required alignment for this section (must be a power of 2)

Why are there two program headers?

                      A----------  B---------- C----------
00000034              01 00 00 00  00 00 00 00 00 00 01 00  |................|
          D---------- E----------  F---------- G----------
00000040  00 00 01 00 98 00 00 00  98 00 00 00 05 00 00 00  |................|
          H----------
00000050  00 00 01 00 

                      A----------  B---------- C----------
00000054              01 00 00 00  98 00 00 00 98 00 02 00  |................|
          D---------- E----------  F---------- G----------
00000060  98 00 02 00 0c 00 00 00  0c 00 00 00 06 00 00 00  |................|
          H----------
00000070  00 00 01 00 

Our actual code is still here:

  .text-------------------------------------------------------------------------
                        01 00 a0 e3  14 10 9f e5 0c 20 a0 e3  |............. ..|
  00000080  04 70 a0 e3 00 00 00 ef  00 00 a0 e3 01 70 a0 e3  |.p...........p..|
  00000090  00 00 00 ef 98 00 02 00  5b 5e 2d 5e 5d 20 5b 5e  |........[^-^] [^|
  000000a0  30 5e 5d 0a                                       |0^].|

Deleting the second program header causes it to return zero but no output to terminal. It keeps loading at 0x00000074. Removing the first causes a segfault

The first program header describes the headers and .text, the second describes the data for ‘[^-^] [^0^]\n’. If bin mangling then the second isn’t needed as long as relative address is grabbing the data from the code segment.

Mangling

Now we have an idea of the layout for a barebones ARM binary and can add our code as needed.

So if I add the shellcode for /bin/sh and just append to that binary template with just one program header, what happens? Turns out that’s all you need. Just change the entry point to 54, change the amount of program headers elf.P.

The size at pgm.E and pgm.F don’t even really matter as long as its bigger than the length of the file.

7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 
02 00 28 00 01 00 00 00 54 00 01 00 34 00 00 00 
E0 00 00 00 00 02 00 05 34 00 20 00 01 00 28 00 
05 00 04 00 01 00 00 00 00 00 00 00 00 00 01 00 
00 00 01 00 98 00 00 00 98 00 00 00 05 00 00 00 
00 00 01 00 01 60 8F E2 16 FF 2F E1 40 40 78 44 
0C 30 49 40 52 40 0B 27 01 DF 01 27 01 DF 2F 2F 
62 69 6E 2F 2F 73 68

00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 28 00 01 00 00 00  54 00 01 00 34 00 00 00  |..(.....T...4...|
00000020  e0 00 00 00 00 02 00 05  34 00 20 00 01 00 28 00  |........4. ...(.|
00000030  05 00 04 00 01 00 00 00  00 00 00 00 00 00 01 00  |................|
00000040  00 00 01 00 98 00 00 00  98 00 00 00 05 00 00 00  |................|
00000050  00 00 01 00 01 60 8f e2  16 ff 2f e1 40 40 78 44  |.....`..../.@@xD|
00000060  0c 30 49 40 52 40 0b 27  01 df 01 27 01 df 2f 2f  |.0I@R@.'...'..//|
00000070  62 69 6e 2f 2f 73 68                              |bin//sh|
00000077

119 bytes, smaller than the 147 bytes in shldr of bin/sh in elf64

7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00
02 00 28 00 01 00 00 00 54 00 01 00 34 00 00 00
E0 00 00 00 00 02 00 05 34 00 20 00 01 00 28 00
05 00 04 00 01 00 00 00 00 00 00 00 00 00 01 00
00 00 01 00 

Change the two 98s to the length of the shellcode + 0x54