Last active
April 27, 2024 18:35
-
-
Save mojobojo/921a5af897e86bb940a2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Compile with nasm | |
; nasm Small.asm -o Small.exe | |
bits 64 | |
%define ImageAddress 0x0000000140000000 | |
%define BaseAddress 0x00010000 | |
%define addr(x) (x+ImageAddress+BaseAddress) | |
%define Kernel32Handle rsp+0x50 | |
%define Kernel32PeHeader rsp+0x58 | |
%define GetProcAddress rsp+0x60 | |
; DOS Header | |
e_magic: | |
dw 0x5A4D | |
Start: | |
jmp Main | |
; Pad all the way until 0x0C (where the PE header should be) | |
times 0x10 - ($ - $$) db 0 | |
; NT Header | |
NTHeader: | |
Siganture: | |
dd 0x4550 | |
Machine: | |
dw 0x8664 | |
NumberOfSections: | |
dw 1 | |
TimeDateStamp: | |
dd 0x0 | |
PointerToSymbolTable: | |
dd 0x0 | |
NumberOfSymbols: | |
dd 0x0 | |
SizeOfOptionalHeaders: | |
dw SectionHeader-OptionalHeaders | |
Characteristics: | |
dw 0x0022 ; 0x030F | |
; Optional Headers | |
OptionalHeaders: | |
Magic: | |
dw 0x20B | |
MajorAndMinorLinkerVersion: | |
db 0 | |
db 0 | |
SizeOfCode: | |
dd 0x0 | |
SizeOfInitalizedData: | |
dd 0x0 | |
SizeOfUninitalizedData: | |
dd 0x0 | |
AddressOfEntryPoint: | |
dd BaseAddress+Start | |
; Since these are overlapping structs this is the DOS headers PE pointer | |
BaseOfData: | |
dd NTHeader | |
ImageBase: | |
dq ImageAddress | |
SectionAlignment: | |
dd 0x00010000 | |
FileAlignment: | |
dd 0x00000200 | |
MajorAndMinorOSVersion: | |
dw 0x0 | |
dw 0x0 | |
MajorAndMinorImageVersion: | |
dw 0x0 | |
dw 0x0 | |
MajorSybsystemVersion: | |
dw 0x0004 | |
MinorSubsystemVersion: | |
dw 0x0000 | |
Win32VersionValue: | |
dd 0 | |
SizeOfImage: | |
dd 0x00020000 | |
SizeOfHeaders: | |
dd HeaderSize | |
CheckSum: | |
dd 0x0 | |
Subsystem: | |
dw 0x0002 | |
DllCharacteristics: | |
dw 0x0000 | |
SizeOfStackReserve: | |
dq 0x0 | |
SizeOfStackCommit: | |
dq 0x0 | |
SizeOfHeapReserve: | |
dq 0x0 | |
SizeOfHeapCommit: | |
dq 0 | |
LoaderFlags: | |
dd 0x0 | |
NumberOfRvaAndSizes: | |
dd 3 | |
DataDirectories: | |
dd 0 ; Export Directory RVA | |
dd 0 ; Export Directory Size | |
dd 0 ; Import Directory RVA | |
dd 0 ; Import Directory Size | |
dd 0 | |
dd 0 | |
SectionHeader: | |
db "HANDMADE" | |
dd 0x00010000 | |
dd 0x00010000 | |
dd 0x00000200 | |
dd 0x00000001 | |
dd 0x0 | |
dd 0 | |
dw 0x0 | |
dw 0x0 | |
dd 0xE00000E0 | |
HeaderSize equ $-$$ | |
Main: | |
; NOTE: The stack needs to be 16 byte aligned and starts out | |
; 8 byte aligned | |
sub rsp, 0x128 | |
; Get the offset to the modules that load with the application | |
mov rax, [gs:0x30] | |
add rax, 0x60 | |
mov rax, [rax] | |
add rax, 0x18 | |
mov rax, [rax] | |
add rax, 0x20 | |
mov rax, [rax] | |
; Loop through each module | |
.NextModule: | |
mov rbx, rax | |
add rbx, 0x30 | |
mov rbx, [rbx] | |
cmp rbx, 0 | |
je Error ; This happens if we dont locate KERNEL32.DLL | |
mov rbx, rax | |
add rbx, 0x50 | |
mov rbx, [rbx] | |
mov rcx, addr(Kernel32DllStr) | |
xor r8, r8 | |
xor r9, r9 | |
xor r10, r10 | |
; Compare strings to find kernel32.dll | |
.Loop: | |
; We are comparing ASCII against unicode here | |
mov r8w, [rbx] ; Module name | |
mov r9b, [rcx] ; kernel32.dll string | |
xor r9, r8 | |
add r10, r9 | |
add rbx, 2 | |
inc rcx | |
cmp r8w, 0 | |
jne .Loop | |
cmp r10, 0 ; If compare succeeds r10 is zero | |
je SearchSuccess | |
mov rax, [rax] | |
jmp .NextModule | |
SearchSuccess: | |
add rax, 0x20 | |
mov rax, [rax] ; Pointer to Kernel32.dll base | |
mov cx, [rax] | |
cmp cx, 0x5A4D | |
jne Error ; Bad DOS ehader | |
mov rbx, rax | |
add rbx, 0x3C ; Offset to PE header | |
xor rcx, rcx | |
mov ecx, [rbx] | |
mov rbx, rax | |
add rbx, rcx | |
mov cx, [rbx] | |
cmp cx, 0x4550 | |
jne Error ; Bad PE header | |
; Last thing we need to do is find GetProcAddress | |
mov rcx, rbx | |
add rcx, 0x88 ; Export directory RVA | |
mov ecx, [rcx] | |
add rcx, rax | |
add rcx, 0x20 | |
mov ecx, [rcx] ; RVA name table | |
add rcx, rax | |
xor r12, r12 | |
.NextOrdinal: | |
xor r8, r8 | |
xor r9, r9 | |
xor r10, r10 | |
xor r11, r11 | |
mov rdx, addr(GetProcAddressName) | |
mov r8d, [rcx] | |
add rcx, 4 | |
add r8, rax | |
.Loop: | |
mov r9b, [rdx] | |
mov r10b, [r8] | |
xor r10, r9 | |
add r11, r10 | |
inc rdx | |
inc r8 | |
cmp r9b, 0 | |
jne .Loop | |
cmp r11, 0 ; If compare succeeds r11 is zero | |
je LoadGetProcAddress | |
inc r12 | |
jmp .NextOrdinal | |
LoadGetProcAddress: | |
; Okay now we found the GetProcAddress ordinal. Now we can finally get it so | |
; we can call it. | |
mov rcx, rbx | |
add rcx, 0x88 ; Export directory RVA | |
mov ecx, [rcx] | |
add rcx, rax | |
add rcx, 0x1C | |
mov ecx, [rcx] | |
add rcx, rax | |
imul r12, 4 | |
add rcx, r12 | |
mov ecx, [rcx] | |
add rcx, rax ; rcx = GetProcAddress | |
mov [Kernel32Handle], rax | |
mov [Kernel32PeHeader], rbx | |
mov [GetProcAddress], rcx | |
mov rcx, [Kernel32Handle] | |
mov rdx, addr(LoadLibraryAStr) | |
call [GetProcAddress] | |
cmp rax, 0 | |
je Error ; In case GetProcAddress failed | |
mov rcx, addr(User32DllStr) | |
call rax ; LoadLibraryA | |
cmp rax, 0 | |
je Error ; Failed to open user32.dll | |
; Resolve MessageBoxA | |
mov rcx, rax | |
mov rdx, addr(MessageBoxAStr) | |
call [GetProcAddress] | |
cmp rax, 0 | |
je Error | |
; Finally call MessageBoxA | |
xor r9, r9 ; uType | |
xor rcx, rcx ; hWnd | |
mov rdx, addr(HelloWorldText) ; lpText | |
mov r8, addr(HelloWorldText) ; lpCaption | |
call rax | |
xor rax, rax | |
jmp EndFunction | |
Error: | |
mov rax, 1 | |
EndFunction: | |
add rsp, 0x128 | |
ret | |
Kernel32DllStr: | |
db "KERNEL32.DLL", 0 | |
User32DllStr: | |
db "USER32.DLL", 0 | |
MessageBoxAStr: | |
db "MessageBoxA", 0 | |
LoadLibraryAStr: | |
db "LoadLibraryA", 0 | |
GetProcAddressName: | |
db "GetProcAddress", 0 | |
HelloWorldText: | |
db "Hello World", 0 | |
; Apparently windows doesnt like it unless its aligned | |
EndPadding: | |
times 1024-($-$$) db 0 | |
ImageSize equ $-$$ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment