ksmod/loader/ksmod.asm
2021-02-08 13:59:18 -06:00

278 lines
6.6 KiB
NASM
Executable File

; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
.686p
.model flat, stdcall
option casemap :none
include ksmod.inc
.code
start:invoke Main
; ##########################################################################
Main proc ; 400
local proc_handle:dword
invoke CheckForDirectory
dbg ttext("Searching for unpatched games...")
invoke FindFirstUnpatchedWindow
mov proc_handle, eax
.if eax == 0
dbg ttext("No unpatched games were found.")
invoke OpenAndPatch
.else
dbg ttext("An unpatched game was found. Patching...")
invoke PatchExistingWindow, proc_handle
dbg ttext("An existing game has been patched.")
.endif
dbg ttext("Exiting.")
invoke ExitProcess, 0
Main endp
; ##########################################################################
OpenAndPatch proc ;300
local Ssi:STARTUPINFO
local Spi:PROCESS_INFORMATION
local cmd_line[512]:byte
local commands[128]:byte
invoke RtlZeroMemory, addr Ssi, sizeof STARTUPINFO
mov Ssi.cb, sizeof STARTUPINFO
dbg ttext("Opening a new game...")
invoke GetFullPathNameA, text("Settings.ini"), sizeof cmd_line, addr cmd_line, 0
error 301
invoke GetPrivateProfileStringA, text("KSMod"), text("Command_Line"), 0, addr commands, sizeof commands, addr cmd_line
error 302
invoke TrimComment, addr commands, sizeof commands
invoke wsprintfA, addr cmd_line, text("%s %s"), text("gw.exe"), addr commands
invoke CreateProcessA, 0, addr cmd_line, 0, 0, 0, CREATE_SUSPENDED, 0, 0, addr Ssi, addr Spi
error 303
dbg ttext("Opened. Patching a new game...")
invoke PatchExistingWindow, Spi.hProcess
invoke ResumeThread, Spi.hThread
inc eax
error 304
invoke CloseHandle, Spi.hThread
error 305
dbg ttext("A new game has been opened and patched.")
ret
OpenAndPatch endp
; ##########################################################################
PatchExistingWindow proc proc_handle:dword ;100
local hpid:dword
local dllloc[512]:byte
local memptr:dword
local hndl:dword
invoke GetFullPathNameA, text("ksmod.dll"), 512, addr dllloc, 0
error 101
invoke VirtualAllocEx, proc_handle, 0, sizeof dllloc, MEM_COMMIT, PAGE_READWRITE
error 102
mov memptr, eax
invoke WriteProcessMemory, proc_handle, memptr, addr dllloc, sizeof dllloc, 0
error 103
invoke GetModuleHandleA, text("Kernel32")
error 104
invoke GetProcAddress, eax, text("LoadLibraryA")
error 105
invoke CreateRemoteThread, proc_handle, 0, 0, eax, memptr, 0, 0
error 106
mov hndl, eax
invoke WaitForSingleObject, hndl, 10000
inc eax
error 107
invoke VirtualFreeEx, proc_handle, memptr, 0, MEM_RELEASE
error 108
invoke CloseHandle, hndl
error 109
invoke CloseHandle, proc_handle
error 110
dbg ttext("Game patched.")
ret
PatchExistingWindow endp
; ##########################################################################
FindFirstUnpatchedWindow proc ; 200
local hwnd:dword
local hpid:dword
invoke EnumWindows, addr EnumWindowsProc, addr hwnd
.if eax == 0
invoke GetLastError
.if eax == ENUM_SUCCEED
invoke GetWindowThreadProcessId, hwnd, addr hpid
error 201
invoke OpenProcess, PROCESS_ALL_ACCESS, 0, hpid
error 202
ret ; Returns PID to caller
.else
xor eax, eax
error 203
.endif
.endif
xor eax, eax
ret
FindFirstUnpatchedWindow endp
; ##########################################################################
EnumWindowsProc proc hwnd:dword, lParam:dword ; 500
local buffer[512]:byte
local hpid:dword
local hMods[200]:dword
local needed:dword
push ebx
invoke GetWindowTextA, hwnd, addr buffer, sizeof buffer
.if eax == 10
invoke lstrcmpA, addr buffer, text("Guild Wars")
.if eax == 0
invoke GetWindowThreadProcessId, hwnd, addr hpid
error 501
invoke OpenProcess, PROCESS_ALL_ACCESS, 0, hpid
error 502
mov hpid, eax
invoke GetProcessImageFileNameA, hpid, addr buffer, sizeof buffer
error 503
.if eax != 0
lea ecx, buffer
add eax, ecx
invoke TrailBack, eax, ecx
invoke lstrcmpiA, eax, text("gw.exe")
.if eax == 0
invoke EnumProcessModules, hpid, addr hMods, sizeof hMods, addr needed
error 504
.if eax != 0
xor ebx, ebx
.while ebx != needed
invoke GetModuleFileNameExA, hpid, dword ptr [hMods+ebx], addr buffer, sizeof buffer
error 505
lea ecx, buffer
add eax, ecx
invoke TrailBack, eax, ecx
invoke lstrcmpiA, eax, text("ksmod.dll")
.if eax != 0
add ebx, 4
.else
pop ebx
or eax, 1
ret
.endif
.endw
mov ecx, lParam
mov eax, hwnd
mov dword ptr [ecx], eax
invoke SetLastError, ENUM_SUCCEED
pop ebx
xor eax, eax
ret
.endif
.endif
.endif
.endif
.endif
pop ebx
or eax, 1
ret
EnumWindowsProc endp
; ##########################################################################
CheckForDirectory proc
invoke CreateFileA, text("gw.exe"), 0, 0, 0, OPEN_EXISTING, 0, 0
push eax
invoke CloseHandle, eax
pop eax
.if eax == INVALID_HANDLE_VALUE
invoke MessageBoxA, 0, text("KSMod must run from the Guild Wars folder."), text("KSMod"), 1000h
invoke ExitProcess, 0
.endif
ret
CheckForDirectory endp
; ##########################################################################
end start