我一直在尝试掌握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);
}