EDIT: Galaxy API dump & new offset for 1.41 can be found on page 4.
EDIT: Galaxy API dump & new offset for 1.40 can be found on page 2.
So, basicly this is my first tutorial in this kind of business and I'll start right away and try to explain how to create a non-desyncable Maphack for SC2 which requires no patches.
You can thank Tracky that I wrote this lol.
The tutorial requires basic skills of C++, knowledge of a few technical terms and common sense.
First, you have to know, that there is a Galaxy API which developers can use to create mods, maps, or whatever...it contains much functions and is well documented on SC2Mapster.com, you can find it here: SC2Mapster.com Wiki - Galaxy / Main Page - StarCraft 2 Maps - SC2Mapster
Yeah, so you have already found the primary suspect VisEnable? If not, here is it for you:
SC2Mapster.com Wiki - galaxy / triggers / enable-disable-visibility - StarCraft 2 Maps - SC2Mapster
Description: Enables/Disables the specified visibility type.
It could mean anything, let's have a closer look at the presets Visibility Type and Enable/Disable Option
Now apply your common sense and you find out that we obviously need
Fog Of War c_visTypeFog
and
Disable.
A preset is defined as the following:
The first variable of an enum is always set to 0 if not set otherwise, and the following variables will be incremented by 1, so c_visTypeFog is 1, as it's the 2nd variable of the preset.Code:Preset is a set of variables with constant values. You can compare it with enum from C/C+ + , but in galaxy you can use all kinds of types for preset.
Also, we want to disable the fog. Let's see what value we need for Disable. The base type of the preset Enable/Disable Option is special this time as its bool and there is no name for it (like c_xxx), instead Enable is just defined as true and Disable as false.
Now, hopefully you have understood the documentation of the Galaxy API and we can proceed on how to call the function.
We need to call the function as the following:
Well, now, of course we can't just copy this into our C++ application as it's not defined anywhere.Code:VisEnable( 1, false ); //1st param = c_visTypeFog, 2nd = Disable
Create a new DLL project and set up some keytoogle code like the following:
We declare this outside function with a typedefCode:while( true ) { if( GetAsyncKeyState( VK_F7 ) & 0x8000 ) { //do something } Sleep( 50 ); }
Just put it at the header. You may ask how I got that offset? Just dump the Galaxy API with the help of DebugString or simply use an IDA script (can be found here: Blizzhackers • View topic - [Documentation] Script API dump ).Code:typedef void ( __fastcall* SC2_GalaxyVisEnable_t) ( DWORD* lpdwParams ); static SC2_GalaxyVisEnable_t SC2_GalaxyVisEnable = (SC2_GalaxyVisEnable_t)0x00A0F560;
You need to update that offset probaly every patch, but for 1.36 you can find the dump here: privatepaste.com :: Paste ID 0aa0355305
Just search for the function VisEnable and you got the offset.
To call the function now, we have to pass an array of the parameter, because most - if not all - Galaxy API functions read the parameters over a single array.
Now we can call the function and we have the following code when this all is done:Code:DWORD dwParams[] = { 1, false }; //1st param = c_visTypeFog, 2nd = Disable, as we had above
DONE!!!Code:#include <Windows.h> bool Initialize( void ); typedef void ( __fastcall* SC2_GalaxyVisEnable_t) ( DWORD* lpdwParams ); static SC2_GalaxyVisEnable_t SC2_GalaxyVisEnable = (SC2_GalaxyVisEnable_t)0x00A0F560; BOOL WINAPI DllMain( HMODULE hDll, DWORD dwReason, LPVOID lpReserved ) { if( dwReason == DLL_PROCESS_ATTACH ) return !!CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)Initialize, 0, 0, 0 ); return TRUE; } bool Initialize( void ) { bool bOnetime = true; //as im too lazy to make a good manager. rather use a WndProc while( true ) { if( bOnetime ) { if( GetAsyncKeyState( VK_F7 ) & 0x8000 ) { DWORD dwParams[] = { 1, false }; SC2_GalaxyVisEnable( dwParams ); bOnetime = false; } } Sleep( 50 ); } }
You can try it out. Open SC2, inject your DLL with an injector like Winject or nInjector, open a game, only enable the Maphack when you are ingame, otherwise the results are unpredictable (I haven't tested yet).
Soon you will notice that you can select the enemy, which is quite useful, but can be easily detected as hacking in the replay and you will also get desynced somewhen (eg. when you shoot upstairs with your tanks when you normally couldn't).
To fix this, we have to "reverse engineer" a bit and go deeper.
Get the latest IDA 6.1 version somewhere. IDA is probaly easier to understand for you because it has a plugin included which allows you to see pseudo-C++ code instead of pure ASM.
Open IDA, File->Open..->( go to your SC2 folder, dir to versions, sort by date, dir to the latest folder, select sc2.exe )
Let IDA analye the file. How long it will take depends on your computer, but probaly around 10 minutes. (the little arrow at the top bar won't move anymore when it's finished)
Press G, enter the offset for VisEnable, which is 0x00A0F560. Press F5 to see the pseudo-C++ code.
Ok, we see nothing special. The functions reads our array and passes it to the next function, so follow it by double clicking the sub_xxx.
Now we know that the parameter a1 is "type", and a2 is "enable" (as seen in the function prototype of VisEnable linked at top).
The code just checks if a1 is != false and then if a1 is 1. After that, 3 functions are called:
sub_EAFB80(a2); //receives our Disable=false=0 directly, so this one will receive our full attention at first
sub_A48440((void *)((v2 != 0) - 1));
result = sub_A60A30();
The functions names can change with another patch, so don't confuse.
Follow that function by double clicking again.
We see a lot of initializations/variable sets there and a bit memory writing. Because we wan't to make the hack patch free and there are no further calls to functions, we won't go any deeper now and just call that function. We declare it first:
then we can call it with:Code:typedef void ( __fastcall* SC2_AddFog_t) ( DWORD dwAddFog ); static SC2_AddFog_t SC2_AddFog = (SC2_AddFog_t)0x00EAFB80;
which results to the following final code:Code:SC2_AddFog( 0 );
Done. Start SC2, inject the hack, go in a match and press F7.Code:#include <Windows.h> bool Initialize( void ); typedef void ( __fastcall* SC2_AddFog_t) ( DWORD dwAddFog ); static SC2_AddFog_t SC2_AddFog = (SC2_AddFog_t)0x00EAFB80; BOOL WINAPI DllMain( HMODULE hDll, DWORD dwReason, LPVOID lpReserved ) { if( dwReason == DLL_PROCESS_ATTACH ) return !!CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)Initialize, 0, 0, 0 ); return TRUE; } bool Initialize( void ) { bool bOnetime = true; //as im too lazy to make a good manager. rather use a WndProc while( true ) { if( bOnetime ) { if( GetAsyncKeyState( VK_F7 ) & 0x8000 ) { SC2_AddFog( false ); bOnetime = false; } } Sleep( 50 ); } }
Go read more about the GalaxyAPI, it can be used for way more features. Happy hacking!
This should be undetected for a long time, I guess.
The Visual Studio project is attached.


LinkBack URL
About LinkBacks







Reply With Quote









are greatly appreciated!