【问题标题】:procedure entry point MessageBoxA could not be located when importing from dll in a custom PE file从自定义 PE 文件中的 dll 导入时找不到过程入口点 MessageBoxA
【发布时间】:2021-06-19 19:31:43
【问题描述】:

我一直在尝试掌握 PE 文件格式(只是为了自学一些新知识)并尝试创建一个简单的.exe,它显示一个消息框然后退出,我使用了tinyPE作为基础,然后使用格式上的microsoft docs 中的内容在其之上构建。

问题是,当我尝试运行它时,我得到一个The procedure entry point MessageBoxA could not be located in the dynamic link library D:\path\to\my\test.exe 弹出窗口(这听起来像是 windows 试图从 exe 本身导入函数,但我不明白它为什么会这样做)

我尝试重新排列内容并使用标题,但没有任何帮助。我还使用 PE Explorer 检查了导入,但它似乎正确读取了导入并说它应该按预期从kernel32.dll 导入

这是我的代码:

bits 32

align 1, db 0

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

pe_header:
    dd "PE"
    dw 0x014C                     ; Machine (Intel 386)
    dw 2                          ; NumberOfSections
    dd 0x4545BE5D                 ; TimeDateStamp
    dd 0                          ; PointerToSymbolTable
    dd 0                          ; NumberOfSymbols
    dw pe_optional_header_size    ; SizeOfOptionalHeader
    dw 0x103                      ; Characteristics (no relocations, executable, 32 bit)

pe_optional_header:
    dw 0x10B                      ; Magic (PE32)
    db 8                          ; MajorLinkerVersion
    db 0                          ; MinorLinkerVersion
    dd text_size                  ; SizeOfCode
    dd 0                          ; SizeOfInitializedData
    dd 0                          ; SizeOfUninitializedData
    dd _main                      ; AddressOfEntryPoint
    dd text_begin                 ; BaseOfCode
    dd filesize                   ; BaseOfData
    dd 0x400000                   ; ImageBase
    dd 1                          ; SectionAlignment
    dd 1                          ; FileAlignment
    dw 4                          ; MajorOperatingSystemVersion
    dw 0                          ; MinorOperatingSystemVersion
    dw 0                          ; MajorImageVersion
    dw 0                          ; MinorImageVersion
    dw 4                          ; MajorSubsystemVersion
    dw 0                          ; MinorSubsystemVersion
    dd 0                          ; Win32VersionValue
    dd filesize                   ; SizeOfImage
    dd header_total_size          ; SizeOfHeaders
    dd 0                          ; CheckSum
    dw 2                          ; Subsystem (Win32 GUI)
    dw 0x400                      ; DllCharacteristics
    dd 0x100000                   ; SizeOfStackReserve
    dd 0x1000                     ; SizeOfStackCommit
    dd 0x100000                   ; SizeOfHeapReserve
    dd 0x1000                     ; SizeOfHeapCommit
    dd 0                          ; LoaderFlags
    dd 4                          ; NumberOfRvaAndSizes

rva:
    dd 0
    dd 0
    dd import_dir_table
    dd import_dir_table_size
    times 12 dd 0, 0              ; This is necessary for a valid executable, probably as padding

pe_optional_header_size equ $ - pe_optional_header

; Section table
text_section:
    db ".text", 0, 0, 0           ; Section name
    dd text_size                  ; Size when loaded
    dd header_total_size          ; Adress when loaded
    dd text_size                  ; Size
    dd text_begin                 ; Points to section beginning
    dd 0, 0                       ; Pointer to relocations and line numbers
    dw 0, 0                       ; Count of relocations and line numbers
    dd 0x60000020                 ; Characteristics
rdata_section:
    db ".rdata", 0, 0             ; Section name
    dd rdata_size                 ; Size when loaded
    dd rdata_begin                ; Adress when loaded
    dd rdata_size                 ; Size
    dd rdata_begin                ; Points to section beginning
    dd 0, 0                       ; Pointer to relocations and line numbers
    dw 0, 0                       ; Count of relocations and line numbers
    dd 0x40000040                 ; Characteristics
    
header_total_size equ $ - $$

; .text section
text_begin:
; Entry function
_main:
    ; try to call the imported function
    push dword 0
    push dword mbox_message + 0x400000 
    push dword 0
    push dword 1
    call [import_adress_table + 0x400000]
    
    mov eax, 42
    ret

text_size equ $ - text_begin

; .rdata section
rdata_begin equ $ - $$

import_dir_table:
    dd import_lookup_table                    ; Import lookup table
    dd 0, 0                                   ; Timestamp and forwarder chain, unused
    dd kernel32                               ; Name of dll
    dd import_adress_table                    ; Import adress table

    ; Empty entry to signify end of import dir table
    dd 0, 0, 0, 0, 0

import_dir_table_size equ $ - import_dir_table

; Like the lookup table, but entries are replaced
; with real adresses of imported functions
import_adress_table:
    dd namehint_table
    dd 0

; Stores DWORD pointers to Name/Hint tables
import_lookup_table:
    dd namehint_table
    dd 0

; Stores a hint (?) and a function name to import
namehint_table:
    db 0, 0
    db "MessageBoxA", 0   ; Function name
    
; String used to import the kernel32.dll
kernel32:
    db "kernel32.dll", 0
    
; Other .rdata stuff

mbox_message:
    db "Hello, World!", 0

rdata_size equ $ - rdata_begin
    
filesize equ $ - $$

我正在使用 NASM 2.15.5 组装它:nasm -f bin -o test.exe test.asm

那么我哪里做错了?提前谢谢你

【问题讨论】:

  • MessageBoxAuser32.dll 导出
  • @RbMm 非常感谢,我不知道为什么我认为它是 kernel32.dll,我现在修复它并且 exe 成功运行但没有任何反应,它只是退出而没有出现消息框跨度>
  • 导入MessageBoxA调用的所有函数解决了

标签: winapi import x86 nasm portable-executable


【解决方案1】:

原来的问题是通过cmets中的RbMm解决的,我错误地导入了kernel32.dll而不是user32.dll(我尝试调用ExitProcess时遗留的)

导入正确的库解决了错误,但要使其正常工作并出现消息框,我必须导入 MessageBoxA 调用的所有函数,要找到这些函数,只需创建一个调用 MessageBoxA 的测试程序,然后查看 MSVC 生成的导入:

#include <winuser.h>
int main()
{
    return MessageBoxA(NULL, "Test", NULL, 0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2012-12-08
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    相关资源
    最近更新 更多