从自定义PE文件中的dll导入时,找不到过程入口点MessageBoxA



我一直在尝试掌握PE文件格式(只是为了教自己一些新的东西(,并试图创建一个简单的.exe,它显示一个消息框,然后退出。我使用tinyPE作为基础,然后使用microsoft文档中关于该格式的内容在其上构建。

问题是,当我尝试运行它时,我会得到一个The procedure entry point MessageBoxA could not be located in the dynamic link library D:pathtomytest.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进行组装

那么我哪里错了?提前感谢

RbMm在评论中解决了最初的问题,我错误地导入了kernel32.dll而不是user32.dll(当我试图调用ExitProcess时遗留下来的(

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

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

最新更新