WARFACE HACK

Today in this quick written tutorial of mine, let's find out how we can find the position of SSystemGlobalEnvironment and how to find other child classes/interfaces positions in it such as IGame, IPhysicalWorld, IEntitySystem etc.This might also work in other games made using CryENGINE, such as Crysis 3 etc. But approaches may somewhat differ. Haven't checked those, so no guarantees. This tutorial and this approach is focused on Warface.









Legend 

Step 1-10: Getting Started with Reversing Warface.
Step 10-16: Finding SSystemGlobalEnvironment struct address
Step 17-21: Finding IGame offset in SSystemGlobalEnvironment
Step 22-23: Finding IRenderer offset in SSystemGlobalEnvironment
Step 24-25: Finding ISystem offset in SSystemGlobalEnvironment
Step 26-27: Finding IPhysicalWorld offset in SSystemGlobalEnvironment
Step 28-29: Finding IEntitySystem offset in SSystemGlobalEnvironment
Step 30-32: Finding ITimer offset in SSystemGlobalEnvironment
Step 33-34: Finding IConsole offset in SSystemGlobalEnvironment
Step 35-36: Finding RayWorldIntersection fu





Step 1

Please update your game to the latest version using your launcher and make sure game integrity checks verified and passes.

Step 2

Please launch your game using the provided launcher and wait until it loads to the main menu.

Step 3

Press Alt + Tab to minimize the game and switch to desktop. Download a process dumping tool such as PETools and open it.

Step 4

Find the "Game.exe" process in it and right click on the row. Click "Dump Full..." and dump the process into a file and name it something like "Dumped.exe". After that, please switch to the game window and quit the game. Close the launcher as well if you don't need it.

Step 5

Download IDA Pro and open IDA. Select "New" in the popup as you're trying to analyze a new file for first time.









Step 6

Browse through your files and open the previously saved Dumped.exe and load it into IDA.

This image has been resized. Click this bar to view the full image. The original image is sized 680x484.


Step 7

In the popup now you get, select the options as following image shows (mostly default options selected resembles this).



Step 8

Click "OK" and it starts to read imports and exports. It might also ask you for several missing assemblies which it can't find.

Commonly it'll ask for "ijl15", "CrashRpt1402" and "ocevogyv".

To resolve those, please navigate to the game installed directory and go into "Bin32Release" folder, then select the each of the DLL file with same name it requested. Example: "ijl15.dll" for "ijl15". Repeat the step until it resolves all the missing assemblies it wasn't able to find.

This image has been resized. Click this bar to view the full image. The original image is sized 678x484.


Then it'll start analyzing the dumped process. This process might take around 5-15 minutes depending on the performance of your computer.

This image has been resized. Click this bar to view the full image. The original image is sized 1366x728.


You can see the process in the Analysis bar, and the current position in footer status bar.





Wait until the analysis process to complete.

Step 9

After the initial analysis completed, your Analysis bar will look similar to this.



And the footer status bar will say "idle".



Now, please save the database by clicking on "Save the Database" icon in your toolbar. It'll then show a progress with "Packing the database" title. Wait until the save process is completed.



Step 10

Now in your menu bar, go to "View" -> "Open subviews" -> "Strings" and open the Strings window.

This image has been resized. Click this bar to view the full image. The original image is sized 647x597.


This will contain all the strings found in the dumped assembly along with their position.

This image has been resized. Click this bar to view the full image. The original image is sized 960x409.


You need this strings list to find SSystemGlobalEnvironment and almost everything else. Locating a nearby string and digging a little deeper is one of the fastest way to find something. With publicly available CryENGINE SDK, it makes everything so much easier.

Step 11

Finally we are here, where we gonna find first thing, which is the position of SSystemGlobalEnvironment. Let's find out how we can find it, shall we?

While focused on the recently opened Strings window, press Ctrl + F to open search pane for that particular window. Now search for "ai_CompatibilityMode" (without quotes, you may start typing it and it'll auto search after each key press).



Step 12

Double click on the only result it found to go to that address.

This image has been resized. Click this bar to view the full image. The original image is sized 846x416.


Now click on top of the "aAi_compatibili" pointer and focus on it.



Step 13

Now press X to open Xrefs (cross references) for that particular address. A window will appear with all the addresses references to this address (in this case, it's only one).

This image has been resized. Click this bar to view the full image. The original image is sized 836x301.


Step 14

Double click on the only result to go to that address. Now we are here...

This image has been resized. Click this bar to view the full image. The original image is sized 960x418.


Step 15

Since this is a noob friendly tutorial, enter this function's pseudocode by pressing F5, and now we are here...

This image has been resized. Click this bar to view the full image. The original image is sized 975x427.


Step 16

Right click on the DWORD near the string "ai_CompatibilityMode" (in this case "dword_1A3F2B8") and select "Rename global item".

This image has been resized. Click this bar to view the full image. The original image is sized 627x243.


Name it "SSystemGlobalEnvironment".

This image has been resized. Click this bar to view the full image. The original image is sized 725x163.


Press "OK" to save the changes. Redo Step 9 and save the database to persist the changes to the disk.

This image has been resized. Click this bar to view the full image. The original image is sized 989x193.


In case if you still haven't noticed, we have found your SSystemGlobalEnvironment. To retrieve it's address, double click on it (the "SSystemGlobalEnvironment"), and it'll take you to it's address.

This image has been resized. Click this bar to view the full image. The original image is sized 758x159.


So, in this instance, SSystemGlobalEnvironment address is: 0x01A3F2B8. 

Step 17

Let's find the IGame offset in SSystemGlobalEnvironment. You ready?

Please repeat Step 11, but this time search for "IsPlayer" in the Strings instead. Bear in mind that the searches should be CASE SENSITIVE!. So it's not "isPlayer", "Isplayer", it MUST be "IsPlayer", and only pick the whole word results. Please refer to the below image to get the idea, look at the highlighted row.

This image has been resized. Click this bar to view the full image. The original image is sized 800x409.


Step 18

Same like before, double click it and go to it's position. Focus on the pointer and press X to open Xrefs.

This image has been resized. Click this bar to view the full image. The original image is sized 839x421.


You might receive multiple references here like that. We need to make sure that we navigate to the correct place, so... double click each of them and visit them until you match one with what I say you to look for.

How to visit each of them when we takes to that position and lose the Xrefs window you say? It's simple. Let's say we visited the first one like this...

This image has been resized. Click this bar to view the full image. The original image is sized 833x416.


You can re-open the Xrefs window by focusing on the same pointer and pressing X.

This image has been resized. Click this bar to view the full image. The original image is sized 824x431.


Step 19

Find a reference with "entityId" string near top of it, and "GetAmmoClassNameById" string and "RemoveDroppedItems" at the near bottom. Something like this, for your information, this is the correct one as well...

This image has been resized. Click this bar to view the full image. The original image is sized 819x417.


Step 20

Enter pseudocode by pressing F5 like before. You will find CryENGINE ScriptBindings. Each named function string accompanied by it's own function. For example, let's continue with IsPlayer function.

This image has been resized. Click this bar to view the full image. The original image is sized 977x414.


1 - ScriptBind function name.
2 - ScriptBind function parameters.
3 - ScriptBind function helper or actual function.

To find what we need (which is IGame offset in SSystemGlobalEnvironment in this case), please enter ScriptBind function of "IsPlayer". In this instance, the 3rd one, "sub_B0C030".

This image has been resized. Click this bar to view the full image. The original image is sized 788x418.


Step 21

Double click it to enter that function's pseudocode. Now we are here...

This image has been resized. Click this bar to view the full image. The original image is sized 755x418.


You'll notice we have our new found SSystemGlobalEnvironment which we recently renamed and saved there.



Right click on the SSystemGlobalEnvironment offset value showing besides it. In this case after the "+", it shows "36". Right click on it and select "Hexadecimals".

This image has been resized. Click this bar to view the full image. The original image is sized 670x253.


You'll end up with it's value converted to hexadecimals, which is 0x24.



In case if you haven't noticed yet, that's the offset of IGame in SSystemGlobalEnvironment. It's SSystemGlobalEnvironment + 0x24 = IGame. 

Step 22

Let's find the offset of IRenderer, what you say? 

Please repeat Step 11, but this time search for "Draw2DLine" in the Strings instead.

This image has been resized. Click this bar to view the full image. The original image is sized 793x410.


Same like before, double click go to that position and press X focusing on the pointer to get Xrefs list.

This image has been resized. Click this bar to view the full image. The original image is sized 822x322.


Go to that position by double clicking the result. Press F5 and enter pseudocode.

This image has been resized. Click this bar to view the full image. The original image is sized 767x414.


Go to the ScriptBind function, in this case "sub_BAF270".

Step 23

Find the SSystemGlobalEnvironment there at top.

This image has been resized. Click this bar to view the full image. The original image is sized 807x415.


Same like before, convert the shown offset into hexadecimals.

This image has been resized. Click this bar to view the full image. The original image is sized 774x110.


In case if you haven't noticed yet, in this case 0x2C the IRenderer offset in SSystemGlobalEnvironment. So, it's SSystemGlobalEnvironment + 0x2C = IRenderer. 

Step 24

OK, now it's time to find ISystem offset in SSystemGlobalEnvironment. Let's get into it...

Please repeat Step 11, but this time search for "GetUserName" in the Strings instead.

This image has been resized. Click this bar to view the full image. The original image is sized 789x416.


Same like before, pick the correct whole word result and go to it's position. Focus on pointer and open Xrefs by pressing X.

This image has been resized. Click this bar to view the full image. The original image is sized 819x419.


Go to the result and enter pseudocode by pressing F5. Enter it's corresponding ScriptBind function.

This image has been resized. Click this bar to view the full image. The original image is sized 710x414.


In this case it's "sub_BADAA0". Double click to enter.

Step 25

Find the SSystemGlobalEnvironment there at the top.

This image has been resized. Click this bar to view the full image. The original image is sized 750x267.


Same like before, convert the shown offset into hexadecimals.

This image has been resized. Click this bar to view the full image. The original image is sized 680x101.


In case if you haven't noticed yet, in this case 0x98 the ISystem offset in SSystemGlobalEnvironment. So, it's SSystemGlobalEnvironment + 0x98 = ISystem. 

Step 26

It's time to find IPhysicalWorld now, this is one of the easiest offsets to find...

Please repeat Step 11, but this time search for "RayWorldIntersection(Game)" in the Strings instead.

This image has been resized. Click this bar to view the full image. The original image is sized 791x411.


Double click the result to go that that position, open Xrefs same as before by pressing X while focused on pointer. This time you'll find many references. Pick one, mostly any of them. If the steps following this doesn't match up with yours, please pick another.

Then go to that address and enter pseudocode.

Step 27

Find the nearest SSystemGlobalEnvironment reference to your string (in this case, nearest one to "RayWorldIntersection(Game)").

This image has been resized. Click this bar to view the full image. The original image is sized 988x428.


Same like before, convert the shown offset into hexadecimals.

This image has been resized. Click this bar to view the full image. The original image is sized 899x140.


In case if you haven't noticed yet, in this case 0x5C the IPhysicalWorld offset in SSystemGlobalEnvironment. So, it's SSystemGlobalEnvironment + 0x5C = IPhysicalWorld. 

Step 28

Oh yeah, now a big one. The "IEntitySystem". Who doesn't like to see all the weapons, ammo drops, explosives in the map with an ESP right? Let's get on with it then...

Please repeat Step 11, but this time search for "GetEntities" in the Strings instead.

This image has been resized. Click this bar to view the full image. The original image is sized 786x416.


Pick the correct result as a whole word same as before and go to it's position. Get Xrefs by focusing on pointer pressing X.

This image has been resized. Click this bar to view the full image. The original image is sized 836x423.


Double click and go to reference's position and enter pseudocode.

This image has been resized. Click this bar to view the full image. The original image is sized 772x421.


Double click and enter it's ScriptBind function. In this case it's "sub_BADF20".

Step 29

Find the first occurrence of SSystemGlobalEnvironment.

This image has been resized. Click this bar to view the full image. The original image is sized 1055x408.


Same like before, convert the shown offset into hexadecimals.



In case if you haven't noticed yet, in this case 0x38 the IEntitySystem offset in SSystemGlobalEnvironment. So, it's SSystemGlobalEnvironment + 0x38 = IEntitySystem. 

Step 30

What do we need to create an awesome Smooth Aim? ITimer of course. To provide us with somewhat accurate engine based frame times. Let's find ITimer offset in SSystemGlobalEnvironment...

Please repeat Step 11, but this time search for "GetFrameTime" in the Strings instead.

This image has been resized. Click this bar to view the full image. The original image is sized 796x411.


Double click and go to the result, open Xrefs by pressing F5 while focusing on the pointer just like before.

This image has been resized. Click this bar to view the full image. The original image is sized 823x419.


Navigate to the only result it found and enter pseudocode.

This image has been resized. Click this bar to view the full image. The original image is sized 687x419.


Double click and enter it's ScriptBind function, in this case "sub_BAD910".

Step 31

Find the offset it's showing WITHIN the "else" clause here. See the highlighted offset, that's the value we looking for here.

This image has been resized. Click this bar to view the full image. The original image is sized 670x340.


Remember the offset you just found.

Step 32

Navigate back in pseudocode by passing Back button in the toolbar.



Now you're back at the end of Step 30. Scroll to the top of the constructed pseudocode. Find the SSystemGlobalEnvironment offsets at the top there like showing in this image...

This image has been resized. Click this bar to view the full image. The original image is sized 731x417.


Pick the one with the offset you found before. In this case it's "+ 96" one.



Same like before, convert the shown offset into hexadecimals.



In case if you haven't noticed yet, in this case 0xA8 the ITimer offset in SSystemGlobalEnvironment. So, it's SSystemGlobalEnvironment + 0xA8 = ITimer. 

Step 33

Let's find "IConsole" too, because why not?! 

Please repeat Step 11, but this time search for "GetCVar" in the Strings instead.

This image has been resized. Click this bar to view the full image. The original image is sized 802x411.


Pick the correct one with whole word and go to it's position, same as before. Open Xrefs by focusing on pointer and pressing X.

This image has been resized. Click this bar to view the full image. The original image is sized 824x420.


Go to the only result, enter pseudocode again by pressing F5, same as before.

This image has been resized. Click this bar to view the full image. The original image is sized 689x415.


Double click and enter it's ScriptBind function, in this case the "sub_BAFAB0".

Step 34

Find the SSystemGlobalEnvironment reference there.

This image has been resized. Click this bar to view the full image. The original image is sized 883x417.


Same like before, convert the shown offset into hexadecimals.

This image has been resized. Click this bar to view the full image. The original image is sized 841x186.


In case if you haven't noticed yet, in this case 0x48 the IConsole offset in SSystemGlobalEnvironment. So, it's SSystemGlobalEnvironment + 0x48 = IConsole. 

Step 35

Let's also find the RayWorldIntersection functions so we can perform ray tracing to check a particular Actor or an Entity/Object is visible from a particular location. This check is important for an Aimbot or for an ESP.

You can find the same address on Step 27 above. But in case if you want to do it from scratch please continue from below.

Please repeat Step 11, but this time search for "RayTraceCheck" in the Strings instead.

This image has been resized. Click this bar to view the full image. The original image is sized 787x412.


Double click and go the position, same like before focus on pointer and press X to show Xrefs. You'll see multiple references here too.

This image has been resized. Click this bar to view the full image. The original image is sized 829x423.


This time, pick any of the references and navigate there. It's okay since all of them contains what we're looking for. I'll pick the second one for this tutorial.

Navigate there, enter pseudocode by pressing F5.

This image has been resized. Click this bar to view the full image. The original image is sized 758x421.


Double click and enter it's ScriptBind function, in this case it's "sub_BB2A40".

Step 36

In the pseudocode, scroll down and find a function containing a parameter which has a string that starts with "RayWorldIntersection" (it can be "RayWorldIntersection(Game)", "RayWorldIntersection(3dEngine)", "RayWorldIntersection(EntitySys)" or whatever).



Double click on that function name to navigate to that function's pseudocode.

This image has been resized. Click this bar to view the full image. The original image is sized 1092x416.


This is the function we are looking for, the get the address of it by refering to it's name. In this instance it's 0x046A1D0 since the function name is "sub_46A1D0". You can additionally right click on it's name and choose "Rename global item" to name the function as "RayWorldIntersection" as well for further reference.

So, in this case the RayWorldIntersection function is at 0x046A1D0. 

Tutorial Writing in Process!
This tutorial is not finished yet and the author is pretty busy at the moment and is still writing it, so the information here are not completed. Please check back again time to time to see more steps to finding the rest of the classes/interfaces.

I hope you learned something from my tutorial. I can't wait to see what you guys make!
Please be kind enough to share whatever you make here. 

If you find it useful, please take 5 seconds to show your appreciation, after all... it costs you nothing... 

Thank you all 
_________________








Comments