如何用绒毛填充马洛克缓冲液?



对长代码表示歉意,但与汇编程序一样:

SECTION .text       ; code
extern _fclose
extern _fopen
extern _fread
extern _fseek
extern _ftell
extern _malloc
extern _printf
global _main
_main:
;   stash base stack pointer
push    ebp
mov     ebp,    esp
push    DWORD   fname
push    DWORD   mopf
push    DWORD   mcls
call    _printf
add     esp,    12          ; clean up stack use
;   open file
push    DWORD   fread
push    DWORD   fname
call    _fopen
add     esp,    8
cmp     eax,    0
jnz     .valid
push    DWORD   mfnf
push    DWORD   mopf
jmp     .error
.valid:
mov     [fh],   eax
;   output result
push    DWORD   [fh]
push    DWORD   mopf
push    DWORD   mret
call    _printf
add     esp,    12
push    DWORD   [fh]
push    DWORD   mskf
push    DWORD   mcld
call    _printf
add     esp,    12
;   C:
;   fseek(fp, 0L, SEEK_END);    ; set up constants: SEEK_END, SEEK_SET, etc.
push    DWORD   [SEEK_END]
push    DWORD   0               ; 0L
push    DWORD   [fh]            ; f_hndl
call    _fseek                  ; ret [eax]: 0 okay; otherwise 1
add     esp,    12              ; reset stack pointer
cmp     eax,    0
je      .success
push    DWORD   mske
push    DWORD   mskf
jmp     .error
.success:
;   output result
push    DWORD   eax
push    DWORD   mskf
push    DWORD   mret
call    _printf
add     esp,    12
;   C:
;   sz = ftell(fp);             ; result to eax
push    DWORD   [fh]
call    _ftell
add     esp,    4
mov     [fsz],  eax
;   output result
push    DWORD   [fsz]
push    DWORD   mszf
push    DWORD   mcld
call    _printf
add     esp,    12
;   allocate buffer
;   C:
;   p* = malloc(size)
push    DWORD   [fsz]
call    _malloc
add     esp,    4
mov     DWORD[buffer],    eax
;   read file
;   size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
push    DWORD   [fh]
push    DWORD   1
push    DWORD   [fsz]
push    DWORD   [buffer]
call    _fread
add     esp,    16
push    DWORD   eax
push    DWORD   mrdf
push    DWORD   mcld
call    _printf
add     esp,    12
jmp     .done
.error:
push    DWORD   merr
call    _printf
add     esp,    12
.done:
push    DWORD   [fh]
call    _fclose
push    DWORD   eax
push    DWORD   mclf
push    DWORD   mcld
call    _printf
add     esp,    16
;   restore base stack pointer
mov     esp,    ebp
pop     ebp
ret
SECTION .bss        ; uninitialized data
fh:     resd    1
fsz:    resd    1
buffer: resb    20

电流输出:

[FILE]调用[open]:d:\asplus\tsources\s1.txt
[FILE]ret[open]:2002397536
[FILE]调用[seek]:2002398536
[FILE]ret[seek]:0
[FILE]调用[size]:6
[FILE]呼叫[read]:0
[FILE]调用[close]:0

根据@Michael的响应校正输出
我添加了一个额外的输出(上面的代码中没有显示),它产生以下结果:

[FILE]ret[╨9=]:6

。。。其遵循CCD_ 1调用:

push    DWORD   [fsz]
push    DWORD   [buffer]
push    DWORD   mret
call    _printf
add     esp,    12

显然,[fsz]的正确值从6(字节)变为[buffer]的长度(20字节)加2。

基于定义size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream),我期望EAX包含读取的字节数。

相对片段:

;   allocate buffer
;   C:
;   p* = malloc(size)
push    DWORD   [fsz]
call    _malloc
add     esp,    4
mov     DWORD[bfr],    eax
;   read file
;   size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
push    DWORD   [fh]      ; FILE* stream (file handle)
push    DWORD   1         ; size_t nmemb
push    DWORD   [fsz]     ; size_t size
push    DWORD   [buffer]  ; void* ptr (buffer previously malloc'd)
call    _fread
add     esp,    16

我从这里的描述中推测:

参数:
*ptr--这是指向最小大小内存块的指针大小为*nmmb字节
*size--这是要读取的每个元素的大小(以字节为单位)
*nmemb——这是元素的数量,每个元素的大小为字节
*stream——这是指向指定输入流的FILE对象的指针。

。。。CCD_ 6将是1字节(字符大小),而CCD_。

首先调用和分配malloc'd缓冲区,然后用对fread的调用填充缓冲区,我做错了什么?

更新
在添加代码以查找回源文件的开头后,我正在读取字节。然而,现在似乎有一些事情引发了几个问题。这是输出:

[FILE]调用[读取]:1
[FILE]ret[1+2;r]:6

文件s1.txt包含fread0,在第2行正确报告了6个字节。但fread显然报告它只读取1个字节?我应该在对fread的调用中使用fsz+1来消除[1 + 2;r]中的r吗?

在读取文件之前,您似乎没有找到文件的开头。因此,如果您尝试从末尾读取,您将获得0个字节。

即。加载项:

push    DWORD   0               ; SEEK_SET = 0
push    DWORD   0               ; 0L
push    DWORD   [fh]            ; f_hndl
call    _fseek                  ; ret [eax]: 0 okay; otherwise 1
add     esp,    12              ; reset stack pointer

文件s1.txt包含1+2;正确报告的是6个字节第二行。但fread显然报告说它只读1字节

否,fread报告它读取了1个结构,共6个字节。你可能想要这个:

push    DWORD   [fh]
push    DWORD   [fsz]
push    DWORD   1                ; Note.. swapped!!!
push    DWORD   [buffer]
call    _fread
add     esp,    16

对于缓冲区末尾的字节,您正在从文件中读取6个字节,但printf需要一个以null结尾的字符串。如果要修复此问题,请分配一个额外的字节空间,并在调用printf之前将最后一个字节设置为"\0"。

来自printf:的文档

返回值
成功时,将返回写入的总字符数。

基于此,此代码不正确:

call    _printf
add     esp,    12
mov     [fsz],  eax

fsz中保存的是printf的返回值,即字符串"[FILE] call [size]: 6"的长度。

相关内容

  • 没有找到相关文章

最新更新