summaryrefslogblamecommitdiffstats
path: root/lace_x86.asm
blob: 12fc1b018f8f2778ba32fc6f3f027521d22d1bdd (plain) (tree)






































































                                                                                                                        

                                             
                        





                                          
                
 
                                                                   
















                                                         
                                                                   











                                          
                                              
               

                

                                               











                                                       
                                                   










                                              
                    

                  
BITS 32

    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            ; |                                                 |
    db      0x00            ; shoff:        0 (File offset)**                   align:      0 (No alignment constraints)
    db      0x00            ; |                                                 |
    db      0x00            ; |                                                 |
    db      0x00            ; |                                                 |
    db      0x00            ; flags:        0
    db      0x00            ; |
    db      0x00            ; |
    db      0x00            ; |
    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:
    xor     edx, edx    ; open(argv[1], 0, 0)
    xor     ecx, ecx
    mov     ebx, [esp+8]
    xor     eax, eax
    mov      al, 5
    int     0x80

    cmp     eax, 0      ; if fail, exit(1)
    mov      bl, 1
    jl      exit

    mov      dl, 16     ; read(argv[1], sockaddr, sizeof(sockaddr))
    mov     ecx, esp
    mov     ebx, eax
    mov      al, 3
    int     0x80

    cmp     eax, 16     ; if fail, exit(2)
    mov      bl, 2
    jne     exit

    push    0           ; socket(AF_INET, SOCK_STREAM, 0)
    push    1
    push    2
    mov     ecx, esp
    mov      bl, 1
    mov      al, 0x66
    int     0x80

    push    16          ; connect(sock, sockaddr, sizeof(sockaddr))
    lea     ecx, [esp+16]
    push    ecx
    push    eax
    mov     ecx, esp
    mov      bl, 3
    mov      al, 0x66
    int     0x80

    cmp     eax, 0      ; if fail, exit(3)
    mov      bl, 3
    jne     exit

    xor     esi, esi    ; pipe(sock_fd, stdin)
    pop     edi
    call    pipe

    inc     esi         ; pipe(stdout, sock_fd)
    xchg    edi, esi
    call    pipe

    xor     ebx, ebx    ; exit(0)
    jmp     exit

pipe:
    mov      dl, 0xff   ; read(src, buff, sizeof(buff))
    lea     ecx, [esp+4]
    mov     ebx, esi
    mov      al, 3
    int     0x80

    cmp     eax, 0      ; if finished/error, return
    jg      pipe_cont
    ret

pipe_cont:
    mov     edx, eax    ; write(dst, buff, nb)
    mov     ebx, edi
    mov      al, 4
    int     0x80
    jmp     pipe        ; loop

exit:
    xor     eax, eax
    mov      al, 1
    int     0x80