Windows 7 在64位Windows 7上运行时出现微小的Pe文件格式程序错误

Windows 7 在64位Windows 7上运行时出现微小的Pe文件格式程序错误,windows-7,assembly,nasm,portable-executable,Windows 7,Assembly,Nasm,Portable Executable,我正在尝试在Windows7Ultimate64位中运行以下汇编代码(使用Nasm组装) ; tiny.asm BITS 32 ; ; MZ header ; ; The only two fields that matter are e_magic and e_lfanew mzhdr: dw "MZ" ; e_magic dw 0 ; e_cblp UNUSED dw

我正在尝试在Windows7Ultimate64位中运行以下汇编代码(使用Nasm组装)

; tiny.asm

BITS 32

;
; MZ header
;
; The only two fields that matter are e_magic and e_lfanew

mzhdr:
    dw "MZ"                       ; e_magic
    dw 0                          ; e_cblp UNUSED
    dw 0                          ; e_cp UNUSED
    dw 0                          ; e_crlc UNUSED
    dw 0                          ; e_cparhdr UNUSED
    dw 0                          ; e_minalloc UNUSED
    dw 0                          ; e_maxalloc UNUSED
    dw 0                          ; e_ss UNUSED
    dw 0                          ; e_sp UNUSED
    dw 0                          ; e_csum UNUSED
    dw 0                          ; e_ip UNUSED
    dw 0                          ; e_cs UNUSED
    dw 0                          ; e_lsarlc UNUSED
    dw 0                          ; e_ovno UNUSED
    times 4 dw 0                  ; e_res UNUSED
    dw 0                          ; e_oemid UNUSED
    dw 0                          ; e_oeminfo UNUSED
    times 10 dw 0                 ; e_res2 UNUSED
    dd pesig                      ; e_lfanew

;
; PE signature
;

pesig:
    dd "PE"

;
; PE header
;

pehdr:
    dw 0x014C                     ; Machine (Intel 386)
    dw 1                          ; NumberOfSections
    dd 0x4545BE5D                 ; TimeDateStamp UNUSED
    dd 0                          ; PointerToSymbolTable UNUSED
    dd 0                          ; NumberOfSymbols UNUSED
    dw opthdrsize                 ; SizeOfOptionalHeader
    dw 0x103                      ; Characteristics (no relocations, executable, 32 bit)

;
; PE optional header
;

filealign equ 1
sectalign equ 1

%define round(n, r) (((n+(r-1))/r)*r)

opthdr:
    dw 0x10B                      ; Magic (PE32)
    db 8                          ; MajorLinkerVersion UNUSED
    db 0                          ; MinorLinkerVersion UNUSED
    dd round(codesize, filealign) ; SizeOfCode UNUSED
    dd 0                          ; SizeOfInitializedData UNUSED
    dd 0                          ; SizeOfUninitializedData UNUSED
    dd start                      ; AddressOfEntryPoint
    dd code                       ; BaseOfCode UNUSED
    dd round(filesize, sectalign) ; BaseOfData UNUSED
    dd 0x400000                   ; ImageBase
    dd sectalign                  ; SectionAlignment
    dd filealign                  ; FileAlignment
    dw 4                          ; MajorOperatingSystemVersion UNUSED
    dw 0                          ; MinorOperatingSystemVersion UNUSED
    dw 0                          ; MajorImageVersion UNUSED
    dw 0                          ; MinorImageVersion UNUSED
    dw 4                          ; MajorSubsystemVersion
    dw 0                          ; MinorSubsystemVersion UNUSED
    dd 0                          ; Win32VersionValue UNUSED
    dd round(filesize, sectalign) ; SizeOfImage
    dd round(hdrsize, filealign)  ; SizeOfHeaders
    dd 0                          ; CheckSum UNUSED
    dw 2                          ; Subsystem (Win32 GUI)
    dw 0x400                      ; DllCharacteristics UNUSED
    dd 0x100000                   ; SizeOfStackReserve UNUSED
    dd 0x1000                     ; SizeOfStackCommit
    dd 0x100000                   ; SizeOfHeapReserve
    dd 0x1000                     ; SizeOfHeapCommit UNUSED
    dd 0                          ; LoaderFlags UNUSED
    dd 16                         ; NumberOfRvaAndSizes UNUSED

;
; Data directories
;

    times 16 dd 0, 0

opthdrsize equ $ - opthdr

;
; PE code section
;

    db ".text", 0, 0, 0           ; Name
    dd codesize                   ; VirtualSize
    dd round(hdrsize, sectalign)  ; VirtualAddress
    dd round(codesize, filealign) ; SizeOfRawData
    dd code                       ; PointerToRawData
    dd 0                          ; PointerToRelocations UNUSED
    dd 0                          ; PointerToLinenumbers UNUSED
    dw 0                          ; NumberOfRelocations UNUSED
    dw 0                          ; NumberOfLinenumbers UNUSED
    dd 0x60000020                 ; Characteristics (code, execute, read) UNUSED

hdrsize equ $ - $$

;
; PE code section data
;

align filealign, db 0

code:

; Entry point

start:
    push byte 42
    pop eax
    ret

codesize equ $ - code

filesize equ $ - $$
代码取自:

我使用以下命令创建可执行文件:nasm-f bin-o tiny.exe tiny.asm 但是当我试图运行tiny.exe时,我得到一个错误:应用程序无法正确启动(0xc0000018)

另一方面,在WindowsXPSP3上,机器可以完美地运行。你知道哪里不对吗

filealign equ 1
sectalign equ 1
Windows 7加载程序不接受小于512的filealign和小于4096的sectionalign

编辑:


鉴于,对齐限制似乎为4/4。

Windows XP在尺寸上的要求比Vista或更高版本小: 它接受截断的OptionalHeader,而更高版本的Windows会拒绝文件(如果文件不完整)

因此,您只需要添加填充就可以在Vista或更高版本下工作

有关源代码和二进制文件的更多详细信息和示例,请参阅


(这绝对与对齐无关)

防病毒软件混淆了?观察得很好!我在禁用防病毒的情况下进行了测试,得到了相同的错误。所以它一定是另外的东西..我没有一直跟踪它,但在ntdll中!LdrpWx86ProtectImagePages调用NtProtectVirtualMemory时,基址为0x00400160,NumberOfBytesToProtect=0x1000,它跨越两个页面(这是一个问题,因为下一个页面未分配),如果我们将基址更改为0x00400000,则它仅为一个页面,并加载和执行。因此,PE标题中的某些值现在导致不正确的舍入,或者他们修复了Win7中XP中曾经错误的某些内容。感谢您的分析。你使用了什么工具?只是WinDbg和一些位置合适的断点。将事件过滤器->创建进程设置为Enabled,这样它在启动时会中断,然后在LdrpInitialize中设置一些断点,并开始单步执行代码,直到失败。哦,我明白了..谢谢!有没有参考资料可以让我阅读有关Windows 7 PE loader的内容?据我所知,没有,我不相信它有很多文档:)我将filealign的值更改为0x200,将sectalign的值更改为0x1000,现在我收到一条消息:tiny.exe不是有效的Win32应用程序!似乎还存在一个错误……你认为round宏错了吗?@Ponty即使两条路线都有EQU,代码也不支持任意数字。如果你想学习PE格式,我建议你学习一个不太激进的例子。4K通常会将代码部分设置为完全重叠标题,并且只使用一个部分,因此减少了对低对齐的需要。我不知道使用e_lfanew=4的程序是否正常工作,但很多以前正常工作的程序已经不工作了。我刚刚查看了最近的4k,它使用elfanew=12、sectionalignment=65536和filealignment=512。