Archive for June, 2009

Hades Extension Loading

Posted in Games, Programming, Reversing, Windows on June 29th, 2009 by Cypherjb – 6 Comments

Hades now has extension loading support! The API is still in the process of being exposed to the extension interface, but that should only take another 15 minutes or so to smooth out.

This is a great step forward because it means extensions can be loaded and unloaded on the fly without having to restart the process (as was the case when it was compiled as a static lib). Furthermore, it means that the modules are independent from changes to the Hades DLL and as long as no breaking interface changes are made should work with updated DLLs without the need for a recompile (as opposed to a static lib where a recompile is obviously necessary, or rather, a relink).

Naturally, both x86 and x64 are tested and working.

One issue I had with this was with the exposure of the interface. It seem that I can’t do what D3D does and do a C-style interface exposure because my interface is just too C++ heavy for me to be able to convert it to work that way. Not that it matters though, all the information exposed via exports is already available in the SDK.

Update (29/06/09):

Scratch that issue, got it working through some minor modifications and the magic of virtual functions! (Okay not magic, but it’s still a nice workaround.)

Calling Exports in an Injected DLL

Posted in Programming, Windows on June 29th, 2009 by Cypherjb – 6 Comments

There’s a long list of things you’re not supposed to do in DllMain, typically you’re supposed to work around this by exporting a function to do all your actual initialization and calling that after your module is fully loaded. The problem is, this is hard when using an injected DLL, because you need to create another remote thread at a location that can only be determined at runtime. When faced with this problem my original solution was to get the module base address in the remote process and manually walk the EAT using ReadProcessMemory. Half way through writing that though I thought of an easier way, a way I could ‘cheat’. Rather than walk the EAT in the remote process I’d simply load the module without calling DllMain or performing any static linking then walk the EAT locally. I did this because I already had local EAT walking code and it’s much simpler to write.

I figured others would have had the same problem so I’m posting some sample code to get you started. I only finished it 10 minutes ago so it’s ANSI only, very lightly tested, relies on a bunch of internal classes, etc. You should easily be able to pull the logic from this though and port it to your needs with minimal changes.

// Call an exported function in a module in a remote process

DWORD Injector::CallExport(DWORD ProcID, const string& ModuleName,

const string& ExportName)

{

// Grab a new snapshot of the process

EnsureCloseHandle Snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,

ProcID));

if (Snapshot == INVALID_HANDLE_VALUE)

throw runtime_error(”Injector::CallExport: Could not get module ”

“snapshot for remote process.”);

// Get the HMODULE of the desired library

MODULEENTRY32W ModEntry = { sizeof(ModEntry) };

bool Found = false;

BOOL bMoreMods = Module32FirstW(Snapshot, &ModEntry);

for (; bMoreMods; bMoreMods = Module32NextW(Snapshot, &ModEntry))

{

wstring ExePath(ModEntry.szExePath);

wstring ModuleTmp(ModuleName.begin(), ModuleName.end());

Found = (ExePath == ModuleTmp);

if (Found) break;

}

if (!Found)

throw runtime_error(”Injector::CallExport: Could not find module in ”

“remote process.”);

// Get module base address

PBYTE ModuleBase = ModEntry.modBaseAddr;

// Get a handle for the target process.

EnsureCloseHandle Process(OpenProcess(

PROCESS_QUERY_INFORMATION |

PROCESS_CREATE_THREAD     |

PROCESS_VM_OPERATION      |

PROCESS_VM_READ,

FALSE, ProcID));

if (!Process)

throw runtime_error(”Injector::CallExport: Could not get handle to ”

“process.”);

// Load module as data so we can read the EAT locally

EnsureFreeLibrary MyModule(LoadLibraryExA(ModuleName.c_str(), NULL,

DONT_RESOLVE_DLL_REFERENCES));

// Get module pointer

PVOID Module = static_cast<PVOID>(MyModule);

// Get pointer to DOS header

PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(

static_cast<HMODULE>(Module));

if (!pDosHeader || pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)

throw runtime_error(”Injector::CustomGetProcAddress: DOS PE header ”

“is invalid.”);

// Get pointer to NT header

PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>

(reinterpret_cast<PCHAR>(Module) + pDosHeader->e_lfanew);

if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)

throw runtime_error(”Injector::CustomGetProcAddress: NT PE header ”

“is invalid.”);

// Get pointer to image export directory

PVOID pExportDirTemp = reinterpret_cast<PBYTE>(Module) +

pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].

VirtualAddress;

PIMAGE_EXPORT_DIRECTORY pExportDir =

reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(pExportDirTemp);

// Symbol names could be missing entirely

if (pExportDir->AddressOfNames == NULL)

throw runtime_error(”Injector::CustomGetProcAddress: Symbol names ”

“missing entirely.”);

// Get pointer to export names table

PDWORD pNamesRvas = reinterpret_cast<PDWORD>(

reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNames);

// Get pointer to export ordinal table

PWORD pNameOrdinals = reinterpret_cast<PWORD>(

reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNameOrdinals);

// Get pointer to export address table

PDWORD pFunctionAddresses = reinterpret_cast<PDWORD>(

reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfFunctions);

// Variable to hold the export address

FARPROC pExportAddr = 0;

// Walk the array of this module’s function names

for (DWORD n = 0; n < pExportDir->NumberOfNames; n++)

{

// Get the function name

PSTR CurrentName = reinterpret_cast<PSTR>(

reinterpret_cast<PBYTE>(Module) + pNamesRvas[n]);

// If not the specified function, try the next function

if (ExportName != CurrentName) continue;

// We found the specified function

// Get this function’s Ordinal value

WORD Ordinal = pNameOrdinals[n];

// Get the address of this function’s address

pExportAddr = reinterpret_cast<FARPROC>(reinterpret_cast<PBYTE>(Module)

+ pFunctionAddresses[Ordinal]);

// We got the func. Break out.

break;

}

// Nothing found, throw exception

if (!pExportAddr)

throw runtime_error(”Injector::CustomGetProcAddress: Could not find ”

+ ExportName + “.”);

// Convert local address to remote address

// TODO: Clean the casts. Currently working but could be simplified.

PTHREAD_START_ROUTINE pfnThreadRtn =

reinterpret_cast<PTHREAD_START_ROUTINE>((reinterpret_cast<DWORD_PTR>(

pExportAddr) - reinterpret_cast<DWORD_PTR>(Module)) +

reinterpret_cast<DWORD_PTR>(ModuleBase));

// Create a remote thread that calls FreeLibrary()

EnsureCloseHandle Thread(CreateRemoteThread(Process, NULL, 0,

pfnThreadRtn, ModEntry.modBaseAddr, 0, NULL));

if (!Thread)

throw runtime_error(”Injector::CallExport: Could not create thread in ”

“remote process.”);

// Wait for the remote thread to terminate

WaitForSingleObject(Thread, INFINITE);

// Get thread exit code

DWORD ExitCode = 0;

if (!GetExitCodeThread(Thread,&ExitCode))

throw runtime_error(”Injector::CallExport: Could not get thread exit ”

“code.”);

// Return thread exit code

return ExitCode;

}

DWORD Injector::CallExport(DWORD ProcID, const string& ModuleName,
const string& ExportName)
{
// Grab a new snapshot of the process
EnsureCloseHandle Snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
ProcID));
if (Snapshot == INVALID_HANDLE_VALUE)
throw runtime_error(”Injector::CallExport: Could not get module “
“snapshot for remote process.”);
// Get the HMODULE of the desired library
MODULEENTRY32W ModEntry = { sizeof(ModEntry) };
bool Found = false;
BOOL bMoreMods = Module32FirstW(Snapshot, &ModEntry);
for (; bMoreMods; bMoreMods = Module32NextW(Snapshot, &ModEntry))
{
wstring ExePath(ModEntry.szExePath);
wstring ModuleTmp(ModuleName.begin(), ModuleName.end());
Found = (ExePath == ModuleTmp);
if (Found) break;
}
if (!Found)
throw runtime_error(”Injector::CallExport: Could not find module in “
“remote process.”);
// Get module base address
PBYTE ModuleBase = ModEntry.modBaseAddr;
// Get a handle for the target process.
EnsureCloseHandle Process(OpenProcess(
PROCESS_QUERY_INFORMATION |
PROCESS_CREATE_THREAD     |
PROCESS_VM_OPERATION      |
PROCESS_VM_READ,
FALSE, ProcID));
if (!Process)
throw runtime_error(”Injector::CallExport: Could not get handle to “
“process.”);
// Load module as data so we can read the EAT locally
EnsureFreeLibrary MyModule(LoadLibraryExA(ModuleName.c_str(), NULL,
DONT_RESOLVE_DLL_REFERENCES));
// Get module pointer
PVOID Module = static_cast<PVOID>(MyModule);
// Get pointer to DOS header
PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(
static_cast<HMODULE>(Module));
if (!pDosHeader || pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
throw runtime_error(”Injector::CustomGetProcAddress: DOS PE header “
“is invalid.”);
// Get pointer to NT header
PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>
(reinterpret_cast<PCHAR>(Module) + pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
throw runtime_error(”Injector::CustomGetProcAddress: NT PE header “
“is invalid.”);
// Get pointer to image export directory
PVOID pExportDirTemp = reinterpret_cast<PBYTE>(Module) +
pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].
VirtualAddress;
PIMAGE_EXPORT_DIRECTORY pExportDir =
reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(pExportDirTemp);
// Symbol names could be missing entirely
if (pExportDir->AddressOfNames == NULL)
throw runtime_error(”Injector::CustomGetProcAddress: Symbol names “
“missing entirely.”);
// Get pointer to export names table
PDWORD pNamesRvas = reinterpret_cast<PDWORD>(
reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNames);
// Get pointer to export ordinal table
PWORD pNameOrdinals = reinterpret_cast<PWORD>(
reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNameOrdinals);
// Get pointer to export address table
PDWORD pFunctionAddresses = reinterpret_cast<PDWORD>(
reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfFunctions);
// Variable to hold the export address
FARPROC pExportAddr = 0;
// Walk the array of this module’s function names
for (DWORD n = 0; n < pExportDir->NumberOfNames; n++)
{
// Get the function name
PSTR CurrentName = reinterpret_cast<PSTR>(
reinterpret_cast<PBYTE>(Module) + pNamesRvas[n]);
// If not the specified function, try the next function
if (ExportName != CurrentName) continue;
// We found the specified function
// Get this function’s Ordinal value
WORD Ordinal = pNameOrdinals[n];
// Get the address of this function’s address
pExportAddr = reinterpret_cast<FARPROC>(reinterpret_cast<PBYTE>(Module)
+ pFunctionAddresses[Ordinal]);
// We got the func. Break out.
break;
}
// Nothing found, throw exception
if (!pExportAddr)
throw runtime_error(”Injector::CustomGetProcAddress: Could not find “
+ ExportName + “.”);
// Convert local address to remote address
// TODO: Clean the casts. Currently working but could be simplified.
PTHREAD_START_ROUTINE pfnThreadRtn =
reinterpret_cast<PTHREAD_START_ROUTINE>((reinterpret_cast<DWORD_PTR>(
pExportAddr) - reinterpret_cast<DWORD_PTR>(Module)) +
reinterpret_cast<DWORD_PTR>(ModuleBase));
// Create a remote thread that calls FreeLibrary()
EnsureCloseHandle Thread(CreateRemoteThread(Process, NULL, 0,
pfnThreadRtn, ModEntry.modBaseAddr, 0, NULL));
if (!Thread)
throw runtime_error(”Injector::CallExport: Could not create thread in “
“remote process.”);
// Wait for the remote thread to terminate
WaitForSingleObject(Thread, INFINITE);
// Get thread exit code
DWORD ExitCode = 0;
if (!GetExitCodeThread(Thread,&ExitCode))
throw runtime_error(”Injector::CallExport: Could not get thread exit “
“code.”);
// Return thread exit code
return ExitCod

Progress Update

Posted in Games, Programming, Reversing, Windows on June 27th, 2009 by Cypherjb – 11 Comments

Yes I know I said I’d be looking at the new mimic build and I still will, but recently I’ve just been busy with more interesting stuff.

I added base .NET support to Hades (thanks Grey and Kynox for the help) . I improved the LUA support. I began adding event subscription support to LUA, I began adding event subscription and callback support to .NET, I continued the implementation of some D3D helper libs I was writing, and lastly, I began working on some random WoW stuff in order to test all the aforementioned things.

It’s just a ‘PVP mode’ ESP hack designed to make PvP just that little bit more unfair. (Thanks to Kynox for the camera/w2s stuff!)

Green is low risk (friendly), yellow is medium risk (hostile but not an immediate thread), red is high risk (hostile and an immediate threat).

Hades Lua Support

Posted in Games, Programming, Reversing, Windows on June 24th, 2009 by Cypherjb – 4 Comments

Just finished adding the very first revision of LUA support to Hades. Currently it’s just a proof of concept, as all it does is load a LUA script which calls a custom function I’ve registered to print the arguments passed to the function to the console. Getting that first bit done and working though is the biggest hurdle, so with that finished I can now move on to writing proper code for it and exposing my whole API.

Both x86 (WoW) and x64 (HL2) builds are tested and working.

Hades x64 Support Improved

Posted in Games, Programming, Reversing, Windows on June 22nd, 2009 by Cypherjb – 6 Comments

Finally fixed a bug that was causing flakey x64 support in Hades (well, the ‘bug’ was actually in HL2 it seems… but I digress). It finally works without issue in both HL2 (which worked in the first build but was flakey at time), and HL2 LC (which didn’t work for the first build). Unfortunately these are the only x64 games I can find the discs for. I’m hoping to get another copy of Crysis and UT 2k4 soon (both of which I have keys for but have lost the actual DVDs) which will allow me to test x64 more extensively, as well as D3D10 (on Crysis, for both x86 and x64), and also ensure Hades doesn’t break the x64 builds of SecuROM (because I had trouble originally with the x86 version before making some of my hooks a little less agressive).

Screenshots of Hades running in x64 builds of HL2 and HL2 LC:

Caution Hooking SetWindowLong(Ptr)

Posted in Games, Programming, Reversing, Windows on June 22nd, 2009 by Cypherjb – 5 Comments

Recently I’ve been doing a lot of bug fixes for Hades in order to increase compatiability with a number of Valve’s games. During this time I came across a bug that fixed a LOT of issues I was having. Currently Hades hooks SetWindowLong and SetWindowLongPtr in order to prevent the game subclassing the window and inserting a custom window procedure above the one owned by Hades. The reason this needs to be done is so that I can ensure Hades always gets ‘first dibs’ on input into the game.

I noticed though that this was causing problems with a number of Valve’s games. After reading over my code for a bit I came across the bug which was obvious in hindsight yet seemed innocent enough at the time. When implementing the hook I got a little lazy, and rather than subclassing only the window handles passed in by the D3D layer, I was just hooking ALL windows that were being passed into the API. Needless to say this is NOT a good idea and can cause great instability.

Low and behold as soon as I filtered it just to rendering windows the issues went away and a handful of games ‘magically’ started working properly.

Whilst I’m much too lazy to actually debug it to the point where I can work out which window was causing issues and why, it suffices to say that it’s probably a bad idea to hook any more windows than you actually need.

Screenshots of the newly supported games:

Hades. Now with x64 support!

Posted in Games, Programming, Reversing, Windows on June 20th, 2009 by Cypherjb – 3 Comments

I just managed to get Hades working in native x64 mode, which is a huge step forward. Not even InnerSpace can do that at the moment. Currently I only have one game to test it on because I can’t find half my fucking game discs >.<. I’ll be getting my hands on some more x64 games soon though, so that should be good.

The game I currenly have and am testing is Half-Life 2. Below is a screenshot of the first working build. Please disregard the profanity, Kynox was trying to troll me on IRC about not being able to get it working, and pretty much just as he said that I did infact get it working .

I had some very minor issues porting the code over, but luckily (and surprisingly) I didn’t fuck up much at all so it nearly worked “out of the box”. Only took about 30 minutes to track down and fix the issues I was having.

Pretty much the only one that was an actual issue and not just caused by a typo, wrong datatype, etc was with hooking the window subclassing APIs. Don’t forget that SetWindowLongPtrA/W resolves to SetWindowLongA/W via a #define under x86, yet is an actual API of that name under x64. If you don’t explicitly handle that then you’ll be hooking the wrong API and you won’t be able to get subclass detection and rehooking working correctly (if at all).

Honestly I’m amazed at how easy it was to get working. Makes me wonder why the rest of the tools out there are lagging so far behind.

Anyway, I guess I’ll test this for a bit longer, fix any bugs I find, then move on to getting D3D10 working and stable.

Update on Mimic

Posted in Games, Programming, Reversing, Windows on June 19th, 2009 by Cypherjb – 3 Comments

Hey, as most of the people interested in the Mimic saga already know, a new version is out.  A bunch of people have contacted me to ask if I would be posting about it, so I figured I’d post an explanation as to why I may or may not be. Kynox has done a minor coverage of the update available.

I may or may not do a full and in-depth coverage for three reasons:

  1. I think it has been proven beyond doubt now that Mimic is indeed full of shit when it comes to their anti-anti-cheat code.
  2. I think they have been given enough handouts for now.
  3. Working on my new project is simply much more fun.

That being said, if I get bored I might take a look at the changes, but all I will be doing is documenting them, and pointing out whether it as a whole is still detectable. I will no longer be handing them free anti-warden ideas, they’re on their own now.

New Game Hacking Framework Project

Posted in Games, Programming, Reversing, Windows on June 18th, 2009 by Cypherjb – 9 Comments

Bored, so I figured I’d post screenies of something I’m currently working on. It’s a generic game-hacking framework (similar to InnerSpace). It’s pretty much just for myself and very close friends for use on whatever game I feel like hacking at the time. I’m hoping to get a really awesome system in place by the time Blizzard release their next MMO. Which so far seems like it will be a while off, which is “good”, because as soon as that comes out I wanna tear it a new arsehole right from the get-go.

Work only really started this week, so progress is slow so far as most of the work is being done designing efficient and easy to use APIs. I’d rather spend a month or so getting the backbone right, then throw lots of features onto something shaky and have to go rewrite it and do 10x the work fixing up the dependencies later on.

Anyway, so far it supports D3D9 games, using both DirectInput and standard message based input. The only game I have that I currently can’t get it working on is HAWX. It renders but I can’t get input hooking in it working properly (though, that being said, InnerSpace doesn’t even render in HAWX, let alone get input, so I’m happy that I’m already +1 in that regard ).

The feature list I’m currently looking at implementing is:

  • DLL injector supporting both CreateProcess (as suspended) and on-the-fly injection methods. Both x86 and x64. (Done.)
  • CreateProcess injection style support for STEAM games. (x86 Done. x64 needs minor fixes due to STEAM being x86 and the x86 DLL not being able to boostrap the x64 injection code. Easy fix, I’m just lazy.)
  • Injection “chaining”, so if you want to use CreateProcess style injection on a program that requries it be launched through a boostrapper — e.g. STEAM, Eve, etc — then the DLL will hook CreateProcess and automatically ‘chain’ injection until it hits the process you request. (Done.)
  • D3D9 support. (Currently in RC)
  • GUI system. (Currently in Alpha. Using CEGUI.)
  • Generic event-based API for rendering, input, etc. (Currently in Alpha.)
  • D3D10 support. (Currently in Alpha)
  • D3D11 support. (Waiting on W7 and a D3D11 game to come out )
  • x64 support. (Currently in Alpha)
  • .NET support.
  • Scripting for the command-line (LUA).
  • Generic Anti-Anti-Cheat. (Currently in Beta. Tested and working against VAC2 and Warden.)
  • Lots of generic helper APIs that can be applied to any game (pattern scanning, memory modification, code hooking, etc).

Before anyone gets the wrong idea though. This is a private project designed solely for my personal use. I am not interested in releasing this publicly, and as such very minimal (if any) code will be provided. The main reason I’m posting about this is because I instead wish to document any problems I come across while developing it, and how I solved them, in the hope that others may find the information useful, or even have a better way to solve the same problem.

Screenshots from the games I’ve tested so far:

Surf’s Up

Posted in Uncategorized on June 17th, 2009 by Cypherjb – 3 Comments

http://kynox.wordpress.com/2009/06/17/surfs-up/