BITS 32
%define PORT 0x3905 ; TCP port 1337
%define ADDRESS 0x0100007f ; 127.0.0.1
org 0x00010000 ; Memory load location
; ELF HEADER CONTENT PROGRAM HEADER TBL ENTRY CONTENT
; ------------------------------------------------------------------------------------------------------------------
db 0x7f, "ELF" ; magic number: 7f454c46
db 0x01 ; class: 1 (32-bit) type: 1 (Loadable segment)
db 0x00 ; data: 0 (invalid)* |
db 0x00 ; version: 0 (invalid)* |
db 0x00 ; abi: 0 (System V) |
db 0x00 ; abi version: 0 offset: 0 (File offset)
db 0x00 ; padding |
db 0x00 ; | |
db 0x00 ; | |
dd $$ ; | vaddr: $$ (File memory location)
db 0x02 ; type: 2 (Executable) paddr: 0x00030002 *
db 0x00 ; | |
db 0x03 ; machine: 3 (Intel i386 x86) |
db 0x00 ; | |
dd _start ; version: _start (invalid)* filesz: _start (too large)***
dd _start ; entry: _start (Program entry point) memsz: _start ***
db 0x04 ; phoff: 4 (File offset) flags: 4 (READ) ***
db 0x00 ; | |
db 0x00 ; | |
db 0x00 ; | |
sockaddr:
db 0x02 ; shoff: ??? (File offset)** align: ???
db 0x00 ; | |
dw PORT ; | |
dd ADDRESS ; flags: ???
db 0x34 ; ehsize: 52
db 0x00 ; |
db 0x20 ; phentsize: 32
db 0x00 ; |
db 0x01 ; phnum: 1 (.text)
db 0x00 ; |
;db 0x00 ; shentsize: 0** [ Cut these out to overlap with program code ]
;db 0x00 ; |
;db 0x00 ; shnum: 0**
;db 0x00 ; |
;db 0x00 ; shstrndx: 0**
;db 0x00 ; |
; For space savings, the above constructs the ELF metadata for this program
; without invoking an external linker. The ELF header and the program
; header entry completely overlap each other. Some concessions were made to
; allow this to be possible. See the asterisks above and explainations
; below for details.
;
; * Invalid values are present to leverage overloading fields that go
; unchecked by the loader at runtime. Such values are likely being set
; to what is required by the other data structure.
;
; ** Section headers are not utilized by this program, so no relevant
; header fields are utilized. As with (*) fields, these too go
; unchecked by the loader.
;
; *** phoff must be == 4 in this arrangement, therefore program header flags
; just match it. This is fine, as apparently execute is implied in this
; case. However, since the writable bit is not set, we can not set
; memsz larger than filesz (the loader is not able to 'write' the extra
; initializing zero bytes). Therefore, both fields are set to the value
; of the program entry point, so that the entry point field from ELF
; (which coinsides) can be set properly. The fact that filesz will be
; larger than that of the actual output file is of no consequence.
_start:
push 0 ; socket(AF_INET, SOCK_STREAM, 0)
push 1
push 2
mov ecx, esp
mov bl, 0x01
mov al, 0x66
int 0x80
push 16 ; connect(fd, sockaddr, sizeof(sockaddr))
lea ecx, sockaddr
push ecx
push eax
mov ecx, esp
mov bl, 0x03
mov al, 0x66
int 0x80
pop edi ; pipe(fd, stdin)
mov ecx, esp
call pipe
inc esi ; pipe(stdout, fd)
xchg edi, esi
call pipe
xor eax, eax ; exit()
inc eax
int 0x80
pipe_loop:
mov edx, eax ; write(edi, ecx, eax)
mov ebx, edi
mov al, 0x04
int 0x80
pipe:
mov dl, 0xff ; read(esi, ecx, 0xff)
mov ebx, esi
mov al, 0x03
int 0x80
cmp eax, 0 ; eof/error, return
jg pipe_loop
ret