问题描述
我有64位手动生成的PE可执行文件。我需要加载两个库kernel32.dll
和user.dll
。它给出了第一个错误。
如果我只有一个库(这是kernel32.dll
),则会收到第二个错误。有什么办法可以得到另一个错误。
有什么办法可以使所有库正确?请记住,代码是从32位可执行文件移植的。您可以在下面看到代码。
bits 64
BASE equ 400000h
ALIGNMENT equ 512
%define SECTALIGN 4096
STD_OUTPUT_HANDLE equ -11
NULL equ 0
%define ROUND(v,a) (((v + a - 1) / a) * a)
%define ALIGNED(v) (ROUND(v,ALIGNMENT))
%define RVA(obj) (obj - BASE)
section header progbits start=0 vstart=BASE
mz_hdr:
dw "MZ" ; DOS magic
times 0x3a db 0 ; [UNUSED] DOS header
dd RVA(pe_hdr) ; address of PE header
pe_hdr:
dw "PE",0 ; PE magic + 2 padding bytes
dw 0x8664 ; i386 architecture
dw 2 ; two sections
dd __POSIX_TIME__ ; [UNUSED] timestamp
dd 0 ; [UNUSED] symbol table pointer
dd 0 ; [UNUSED] symbol count
dw OPT_HDR_SIZE ; optional header size
dw 0x0002 ; characteristics: 32-bit,executable
opt_hdr:
dw 0x020b ; optional header magic
db 13,37 ; [UNUSED] linker version
dd ALIGNED(S_TEXT_SIZE) ; [UNUSED] code size
dd ALIGNED(S_IDATA_SIZE) ; [UNUSED] size of initialized data
dd 0 ; [UNUSED] size of uninitialized data
dd RVA(section..text.vstart) ; entry point address
dd RVA(section..text.vstart) ; [UNUSED] base of code
dd RVA(section..idata.vstart) ; [UNUSED] base of data
dq BASE ; image base
dd SECTALIGN ; section alignment
dd ALIGNMENT ; file alignment
dw 4,0 ; [UNUSED] OS version
dw 0,0 ; [UNUSED] image version
dw 4,0 ; subsystem version
dd 0 ; [UNUSED] Win32 version
dd RVA(the_end) ; size of image
dd ALIGNED(ALL_HDR_SIZE) ; size of headers
dd 0 ; [UNUSED] checksum
dw 3 ; subsystem = console
dw 0 ; [UNUSED] DLL characteristics
dq 0x0010000000000000 ; [UNUSED] maximum stack size
dq 0x0000100000000000 ; initial stack size
dq 0x0010000000000000 ; maximum heap size
dq 0x0000100000000000 ; [UNUSED] initial heap size
dd 0 ; [UNUSED] loader flags
dd 16 ; number of data directory entries
dd 0,0 ; no export table
dd RVA(import_table) ; import table address
dd IMPORT_TABLE_SIZE ; import table size
times 14 dd 0,0 ; no other entries in the data directories
OPT_HDR_SIZE equ $ - opt_hdr
sect_hdr_text:
db ".text",0 ; section name
dd ALIGNED(S_TEXT_SIZE) ; virtual size
dd RVA(section..text.vstart) ; virtual address
dd ALIGNED(S_TEXT_SIZE) ; file size
dd section..text.start ; file position
dd 0,0 ; no relocations or debug info
dw 0,0 ; no relocations or debug info
dd 0x60000020 ; flags: code,readable,executable
sect_hdr_idata:
db ".idata",0 ; section name
dd ALIGNED(S_IDATA_SIZE) ; virtual size
dd RVA(section..idata.vstart) ; virtual address
dd ALIGNED(S_IDATA_SIZE) ; file size
dd section..idata.start ; file position
dd 0,0 ; no relocations or debug info
dd 0xC0000040 ; flags: data,writeable
ALL_HDR_SIZE equ $ - $$
;;;;;;;;;;;;;;;;;;;; .text ;;;;;;;;;;;;;;;;;
section .text progbits follows=header align=ALIGNMENT vstart=BASE+SECTALIGN*1
s_text:
; set up stack frame for *lpBytesWritten
; push STD_OUTPUT_HANDLE
; call [GetStdHandle]
; push NULL
; push buffer
; push message_size
; push message
; push eax
; call [WriteConsoleA]
push rbp
mov rbp,rsp
sub rsp,40
push 0
call [ExitProcess]
mov rsp,rbp
pop rbp
ret
S_TEXT_SIZE equ $ - s_text
;;;;;;;;;;;;;;;;;;;; .idata ;;;;;;;;;;;;;;;;;
section .idata progbits follows=.text align=ALIGNMENT vstart=BASE+SECTALIGN*2
s_idata:
; message db "Hello World!",0
; message_size equ $ - message
; buffer resd 4
; buffer2 resb 64
import_table:
; import of kernel32.dll
dd 0 ; [UNUSED] read-only IAT
dd 0 ; [UNUSED] timestamp
dd 0 ; [UNUSED] forwarder chain
dd RVA(N_kernel32) ; library name
dd RVA(IAT_kernel32) ; IAT pointer
; import of user32.dll
dd 0 ; [UNUSED] read-only IAT
dd 0 ; [UNUSED] timestamp
dd 0 ; [UNUSED] forwarder chain
dd RVA(N_user32) ; library name
dd RVA(IAT_user32) ; IAT pointer
; terminator (empty item)
times 5 dd 0
IMPORT_TABLE_SIZE: equ $ - import_table
IAT_kernel32:
ExitProcess: dd RVA(H_ExitProcess)
GetStdHandle: dd RVA(H_GetStdHandle)
WriteConsoleA: dd RVA(H_WriteConsoleA)
dd 0
IAT_user32:
MessageBoxA: dd RVA(H_MessageBoxA)
dd 0
align 4,db 0
N_kernel32: db "kernel32.dll",0
align 4,db 0
N_user32: db "user32.dll",0
align 2,db 0
H_MessageBoxA: db 0,"MessageBoxA",db 0
H_GetStdHandle: db 0,"GetStdHandle",db 0
H_WriteConsoleA: db 0,"WriteConsoleA",db 0
H_ExitProcess: db 0,"ExitProcess",0
S_IDATA_SIZE equ $ - s_idata
align ALIGNMENT,db 0
the_end:
解决方法
@ user2426998-与加载错误的.dll相比,您显然有更大的问题。
建议:
-
请更新您的信息,并说明您要执行的操作。
问:这个项目的“目标”是什么?
不是“使用自定义PE32 +可执行文件构建程序”。 为什么确实需要“自定义PE32 +可执行文件”(例如,仅将旧的.c / .cpp程序重新编译为64位)?您从什么代码/二进制开始?与任何“普通” 64位Windows .exe相比,您的PE32 +映像需要“与众不同”吗? 64位Windows .exe实际上是您的目标吗?还是您需要完成“其他任务”? -
我假设您具有Microsoft Visual Studio。
尽可能多地使用它:如果您可以在MSVS中做某事,那么您可能应该在MSVS中做某事。 它将使您的生活变得非常轻松:) -
确定地编写一些.c“测试模块”,然后使用“ / Fa”在MSVS中进行构建和构建。 这将为您提供一个用于手动编写自己的汇编代码的“模板”。 特别是,它将向您展示如何正确传递参数:)
-
肯定使用诸如dumpbin之类的MSVS工具或诸如PE Internals之类的第三方工具。将“您的代码”与“其他有效示例”进行比较和对比。
'希望有帮助...
,答案: 功能分配部分需要调整。代替双字,应使用四字。
IAT_kernel32:
ExitProcess: dq RVA(H_ExitProcess)
GetStdHandle: dq RVA(H_GetStdHandle)
WriteConsoleA: dq RVA(H_WriteConsoleA)
dq 0
IAT_user32:
MessageBoxA: dq RVA(H_MessageBoxA)
dq 0
应根据此示例校正路线
align 16,db 0
N_kernel32: db "kernel32.dll",0
align 16,db 0
N_user32: db "user32.dll",0
align 8,db 0
H_ExitProcess: db 0,"ExitProcess",db 0
H_GetStdHandle: db 0,"GetStdHandle",db 0
H_WriteConsoleA: db 0,"WriteConsoleA",db 0
H_MessageBoxA: db 0,"MessageBoxA",0