Warface:Internal No Flash from Scratch
Original work by: Dark1027 |
Contents
Dump Warface
You can use PETools. Start the game from the games directory, not via the launcher!
In my case the Game.exe is located here:
E:\Warface\Warface My.Com\Bin32Release
You should get an error message like this when running Game.exe:
Save it as "Dumped" or something like that.
No open it up in IDA. (You need at least IDA 6.6 Pro or newer.)
Follow this tutorial on how to do so.
Reverse SSystemGlobalEnvironment and I3DEngine
After you opened it and IDA finished analyzing it we want to find SSystemGlobalEnvironment.
Because in warface you can do an internal no flash like this:
SSystemGlobalEnvironment->I3DEngine->SetPostEffectParam("Flashbang_Time", 0, true)
So, lets find SSGE.
Press Shift+F12 to bring up a list of the games strings.
Now press Ctrl+F and search for "ai_CompatibilityMode" (without the ")
It should look like this:
Now double click it and should bring you here:
Press x on "aAi_compatibily" and press OK on the window that opens.
This should bring you here:
Now look at the line above the string.
The "dword_" is our SSystemGlobalEnvironment. Right click on it and select "Rename" or press n:
and rename it to something like SSystemGlobalEnvironment.
Remember what else we need? Right, I3DEngine and SetPostEffectParam.
To find them open the strings but this time search for "Dof_Active", double click on it and press x.
Now you see that there are a few more results.
Lets just chose the first one because its most likely a working one.
Select it and press OK. This should take you here:
You can already see the references to SSystemGlobalEnvironment. Now lets press Tab (or F5) to open the Hex-Rays pseudocode.
If that doesnt work try it again and make sure you have the Pro version, it sometimes shows something weird on the first try.
It should now take you here:
There we can already see the call:
Right click on the 148 and select Hexadecimal to show the value as a hexadecimal value.
Now it should look like this:
So here we have SSystemGlobalEnvironment + 0x94. That is I3DEngine.
Reconstruct SSystemGlobalEnvironment and I3DEngine
Lets hop into ReClass to create the SSystemGlobalEnvironment class.
It should look something like this when you open it up (make sure its not a x64 ReClass):
Now lets press on "New" at the top to create a new class. It should look like this:
Now lets rename the class to "SSystemGlobalEnvironment" and add a pointer at the 0x94, because thats where I3DEngine in SSGE is.
You will notice that the class now looks like this but 0x94 is missing.
Thats because the class is too small.
Switch to the modify tab at the top and press the "Add 64" at the top to increase the size of the class.
Now select 0094 and set the type to "Pointer"
It should now look like this:
Press the small arrow on the left.
It should now look like this:
Now you see after the "Ptr" it says something like "N00000026". Double click on it to rename it and name it "p3DEngine" and rename the "N000..." after the "Class" below to "I3DEngine".
It should then look like this:
Now select the first like in the I3DEngine Class and change the type to "VTable"
It should look like this:
There we have the virtual functions. But on what virtual is SetPostEffectParam? Lets take a look at the IDA pseudocode again.
There it says "SSystemGlobalEnvironment + 0x94) + 720". 720 /4 is the virtual.
Why / 4? Because Warface is a 32bit game. For 64bit games it would be divided by 8.
So, 720 / 4 = 180. That means that in the current version
virtual void SetPostEffectParam(const char *pParam, float fValue, bool bForceValue = false);
is at virtual 180.
Lets do that in ReClass.
We have our virtual functions but they only go up to 9, same problem as before: same solution.
Select one of the virtual functions and press "Add 64" a few times util you have 180 virtual functions.
Here we go, it should now look something like this:
Now double click on the "Function_180" to change its name, type and parameters:
Now we're basically done with the reclass part. Only thing missing ig that we have 185 virtual function but only need up to 180.
Simply select the unneeded stuff and press "Delete"
Same goes for the addidtional size of SSystemGlobalEnvironment:
Now go to the "Home" tab at the top again and press "Generate" to generate the classes.
It should open a windows that should display something like this:
Code the cheat
Now create a new project in visual studio.
As the Confguration type select Dynamic Library (.dll)
Now lets create a main.cpp source file.
include windows.h and create the dll entrypoint:
int __stdcall DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { if (reason == 1) //DLL_PROCESS_ATTACH { } return 1; }
Now create a function called NoFlash or whatever you like and add an infinite loop to it:
void no_flash() { while (true) { } }
And add a createthread call into dllmain:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)no_flash, 0, 0, 0);
Now that thats done we can create a "classes.h" header file and paste the generated code from ReClass into it.
Now lets hop back into the no_flash function.
We want to access our SSystemGlobalEnvironment.
You can do it like this:
SSystemGlobalEnvironment* pEnv = (SSystemGlobalEnvironment*)(*(DWORD*)(0x18B22E8));
You may have nticed that SSystemGlobalEnvironment is undefined. Thats because we didnt include classes.h yet. Add this to the top of main.cpp:
#include "classes.h"
Now it should work fine.
The 0x18B22E8 is the current address of SSystemGlobalEnvironment that we found in IDA, remember? The dword_...
Now to our actual no flash.
In the loop lets first of all check if out pEnv is valid, if not continue.
if (!pEnv) continue;
Okay, now lets get our I3DEngine:
I3DEngine* p3DEngine = pEnv->p3DEngine;
and also check if its valid:
if (!p3DEngine) continue;
Good, now lets do the actual no flash:
p3DEngine->SetPostEffectParam("Flashbang_Time", 0, true);
Our complete code should look like this:
main.cpp:
#include <windows.h> #include "classes.h" void no_flash() { SSystemGlobalEnvironment* pEnv = (SSystemGlobalEnvironment*)(*(DWORD*)(0x18B22E8)); while (true) { if (!pEnv) continue; I3DEngine* p3DEngine = pEnv->p3DEngine; if (!p3DEngine) continue; p3DEngine->SetPostEffectParam("Flashbang_Time", 0, true); } } int __stdcall DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { if (reason == 1) //DLL_PROCESS_ATTACH { CreateThread(0, 0, (LPTHREAD_START_ROUTINE)no_flash, 0, 0, 0); } return 1; }
classes.h
#pragma once // Generated using ReClass 2015 class SSystemGlobalEnvironment; class I3DEngine; class SSystemGlobalEnvironment { public: char pad_0x0000[0x94]; //0x0000 I3DEngine* p3DEngine; //0x0094 }; //Size=0x0098 class I3DEngine { public: virtual void Function0(); // virtual void Function1(); // virtual void Function2(); // virtual void Function3(); // virtual void Function4(); // virtual void Function5(); // virtual void Function6(); // virtual void Function7(); // virtual void Function8(); // virtual void Function9(); // virtual void Function10(); // virtual void Function11(); // virtual void Function12(); // virtual void Function13(); // virtual void Function14(); // virtual void Function15(); // virtual void Function16(); // virtual void Function17(); // virtual void Function18(); // virtual void Function19(); // virtual void Function20(); // virtual void Function21(); // virtual void Function22(); // virtual void Function23(); // virtual void Function24(); // virtual void Function25(); // virtual void Function26(); // virtual void Function27(); // virtual void Function28(); // virtual void Function29(); // virtual void Function30(); // virtual void Function31(); // virtual void Function32(); // virtual void Function33(); // virtual void Function34(); // virtual void Function35(); // virtual void Function36(); // virtual void Function37(); // virtual void Function38(); // virtual void Function39(); // virtual void Function40(); // virtual void Function41(); // virtual void Function42(); // virtual void Function43(); // virtual void Function44(); // virtual void Function45(); // virtual void Function46(); // virtual void Function47(); // virtual void Function48(); // virtual void Function49(); // virtual void Function50(); // virtual void Function51(); // virtual void Function52(); // virtual void Function53(); // virtual void Function54(); // virtual void Function55(); // virtual void Function56(); // virtual void Function57(); // virtual void Function58(); // virtual void Function59(); // virtual void Function60(); // virtual void Function61(); // virtual void Function62(); // virtual void Function63(); // virtual void Function64(); // virtual void Function65(); // virtual void Function66(); // virtual void Function67(); // virtual void Function68(); // virtual void Function69(); // virtual void Function70(); // virtual void Function71(); // virtual void Function72(); // virtual void Function73(); // virtual void Function74(); // virtual void Function75(); // virtual void Function76(); // virtual void Function77(); // virtual void Function78(); // virtual void Function79(); // virtual void Function80(); // virtual void Function81(); // virtual void Function82(); // virtual void Function83(); // virtual void Function84(); // virtual void Function85(); // virtual void Function86(); // virtual void Function87(); // virtual void Function88(); // virtual void Function89(); // virtual void Function90(); // virtual void Function91(); // virtual void Function92(); // virtual void Function93(); // virtual void Function94(); // virtual void Function95(); // virtual void Function96(); // virtual void Function97(); // virtual void Function98(); // virtual void Function99(); // virtual void Function100(); // virtual void Function101(); // virtual void Function102(); // virtual void Function103(); // virtual void Function104(); // virtual void Function105(); // virtual void Function106(); // virtual void Function107(); // virtual void Function108(); // virtual void Function109(); // virtual void Function110(); // virtual void Function111(); // virtual void Function112(); // virtual void Function113(); // virtual void Function114(); // virtual void Function115(); // virtual void Function116(); // virtual void Function117(); // virtual void Function118(); // virtual void Function119(); // virtual void Function120(); // virtual void Function121(); // virtual void Function122(); // virtual void Function123(); // virtual void Function124(); // virtual void Function125(); // virtual void Function126(); // virtual void Function127(); // virtual void Function128(); // virtual void Function129(); // virtual void Function130(); // virtual void Function131(); // virtual void Function132(); // virtual void Function133(); // virtual void Function134(); // virtual void Function135(); // virtual void Function136(); // virtual void Function137(); // virtual void Function138(); // virtual void Function139(); // virtual void Function140(); // virtual void Function141(); // virtual void Function142(); // virtual void Function143(); // virtual void Function144(); // virtual void Function145(); // virtual void Function146(); // virtual void Function147(); // virtual void Function148(); // virtual void Function149(); // virtual void Function150(); // virtual void Function151(); // virtual void Function152(); // virtual void Function153(); // virtual void Function154(); // virtual void Function155(); // virtual void Function156(); // virtual void Function157(); // virtual void Function158(); // virtual void Function159(); // virtual void Function160(); // virtual void Function161(); // virtual void Function162(); // virtual void Function163(); // virtual void Function164(); // virtual void Function165(); // virtual void Function166(); // virtual void Function167(); // virtual void Function168(); // virtual void Function169(); // virtual void Function170(); // virtual void Function171(); // virtual void Function172(); // virtual void Function173(); // virtual void Function174(); // virtual void Function175(); // virtual void Function176(); // virtual void Function177(); // virtual void Function178(); // virtual void Function179(); // virtual void SetPostEffectParam(const char *pParam, float fValue, bool bForceValue = false); // }; //Size=0x0004
Now press Ctrl+B to build the solution and inject/load it.