Initial commit

This commit is contained in:
kuntz 2021-02-08 13:59:18 -06:00
parent 8a0c46687c
commit ef157f9223
40 changed files with 1774 additions and 1 deletions

View File

@ -1,2 +1,45 @@
# ksmod
KSMod 3.2 - High Definition Textures, Multi-Client Virtualization, UT99 Sound Effects
(This is an archival backup of an old game mod I made)
Guild Wars KSMod 3.2 - High Definition Textures, Multi-Client Virtualization, UT99 Sound Effects
https://wiki.guildwars.com/wiki/User:Kuntz/KSMod
https://archive.guildwarslegacy.com/06/06%20Community%20Works/00002%20KSMod%203.2%20-%20High%20Definition%20Textures,%20Multi-Client%20Virtualization,%20UT99%20Sound%20Effects.001.html
"KSMod is the longest running and most popular Modification for Guild Wars. Based upon G-Stats, KSMod is a spin-off that enables the UT99 Sound Effects in Guild Wars, adds some graphical effects not available any where else such as High Definition Textures, and it can virtualize the Guild Wars client allowing you to run as many clients as you wish using the same GW.EXE and GW.DAT. The Mod itself is almost as old as Guild Wars, coming out shortly after retail in April 2005. KSMod is used by over 20,000 members of the GW community."
KSMod 3.2 Currently Features:
High Definition Texturing for all Models in all Outposts, Capes Included! (Make sure to use -image command line option)
Multi-Client virtualization
UT99 Sound Effects!
Command Line Switches!
High Definition Textures:
Version 2.x and newer offers the ability to enable High Definition Textures in all Outposts and Areas.
Multi-Client Virtualization:
Version 3.x allows full virtualization of the Guild Wars client, allowing you to run as many copies of the game as you wish. The performance of this method for Multi-Client should be significantly better than other methods that have been offered in the past. There is also a few Disk I/O options included to increase performance even more on newer high memory computer systems.
UT99 Sound Efects:
Every time you get a kill, either in PvE or PvP, you start a new Chain-Kill session. You have up to 10 seconds to get more kills to add to your chain, and every kill you get buys you another 10 seconds. You can chain kills all the way up to 15 (God Like). The order of the kills are as follows:
Headshot
Double-Kill
Triple-Kill
Multi-Kill
Mega-Kill
Ultra-Kill
Ludicrous-Kill
Monster-Kill
Killing-Spree
Rampage
Dominating
Unstoppable
Wicked-Sick
Holy-S***
God-Like

105
Readme.txt Executable file
View File

@ -0,0 +1,105 @@
---------
KSMod 3.2
---------
Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
v1.1 Changes:
-------------
Fixed the Kill Counter which was counting misc related things as Kills (such as dieing, or getting Faction, ect)
v1.2 Changes:
-------------
Made the search loop in the auto-update proc ultra fast.
v1.3 Changes:
-------------
Fixed the preservation of the ECX register in the KillSounds proc. Although this wasn't an issue now, in future versions of GW, the ECX register may be used and earlier versions of KSMod will cause GW to crash.
v1.4 Changes:
-------------
Updated for massive April build.
v1.5 Changes:
-------------
Updated for July build or something.
v1.6 Changes:
-------------
Anet changed the way Graphics.dll was loaded, and thus it causes 1.5 to hang upon load. This was fixed.
v1.7 Changes:
-------------
Updated for November build.
v2.0 Changes:
-------------
Added Settings.ini file and HighDefComposite option.
v2.1 Changes:
-------------
Changed the way the auto-updater works, should be able to conquer even more GW updates. Updated to latest build.
v2.2 Changes:
-------------
Updated to latest build.
v2.3 Changes:
-------------
Updated to latest build.
v2.4 Changes:
-------------
Updated to latest build.
v2.5 Changes:
-------------
Updated to latest build and included new EXE Loader.
v2.6 Changes:
-------------
Fixed bugs in loader. Added Command Line switches to INI file.
v3.0 Changes:
-------------
-Rebuilt KSMod from the ground up. New code and much better support for newer OS's like Windows Vista and Windows 7. Hense the 3.0 major version change!
-New loader does a much better and more thorough job, it should also be more compatible with different system configurations.
-Added commenting to Settings.ini.
-Added Multi-Launch capabilities. KSMod will now virtualize Guild Wars in an environment so you can run multiple copies of the game using the same gw.exe and gw.dat! This should increase your multi-client performance significantly!
-Added two Disk I/O performance tweaks aimed at new-age computer systems. Virtualization must be enabled.
v3.1 Changes:
-------------
Fixed small compatibility bugs.
v3.2 Changes:
-------------
Fixed more small compatibility bugs.
Desc:
-----
UT99_Sound_FX: Adds the oldschool Unreal Tournament '99 (UT99) Sound Effects to Guild Wars, plus some of the new ones from DotA. A UT Sound is played every time players or NPCs are killed. To achieve chain kills you must kill the next player or NPC within 10 seconds of the last. Every new kill resets the 10 second timer, the highest chain kill availble is 15 (Godlike). Disabled by default.
High_Def_Composite: Forces the engine to load the High Definition Textures whenever possible. Make sure to use the -image command line option to download all the High Definition Textures. Enabled by default.
Virtualization: Virtualizes the Guild Wars engine and data streams allowing a user to run mutliple copies of the game while maintaining system performance. Disabled by default.
VR_DisableCache: Requires Virtualization: Disable GW's cache options, will greatly speed up disk I/O on high memory systems. Recommend Windows 7 and 2GB+ memory. Disabled by default.
Command_Line: Loads GW with these command line switches. Useful for things like -perf and -nosound. Empty by default.
Install:
--------
Extract + copy KSMod.exe, KSMod.dll, and Settings.ini into your Guild Wars folder (same dir as GW.exe), run the KSMod.exe loader.
Run the loader as many times as you want for as many GW clients as you want open.

19
Settings.ini Executable file
View File

@ -0,0 +1,19 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
; KSMod 3.2 Configuration File
####################################################################################################
; Read the Readme.txt file for more information on these settings.
[KSMod]
UT99_Sound_FX=0 ; Unreal Tournament '99 Sound Effects
High_Def_Composite=1 ; High Def Textures in Outposts. Use -image command line for stability.
Virtualization=0 ; Allows multiple GW.EXE clients to run at once using the same data streams.
VR_DisableCache=0 ; Requires Virtualization: Disable GW's cache options, will greatly speed
; up disk I/O on high memory systems. Recommend Windows 7 and 2GB+ memory.
Command_Line= ; Optional command line for things like -perf and -nosound

49
breakpoint.asm Executable file
View File

@ -0,0 +1,49 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
setbreakpoint proto :dword, :dword, :dword
SetJMP proto :dword, :dword
.code
; ##########################################################################
setbreakpoint proc bpaddy:dword, procaddy:dword, len:dword
local meminfo:MEMORY_BASIC_INFORMATION
local buff[12]:byte
invoke VirtualProtect, bpaddy, 12, PAGE_EXECUTE_READWRITE, addr meminfo
push esi
push edi
mov dword ptr [buff], 909090E8h
mov dword ptr [buff+4], 90909090h
mov dword ptr [buff+8], 90909090h
mov ecx, 5
mov eax, procaddy
add ecx, bpaddy
sub eax, ecx
mov dword ptr [buff+1], eax
lea esi, buff
mov edi, bpaddy
mov ecx, len
rep movsb
pop edi
pop esi
ret
setbreakpoint endp
; ##########################################################################
SetJMP proc pAddr:dword, pNewProc:dword
local meminfo:MEMORY_BASIC_INFORMATION
invoke VirtualProtect, pAddr, 5, PAGE_EXECUTE_READWRITE, addr meminfo
mov eax, pAddr
mov ecx, pNewProc
sub ecx, eax
sub ecx, 5
mov byte ptr [eax], 0E9h
mov dword ptr [eax+1], ecx
ret
SetJMP endp
; ##########################################################################

30
hooks/closehandlehook.asm Executable file
View File

@ -0,0 +1,30 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
CloseHandleHook proto :dword
.data?
CloseHandleOrig dd ?
.code
; ##########################################################################
CloseHandleHook proc hObject:dword
.if hObject != 0
.if DidWeCreateTheDAT == FALSE
invoke CheckForSwap, addr hObject
.endif
.endif
push hObject
push offset CloseHandleRet
CloseHandleStub STUB
jmp CloseHandleOrig
CloseHandleRet:
ret
CloseHandleHook endp
; ##########################################################################

55
hooks/createfilehook.asm Executable file
View File

@ -0,0 +1,55 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
CreateFileWHook proto :dword, :dword, :dword, :dword, :dword, :dword, :dword
.data?
CreateFileWOrig dd ?
.data
GWDATUNICODE dw 'G', 'W', '.', 'D', 'A', 'T', 0
.code
; ##########################################################################
CreateFileWHook proc lpFileName:dword, dwDesiredAccess:dword, dwShareMode:dword, lpSecurityAttributes:dword, dwCreationDisposition:dword, dwFlagsAndAttributes:dword, hTemplateFile:dword
.if lpFileName != 0
invoke lstrlenW, lpFileName
shl eax, 1
.if eax >= 12
mov ecx, lpFileName
lea ecx, [ecx+eax-12]
invoke lstrcmpiW, ecx, addr GWDATUNICODE
.if eax == 0
dbg ttext("GW.DAT has been created with sharing")
mov dwShareMode, FILE_SHARE_READ
mov dwDesiredAccess, GENERIC_READ
mov DidWeCreateTheDAT, TRUE
mov IsDATLocked, FALSE
.endif
.endif
.endif
push hTemplateFile
push dwFlagsAndAttributes
push dwCreationDisposition
push lpSecurityAttributes
push dwShareMode
push dwDesiredAccess
push lpFileName
push offset CreateFileWRet
CreateFileWStub STUB
jmp CreateFileWOrig
CreateFileWRet:
ret
CreateFileWHook endp
; ##########################################################################

35
hooks/createmutexhook.asm Executable file
View File

@ -0,0 +1,35 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
CreateMutexAHook proto :dword, :dword, :dword
.data?
CreateMutexAOrig dd ?
.code
; ##########################################################################
CreateMutexAHook proc lpMutexAttributes:dword, bInitialOwner:dword, lpName:dword
local lzNewMutexName[32]:byte
.if lpName != 0
invoke Sleep, 10
invoke GetTickCount
invoke wsprintfA, addr lzNewMutexName, text("KSMod Mutex - %08X"), eax
lea eax, lzNewMutexName
mov lpName, eax
.endif
push lpName
push bInitialOwner
push lpMutexAttributes
push offset CreateMutexARet
CreateMutexAStub STUB
jmp CreateMutexAOrig
CreateMutexARet:
ret
CreateMutexAHook endp
; ##########################################################################

166
hooks/disasm.asm Executable file
View File

@ -0,0 +1,166 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
DisAsm proto :dword, :dword
RubTheStub proto :dword, :dword, :dword
InvalidInst proto :dword
ExistingHook proto
Hook proto :dword, :dword, :dword, :dword, :dword
.code
; ##########################################################################
Hook proc szModule:dword, szProcedure:dword, pHook:dword, pStub:dword, pRet:dword
local Stub[STUBSIZE]:byte
local StubSize:dword
local LocalOrig:dword
invoke GetModuleHandle, szModule
invoke GetProcAddress, eax, szProcedure
mov LocalOrig, eax
invoke DisAsm, LocalOrig, addr Stub
mov StubSize, eax
invoke RubTheStub, pStub, addr Stub, StubSize
invoke SetJMP, LocalOrig, pHook
mov eax, StubSize
add eax, LocalOrig
mov ecx, pRet
mov dword ptr [ecx], eax
ret
Hook endp
; ##########################################################################
RubTheStub proc pOffset:dword, pStub:dword, pStubSize:dword
local meminfo:MEMORY_BASIC_INFORMATION
invoke VirtualProtect, pOffset, STUBSIZE, PAGE_EXECUTE_READWRITE, addr meminfo
mov eax, pOffset
mov ecx, pStubSize
mov edx, pStub
push ebx
.while ecx != 0
dec ecx
mov bl, byte ptr [edx+ecx]
mov byte ptr [eax+ecx], bl
.endw
pop ebx
ret
RubTheStub endp
; ##########################################################################
DisAsm proc pOffset:dword, pStub:dword
push ebx
mov edx, pOffset
mov ecx, edx
@@: mov al, byte ptr [edx]
mov ebx, edx ; Later we check to see if we didn't disasm anything...
.if al == 0E8h || al == 0E9h
invoke ExistingHook
.endif
.if al == 8Bh
mov ah, byte ptr [edx+1]
and ah, 11000000b
.if ah == 11000000b
; MOV REG, REG
add edx, 2
.endif
.endif
mov ah, al
and ah, 11111000b
.if ah == 01010000b
; PUSH REG
inc edx
.elseif ah == 10111000b
; MOV REG, DWORD
add edx, 5
.elseif ah == 10110000b
; MOV REG, BYTE
add edx, 2
.endif
.if al == 01101000b
; PUSH DWORD
add edx, 5
.elseif al == 01101010b
; PUSH BYTE
add edx, 2
.endif
.if ebx == edx ; We didn't find any instructions in our mini-disasm
invoke InvalidInst, ebx
.endif
mov eax, ecx
sub eax, edx
cmp eax, -5 ; We need at least 5 bytes of room for a patch
jg @B
neg eax
push eax
; Self-modifying code (copies stub into our dll procedures)
mov ecx, pStub
mov edx, pOffset
@@: mov ah, byte ptr [edx]
mov byte ptr [ecx], ah
inc edx
inc ecx
dec al
jnz @B
pop eax
pop ebx
ret
DisAsm endp
; ##########################################################################
InvalidInst proc pOffset:dword
local buffer[64]:byte
mov edx, pOffset
mov eax, dword ptr [edx]
bswap eax
mov ebx, dword ptr [edx+4]
bswap ebx
mov ecx, dword ptr [edx+8]
bswap ecx
invoke wsprintfA, addr buffer, text("Invalid Instruction: %08X-%08X-%08X"), eax, ebx, ecx
invoke MessageBoxA, 0, addr buffer, text("KSMod"), 1000h
invoke ExitProcess, 0
InvalidInst endp
; ##########################################################################
ExistingHook proc
invoke MessageBoxA, 0, text("A security program or a piece of malware (for example, a rootkit) is blocking KSMod's ability to function properly. Please switch security applications off and/or scan your system for malware."), text("KSMod"), 1000h
invoke ExitProcess, 0
ExistingHook endp
; ##########################################################################

49
hooks/flushfilebuffershook.asm Executable file
View File

@ -0,0 +1,49 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
FlushFileBuffersHook proto :dword
.data?
FlushFileBuffersOrig dd ?
.code
; ##########################################################################
FlushFileBuffersHook proc hFile:dword
.if hFile != 0
.if DidWeCreateTheDAT == FALSE
.if IsDATLocked == TRUE
invoke CheckAndUnlockTheDAT, hFile
.endif
invoke CheckForSwap, addr hFile
.endif
.if VR_DisableCache == ENABLED
invoke GetFileType, hFile
.if eax == FILE_TYPE_DISK
or eax, 1
ret
.endif
.endif
.endif
push hFile
push offset FlushFileBuffersRet
FlushFileBuffersStub STUB
jmp FlushFileBuffersOrig
FlushFileBuffersRet:
ret
FlushFileBuffersHook endp
; ##########################################################################

39
hooks/getfiletimehook.asm Executable file
View File

@ -0,0 +1,39 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
GetFileTimeHook proto :dword, :dword, :dword, :dword
.data?
GetFileTimeOrig dd ?
.code
; ##########################################################################
GetFileTimeHook proc hFile:dword, lpCreationTime:dword, lpLastAccessTime:dword, lpLastWriteTime:dword
.if hFile != 0
.if DidWeCreateTheDAT == FALSE
.if IsDATLocked == TRUE
invoke CheckAndUnlockTheDAT, hFile
.endif
invoke CheckForSwap, addr hFile
.endif
.endif
push lpLastWriteTime
push lpLastAccessTime
push lpCreationTime
push hFile
push offset GetFileTimeRet
GetFileTimeStub STUB
jmp GetFileTimeOrig
GetFileTimeRet:
ret
GetFileTimeHook endp
; ##########################################################################

57
hooks/readfilehook.asm Executable file
View File

@ -0,0 +1,57 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
ReadFileHook proto :dword, :dword, :dword, :dword, :dword
.data?
ReadFileOrig dd ?
LZCRASHDELETED dd ?
.code
; ##########################################################################
ReadFileHook proc hFile:dword, lpBuffer:dword, nNumberOfBytesToRead:dword, lpNumberOfBytesRead:dword, lpOverlapped:dword
.if hFile != 0
.if DidWeCreateTheDAT == FALSE
.if IsDATLocked == TRUE
invoke CheckAndUnlockTheDAT, hFile
.endif
invoke CheckForSwap, addr hFile
.endif
.endif
push lpOverlapped
push lpNumberOfBytesRead
push nNumberOfBytesToRead
push lpBuffer
push hFile
push offset ReadFileRet
ReadFileStub STUB
jmp ReadFileOrig
ReadFileRet:
;.if eax != 0 && LZCRASHDELETED == 0
; invoke DebugCheck
; .if eax != 0
; or LZCRASHDELETED, 00440002h
; invoke DeleteModuleFromPEB, addr lzCRASHMODULE
; dbg ttext("NTDLL.DLL DELETED")
; .endif
;.endif
ret
ReadFileHook endp
; ##########################################################################

44
hooks/setendoffilehook.asm Executable file
View File

@ -0,0 +1,44 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
SetEndOfFileHook proto :dword
.data?
SetEndOfFileOrig dd ?
.code
; ##########################################################################
SetEndOfFileHook proc hFile:dword
.if hFile != 0
.if DidWeCreateTheDAT == FALSE
.if IsDATLocked == TRUE
invoke CheckAndUnlockTheDAT, hFile
.endif
invoke CheckForSwap, addr hFile
.endif
invoke IsHandleTheDAT, hFile
.if eax != 0
ret
.endif
.endif
push hFile
push offset SetEndOfFileRet
SetEndOfFileStub STUB
jmp SetEndOfFileOrig
SetEndOfFileRet:
ret
SetEndOfFileHook endp
; ##########################################################################

54
hooks/setfilepointerhook.asm Executable file
View File

@ -0,0 +1,54 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
SetFilePointerHook proto :dword, :dword, :dword, :dword
.data?
SetFilePointerOrig dd ?
LZMODDELETED dd ?
.code
; ##########################################################################
SetFilePointerHook proc hFile:dword, lDistanceToMove:dword, lpDistanceToMoveHigh:dword, dwMoveMethod:dword
.if hFile != 0
.if DidWeCreateTheDAT == FALSE
.if IsDATLocked == TRUE
invoke CheckAndUnlockTheDAT, hFile
.endif
invoke CheckForSwap, addr hFile
.endif
.endif
push dwMoveMethod
push lpDistanceToMoveHigh
push lDistanceToMove
push hFile
push offset SetFilePointerRet
SetFilePointerStub STUB
jmp SetFilePointerOrig
SetFilePointerRet:
;.if (eax != INVALID_SET_FILE_POINTER || edi != 0 || esi == 0080FF00h) && LZMODDELETED == 0
; push eax
; or LZMODDELETED, 0080FF00h
; invoke DeleteModuleFromPEB, addr lzMODULE
; dbg ttext("KSMOD.DLL DELETED")
; pop eax
;.endif
ret
SetFilePointerHook endp
; ##########################################################################

47
hooks/setfiletimehook.asm Executable file
View File

@ -0,0 +1,47 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
SetFileTimeHook proto :dword, :dword, :dword, :dword
.data?
SetFileTimeOrig dd ?
.code
; ##########################################################################
SetFileTimeHook proc hFile:dword, lpCreationTime:dword, lpLastAccessTime:dword, lpLastWriteTime:dword
.if hFile != 0
.if DidWeCreateTheDAT == FALSE
.if IsDATLocked == TRUE
invoke CheckAndUnlockTheDAT, hFile
.endif
invoke CheckForSwap, addr hFile
.endif
invoke IsHandleTheDAT, hFile
.if eax != 0
ret
.endif
.endif
push lpLastWriteTime
push lpLastAccessTime
push lpCreationTime
push hFile
push offset SetFileTimeRet
SetFileTimeStub STUB
jmp SetFileTimeOrig
SetFileTimeRet:
ret
SetFileTimeHook endp
; ##########################################################################

57
hooks/writefilehook.asm Executable file
View File

@ -0,0 +1,57 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
WriteFileHook proto :dword, :dword, :dword, :dword, :dword
.data?
WriteFileOrig dd ?
.code
; ##########################################################################
WriteFileHook proc hFile:dword, lpBuffer:dword, nNumberOfBytesToWrite:dword, lpNumberOfBytesWritten:dword, lpOverlapped:dword
.if hFile != 0
.if DidWeCreateTheDAT == FALSE
.if IsDATLocked == TRUE
invoke CheckAndUnlockTheDAT, hFile
.endif
invoke CheckForSwap, addr hFile
.endif
invoke IsHandleTheDAT, hFile
.if eax != 0
.if lpNumberOfBytesWritten != 0
mov eax, lpNumberOfBytesWritten
mov ecx, nNumberOfBytesToWrite
mov dword ptr [eax], ecx
.endif
or eax, 1
ret
.endif
.endif
push lpOverlapped
push lpNumberOfBytesWritten
push nNumberOfBytesToWrite
push lpBuffer
push hFile
push offset WriteFileRet
WriteFileStub STUB
jmp WriteFileOrig
WriteFileRet:
ret
WriteFileHook endp
; ##########################################################################

224
ksmod.asm Executable file
View File

@ -0,0 +1,224 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
.686p
.model flat, stdcall
option casemap :none
include ksmod.inc
.code
; ##########################################################################
LibMain proc hint:dword, reason:dword, param:dword
local meminfo:MEMORY_BASIC_INFORMATION
local cmd_line[512]:byte
local Base:dword
pushad
.if reason == DLL_PROCESS_ATTACH
dbg ttext("Entering.")
mov eax, hint
mov hInst, eax
invoke GetModuleHandle, text("gw.exe")
add eax, 1000h
mov Base, eax
invoke VirtualQuery, Base, addr meminfo, sizeof MEMORY_BASIC_INFORMATION
invoke GetFullPathNameA, text("Settings.ini"), sizeof cmd_line, addr cmd_line, 0
invoke PatchSound, meminfo.RegionSize, Base, addr cmd_line
invoke PatchTextures, meminfo.RegionSize, Base, addr cmd_line
invoke GetPrivateProfileInt, text("KSMod"), text("Virtualization"), 0, addr cmd_line
.if eax == 1
dbg ttext("Virtualization has been enabled.")
invoke GetPrivateProfileInt, text("KSMod"), text("VR_DisableCache"), 0, addr cmd_line
mov VR_DisableCache, eax
invoke GetUniqueDatID
mov IsDATLocked, TRUE
invoke Hook, text("Kernel32"), text("CreateMutexA"), addr CreateMutexAHook, addr CreateMutexAStub, addr CreateMutexAOrig
invoke Hook, text("Kernel32"), text("CreateFileW"), addr CreateFileWHook, addr CreateFileWStub, addr CreateFileWOrig
invoke Hook, text("Kernel32"), text("CloseHandle"), addr CloseHandleHook, addr CloseHandleStub, addr CloseHandleOrig
invoke Hook, text("Kernel32"), text("ReadFile"), addr ReadFileHook, addr ReadFileStub, addr ReadFileOrig
invoke Hook, text("Kernel32"), text("WriteFile"), addr WriteFileHook, addr WriteFileStub, addr WriteFileOrig
invoke Hook, text("Kernel32"), text("SetFilePointer"), addr SetFilePointerHook, addr SetFilePointerStub, addr SetFilePointerOrig
invoke Hook, text("Kernel32"), text("FlushFileBuffers"), addr FlushFileBuffersHook, addr FlushFileBuffersStub, addr FlushFileBuffersOrig
invoke Hook, text("Kernel32"), text("SetEndOfFile"), addr SetEndOfFileHook, addr SetEndOfFileStub, addr SetEndOfFileOrig
invoke Hook, text("Kernel32"), text("GetFileTime"), addr GetFileTimeHook, addr GetFileTimeStub, addr GetFileTimeOrig
invoke Hook, text("Kernel32"), text("SetFileTime"), addr SetFileTimeHook, addr SetFileTimeStub, addr SetFileTimeOrig
.endif
dbg ttext("Exiting.")
.endif
popad
or eax, 1
ret
LibMain Endp
; ##########################################################################
SearchBP proc pMemory:dword, pMemSize:dword, pSearchBytes:dword, pOffset:dword, pProc:dword, pCodeLen:dword
push ebx
push edi
push esi
mov ebx, pSearchBytes
mov eax, pMemSize
sub eax, 4
mov ecx, dword ptr [ebx]
mov edx, dword ptr [ebx+4]
mov edi, dword ptr [ebx+8]
mov esi, dword ptr [ebx+12]
mov ebx, pMemory
jmp @F
align 16
@@: inc ebx
dec eax
jz @F
cmp ecx, dword ptr [ebx]
jne @B
cmp edx, dword ptr [ebx+4]
jne @B
cmp edi, dword ptr [ebx+8]
jne @B
cmp esi, dword ptr [ebx+12]
jne @B
add ebx, pOffset
invoke setbreakpoint, ebx, pProc, pCodeLen
or eax, -1
@@: pop esi
pop edi
pop ebx
ret
SearchBP endp
; ##########################################################################
KillSounds proc
test esi, esi
jnz @F
cmp edi, 100
jz @F
cmp edi, 250
jae @F
push eax
push ecx
push edx
invoke GetTickCount
mov ecx, eax
sub eax, KillTime
mov KillTime, ecx
.if eax > 10000
mov eax, 1
mov Kills, eax
.else
inc Kills
mov eax, Kills
.if eax > 15
mov eax, 15
.endif
.endif
mov ecx, dword ptr [4*eax+sndarray]
invoke PlaySound, ecx, hInst, SND_ASYNC or SND_RESOURCE or SND_NODEFAULT
.if eax == 0
.endif
pop edx
pop ecx
pop eax
@@: mov [ebx+esi*8+6DCh], edx ; ORIGINAL 7B9C71
ret
KillSounds endp
; ##########################################################################
HighResComposite proc
xor edi, edi
ret
HighResComposite endp
; ##########################################################################
PatchSound proc memsize:dword, base:dword, cmd_line:dword
local buffer[512]:byte
invoke GetPrivateProfileInt, text("KSMod"), text("UT99_Sound_FX"), 0, cmd_line
.if eax == 1
invoke SearchBP, base, memsize, addr SearchBytes, 9, addr KillSounds, 7
.if eax == 0
dbg ttext("UT99_Sound_FX not found.")
invoke wsprintf, addr buffer, addr lzERROR, text("UT99_Sound_FX")
invoke MessageBox, 0, addr buffer, text("KSMod"), 1000h
.else
dbg ttext("UT99_Sound_FX patched.")
.endif
.endif
ret
PatchSound endp
; ##########################################################################
PatchTextures proc memsize:dword, base:dword, cmd_line:dword
local buffer[512]:byte
invoke GetPrivateProfileInt, text("KSMod"), text("High_Def_Composite"), 0, cmd_line
.if eax == 1
invoke SearchBP, base, memsize, addr SearchByte2, 7, addr HighResComposite, 5
.if eax == 0
dbg ttext("High_Def_Composite not found.")
invoke wsprintf, addr buffer, addr lzERROR, text("High_Def_Composite")
invoke MessageBox, 0, addr buffer, text("KSMod"), 1000h
.else
dbg ttext("High_Def_Composite patched.")
.endif
.endif
ret
PatchTextures endp
; ##########################################################################
GetUniqueDatID proc
local Handle:dword
local lpFileInformation:BY_HANDLE_FILE_INFORMATION
invoke CreateFileA, text("gw.dat"), 0, 0, 0, OPEN_EXISTING, 0, 0
mov Handle, eax
.if eax != INVALID_HANDLE_VALUE
invoke GetFileInformationByHandle, Handle, addr lpFileInformation
.if eax != 0
mov eax, lpFileInformation.dwVolumeSerialNumber
mov ecx, lpFileInformation.nFileIndexHigh
mov edx, lpFileInformation.nFileIndexLow
mov UniqueFileID, eax
mov UniqueFileID+4, ecx
mov UniqueFileID+8, edx
.endif
invoke CloseHandle, Handle
.endif
ret
GetUniqueDatID endp
; ##########################################################################
End LibMain

119
ksmod.inc Executable file
View File

@ -0,0 +1,119 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
; ##########################################################################
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\winmm.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\winmm.lib
; ##########################################################################
text macro arg
local nustr
.data
nustr db arg, 0
.code
exitm <offset nustr>
endm
ttext macro arg
local nustr
.data
nustr db "ksmod.dll - ", arg, 0
.code
exitm <offset nustr>
endm
dbg macro arg
pushad
push arg
call OutputDebugStringA
popad
endm
DISABLED equ 0
ENABLED equ 1
FALSE equ 0
TRUE equ 1
STUBSIZE equ 12
STUB equ <db STUBSIZE dup(90h)>
; ##########################################################################
KillSounds proto
HighResComposite proto
SearchBP proto :dword, :dword, :dword, :dword, :dword, :dword
PatchSound proto :dword, :dword, :dword
PatchTextures proto :dword, :dword, :dword
GetUniqueDatID proto
; ##########################################################################
.data?
hInst dd ?
Kills dd ?
KillTime dd ?
VR_DisableCache dd ?
DidWeCreateTheDAT dd ?
IsDATLocked dd ?
.data
lzERROR db "Unable To Enable: '%s'", 13, 10, 13, 10,
"This happens from time to time and is most likely due to a large GW update.", 13, 10, 13, 10,
"You can check my website for a new version: http://www.pickupgroup.com/ksmod/", 0
lzMODULE dw 'k', 's', 'm', 'o', 'd', '.', 'd', 'l', 'l', 0
lzCRASHMODULE dw 'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0
sndtext1 db "Headshot", 0
sndtext2 db "DoubleKill", 0
sndtext3 db "TripleKill", 0
sndtext4 db "MultiKill", 0
sndtext5 db "MegaKill", 0
sndtext6 db "UltraKill", 0
sndtext7 db "LudicrousKill", 0
sndtext8 db "MonsterKill", 0
sndtext9 db "KillingSpree", 0
sndtext10 db "Rampage", 0
sndtext11 db "Dominating", 0
sndtext12 db "Unstoppable", 0
sndtext13 db "WickedSick", 0
sndtext14 db "HolyShit", 0
sndtext15 db "GodLike", 0
align 4
sndarray dd 0, offset sndtext1, offset sndtext2, offset sndtext3, offset sndtext4, offset sndtext5,
offset sndtext6, offset sndtext7, offset sndtext8, offset sndtext9, offset sndtext10,
offset sndtext11, offset sndtext12, offset sndtext13, offset sndtext14, offset sndtext15
SearchBytes dd 0DCF3948Bh, 03000006h, 0F39489D7h, 000006DCh
SearchByte2 dd 0F8830000h, 0BF077401h, 00000001h, 0FF3302EBh
; ##########################################################################
include breakpoint.asm
include misc.asm
include hooks\disasm.asm
include hooks\createmutexhook.asm
include hooks\createfilehook.asm
include hooks\readfilehook.asm
include hooks\writefilehook.asm
include hooks\setfilepointerhook.asm
include hooks\closehandlehook.asm
include hooks\flushfilebuffershook.asm
include hooks\setendoffilehook.asm
include hooks\getfiletimehook.asm
include hooks\setfiletimehook.asm
; ##########################################################################

17
ksmod.rc Executable file
View File

@ -0,0 +1,17 @@
// Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
HeadShot WAVE sounds\1_headshot.wav
DoubleKill WAVE sounds\2_doublekill.wav
TripleKill WAVE sounds\3_triplekill.wav
MultiKill WAVE sounds\4_multikill.wav
MegaKill WAVE sounds\5_megakill.wav
UltraKill WAVE sounds\6_ultrakill.wav
LudicrousKill WAVE sounds\7_ludicrouskill.wav
MonsterKill WAVE sounds\8_monsterkill.wav
KillingSpree WAVE sounds\9_killingspree.wav
Rampage WAVE sounds\10_rampage.wav
Dominating WAVE sounds\11_dominating.wav
Unstoppable WAVE sounds\12_unstoppable.wav
WickedSick WAVE sounds\13_wickedsick.wav
HolyShit WAVE sounds\14_holyshit.wav
GodLike WAVE sounds\15_godlike.wav

278
loader/ksmod.asm Executable file
View File

@ -0,0 +1,278 @@
; 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

63
loader/ksmod.inc Executable file
View File

@ -0,0 +1,63 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
; ##########################################################################
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\psapi.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\psapi.lib
; ##########################################################################
text macro arg
local nustr
.data
nustr db arg, 0
.code
exitm <offset nustr>
endm
ttext macro arg
local nustr
.data
nustr db "ksmod.exe - ", arg, 0
.code
exitm <offset nustr>
endm
error macro arg
local ovskip
test eax, eax
jnz ovskip
push arg
call ErrorMsg
ovskip:
endm
dbg macro arg
pushad
push arg
call OutputDebugStringA
popad
endm
ENUM_SUCCEED equ <20001234h>
; ##########################################################################
Main proto
FindFirstUnpatchedWindow proto
EnumWindowsProc proto :dword, :dword
PatchExistingWindow proto :dword
OpenAndPatch proto
CheckForDirectory proto
; ##########################################################################
include misc.asm
; ##########################################################################

44
loader/makeit.bat Executable file
View File

@ -0,0 +1,44 @@
rem Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
@echo off
if not exist rsrc.rc goto over1
\masm32\bin\rc /v rsrc.rc
\masm32\bin\cvtres /machine:ix86 rsrc.res
:over1
if exist "ksmod.obj" del "ksmod.obj"
if exist "ksmod.exe" del "ksmod.exe"
\masm32\bin\ml /c /coff "ksmod.asm"
if errorlevel 1 goto errasm
if not exist rsrc.obj goto nores
\masm32\bin\Link /SUBSYSTEM:WINDOWS "ksmod.obj" rsrc.res
if errorlevel 1 goto errlink
dir "ksmod.*"
goto TheEnd
:nores
\masm32\bin\Link /SUBSYSTEM:WINDOWS "ksmod.obj"
if errorlevel 1 goto errlink
dir "ksmod.exe"
goto TheEnd
:errlink
echo _
echo Link error
goto TheEnd
:errasm
echo _
echo Assembly Error
goto TheEnd
:TheEnd
pause
del ksmod.obj

73
loader/misc.asm Executable file
View File

@ -0,0 +1,73 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
ErrorMsg proto :dword
TrimComment proto :dword, :dword
TrailBack proto :dword, :dword
.code
; ##########################################################################
ErrorMsg proc pCount:dword
local buffer[128]:byte
invoke GetLastError
invoke wsprintfA, addr buffer, text("KSMod Loader Error: %u - %u"), pCount, eax
invoke MessageBoxA, 0, addr buffer, text("KSMod"), 1000h
invoke ExitProcess, 0
ErrorMsg endp
; ##########################################################################
TrimComment proc pSource:dword, pSize:dword
mov eax, pSource
mov ecx, pSize
.while byte ptr [eax] != ';' && ecx != 0
inc eax
dec ecx
.endw
.if ecx != 0
and byte ptr [eax], 0
.endif
ret
TrimComment endp
; ##########################################################################
TrailBack proc pBuff:dword, pStart:dword ; 600
mov eax, pBuff
mov ecx, pStart
.if byte ptr [eax] == '"'
and byte ptr [eax], 0
.endif
.while byte ptr [eax] != '\' && eax != ecx
dec eax
.endw
.if eax == ecx
xor eax, eax
error 601
.endif
inc eax
ret
TrailBack endp
; ##########################################################################

19
makeit.bat Executable file
View File

@ -0,0 +1,19 @@
rem Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
@echo off
if exist ksmod.obj del ksmod.obj
if exist ksmod.dll del ksmod.dll
\masm32\bin\rc /v ksmod.rc
\masm32\bin\cvtres /machine:ix86 ksmod.res
cls
\masm32\bin\ml /c /coff ksmod.asm
\masm32\bin\Link /SUBSYSTEM:WINDOWS /DLL ksmod.obj ksmod.res
dir ksmod.dll
pause
del *.obj
del ksmod.res

84
misc.asm Executable file
View File

@ -0,0 +1,84 @@
; Copyright © 2005 - 2021 by Brett Kuntz. All rights reserved.
IsHandleTheDAT proto :dword
CheckAndUnlockTheDAT proto :dword
CheckForSwap proto :dword
.data?
UniqueFileID dd 3 dup(?)
OldGlobalHandle dd ?
NewGlobalHandle dd ?
.code
; ##########################################################################
CheckForSwap proc hFile:dword
mov eax, hFile
mov ecx, [eax]
.if ecx == OldGlobalHandle
mov ecx, NewGlobalHandle
mov [eax], ecx
.endif
ret
CheckForSwap endp
; ##########################################################################
CheckAndUnlockTheDAT proc hFile:dword
invoke IsHandleTheDAT, hFile
.if eax != 0
dbg ttext("GW.DAT has been Unlocked.")
invoke CloseHandle, hFile
invoke CreateFileA, text("gw.dat"), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
mov NewGlobalHandle, eax
mov eax, hFile
mov OldGlobalHandle, eax
mov IsDATLocked, FALSE
invoke MessageBoxA, 0, text("An already-running game has been successfully patched!"), text("KSMod"), 1000h
.endif
ret
CheckAndUnlockTheDAT endp
; ##########################################################################
IsHandleTheDAT proc hFile:dword
local lpFileInformation:BY_HANDLE_FILE_INFORMATION
.if hFile != 0
invoke GetFileInformationByHandle, hFile, addr lpFileInformation
.if eax != 0
mov eax, lpFileInformation.dwVolumeSerialNumber
mov ecx, lpFileInformation.nFileIndexHigh
mov edx, lpFileInformation.nFileIndexLow
.if eax == UniqueFileID && ecx == UniqueFileID+4 && edx == UniqueFileID+8
or eax, 1
ret
.endif
.endif
.endif
xor eax, eax
ret
IsHandleTheDAT endp
; ##########################################################################

BIN
sounds/10_rampage.wav Executable file

Binary file not shown.

BIN
sounds/11_dominating.wav Executable file

Binary file not shown.

BIN
sounds/12_unstoppable.wav Executable file

Binary file not shown.

BIN
sounds/13_wickedsick.wav Executable file

Binary file not shown.

BIN
sounds/14_holyshit.wav Executable file

Binary file not shown.

BIN
sounds/15_godlike.wav Executable file

Binary file not shown.

BIN
sounds/1_headshot.wav Executable file

Binary file not shown.

BIN
sounds/2_doublekill.wav Executable file

Binary file not shown.

BIN
sounds/3_triplekill.wav Executable file

Binary file not shown.

BIN
sounds/4_multikill.wav Executable file

Binary file not shown.

BIN
sounds/5_megakill.wav Executable file

Binary file not shown.

BIN
sounds/6_ultrakill.wav Executable file

Binary file not shown.

BIN
sounds/7_ludicrouskill.wav Executable file

Binary file not shown.

BIN
sounds/8_monsterkill.wav Executable file

Binary file not shown.

BIN
sounds/9_killingspree.wav Executable file

Binary file not shown.

3
sounds/License & Readme.txt Executable file
View File

@ -0,0 +1,3 @@
To the best of my knowledge these sound effects are from Unreal Tournament '99 and/or most Counter-Strike servers in the 1990's.
I did not create these sound effects, I claim no ownership of the .WAV contents of this folder.