【问题标题】:Read/write blocks to file in assembly读/写块到汇编中的文件
【发布时间】:2015-12-14 22:07:31
【问题描述】:

我必须编写应该以 64 字节块从 .txt 文件中读取文本的代码,加密每个块,然后将其写入另一个 .txt 文件。现在,我希望能够读取 64 字节块并写入它们,而无需对目标文件进行任何更改。我知道我的代码存在很多问题,但我不知道如何解决它们,因此非常感谢任何帮助和建议。这是我设法做到的。

.386
.model flat, stdcall

includelib msvcrt.lib
extern exit: proc
extern printf: proc
extern scanf: proc
extern fscanf: proc
extern fprintf: proc
extern fopen: proc
extern fclose: proc

public start


.data

  type_read db "r",0

  type_write db "w", 0

  destination db "destination.txt",0      ;name of destination file
  fscanf_format db "%lld",0 
  fprintf_format db "%lld",0

  msg_start db "Source file path:",0

  source dd 0  ;name of source file
  source_format db "%s", 0
  block64 dq 0
  pointer_source db 0
  pointer_destination dd 0

.code

start:
    mov eax,0
    push offset msg_start
    call printf
    add esp,4

    ; read name source file
    push  offset source
    push offset source_format
    call scanf
    add esp,8

    ; open source file
    push offset type_read
    push offset sursa
    call fopen
    add esp,8
    mov pointer_source,eax  ;save source pointer eax

    ; open destination file
    push offset type_write
    push offset destination
    call fopen
    add esp,8
    mov pointer_destination,ebx

    reading:
    ;file reading
    push    offset block64           ;offset of qword variable
    push    offset fscanf_format     ;format string "%lld",0
    push    pointer_source            ;file pointer
    call    fscanf
    add     esp,16

    ;i tried to write what i've read to file destination.txt but i am not sure how to
    pop     ebx
    sub     esp,8

    cmp eax,0ffffffffh;end of file?
    je finish
    end reading

    finish:
    push 0
    call exit
    end finish

end start

【问题讨论】:

  • 您的问题有被关闭的危险。您可能需要重新阅读有关如何正确提出问题的说明,尤其是在清楚地描述问题以及您到目前为止所做的事情时。 “这不起作用,告诉我为什么”甚至还没有接近。 :)
  • 显然这是作业。你应该只使用C库吗?如果是这样,则在二进制文件上使用 fopen/fread/frwite 进行 I/O。 scanf/fscanf 解析输入数据,所以你只想用它来获取文件名(或者更好,将文件名作为命令行参数)。
  • @DavidHoelzer OP 提供了程序要做什么的描述,完整的源代码 [主要工作,AFAICT],并在代码注释中描述了他具体遇到问题的行。如果他将评论提升到帖子顶部,那一切都会好起来的。但是,对于任何 asm 人来说,已经有足够的信息来给出答案 [他得到了一个]。随着 1 分的发布,我看到的情况要糟糕得多。
  • @CraigEstey 我是一名装配人员。我不必费力地通过代码来弄清楚“我知道我的代码存在很多问题,但我不知道如何解决它们”的含义。这对我来说不是一个明确的问题陈述。 :) 对不起,如果我冒犯了。
  • 我要质疑的是第 3 方 (David Tansey) 将 64 位块更改为 64 字节块。如果是 OP 做出改变,我可能会理解。我有点不清楚 OP 想要回答的原始问题是什么。

标签: assembly masm


【解决方案1】:

更新,问题已从 64 位块更改为 64 字节块,显然是由第三人(请参阅问题后的 cmets,或查看编辑历史记录)。下面两个例子,一个用于 64 位使用 fscanf / fprintf,一个用于 64 字节块使用 fread / fwrite。

没有解释要使用哪种加密方案。这可能会影响每个块的字节数,例如 AES,它处理 16 字节块(较小的块必须填充到 16 字节)。

使用 Microsoft masm (ml.exe) 进行 64 位复制的工作示例。

        .data
block64 dd      0,0                     ;two dd's for 64 bits
pointer_source dd 0                     ;source FILE * value
pointer_destination dd 0                ;dest   FILE * value

msg_start   db "Source file path:",0
source      db "                "       ;name of source file (read in)
destination db "destination.txt",0      ;name of destination file
fscanf_format db "%lld",0 
fprintf_format db "%lld",10,0           ;added new line
source_format db "%s", 0
type_read db "r",0
type_write db "w", 0
        .code
        ; ...
        push    offset msg_start
        call    printf
        add     esp,4

        ; read name source file
        push    offset source
        push    offset source_format
        call    scanf
        add     esp,8

        ; open source file
        push    offset type_read
        push    offset source
        call    fopen
        add     esp,8
        mov     pointer_source,eax      ;save source FILE *

        ; open destination file
        push    offset type_write
        push    offset destination
        call    fopen
        add     esp,8
        mov     pointer_destination,eax ;save destination FILE *

reading:
        push    offset block64
        push    offset fscanf_format
        mov     eax,pointer_source      ;push file pointer value
        push    eax
        call    fscanf
        add     esp,12                  ;restore esp
        cmp     eax,0ffffffffh          ;br if end of file
        je      finish
        mov     eax,block64+4           ;push 64 bit block
        push    eax                     ;   
        mov     eax,block64             ;
        push    eax                     ;
        push    offset fprintf_format   ;push ptr to format string
        mov     eax,pointer_destination ;push file pointer value
        push    eax                     ;
        call    fprintf                 ;print value
        add     esp,16                  ;restore esp
        jmp     short reading           ;short is optional
;
finish:
        mov     eax,pointer_destination ;push file pointer value
        push    eax                     ;
        call    fclose                  ;close file
        add     esp,4
        mov     eax,pointer_source      ;push file pointer value
        push    eax
        call    fclose                  ;close file
        add     esp,4
        push    dword ptr 0             ;(masm needs dword ptr)
        call    exit

64 字节块复制示例。

        .data
block64 db      64 dup (0)              ;64 byte buffer
pointer_source dd 0                     ;source FILE * value
pointer_destination dd 0                ;dest   FILE * value

msg_start   db "Source file path:",0
source      db "                "       ;name of source file (read in)
destination db "destination.txt",0      ;name of destination file
source_format db "%s", 0
type_read db "rb",0                     ;read binary
type_write db "wb", 0                   ;write binary
        .code
        ; ...
        push    offset msg_start
        call    printf
        add     esp,4

        ; read name source file
        push    offset source
        push    offset source_format
        call    scanf
        add     esp,8

        ; open source file
        push    offset type_read
        push    offset source
        call    fopen
        add     esp,8
        mov     pointer_source,eax      ;save source FILE *

        ; open destination file
        push    offset type_write
        push    offset destination
        call    fopen
        add     esp,8
        mov     pointer_destination,eax ;save destination FILE *

reading:
        mov     eax,pointer_source      ;push FILE * value
        push    eax
        push    dword ptr 64            ;count
        push    dword ptr 1             ;size
        push    offset block64          ;ptr to buffer
        call    fread                   ;read 64 bytes (or less)
        add     esp,16                  ;restore esp
        test    eax,eax                 ;br if end file
        je      finish
        mov     ebx,pointer_destination ;push file pointer value (ebx)
        push    ebx                     ;
        push    eax                     ;count
        push    dword ptr 1             ;size
        push    offset block64          ;ptr to buffer
        call    fwrite                  ;write 64 bytes (or less)
        add     esp,16                  ;restore esp
        jmp     short reading           ;short is optional
;
finish:
        mov     eax,pointer_destination ;push file pointer value
        push    eax                     ;
        call    fclose                  ;close file
        add     esp,4
        mov     eax,pointer_source      ;push file pointer value
        push    eax
        call    fclose                  ;close file
        add     esp,4
        push    dword ptr 0
        call    exit

【讨论】:

  • 知道为什么这被[不是我]否决了吗?是否在解释代码如何从 OP 更改的代码之外缺少冗长的措辞?或者,因为它被认为是在回答家庭作业[其中大部分,加密,要写]?您已经添加了足够多的代码 cmets 应该清楚的地方。
  • 没有 cmets 的否决票 - SO 的无用功能。我已经不在乎这些了。这是一个工作示例(我对此进行了测试)。
  • 我相信你做到了,而且你已经得到了适当的奖励 ;-)
  • 没有什么比评论少反对票更糟糕的了。我希望我们能投反对票。
  • 第三人将问题从 64 位块更改为 64 字节块(有关原始问题,请参阅 cmets 或查看编辑历史记录)。我举了两个例子。也许downvote与64位/字节混淆有关,现在已经消失了。
猜你喜欢
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
  • 2016-07-22
  • 2018-05-03
相关资源
最近更新 更多