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
Generic AT Commands