This .exe PE format program that should print "owwwmagawd" in cmd when run, but instead the program hangs without printing anything. I figured there could be a problem with windows not filling the import address table, because I added some assembly code that loops infinitely if the imports in the import address table are 0. And if I remove that loop, the program closes immediately, which means the imports are 0. What's wrong with my program? I literally tried everything
P.S the code actually start running on the line after the infinite loop at 0x2002 rather than 0x2000 ("wat: jmp wat") as written in the "AddressOfEntryPoint" field in the optional header, so if the dll imports worked, the infinite loop would not run and the program would close immediately
BITS 64
DEFAULT REL
; MS-DOS STUB
start: db "MZ"
times 0x3A db 0
dd 0x40 ; 0x3c offset
db "PE", 0, 0 ; signature
; COFF HEADER
dw 0x8664 ; Machine
dw 2 ; NumberOfSections
dd 1749503318 ; TimeDateStamp
dd 0 ; PointerToSymbolTable
dd 0 ; NumberOfSymbols
dw 0xF0 ; SizeOfOptionalHeader
dw 0x222 ; Characteristics
; OPTIONAL HEADER
dw 0x20B ; Magic
db 0 ; MajorLinkerVersion
db 0 ; MinorLinkerVersion
dd 0x1000 ; SizeOfCode
dd 0x1000 ; SizeOfInitializedData
dd 0 ; SizeOfUninitializedData
dd 0x2002 ; AddressOfEntryPoint
dd 0x2000 ; BaseOfCode
dq 0x140000000 ; ImageBase
dd 0x1000 ; SectionAlignment
dd 0x200 ; FileAlignment
dw 6 ; MajorOperatingSystemVersion
dw 0 ; MinorOperatingSystemVersion
dw 0 ; MajorImageVersion
dw 0 ; MinorImageVersion
dw 6 ; MajorSubsystemVersion
dw 0 ; MinorSubsystemVersion
dd 0 ; Win32VersionValue
dd 0x3000 ; SizeOfImage
dd 0x1000 ; SizeOfHeaders
dd 0 ; CheckSum
dw 3 ; Subsystem
dw 0x8160 ; DllCharacteristics
dq 0x100000 ; SizeOfStackReserve
dq 0x1000 ; SizeOfStackCommit
dq 0x100000 ; SizeOfHeapReserve
dq 0x1000 ; SizeOfHeapCommit
dd 0 ; LoaderFlags
dd 16 ; NumberOfRVAAndSizes
dq 0 ; export table
dd 0x1000 ; import table RVA
dd 0x98 ; import table size
times 14 dq 0 ; other tables
; SECTION HEADERS
dq ".text" ; Name
dd 0x1000 ; VirtualSize
dd 0x1000 ; VirtualAddress
dd 0x1000 ; SizeOfRawData
dd 0x1000 ; PointerToRawData
dd 0 ; PointerToRelocations
dd 0 ; PointerToLineNumbers
dw 0 ; NumberOfRelocations
dw 0 ; NumberOfLineNumbers
dd 0xC0000040 ; Characteristics
dq ".code" ; Name
dd 0x1000 ; VirtualSize
dd 0x2000 ; VirtualAddress
dd 0x1000 ; SizeOfRawData
dd 0x2000 ; PointerToRawData
dd 0 ; PointerToRelocations
dd 0 ; PointerToLineNumbers
dw 0 ; NumberOfRelocations
dw 0 ; NumberOfLineNumbers
dd 0x60000020 ; Characteristics
endofheader: times (0x1000-(endofheader-start)) db 0
; TEXT
; IMPORT DIRECTORY TABLE
dd 0x1028 ; Import Lookup Table RVA
dd 0 ; Time/Date Stamp
dd 0 ; Forwarder Chain
dd 0x108A ; Name RVA
dd 0x1072 ; Import Address Table RVA
times 20 db 0
; IMPORT LOOKUP TABLE
dq 0x1048 ; GetStdHandle
dq 0x1058 ; WriteFile
dq 0x1064 ; ExitProcess
dq 0
; HINT/NAME TABLE
dw 0 ; GetStdHandle
db "GetStdHandle", 0, 0
dw 0 ; WriteFile
db "WriteFile", 0
dw 0 ; ExitProcess
db "ExitProcess", 0
; IMPORT ADDRESS TABLE
GetStdHandle: dq 0
WriteFile: dq 0
ExitProcess: dq 0
; NAME RVA
db "kernel32.dll", 0, 0
; DATA
text: db "owwwmagawd", 0
endoftext: times (0x2000-(endoftext-start)) db 0
; CODE
wat:
jmp wat
mov rax, [GetStdHandle]
test rax, rax
jz wat
sub rsp, 40
mov ecx, -11
call [GetStdHandle]
add rsp, 32
mov rcx, rax
mov rdx, text
mov r8d, 12
mov r9d, 0
sub rsp, 8
push 0
sub rsp, 32
call [WriteFile]
add rsp, 48
mov ecx, 0
sub rsp, 32
call [ExitProcess]
endofcode: times (0x3000-(endofcode-start)) db 0
Yes, Windows does not fill the Import Address Table of your program.
You have created the IMPORT directory in optional header (slot number 1), but not IAT (slot number 12), so MS Windows does not bind the three imported symbols in IAT