187 lines
3.4 KiB
NASM
187 lines
3.4 KiB
NASM
BITS 64
|
|
|
|
; Macro definitions
|
|
|
|
; read dst, pSrc, size
|
|
%macro read 3
|
|
|
|
mov %1, [%2]
|
|
add %2, %3
|
|
|
|
%endmacro
|
|
|
|
; copy pDst, pSrc, temp, tempSize
|
|
%macro copy 4
|
|
|
|
mov %3, [%2]
|
|
mov [%1], %3
|
|
add %1, %4
|
|
add %2, %4
|
|
|
|
%endmacro
|
|
|
|
; unprotect addr, size, fn
|
|
%macro unprotect 3
|
|
|
|
mov rcx, %1
|
|
mov rdx, %2
|
|
mov r8, 40h ; PAGE_EXECUTE_READWRITE
|
|
lea r9, [rel oldProtect]
|
|
|
|
call %3
|
|
|
|
%endmacro
|
|
|
|
; reprotect addr, size, fn
|
|
%macro reprotect 3
|
|
|
|
mov rcx, %1
|
|
mov rdx, %2
|
|
lea r9, [rel oldProtect]
|
|
mov r8d, [r9]
|
|
|
|
call %3
|
|
|
|
%endmacro
|
|
|
|
|
|
main: ; Replacement entry point
|
|
push rsi
|
|
push rdi
|
|
push r12
|
|
push r13
|
|
push r14
|
|
|
|
|
|
call GetKernel32ModuleHandle
|
|
mov rsi, rax ; kernel32.dll
|
|
|
|
mov rcx, rax
|
|
call GetAddressOf_GetProcAddress
|
|
mov rdi, rax ; *GetProcAddress
|
|
|
|
|
|
mov rcx, rsi ; kernel32.dll
|
|
lea rdx, [rel s_VirtualProtect]
|
|
call rdi ; rax = *VirtualProtect
|
|
|
|
mov rcx, rax
|
|
call RecoverExecutable
|
|
|
|
|
|
mov rcx, rsi ; kernel32.dll
|
|
lea rdx, [rel s_LoadLibraryW]
|
|
call rdi ; rax = *LoadLibraryW
|
|
|
|
lea rcx, [rel dllPath]
|
|
call rax ; LoadLibraryW(dllPath)
|
|
|
|
|
|
mov rcx, rsi ; kernel32.dll
|
|
lea rdx, [rel s_GetModuleHandleA]
|
|
call rdi ; rax = *GetModuleHandle
|
|
mov r12, rax
|
|
|
|
mov rcx, 0
|
|
call rax ; rax = .exe base address
|
|
mov r13, rax
|
|
|
|
mov rcx, rsi ; kernel32.dll
|
|
lea rdx, [rel s_GetCommandLineW]
|
|
call rdi ; rax = *GetCommandLineW
|
|
|
|
call rax ; rax = command line
|
|
mov r14, rax
|
|
|
|
|
|
lea rcx, [rel s_UnityPlayer.dll]
|
|
call r12 ; rax = UnityPlayer.dll
|
|
|
|
mov rcx, rax
|
|
lea rdx, [rel s_UnityMain]
|
|
call rdi ; rax = *UnityMain
|
|
|
|
mov rcx, r13 ; .exe base address
|
|
mov rdx, 0 ; hPrevInstance - 0
|
|
mov r8, r14 ; command line
|
|
mov r9, 1 ; SW_NORMAL
|
|
call rax ; UnityMain(...)
|
|
|
|
|
|
pop r14
|
|
pop r13
|
|
pop r12
|
|
pop rdi
|
|
pop rsi
|
|
ret
|
|
|
|
|
|
RecoverExecutable: ; expects *VirtualProtect in rcx
|
|
push rbx
|
|
push r12
|
|
push r13
|
|
push r14
|
|
sub rsp, 8
|
|
|
|
mov r13, rcx
|
|
|
|
; Find the recovery data structure
|
|
lea rbx, [rel dllPath]
|
|
|
|
.search:
|
|
read ax, rbx, 2
|
|
test ax, ax
|
|
jnz .search
|
|
|
|
; Recover entry point bytes (6 + 8 = 14 total)
|
|
read r12, rbx, 8 ; Address
|
|
mov r14, r12
|
|
|
|
unprotect r14, 14, r13
|
|
copy r12, rbx, rax, 8
|
|
copy r12, rbx, eax, 4
|
|
copy r12, rbx, ax, 2
|
|
reprotect r14, 14, r13
|
|
|
|
; Recover import descriptor bytes (20 total)
|
|
read r12, rbx, 8
|
|
mov r14, r12
|
|
|
|
unprotect r14, 20, r13
|
|
copy r12, rbx, rax, 8
|
|
copy r12, rbx, rax, 8
|
|
copy r12, rbx, eax, 4
|
|
reprotect r14, 20, r13
|
|
|
|
; Recover import data directory entry size bytes (4 total)
|
|
read r12, rbx, 8
|
|
mov r14, r12
|
|
|
|
unprotect r14, 4, r13
|
|
copy r12, rbx, eax, 4
|
|
reprotect r14, 4, r13
|
|
|
|
add rsp, 8
|
|
pop r14
|
|
pop r13
|
|
pop r12
|
|
pop rbx
|
|
ret
|
|
|
|
|
|
%include "gpa.asm"
|
|
|
|
oldProtect: dd 0
|
|
|
|
; Strings
|
|
s_VirtualProtect: db "VirtualProtect", 0
|
|
s_LoadLibraryW: db "LoadLibraryW", 0
|
|
s_GetModuleHandleA: db "GetModuleHandleA", 0
|
|
s_GetCommandLineW: db "GetCommandLineW", 0
|
|
s_UnityPlayer.dll: db "UnityPlayer.dll", 0
|
|
s_UnityMain: db "UnityMain", 0
|
|
|
|
dllPath:
|
|
; This will be filled out by the launcher payload dll
|
|
; Path to the dll to inject into the game
|