Initial commit
This commit is contained in:
parent
8a0c46687c
commit
ef157f9223
45
README.md
45
README.md
|
@ -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
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
|
@ -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
|
||||
|
||||
; ##########################################################################
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
; ##########################################################################
|
|
@ -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
|
|
@ -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
|
||||
; ##########################################################################
|
|
@ -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
|
|
@ -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
|
||||
; ##########################################################################
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.
|
Loading…
Reference in New Issue