mem-mem
December 1st, 2006, 11:07 PM
Here is the whole thing.
#define VERSION "v1.0"
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <d3d9.h>
#include "CDetour.h"
#include <Addrs.h>
//-------------
//Handy macro to execute a chunk of code only once
#define ONCE( var ) static bool var = false; if(! var ){ var = true;
//-------------
//Holds this DLL's address, for unloading later
HMODULE g_hLocalModule = NULL;
//Pointers to pointers to Direct3D instances Gunz uses
IDirect3D9** g_ppD3D = (IDirect3D9**)ADDR_PPD3D;
IDirect3DDevice9** g_ppDevice = (IDirect3DDevice9**)ADDR_PPDEVICE;
//Our local copies of those
IDirect3D9* g_pD3D = NULL;
IDirect3DDevice9* g_pDevice = NULL;
//A pointer to the almighty ZGame instance. Bow down. (NULL when not in game)
DWORD* g_pGame = (DWORD*)ADDR_PGAME;
//-------------
//This function returns a pointer to the local player - will return NULL if not in game
DWORD MyChar(){
//Omg, yes, so return the address of the local player as stored in the ZGame class instance (offset 0x4C)
return *(DWORD*)(*g_pGame + 0x4C);
}
//-------------
//The definition of the Gunz output chat function
typedef void (__cdecl* ZChatOutputFunc)(const char* lpcMsg, int iType /*= 0*/,int iLoc /*= 0*/, DWORD dwColor);
//Making the pointer to that func in Gunz
ZChatOutputFunc ZChatOutput = (ZChatOutputFunc)ADDR_ZCHATOUTPUT;
//Our own little interface function to it - works just like printf()
void Echo(const char* lpcFmt, ...){
//Temp buffer
char szBuf[0x4000];
//Our args list
va_list vaArgs;
//Take whatevers in lpcFmt and make a real string out of it
va_start(vaArgs, lpcFmt);
_vsnprintf(szBuf, sizeof(szBuf), lpcFmt, vaArgs);
va_end(vaArgs);
//Now that szBuf holds the formatted string, let's dump it to the chat display
ZChatOutput(szBuf, 1, 0, 0xFFFFFFFF);
}
//-------------
//This holds where the function should return back to (whoever actually called ZChat__Input)
DWORD g_dwUnloadRetAddr = 0;
//-------------
//This is where ZChat__Input is in Gunz
DWORD ZChat__Input = ADDR_ZCHATINPUT;
//The Detour for ZChat__Input
CDetour ZChat__InputDet;
//This is the ZChat__Input hook routine (who'd have guessed)
//Thanks to that detour, this will be called first whenever Gunz calls ZChat__Input
//Also, I highly recommend writing a command manager with argument handling. It's quite nice.
bool __stdcall ZChat__InputHook(const char* lpcLine){
//Var holding whether or not we should return back to ZChat__Input (let it actually run)
bool bRet = true;
//Was the chat entered "!info"?
if(stricmp(lpcLine, "!info") == 0){
//If so, we're intercepting it, so don't let Gunz actually send "!info" to the other people in the chat room! :P
bRet = false;
//Echo some ****
Echo("mem's dll " VERSION " Made by mem");
//Again, but for the unload command
}else if(stricmp(lpcLine, "!unload") == 0){
bRet = false;
Echo("Hax Unloading");
//Here's some magic - get the original return address of the ZChat__Input caller and slap that mofo in g_dwUnloadRetAddr
g_dwUnloadRetAddr = (DWORD)ZChat__InputDet.GetGateRetAddress();
//Are the first 7 characters "!fkmsg " ?
}else if(memcmp((void*)lpcLine, "!fkmsg ", 7) == 0)
//If so, replace that **** with new lines, but let the modified message be sent to the real chat handler
memset((void*)lpcLine, '\n', 7);
//Only return back to the original function (e.g. only let Gunz send the chat string) if bRet is true
ZChat__InputDet.Ret(bRet);
//Return true, telling Gunz that the string was handled (returning false will make whatever was typed stay in the box)
return true;
}
//No Clip
#define ADDR_NOCLIP 0x004D76DA
BYTE* NoClip_Addr = (BYTE*)ADDR_NOCLIP;
//Enable Cussing
#define ADDR_ENABLECUSSING 0x0050AE66
BYTE* EnableCussing_Addr = (BYTE*)ADDR_ENABLECUSSING;
//Name Hack
#define ADDR_NAMEHACK1 0x00409F2E
BYTE* NameHack1_Addr = (BYTE*)ADDR_NAMEHACK1;
#define ADDR_NAMEHACK2 0x00409F6E
BYTE* NameHack2_Addr = (BYTE*)ADDR_NAMEHACK2;
//Power Level
#define ADDR_PLVL 0x004720fc
BYTE* PowerLevel_Addr = (BYTE*)ADDR_PLVL;
//No Reload
#define ADDR_NORELOAD1 0x0047D692
BYTE* NoReload_Addr1 = (BYTE*)ADDR_NORELOAD1;
#define ADDR_NORELOAD2 0x0047D69C
BYTE* NoReload_Addr2 = (BYTE*)ADDR_NORELOAD2;
#define ADDR_NORELOAD3 0x0047D6BC
BYTE* NoReload_Addr3 = (BYTE*)ADDR_NORELOAD3;
//Infinite Guard
#define ADDR_INFINITEGUARD 0x0047D5E2
BYTE* InfiGuard_Addr = (BYTE*)ADDR_INFINITEGUARD;
//Lawnmower
#define ADDR_LAWNMOWER1 0x0047D548
BYTE* Lawnmower_Addr1 = (BYTE*)ADDR_LAWNMOWER1;
#define ADDR_LAWNMOWER2 0x0047D551
BYTE* Lawnmower_Addr2 = (BYTE*)ADDR_LAWNMOWER2;
#define ADDR_LAWNMOWER3 0x0047D55C
BYTE* Lawnmower_Addr3 = (BYTE*)ADDR_LAWNMOWER3;
//MSLawnmower
#define ADDR_MSLAWNMOWER 0x0047D643
BYTE* MSLawnmower = (BYTE*)ADDR_MSLAWNMOWER;
//Enable Spam
#define ADDR_ENABLESPAM 0x0042C6DE
BYTE* EnableSpam_Addr = (BYTE*)ADDR_ENABLESPAM;
//Rollerskates
#define ADDR_ROLLERSKATES1 0x00472062
BYTE* Rollerskates_Addr1 = (BYTE*)ADDR_ROLLERSKATES1;
#define ADDR_ROLLERSKATES2 0x0047206E
BYTE* Rollerskates_Addr2 = (BYTE*)ADDR_ROLLERSKATES2;
//Air Hook
#define ADDR_AIRHOOK1 0x00479819
BYTE* AirHook_Addr1 = (BYTE*)ADDR_AIRHOOK1;
#define ADDR_AIRHOOK2 0x00479BF0
BYTE* AirHook_Addr2 = (BYTE*)ADDR_AIRHOOK2;
#define ADDR_AIRHOOK3 0x0047D9A8
BYTE* AirHook_Addr3 = (BYTE*)ADDR_AIRHOOK3;
//No Ceiling
#define ADDR_NOCEILING 0x004F9A58
BYTE* NoCeiling_Addr = (BYTE*)ADDR_NOCEILING;
//Ninja Jump
#define ADDR_NINJAJUMP1 0x0047EBD2
BYTE* NinjaJump_Addr1 = (BYTE*)ADDR_NINJAJUMP1;
#define ADDR_NINJAJUMP2 0x0047EE8B
BYTE* NinjaJump_Addr2 = (BYTE*)ADDR_NINJAJUMP2;
//Float (Air Walk)
#define ADDR_FLOAT 0x00481EDB
BYTE* Float_Addr = (BYTE*)ADDR_FLOAT;
//Gunlock
#define ADDR_GUNLOCK 0x004D1704
BYTE* Gunlock_Addr = (BYTE*)ADDR_GUNLOCK;
//------------------------------------------------------------------------------------------------
//This takes the address of a character and returns a float pointer to it's location variable. It's a float[3], with x,y, and z coords
float* ZObject__GetPosition(void* pChar){
return (float*)((DWORD)pChar + 0x48);
}
//This takes the address of a character and returns a float pointer to it's location variable. It's a float[3], with x,y, and z coords
float* ZObject__GetDirection(void* pChar){
return (float*)((DWORD)pChar + 0x54);
}
//------------------------------------------------------------------------------------------------
float zspawnD[3] = {0, 0, 0};
float zspawnP[3] = {0, 0, 0};
DWORD dwMe = MyChar();
//------------------------------
if(stricmp(lpcLine, "/info") == 0){
bRet = false;
Echo("Commands: /noclip /noreload /float /rollerskates /gunlock /airhook /ninja /plvl /lawnmower /mslawnmower\nFunctions on Injection: Name Hack, Infinite Guard, Enable Cussing,\nEnable Spam");
//No Clip
{else if(stricmp(lpcLine, "/noclip") == 0){
bRet = false;
if(NoClip_Addr[4] != 0x90){
BYTE noclip[] = {0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_NOCLIP, noclip, 5);
Echo("No Clip ON");
}
else{
BYTE noclip[] = {0xE8, 0x91, 0x19, 0x02, 0x00};
EnableHack((BYTE*)ADDR_NOCLIP, noclip, 5);
Echo("No Clip OFF");
}
//Power Level
{else if(stricmp(lpcLine, "/plvl") == 0){
bRet = false;
if(PowerLevel_Addr[5] != 0x90){
BYTE powerlevel[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_PLVL, powerlevel, 6);
Echo("Power Level ON");
}
else{
BYTE powerlevel[] = {0xFF, 0x90, 0xB8, 0x00, 0x00, 0x00};
EnableHack((BYTE*)ADDR_PLVL, powerlevel, 6);
Echo("Power Level OFF");
}
//No Reload
{else if(stricmp(lpcLine, "/noreload") == 0){
bRet = false;
if(NoReload_Addr1[1] != 0x90){
BYTE noreload1[] = {0x90, 0x90};
BYTE noreload2[] = {0x90, 0x90};
BYTE noreload3[] = {0x90, 0x90};
EnableHack((BYTE*)ADDR_NORELOAD1, noreload1, 2);
EnableHack((BYTE*)ADDR_NORELOAD2, noreload2, 2);
EnableHack((BYTE*)ADDR_NORELOAD3, noreload3, 2);
Echo("Instant Reload ON");
}
else{
BYTE noreload1[] = {0x84, 0xC9};
BYTE noreload2[] = {0xA8, 0x08};
BYTE noreload3[] = {0x84, 0xC0};
EnableHack((BYTE*)ADDR_NORELOAD1, noreload1, 2);
EnableHack((BYTE*)ADDR_NORELOAD2, noreload2, 2);
EnableHack((BYTE*)ADDR_NORELOAD3, noreload3, 2);
Echo("Instant Reload OFF");
}
//Lawnmower
{else if(stricmp(lpcLine, "/lawnmower") == 0){
bRet = false;
if(Lawnmower_Addr1[1] != 0x90){
BYTE lawnmower1[] = {0x90, 0x90};
BYTE lawnmower2[] = {0x90, 0x90};
BYTE lawnmower3[] = {0x90, 0x90};
EnableHack((BYTE*)ADDR_LAWNMOWER1, lawnmower1, 2);
EnableHack((BYTE*)ADDR_LAWNMOWER2, lawnmower2, 2);
EnableHack((BYTE*)ADDR_LAWNMOWER3, lawnmower3, 2);
Echo("Lawnmower ON");
}
else{
BYTE lawnmower1[] = {0x74, 0x6B};
BYTE lawnmower2[] = {0x75, 0x62};
BYTE lawnmower3[] = {0x75, 0x57};
EnableHack((BYTE*)ADDR_LAWNMOWER1, lawnmower1, 2);
EnableHack((BYTE*)ADDR_LAWNMOWER2, lawnmower2, 2);
EnableHack((BYTE*)ADDR_LAWNMOWER3, lawnmower3, 2);
Echo("Lawnmower OFF");
}
//MSLawnmower
{else if(stricmp(lpcLine, "/mslawnmower") == 0){
bRet = false;
if(MSLawnmower[1] != 0x90){
BYTE mslawnmower[] = {0x90, 0x90};
EnableHack((BYTE*)ADDR_MSLAWNMOWER, mslawnmower, 2);
Echo("MSLawnmower ON");
}
else{
BYTE mslawnmower[] = {0x74, 0x39};
EnableHack((BYTE*)ADDR_MSLAWNMOWER, mslawnmower, 2);
Echo("MSLawnmower OFF");
}
//Rollerskates
{else if(stricmp(lpcLine, "/rollerskates") == 0){
bRet = false;
if(Rollerskates_Addr1[1] != 0x90){
BYTE rollerskates1[] = {0x90, 0x90};
BYTE rollerskates2[] = {0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_ROLLERSKATES1, rollerskates1, 2);
EnableHack((BYTE*)ADDR_ROLLERSKATES2, rollerskates2, 3);
Echo("Rollerskates ON");
}
else{
BYTE rollerskates1[] = {0x89, 0x0E};
BYTE rollerskates2[] = {0x89, 0x56, 0x04};
EnableHack((BYTE*)ADDR_ROLLERSKATES1, rollerskates1, 2);
EnableHack((BYTE*)ADDR_ROLLERSKATES2, rollerskates2, 3);
Echo("Rollerskates OFF");
}
//Air Hook
{else if(stricmp(lpcLine, "/airhook") == 0){
bRet = false;
if(AirHook_Addr1[5] != 0x90){
BYTE airhook1[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
BYTE airhook2[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
BYTE airhook3[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_AIRHOOK1, airhook1, 6);
EnableHack((BYTE*)ADDR_AIRHOOK2, airhook2, 6);
EnableHack((BYTE*)ADDR_AIRHOOK3, airhook3, 6);
Echo("Air Hook ON");
}
else{
BYTE airhook1[] = {0x88, 0x96, 0x21, 0x06, 0x00, 0x00};
BYTE airhook2[] = {0x88, 0x96, 0x21, 0x06, 0x00, 0x00};
BYTE airhook3[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_AIRHOOK1, airhook1, 6);
EnableHack((BYTE*)ADDR_AIRHOOK2, airhook2, 6);
EnableHack((BYTE*)ADDR_AIRHOOK3, airhook3, 6);
Echo("Air Hook OFF");
}
//Ninja Jump
{else if(stricmp(lpcLine, "/ninja") ==0){
bRet = false;
if(NinjaJump_Addr1[5] != 0x90){
BYTE ninjajump1[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_NINJAJUMP1, ninjajump1, 6);
Echo("Ninja Jump ON");
}
else{
BYTE ninjajump1[] = {0x0F, 0x84, 0xB2, 0x01, 0x00, 0x00};
EnableHack((BYTE*)ADDR_NINJAJUMP1, ninjajump1, 6);
Echo("Ninja Jump OFF");
}
//Float (Air Walk)
{else if(stricmp(lpcLine, "/float") == 0){
bRet = false;
if(Float_Addr[2] != 0x90){
BYTE float_addr[] = {0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_FLOAT, float_addr, 3);
Echo("Float (Air Walk) ON");
}
else{
BYTE float_addr[] = {0xD9, 0x5E, 0x10};
EnableHack((BYTE*)ADDR_FLOAT, float_addr, 3);
Echo("Float (Air Walk) OFF");
}
//Gunlock
{else if(stricmp(lpcLine, "/gunlock") == 0){
bRet = false;
if(Gunlock_Addr[5] != 0x90){
BYTE gunlock[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_GUNLOCK, gunlock, 6);
Echo("Gunlock ON");
}
else{
BYTE gunlock[] = {0x89, 0x81, 0x28, 0x11, 0x00, 0x00};
EnableHack((BYTE*)ADDR_GUNLOCK, gunlock, 6);
Echo("Gunlock OFF");
}
//------------------------------------------------------------------------------------------------
//Fake Message
{else if(memcmp((void*)lpcLine, "/fkmsg ", 7) == 0)
memset((void*)lpcLine, '\n', 7);
ZChat__InputDet.Ret(bRet);
return true;
}
//------------------------------------------------------------------------------------------------
//Name Hack
BYTE namehack1[] = {0x90, 0x90};
EnableHack((BYTE*)ADDR_NAMEHACK1, namehack1, 2);
BYTE namehack2[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_NAMEHACK2, namehack2, 6);
//Infinite Guard
BYTE infiguard[] = {0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_INFINITEGUARD, infiguard, 3);
//Enable Spam
BYTE enablespam[] = {0x90, 0x90};
EnableHack((BYTE*)ADDR_ENABLESPAM, enablespam, 2);
//Enable Cussing
BYTE enablecussing[] = {0x90, 0x90};
EnableHack((BYTE*)ADDR_ENABLECUSSING, enablecussing, 2);
//No Ceiling
BYTE nostun[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
EnableHack((BYTE*)ADDR_NOCEILING, nostun, 6);
//-------------
//The address of the RealSpace2__RFlip function in Gunz (called after everything's rendered but before it's put on screen)
DWORD RealSpace2__RFlip = ADDR_RFLIP;
//The Detour
CDetour RealSpace2__RFlipDet;
//A handy yet ghetto macro of doing keybinds
#define KEYBIND( var , key ) static bool var = false; if(GetAsyncKeyState( key ) < 0){ var = true; }else if( var ){ var = false;
//Anchor feature variables
bool g_bAnchor = false;
float g_fAnchorPos[3] = {0, 0, 0};
//The function that will be called whenever Gunz calls RealSpace2__RFlip
void RealSpace2__RFlipHook(){
//Get my character
DWORD dwMe = MyChar();
//Do we have a character? If not, Gunz could be loading, you could be in a chat room, or whatever.
//Bottom line is that we don't wanna do game stuff when not in game
if(dwMe){
//Check for the Anchor toggle key (C)
KEYBIND(bAnchor, 'C')
//It was pressed, so toggle our anchor variable
g_bAnchor = !g_bAnchor;
//Is it currently on?
if(g_bAnchor)
//If so, grab our player's location and put it into g_fAnchorPos
//We will set it to g_fAnchorPos every frame, effectively 'anchoring' us in 1 location
memcpy(g_fAnchorPos, ZObject__GetPosition((void*)dwMe), sizeof(float) * 3);
//Handy.
Echo("Anchor: %s", ((g_bAnchor) ? "On" : "Off"));
}
//Is Anchor on?
if(g_bAnchor)
//If so, teleport us to wherever we turned the anchor on (regardless of gravity, velocity, round reset, whatever - we'll be there)
memcpy(ZObject__GetPosition((void*)dwMe), g_fAnchorPos, sizeof(float) * 3);
//Render your HUD here - look up some d3d9 tuts
}
}
//-------------
//The function we call when the DLL is loaded
void Initialize(){
//Apply our RealSpace2__RFlip detour
RealSpace2__RFlipDet.Detour((BYTE*)RealSpace2__RFlip, (BYTE*)RealSpace2__RFlipHook, true);
RealSpace2__RFlipDet.Apply();
//Apply the ZChat__Input detour.
ZChat__InputDet.Detour((BYTE*)ZChat__Input, (BYTE*)ZChat__InputHook, true);
ZChat__InputDet.Apply();
//Set up our MLog detour to route to echo, but don't apply it just yet
MLogDet.Detour((BYTE*)MLog, (BYTE*)MLogHook);
//Huzzah.
Echo("GunzHax Loaded");
}
//This one's called when our DLL is unloading, either when Gunz is closing or when the unload command is run.
//Note that if Gunz is closing, you're really kinda allowed to crash, it doesn't really matter at that point.
void Shutdown(){
//Remove our detours
RealSpace2__RFlipDet.Remove();
ZChat__InputDet.Remove();
}
//-------------
//The function windows calls when DLL events happen (loading, unloading, some thread stuff)
bool WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved){
//Was the reason this was called because our DLL just loaded?
if(dwReason == DLL_PROCESS_ATTACH){
//Extra saftey, but should never happen
ONCE(bHasLoaded)
//Set our global variable that holds our local image base
g_hLocalModule = hModule;
//Lets get this **** going
Initialize();
}
//Or maybe we're being unloaded
}else if(dwReason == DLL_PROCESS_DETACH){
//Again, sweet sanity
ONCE(bHasShutdown)
//DIE DIE DIE.
Shutdown();
}
}
}