Reputation: 2441
I have the following ASM code on Debian that I am trying to compile but am having issues with both ld
and gcc
.
uname -a: Linux kali 4.18.0-kali3-amd64 #1 SMP Debian 4.18.20-2kali2 (2018-11-30) x86_64 GNU/Linux
I start off by running: nasm -f elf shellcode.asm
This completes with no issues.
GCC Issue...
Command: gcc -m32 -o key shellcode.o
Error:
/usr/bin/ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0x0): multiple definition of `_start'; /usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib32/Scrt1.o:(.text+0x0): first defined here
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib32/Scrt1.o: in function `_start':
(.text+0x28): undefined reference to `main'
/usr/bin/ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0xbc): relocation truncated to fit: R_386_PC8 against `*UND*'
collect2: error: ld returned 1 exit status
I also tried with ld
.
Command: ld -m elf_i386 -s -o key shellcode.o
Error...
ld: shellcode.o: in function `_start':
shellcode.asm:(.text+0xbc): relocation truncated to fit: R_386_PC8 against `*UND*'
The latter appears to be less full of errors and point to an issue with the ASM syntaxt.
My question then is, which of these commands in the correct one to use and what am I doing wrong?
shellcode.asm
global _start
_start:
xor eax,eax
push eax
push dword 0x76767975
push dword 0x22717172
push dword 0x22737972
push dword 0x77207922
push dword 0x78272079
push dword 0x27277976
push dword 0x77707470
push dword 0x22777272
push dword 0x22277622
push dword 0x79727473
push dword 0x27727377
push dword 0x75747078
push dword 0x70227479
push dword 0x75222073
push dword 0x24747176
push dword 0x74782324
push dword 0x72727320
push dword 0x27762779
push dword 0x20277777
push dword 0x22207573
push dword 0x70247827
push dword 0x70277479
push dword 0x24712379
push dword 0x77742027
push dword 0x76242379
push dword 0x22702270
push dword 0x73762577
push dword 0x24752272
push dword 0x20277172
push dword 0x23712720
push dword 0x72722478
push dword 0x70252723
push esp
pop esi
mov edi,esi
mov edx,edi
cld
mov ecx,0x80
mov ebx,0x41
xor eax,eax
push eax
lodsb
xor eax,ebx
stosb
loop 0xb7
push esp
pop esi
int3
db 0x0a
Upvotes: 0
Views: 252
Reputation: 365332
To build with gcc, you're defining _start
not main
, so you need to use -nostdlib
. Like gcc -m32 -nostdlib -static -o key shellcode.o
. That will make gcc invoke ld
the way you did manually.
loop
is only available with a rel8 displacement, so it can't reach absolute address 0xb7
from the much higher address where ld
places it in the code segment.
If you actually did want to do that (but you almost certainly don't), you could use dec ecx / jnz 0xb7
, which would use a jcc rel32
encoding and thus can reach any absolute address via EIP + rel32
. Or use a linker script to link the TEXT segment at a very low virtual address so loop rel8
can reach.
(But either way that's not position-independent. Normally shellcode is supposed to work after being injected at an unknown address. If you really wanted to jump to an absolute address in position-independent shellcode, like to trigger a specific page fault(?), you'd need the address in a register and use jmp eax
)
But much more likely you wanted to jump to somewhere else in your code, not to some low absolute address. Place a label on your branch target and use dec ecx / jnz label
. (Or use the loop
instruction since you're probably optimizing for code-size regardless of it being slow.)
If you borrowed this code from somewhere, maybe it was in an assembler where loop 0xb7
set the value of the rel8
displacement. Or maybe it was NASM with org 0x0
and BITS 32
making a flat binary? But it would make so much more sense just to use a label if you want to branch back into somewhere in this code.
Upvotes: 2