Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
;name: downloadfile.asm
;description: demo on downloading a file
;build: nasm -felf64 -Fdwarf -g -l downloadfile.lst downloadfile.asm -o downloadfile.o
;       ld -g -melf_x86_64 downloadfile.o -o downloadfile
;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    (at your option) any later version.
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    GNU General Public License for more details.
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <>
bits 64

%include ""

global _start

section .bss

section .data
    httpheader:     db  'Content-type: application/octet-stream', 10
                    db  'Content-Disposition: attachment; filename="logo.png"', 10, 10
    .length:        equ $-httpheader
    response:       db  'Content-type: text/html', 10, 10
                    db  '<span>the file was not found</span>', 10
    .length:        equ $-response
    filename:       db  'downloads/logo.png',0    ; put it wherever you want, just keep track of the right location in your path
    errorfile:      db  '[downloadfile] $[CGIROOT]/downloads/logo.png not found error', 10
    .length:        equ $-errorfile
    errorNoMemory:  db  '[downloadfile error] out of memory error', 10     ; this message will be written to the Apache error log
    .length:        equ $-errorNoMemory
    STAT stat      ;STAT structure instance for FSTAT
section .text

    ; open the file and get filedescriptor
    syscall open,filename,O_RDONLY
    and     rax,rax
    js      .error                          ;error, file doesn't exists
    mov     r15,rax                         ;save filedescriptor
    ; read the filesize
    syscall fstat,r15,stat
    ; get memory break
    syscall brk,0
    and     rax,rax
    jle     .errormemory                    ;no memory available to allocate
    mov     r14,rax                         ;save pointer to memory break
    add     rax,qword[stat.st_size]         ;add filesize to allocate memory
    ; try to allocate additional memory
    syscall brk,rax
    cmp     rax,rdi                         ;new memory break equal to calculated one?
    jne     .error                          ;not enough memory available
    ; read the file in the allocated memory
    syscall read,r15,r14,qword[stat.st_size]
    ; close the file
    syscall close,r15
    ; write the HTTP header
    syscall write,stdout,httpheader,httpheader.length
    ; write the filecontents
    syscall write,stdout,r14,qword[stat.st_size]
    ; release allocated memory
    syscall brk,r14
    ; exit the program
    syscall exit,0

    mov     rsi,errorNoMemory
    mov     rdx,errorNoMemory.length
    jmp     .tologfile
    mov     rsi,response
    mov     rdx,response.length
    syscall write,stdout                    ;to web client
    mov     rsi,errorfile
    mov     rdx,errorfile.length
    syscall write,stdout                    ;to Apache log file
    jmp     .exit
%define _downloadfile_inc_

%include ""
%include ""

%endif 		;; _downloadfile_inc_

<head> <title>CGI - Download file</title> </head> <body> <form method="post" action="/cgi-bin/downloadfile"> <pre><h1>Download file</h1> <button type="submit" name="submit">download file</button> </form> </body> </html>