You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows 64位NASM文件读写异常:文件创建后为空无法写入

文件创建后无法写入的问题修复

问题描述

文件已创建但无法写入,程序执行到写入阶段时略有卡顿,预期生成包含内容的文件,但实际生成的是空文件。

原代码

DEFAULT REL

global main

extern CreateFileA
extern CloseHandle
extern WriteFile

section .data 
    filename db "f.txt", 0

section .text 
main: 
    sub rsp, 48h

    mov rcx, filename   
    mov dword [rsp+40], 40000000h | 2 
    xor r9d, r9d       
    xor r8d, r8d      
    mov dword [rsp+32], 2 
    mov edx, 2
    сall CreateFileA
    
    mov rdx, rax
    
    mov rcx, rdx
    lea rdx, [filename]
    mov r8, 6
    mov r9, 0
    call WriteFile
    
    mov rcx, rdx
    call CloseHandle
    
    xor eax,eax 
    add rsp, 48h
    ret

错误分析与修复

1. 语法与调用约定错误

  • 替换俄文с为英文c:原代码中сall CreateFileA的с是俄文字符,会导致汇编器识别失败,需改为标准英文指令call。
  • 修正CreateFileA参数布局:Windows x64调用约定要求前4个参数用RCX、RDX、R8、R9传递,剩余参数从右往左放入栈中(栈需16字节对齐)。原代码参数位置完全混乱,正确的参数对应:
    • RCX:文件名(原代码正确)
    • RDX:访问权限,设为GENERIC_WRITE即40000000h
    • R8:共享模式,设为FILE_SHARE_WRITE即2
    • R9:安全属性,设为NULL即0
    • [rsp+32]:创建方式,设为CREATE_ALWAYS即2
    • [rsp+40]:文件属性,设为FILE_ATTRIBUTE_NORMAL即80h
    • 原代码中mov dword [rsp+40], 40000000h | 2的位或操作不符合汇编语法,需直接使用合并后的值40000002h或提前用or指令计算。

2. WriteFile参数缺失与句柄丢失

  • 补充第五个参数:Windows x64下调用WriteFile必须显式传入第五个参数(重叠结构指针),即使设为NULL也要放在[rsp+32]位置,否则会栈不平衡导致调用失败。
  • 保护文件句柄:原代码将CreateFileA返回的句柄存在RDX,但WriteFile调用时RDX被用作缓冲区参数,导致后续CloseHandle传入的是缓冲区地址而非句柄,需将句柄保存到RBX这类不会被覆盖的寄存器。
  • 添加写入字节数指针:WriteFile的第四个参数需要传入指针接收实际写入字节数,不能直接传0,需在.bss段分配变量存储该值。

修复后的代码

DEFAULT REL

global main

extern CreateFileA
extern CloseHandle
extern WriteFile

section .data 
    filename db "f.txt", 0

section .bss
    bytes_written resd 1  ; 存储实际写入字节数

section .text 
main: 
    sub rsp, 48h  ; 16字节对齐,预留参数空间

    ; 调用CreateFileA创建/打开文件
    mov rcx, filename                ; 参数1: 文件名
    mov rdx, 40000000h               ; 参数2: GENERIC_WRITE
    mov r8, 2                        ; 参数3: FILE_SHARE_WRITE
    xor r9, r9                       ; 参数4: NULL 安全属性
    mov dword [rsp+32], 2            ; 参数5: CREATE_ALWAYS
    mov dword [rsp+40], 80h          ; 参数6: FILE_ATTRIBUTE_NORMAL
    call CreateFileA

    ; 检查句柄是否有效(INVALID_HANDLE_VALUE = -1)
    cmp rax, -1
    je cleanup

    mov rbx, rax                     ; 保存文件句柄到RBX

    ; 调用WriteFile写入内容
    mov rcx, rbx                     ; 参数1: 文件句柄
    lea rdx, [filename]              ; 参数2: 写入缓冲区(这里写入"f.txt")
    mov r8, 6                        ; 参数3: 写入字节数(含终止0)
    mov r9, bytes_written            ; 参数4: 实际写入字节数指针
    mov qword [rsp+32], 0            ; 参数5: NULL 重叠结构
    call WriteFile

cleanup:
    ; 关闭文件句柄
    mov rcx, rbx
    call CloseHandle

    xor eax, eax 
    add rsp, 48h
    ret

内容的提问来源于stack exchange,提问作者dtroyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 03:57:43