如何将具有ReadFile的文件读入NASM x86程序集中的堆栈?

时间:2015-07-07 15:03:49

标签: winapi assembly x86 nasm

我已经用OpenFile打开了一个文件,并用GetFileSize获得了它的大小。我希望使用ReadFile并使用堆栈作为它所需的缓冲区,在堆栈上分配足够的空间和GetFileSize返回的文件大小。当我运行它时,我没有输出。

这是我的代码......

extern GetStdHandle
extern GetModuleFileNameA
extern OpenFile
extern ReadFile
extern WriteFile
extern CloseHandle
extern GetFileSize
extern ExitProcess

import GetStdHandle kernel32.dll
import GetModuleFileNameA kernel32.dll
import OpenFile kernel32.dll
import ReadFile kernel32.dll
import WriteFile kernel32.dll
import CloseHandle kernel32.dll
import GetFileSize kernel32.dll
import ExitProcess kernel32.dll

global ..start

segment .code USE32

..start:

;Setting up the stack...
push ebp
mov ebp, esp

;Get standard output to console
push dword -11
call [GetStdHandle]
mov dword [hStdOut], eax

;Get filepath...
push dword filepath
push dword 0
call [GetModuleFileNameA]

;Outputting filepath
;Doesn't show up on the console but if you dump it to a file
;and edit it it is there...
;push dword 0
;push dword bytesRead
;push dword 128 ;Maximum path size for OpenFile...
;push dword filepath
;push dword [hStdOut]
;call [WriteFile]

;Opening the file and getting the handle...
push dword 0
push dword ofstruct
push dword filepath
mov dword [hSelfFile]

;Getting the file size...
push dword 0
push dword hSelfFile
call [GetFileSize]
mov dword [fSize], eax

;Allocating data on the stack...
sub esp, fSize

;Reading the file...
push dword 0
push dword bytesRead
push dword fSize
push dword ebp ;ebp or esp?
push dword [hSelfFile]
call [ReadFile]

;Outputting the read file...
push dword 0
push dword bytesRead
push dword fSize
push dword ebp ;ebp or esp?
push dword [hStdOut]
call [WriteFile]

;Closing the file handle...
push dword hSelfFile
call [CloseHandle]

;Cleaning up the stack...
mov esp, ebp
pop ebp

xor eax, eax
push eax
call [ExitProcess]

segment .data

segment .bss

hStdOut resd 1
hSelfFile resd 1
bytesRead resd 1
ofstruct resb 136 ;The size in bytes of ofstruct
fSize resd 1
filepath resb 128 ;Maximum path OpenFile will allow

我做错了什么?

1 个答案:

答案 0 :(得分:2)

的malloc?当存在属于Windows的内存函数时,为什么要链接到C库?

除了代码中的所有错误之外,您确实意识到您正在尝试打开可执行文件并将内容打印到控制台?你不能这样做(你可以,但你不会得到任何漂亮的东西)因为exes包含不可打印的字符,你会在屏幕上看到很多垃圾。

下面是一些示例代码,它将在exes目录中打开一个文本文件,获取大小,分配一些内存来保存文件,读取文件,并将内容显示到控制台。

此处绝对没有错误检查,您当然会在普通应用中添加错误检查。

创建一个名为test.txt的文本文件并将其保存在exes目录中。您可以使用此测试所需的任何文本填充此文件。我选择使用培根lorem ipsum发生器,因为我喜欢培根: - )

%define STD_OUTPUT_HANDLE -11
%define OPEN_EXISTING 3
%define NULL 0
%define HEAP_ZERO_MEMORY 8
%define FILE_READ_DATA 1

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
section .bss
hConOut         resd 1
lpBytesWritten  resd 1
hSelfFile       resd 1
hHeap           resd 1
lpFileSize      resd 1
hReadBuf        resd 1

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
section .data
szTestFile      db 'test.txt', 0
szCRLF          db 13, 10 

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global Start
section .text
Start:    
    call    GetProcessHeap                  ; get handle to apps heap
    mov     [hHeap], eax        

    push    STD_OUTPUT_HANDLE               ; um, self explanitory
    call    GetStdHandle
    mov     [hConOut], eax

    push    NULL
    push    NULL
    push    OPEN_EXISTING
    push    NULL
    push    0
    push    FILE_READ_DATA
    push    szTestFile
    call    CreateFileA                     ; Let's open the damn file
    mov     [hSelfFile], eax   

    push    NULL
    push    eax
    call    GetFileSize                     ; well, get the size of file to read
    add     eax, 1
    mov     [lpFileSize], eax

    push    eax
    push    HEAP_ZERO_MEMORY
    push    dword [hHeap]
    call    HeapAlloc                       ; now allocate some memory to hold contents
    mov     [hReadBuf], eax

    push    NULL
    push    lpBytesWritten
    push    dword [lpFileSize]
    push    dword [hReadBuf]
    push    dword [hSelfFile]
    call    ReadFile                        ; slurp it into memory

    push    dword [hSelfFile]
    call    CloseHandle                     ; don't need anymore

    push    NULL
    push    lpBytesWritten 
    push    dword [lpFileSize]
    push    dword [hReadBuf]
    push    dword [hConOut]
    call    WriteFile                       ; print to console

    push    NULL
    push    lpBytesWritten 
    push    2
    push    szCRLF                          
    push    dword [hConOut]
    call    WriteFile                       ; "display carrage return/linefeed"

    push    NULL
    push    hReadBuf
    call    HeapFree                        ; free the our buffer memory

    push    0
    call    ExitProcess

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
extern GetStdHandle
extern CreateFileA
extern ReadFile
extern WriteFile
extern CloseHandle
extern GetFileSize
extern ExitProcess
extern GetProcessHeap
extern HeapAlloc
extern HeapFree