DyslexicCheater
6th November 2005, 05:32
I see people are still using UScript, and it saddens me. So, I guess I'll just have to teach you guys how to write your basic DLL Hook in C because noone is going to take the initiative and go do it themselves (Note, the word "Basic" - This won't give you any protection, but you will have access to everything within RvS' memory space).
Open your desired C/C++ IDE (For the purposes of this tutorial, I will use Microsoft Visual C++ 6). Create a new project and workspace. After that's done, create a new header file called "MyDLL.h". This will be the bulk of our DLL, as it will contain everything that makes it work. Open it in the editor. Now, the first thing that we are going to do is give some commands to the compiler from within our source to help us later during the release process. With that in mind, paste the following into our new header:#if _MSC_VER > 1000
#pragma once
#endif
#define VC_EXTRALEANHere we are telling the compiler that when it parses the headers that we define further on in our code, to only use the most common stuff in them. This saves us file size and speed due to the fact there is less shit to load into memory. Now we need to define the headers we wish to include.#include <windows.h> // Windows System APITo make our hack work, and to avoid having to create a lot of extra stuff on our own, we need access to Windows System API's. Our next task is to setup our macros and our naming conventions. I personally choose to use all capital letters in my conventions.#define FASTCALL __fastcall
#define BOOL bool
#define VOID void
typedef long LONG;
typedef int INT4;
typedef char CHAR;Now that all of that is over with, we can finally start programming our hacks and other other such things. This next function is one I wrote a long time ago to deal with placing function calls within the game's memory that lead to functions in my DLL. It is quite useful - but we will not be making use of it in this example.// This function will place a call instruction at a location of your choice, and optionally
// pad it with NOP instructions. It has 3 parameters. The first is the address at which you
// are placing the call. The second is the address of the function to call. The third is the
// amount of bytes to fill with NOP's. The third parameter accepts NULL as it's value.
// Example: fnPlaceFxnCall(0x508600, (DWORD)&fnStatHack, 4);
VOID FASTCALL fnPlaceFxnCall(DWORD dwAddressToPatch, DWORD dwFxnAddress, DWORD dwPadSize) {
// If the number of bytes to fill is NULL, make it 0.
dwPadSize = dwPadSize == NULL ? 0 : dwPadSize;
BYTE bytCallOperand = 0xE8;
DWORD dwDataBuffer = (FxnAddress - (AddressToPatch + 5));
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)AddressToPatch, 5 + dwPadSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
__asm {
MOV BYTE PTR [AddressToPatch], bytCallOperand
MOV [AddressToPatch+1], dwDataBuffer
}
for (DWORD x = dwPadSize; x > 0; x--) {
__asm {
MOV BYTE PTR [AddressToPatch+x], 90h
}
}
VirtualProtect((LPVOID)AddressToPatch, 5 + dwPadSize, dwOldProtect, &dwOldProtect);
}We are almost done :). The last thing we need for our DLL in our pre-compiled header is the function that activates our hack(s). Please note, that I haven't played RvS in a year or more, and I'm far too lazy to create a working hack for this example. So, with that out of the way, we will be using my very old (RvS v1.55) Infinite Ammo hack. This way you see how to do it, and at the same time I have less work to do (Again, I cannot stress enough - by using this hack, the end resulting DLL WILL NOT WORK! This is simply for the purposes of showing you the structure of a C DLL Hack).
Now, the part of code we want to change inside RvS is at the address 0x1011FA7A. Here we find the following code:DEC BYTE PTR [EDI]This code tells RvS to decrement (reduce by 1) the byte pointer at the address indicated by the EDI register. This is basically the pointer to the amount of ammo our player possesses. Now, we need to replace the DEC instruction with the NOP instruction (no process). With this information, we can begin to create our hack function.VOID fnAmmoHack() {
}Our first task in our new function is to setup the variables we will use.VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
}Now we have to unprotect the section of memory where the hack will be located (Note, that this step is only for use on Windows NT machines, as they are the only machines that possess this API and the ability to protect memory sections).VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)dwAmmoAddress, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect);
}Now we need to replace the 2 bytes of memory where our hack will be located (the DEC instruction with two NOP instructions).VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)dwAmmoAddress, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect);
__asm {
MOV BYTE PTR [dwAmmoAddress], 90h
MOV BYTE PTR [dwAmmoAddress+1], 90h
}
}Now we can finish up the hack by protecting the memory section again like it was before we messed with it.VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)dwAmmoAddress, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect);
__asm {
MOV BYTE PTR [dwAmmoAddress], 90h
MOV BYTE PTR [dwAmmoAddress+1], 90h
}
VirtualProtect((LPVOID)dwAmmoAddress, 2, dwOldProtect, &dwOldProtect);
}
Ok, the hack is done but we're not done yet. Make a new C/C++ source file called "MyDLL.cpp". We need to setup our DLL to handle communications with our target process.#include "MyDLL.h"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
// The DLL is being loaded into memory. Activate the hacks!
// Call our hack, activating it.
fnAmmoHack();
break;
case DLL_PROCESS_DETACH:
// The DLL is being unloaded from memory. Deactivate the hacks, and clean up!
// We don't need to clean anything up for this DLL.
break;
}
return true;
}
And we're done. Compiler options and settings aren't really a big issue for a small project like this. So, post your questions/comments.
Open your desired C/C++ IDE (For the purposes of this tutorial, I will use Microsoft Visual C++ 6). Create a new project and workspace. After that's done, create a new header file called "MyDLL.h". This will be the bulk of our DLL, as it will contain everything that makes it work. Open it in the editor. Now, the first thing that we are going to do is give some commands to the compiler from within our source to help us later during the release process. With that in mind, paste the following into our new header:#if _MSC_VER > 1000
#pragma once
#endif
#define VC_EXTRALEANHere we are telling the compiler that when it parses the headers that we define further on in our code, to only use the most common stuff in them. This saves us file size and speed due to the fact there is less shit to load into memory. Now we need to define the headers we wish to include.#include <windows.h> // Windows System APITo make our hack work, and to avoid having to create a lot of extra stuff on our own, we need access to Windows System API's. Our next task is to setup our macros and our naming conventions. I personally choose to use all capital letters in my conventions.#define FASTCALL __fastcall
#define BOOL bool
#define VOID void
typedef long LONG;
typedef int INT4;
typedef char CHAR;Now that all of that is over with, we can finally start programming our hacks and other other such things. This next function is one I wrote a long time ago to deal with placing function calls within the game's memory that lead to functions in my DLL. It is quite useful - but we will not be making use of it in this example.// This function will place a call instruction at a location of your choice, and optionally
// pad it with NOP instructions. It has 3 parameters. The first is the address at which you
// are placing the call. The second is the address of the function to call. The third is the
// amount of bytes to fill with NOP's. The third parameter accepts NULL as it's value.
// Example: fnPlaceFxnCall(0x508600, (DWORD)&fnStatHack, 4);
VOID FASTCALL fnPlaceFxnCall(DWORD dwAddressToPatch, DWORD dwFxnAddress, DWORD dwPadSize) {
// If the number of bytes to fill is NULL, make it 0.
dwPadSize = dwPadSize == NULL ? 0 : dwPadSize;
BYTE bytCallOperand = 0xE8;
DWORD dwDataBuffer = (FxnAddress - (AddressToPatch + 5));
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)AddressToPatch, 5 + dwPadSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
__asm {
MOV BYTE PTR [AddressToPatch], bytCallOperand
MOV [AddressToPatch+1], dwDataBuffer
}
for (DWORD x = dwPadSize; x > 0; x--) {
__asm {
MOV BYTE PTR [AddressToPatch+x], 90h
}
}
VirtualProtect((LPVOID)AddressToPatch, 5 + dwPadSize, dwOldProtect, &dwOldProtect);
}We are almost done :). The last thing we need for our DLL in our pre-compiled header is the function that activates our hack(s). Please note, that I haven't played RvS in a year or more, and I'm far too lazy to create a working hack for this example. So, with that out of the way, we will be using my very old (RvS v1.55) Infinite Ammo hack. This way you see how to do it, and at the same time I have less work to do (Again, I cannot stress enough - by using this hack, the end resulting DLL WILL NOT WORK! This is simply for the purposes of showing you the structure of a C DLL Hack).
Now, the part of code we want to change inside RvS is at the address 0x1011FA7A. Here we find the following code:DEC BYTE PTR [EDI]This code tells RvS to decrement (reduce by 1) the byte pointer at the address indicated by the EDI register. This is basically the pointer to the amount of ammo our player possesses. Now, we need to replace the DEC instruction with the NOP instruction (no process). With this information, we can begin to create our hack function.VOID fnAmmoHack() {
}Our first task in our new function is to setup the variables we will use.VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
}Now we have to unprotect the section of memory where the hack will be located (Note, that this step is only for use on Windows NT machines, as they are the only machines that possess this API and the ability to protect memory sections).VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)dwAmmoAddress, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect);
}Now we need to replace the 2 bytes of memory where our hack will be located (the DEC instruction with two NOP instructions).VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)dwAmmoAddress, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect);
__asm {
MOV BYTE PTR [dwAmmoAddress], 90h
MOV BYTE PTR [dwAmmoAddress+1], 90h
}
}Now we can finish up the hack by protecting the memory section again like it was before we messed with it.VOID fnAmmoHack() {
DWORD dwAmmoAddress = 0x1011FA7A;
DWORD dwOldProtect = 0;
VirtualProtect((LPVOID)dwAmmoAddress, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect);
__asm {
MOV BYTE PTR [dwAmmoAddress], 90h
MOV BYTE PTR [dwAmmoAddress+1], 90h
}
VirtualProtect((LPVOID)dwAmmoAddress, 2, dwOldProtect, &dwOldProtect);
}
Ok, the hack is done but we're not done yet. Make a new C/C++ source file called "MyDLL.cpp". We need to setup our DLL to handle communications with our target process.#include "MyDLL.h"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
// The DLL is being loaded into memory. Activate the hacks!
// Call our hack, activating it.
fnAmmoHack();
break;
case DLL_PROCESS_DETACH:
// The DLL is being unloaded from memory. Deactivate the hacks, and clean up!
// We don't need to clean anything up for this DLL.
break;
}
return true;
}
And we're done. Compiler options and settings aren't really a big issue for a small project like this. So, post your questions/comments.