Code: ; Like this MOV EAX, 1440h ; And this MOV QWORD PTR SS:[RBP+1460], RSI

Code: mov qword ptr ss:[rsp+10],rdx mov qword ptr ss:[rsp+18],r8 mov qword ptr ss:[rsp+20],r9 ret

C++: void Log(const char* rcx, void* rdx, void* r8, void* r9) { printf(rcx, rdx, r8, r9); }

C++: // You know what this does: comon moduleBaseAddr = (uintptr_t)GetModuleHandle(NULL); // Hook for retriving console output uintptr_t consoleOutput = (moduleBaseAddr + 0x401F620); printf("[?] Console hook at: %llx

", consoleOutput); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)consoleOutput, Log); LONG lError = DetourTransactionCommit(); if (lError != NO_ERROR) { printf("[-] Failed to detour"); return FALSE; }

C++: // Win32 message handler extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (bShowConsole) { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return 0; } switch (msg) { case WM_KEYDOWN: if (wParam == 192) { // ~ bShowConsole = !bShowConsole; ImGuiIO& io = ImGui::GetIO(); (void)io; io.MouseDrawCursor = bShowConsole; } return 0; case WM_DESTROY: ::PostQuitMessage(0); return 0; } return ::DefWindowProc(hWnd, msg, wParam, lParam); }

C++: // Setup the structure uintptr_t baseObject = *((uintptr_t*)(moduleBaseAddr + 0x218BDA0)); char* cmdString = (char*)(baseObject + 0x28); int* cmdLength = (int*)(baseObject + 0x20); // Overwrite the data memcpy(cmdString, cmd, strlen(cmd) + 1); *cmdLength = strlen(cmd) + 1; // Create a function pointer to the exec command typedef void(__fastcall* executeCommand_t)(uintptr_t); executeCommand_t fnExecuteCommand = (executeCommand_t)(moduleBaseAddr + 0x3FA6B10); // EXECUTE fnExecuteCommand(baseObject);

still

Dishonored 2Arkane StudiosVoidEngine (based on idTech 5)v1.77.5.0DenuvoStill not quite finished with messing around in the internals of the idTech engine I decided to take a look at Dishonored 2 which switched from Unreal Engine 3 over to idTech for the sequel. The first thing I noticed was no console. No matter what command line options I used or config files I changed I couldn't get the console to come down. Puzzled I started searching the web looking for any references I could when I stumbled upon this post by SunBeam on Fearless Interesting. If you're too lazy to read (which I highly recommend you do) he basically comes to the conclusion that code responsible for powering the console has been stripped from the executable. My response was similar to the following:So I set off to restore the console to it's former glory.Within the idTech engine there's a few key functions responsible for retrieving what the user types, parsing it and displaying it. However with DH2 the code that draws to the screen is gone as is the memory buffer which the console allocates to store all the text (or appeared that way anyhow). In order to fix this we're going to have to place a few hooks and write some replacement code for the missing parts. This is not as as difficult as writing a w2s for AOE so don't panic ( @BDKPlayer ).How do we find all these functions to hook? x64dbg, a coffee and some decent tunes. Fair warning to those new to reversing it takes time and it is an extremely long process until you're very familiar with the internals of the game and assembly code in general. So if you lack the disciprine or motivation to spend hours trawling over red hot assembler maybe just stick to changing your ammo to 1337 on AssaultCube with Cheat Engine.In the post SunBeam mentions the parse / execute function of the console. At least in my version of the game the execute function was not located in the same place in memory. So how to find? Well if we examine the assembler code there's a few instructions that look fairly unique:However this can change from version to version.Another way to find it is if you know idTech (which I do) there's a number of hard-coded strings in most games when you type an invalid console command:And if we scroll up slightly:This is typically where experience and intuition pays off for reversing. Although the functions are slightly different from one another they are functionally identical and a quick read through the code reveals that.So since we have no console to type anything, nor do we know the names of any functions to test we'll have to leave the executing of commands for later. What would be really helpful is if we could somehow capture the output from the game to learn more about the internals. One of the good things about idTech is it has so many fucking strings it makes it really easy to locate code in a debugger.If we go back to our string references we can attempt to locate a string that would (probably) be out-putted to the console. Some useful things to try would be the name of developers, the name of the engine, map, initialization, "%s

" etc.For example:If we drop into the function where the string is referenced:Take a few seconds to read over the code and tell me what you see. There's a pattern here try to figure it out before continuing the article (I'll wait).If you said MOV EDX, LEA RCX, CALL: you win the prize! It's a pretty safe bet that dishonored2.14401F620 is some type of logging call. However just from looking at the disassembly above we can see it most likely takes variable parameters. Meaning our function is going to need to be able to handle that without corrupting the stack.If this is starting to become too intense for you, stop the tutorial go through the beginner's guide (specifically the calling internal functions one) and come back to this later.If we place a break point on the dishonored2.14401F620 function we can observe the stack and see what the function does with the passed in parameters.Here's the disassembly of the function (it's weird):That looks like an incomplete call to a class function, there's a similar function in Doom 2016 and it has bit more going on. I guess this sort of proves SunBeam was correct for assuming the code had been stripped in the release binary.This is where Denuvo is a goddamn pain in the ass. You can't launch the game with a debugger attached or it will refuse to load. If you're quick enough you can run the game and immediately attach x64dbg as the window opens. This is the first annoyance with Denuvo there's several more coming. You really want to attach as quickly as possible so you can view all the data flowing into the function.Here's a dump of the registers:So we can see that the string is passed in via RCX, followed by three parameters in RDX, R8 and R9. If I was to guess I'd say the function looks a bit like this:In fact we can test this by quickly throwing a DLL together and hooking that function:And we should get some nice output like so:This is all good and well but it's a bit basic and crappy looking. How about making it look a bit more professional and actually having the console inside the game and usable like it's supposed to be? It's fairly simple to integrate ImGui and borrow the ConsoleApp code from the examples.Now check this out:It's pretty hard to click on a thing if you have to guess where your mouse cursor is. Luckily we can just ask ImGui to render the mouse for us when the console is active:So good so far we can toggle the console with '~' and draw a mouse pointer to interact with it. But we're only HALF done we need to go back and finish our console execution code.And the only solution is executing internal game functions. Luckily SunBeam put most of the pieces together on this one (HINT: Go read his post). All we need to do quickly put some code together in C++.I'll re-explain how it works just in-case the post goes offline.The function takes a pointer to a structure but it only cares about the string pointer and length at offset 0x28 and 0x20 repectively. This structure already exists within the game's memory so we can simply overwrite it with our values:Now we should be able to run the game, inject our DLL and BEHOLD:It'll become immediately apparent that our console is fairly limited in what we can do. Arkane Studios decided that they didn't want any filthy, disgusting, leprous cheaters dicking about in their super secret dev console. There's a number of protections in place but the biggest one is a lot of commands either point to partial or null code. So bypassing the protection is useless if calling the command will crash the game.However some commandsdo work. I couldn't be bothered to try them all but one command I found particularly useful and built it into my code.