PDA

View Full Version : [tutorial] How to Use ModTools.h Class



zonemikel
11-18-2008, 07:18 PM
http://www.zonemikel.com/crap/scmodtools.JPG


How to use ModTools.h class to make a unit alert mod




What Is ModTools.h? This is the main point of this article, modtools.h is a class that i made to facilitate codecaving and hijacking other programs. It should be known that this example is for starcraft but modtools could work with any program (mostly) as long as you can inject the .dll it should work.

Intended audience: People who know how to program using c++ and classes but may not know the in-out of codecaves and such. Or, just people who want a quick easy way to make codecaves and mods. You should be well versed with c++ and know at least how to mov and pushad/popad in asm.

Purpose: To show people how to use the ModTools class to quickly make mods. This tutorial is not a in depth "how to make a unit alert" if you want that look at yonders tutorial. This tutorial will just get you started making a unit alert. Also I dont show how I got the offsets we use until the end (Appendix).

Software Used:
Visual Studio 2008
Windows XP (this tut might not work in vista)
Cheat engine - not needed
Olly debug - not needed
Windows Calculator - great tool

Date: 11/18/08
Author: zonemikel
SCVer: 1.15.3

TIME: it took me about 2 hours to do this while writing the tutorial alongside, and then i came back and revised it later took me like 30 minutes to revise. It should take you about 30 minutes to do everything.

Revised: 11/19/08, it actually prints out all units and the player that made them now. See screen shot.

Steps


Create a new VS project
Set up the ModTools class and includes
Call the constructor with the right variables
Create a function for our code cave
Setup our code cave using the class and nop out the garbage
use printf statments to print the unit type to our debug console

Note: This class is a work in progress, if you find anything wrong with it or think of better ways to do stuff let me know.
Thanks: Yonder, Jakor and others (like hellinsect)

Create a new VS project
Setup a VS 2008 project to work as a .dll



Start visual studio and create a new project of type "win32 project"
Name it UnitAlert click OK
(IMPORTANT) click next, not finish
Under application type click DLL
Now click finish

Set up the ModTools class and includes
Insert the ModTools.h class into your header files


Download ModTools.h (http://www.bwhacks.com/forums/attachments/hacking-tutorials/12371d1227064582-tutorial-how-use-modtools-h-class-modtools.zip)
Right click on header files
Add -> Existing Item
Navagate to where you put Modtools.h, select it
Click add
(IMPORTANT) also copy the file ModTools.h to your UnitAlert\UnitAlert directory

You must now add all the includes that I used


Double click stdafx.h to open it
type these lines in at the bottom


#include <stdio.h>
#include <iostream>
#include <io.h>
#include <stdio.h>
#include <fstream>
using namespace std;

Now we include ModTools.h in your UnitAlert.cpp



Double click UnitAlert.cpp
Type in this line just below #include stdafx.h


#include "ModTools.h"Now is a great time to try and compile to make sure everything works !

Call the constructor with the right variables
There are three constructors, we will use the third

Before we can call the constructor we need to create what i call a "engine" , this will be the heart of your program. It will be run every 10milliseconds in the thread that will be created. So type this in your program



long WINAPI myEngine(long lparam)
{
mt.Console(); // start a console for debugging output
// ------- stuff that runs once here !!
while(1){ // this goes forever
Sleep(10); // ~10 millisecond delay so it dont lag
if(GetAsyncKeyState(VK_F12) == -32767) // if they hit F12
{
mt.Console(); // toggle console on/off
}

}
return 0;
}
From there we can call the constructor. From there you can add a declaration or put this below the "engine", you should know what i mean. Anyway add this code.



ModTools mt("brood war", &myEngine);
Now is a good time to compile to make sure it all works

Create a function for our code cave
We now create the function for our jmp patch

One of the neat things about my class is that you can use normal functions as code caves. The function stripJmpPatch() will search through the jmps and find your function. It will also strip off the first part of your function so it does not have the c++ code, just your asm.

The drawback of this are thus:
The first line of your code cave function must be __asm{
The asm must return

Of course you can still do it the way most people do, but for this tutorial ill show how to use stripJmpPatch.

Before we can patch to our codecave function we need to create it so type this in at the bottom somewhere then declare it at the top.



void myCodeCave1()
{
__asm{
PUSHAD
MOV newUnitPtr, ESI // save location of new unit
POPAD
// replace the line of code we nop'd
MOV DWORD PTR DS:[ECX*0x04+0x6283E0],ESI
JMP returnPt // return to after our jmppatch
}
}
this code gets pointers to all newly created units and stores it in the variable newUnitPtr, so create that var in a global scope;



DWORD newUnitPtr = 0; // pointer to new units
we also jmp retrunPt as the last line in our codecave function, that returns us to just after the place where we patched. So be sure to make that var in a global scope like so



DWORD returnPt = 0x004A02BB; // return from our code cave
Now compile again make sure it works.

Setup our code cave using the class and nop out the garbage
now we actually patch to our code cave function



go to the point in the engine where the comment "// ------- stuff that runs once here !! " and just below that line type



mt.stripJmpPatch(&myCodeCave1, (PBYTE)0x004A02B6);
mt.nopIt((PBYTE)0x004A02BB, 2); // nop out the code we messed up
This will strip our function mycodecave1 and make it look like a naked function, then it will find the new location of our function through the jmps and then it will setup the jmp patch.
After that the "nopIt" nops out 2 bytes after the place where we put the patch, we replace this code in our code cave (you can look).

use printf statments to print the unit type to our debug console
We now use all the stuff we have just set up to actually do something

What we want to do is print out the unit type every time a unit is created. We know that from the unit pointer the offset to the unit type is 0x64 and the offset to the unit owner is 0x4C. There are tons of offsets if you look at my other posts (http://www.bwhacks.com/forums/starcraft-hacking-related/36131-sc-brood-war-offsets-1-5-3-a.html).

So basically our algorithm is
if newUnitPtr != 0
print unit info and unit owner info
set newUnitPtr to 0

Pretty simple, so lets put this code in our engine just below Sleep(10), or wherever you want.



if(newUnitPtr != 0)
{
printf("\n New Unit Player: 0x%X Type 0x%X",
*(BYTE*)(newUnitPtr+0x4C), // dereference player number from unitptr
*(BYTE*)(newUnitPtr+0x64) // dereference unit type from unit ptr
);
newUnitPtr = 0; // reset unit pointer to 0
}


The end

Thats it, compile it and then inject it into starcraft using a dll injector or a free program like RemoteDLL.

FINAL NOTE: I fixed this up so it now shows the player and the unit type. Its your job now to make units that you want to be alerted of like lurkers and dt's and record their type. Then change your if statment to only print out if its a unit you care about, which should be pretty easy, good luck!

Also i tried to add the whole UnitAlert project but bwhacks like wont let me upload it , it times out you can dl it here (http://www.zonemikel.com/crap/UnitAlert.zip) its 6meg.

And of course you dont want it to print out stuff in the debug console you want it to print out in starcraft. Im not including anything like "bwpubprint" in modtools.h because printing to starcrafts screen is unique to starcraft. I want modtools.h to be modular and work with any application, i have functions like bwpubprint and such in another header called scfxn.h, i might write a tutorial about that later but im not finished with it yet.

Download the entire ProjectAfter deleting some stuff from the project i got it small enough to upload to bwhacks. You can download the entire working project (1.5.3) from here (http://www.bwhacks.com/forums/attachment.php?attachmentid=12385&stc=1&d=1227149098).

This is what your unitalert.cpp should look like


// UnitAlert.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "ModTools.h"

long WINAPI myEngine(long lparam);
void myCodeCave1();
DWORD newUnitPtr = 0; // unit type
DWORD returnPt = 0x004A02BB; // return from our code cave

ModTools mt("brood war", &myEngine);




long WINAPI myEngine(long lparam)
{
mt.Console(); // start a console for debugging output
// ------- stuff that runs once here !!
mt.stripJmpPatch(&myCodeCave1, (PBYTE)0x004A02B6);
mt.nopIt((PBYTE)0x004A02BB, 2); // nop out the code we messed up
while(1){ // this goes forever
Sleep(10); // ~10 millisecond delay so it dont lag
if(newUnitPtr != 0)
{
printf("\n New Unit Player: 0x%X Type 0x%X",
*(BYTE*)(newUnitPtr+0x4C), // dereference player number from unitptr
*(BYTE*)(newUnitPtr+0x64) // dereference unit type from unit ptr
);
newUnitPtr = 0; // reset unit pointer to 0
}
if(GetAsyncKeyState(VK_F12) == -32767) // if they hit F12
{
mt.Console(); // toggle console on/off
}

}
return 0;
}


void myCodeCave1()
{
__asm{
PUSHAD
MOV newUnitPtr, ESI // save location of new unit
POPAD
// replace the line of code we nop'd
MOV DWORD PTR DS:[ECX*0x04+0x6283E0],ESI
JMP returnPt // return to after our jmppatch
}
}






APPENDIX
How to find the place in starcraft's code where units are created ?

This is really all covered in yonders tutorial (http://www.bwhacks.com/forums/hacking-tutorials/15826-tutorial-unit-alert-aimed-beginners.html) in better depth, but ill cover the basics here. Full credits to yonder (thanks buddy, yes im still reading your freaking tutorial LOL !!)

Every unit in starcraft is counted for each player and each type of unit. So start a new game, you start with 4 scv's so do a search for 4 byte value of 4. Then make another scv and search for 5, then make another and search for 6 and so on until you have only a few values. Set a breakpoint on the value you have found in ollydebug "on write" then make another unit it should break here

004889FA 011C8D CC1D5800 ADD DWORD PTR DS:[ECX*4+581DCC],EBX

execute till return, step into and you should be here

004A02B6 89348D E0836200 MOV DWORD PTR DS:[ECX*4+6283E0],ESI

Which is where we put our code cave. You can see it takes up 7 bytes, our code cave takes five then we nop the next two. We then replace this line in our asm code after the popad. ESI holds the unitPtr to the unit we just created.

How to find the unit offsets (type, player number, etc)

For this just go to the unit in the memory dump, look over it pretty well. Copy it to a text editor and then get another type of unit and copy it to a text editor look and see what the differences are, you know one will have to be the unit type, another location and such. Everything is in there, some of the offsets i've found are:

Unit owner +0x4c
Unit Type +0x64
unit ptr + 0x09 = current hp
unit ptr + 16d = going to (mouse click)

zonemikel
11-22-2008, 09:13 PM
I edited the stripFxn function in mod tools. If you have troubles with it change that function to this. This one will nop out all code before it reaches the first pushad, so the first line of your function must be "__asm{pushad", everything before that will be deleted.



void ModTools::stripFxn(void *pFxn)
{
int i=0; // keep track of where we are
if ( *(BYTE*)((DWORD)pFxn) != 0xE9){ // if its not a jmp
while(*(BYTE*)((DWORD)pFxn) != 0x60 && i<50){ // terribly dangerous
nopIt(pFxn, 1);
__asm{inc pFxn}
}// end while
}else{ // else if
msgbox("Your Stripping a jmp!","Error stripFxn");
}
}

ViperSRT3g
11-22-2008, 10:23 PM
Looks very nice zone you make me wanna make a tut of my own.

homegrownpeas
11-23-2008, 04:43 PM
This is a very nice tutorial, thankyou very much for making it. :)

zonemikel
11-23-2008, 04:49 PM
Oh no problem, thanks for the positive feedback. I like writing tutorials, i used to write them before and they would come out really crappy. Im taking c++ and tech writing this semester and you see both of them at work in this tutorial.

homegrownpeas
11-23-2008, 04:52 PM
haha thats pretty cool man. I am currently working on something big, its a C++ DLL template, ill be releasing soon on these forums, its almost ready to be released (just being edited by some people right now). but you should really take a look at it once it comes out, its a very good tool for anybody.

zonemikel
11-23-2008, 05:28 PM
haha thats pretty cool man. I am currently working on something big, its a C++ DLL template, ill be releasing soon on these forums, its almost ready to be released (just being edited by some people right now). but you should really take a look at it once it comes out, its a very good tool for anybody.

I'd love to see it, if its anything like mine we should really all be working (collaborating) on one file that everyone can use.

homegrownpeas
11-23-2008, 08:06 PM
no, its very structured and organized, designed to be generic and compatible with all hacking needs. it teaches how to correctly use C++ to make a good clean DLL.

ill be releasing it tomorrow most likely.

zonemikel
11-24-2008, 08:39 AM
no, its very structured and organized, designed to be generic and compatible with all hacking needs. it teaches how to correctly use C++ to make a good clean DLL.

Unlike mine ? So your saying mine is unstructured and unorganized and does not use c++ correctly? Well i cant wait to see yours then:lol:

homegrownpeas
11-24-2008, 06:38 PM
oh no no no sorry dude i totally didnt mean to say that. i really didnt mean to say that!!!

yours is very good. mine is only slightly more structured, you'll find out.

zonemikel
11-24-2008, 07:36 PM
oh no no no sorry dude i totally didnt mean to say that. i really didnt mean to say that!!!

yours is very good. mine is only slightly more structured, you'll find out.

np, i was just kidding. I never claim to be a programming guru or anything like that, there is always a mountain of information to learn. I was serious about wanting to see your code though.

Zryphor
11-27-2008, 08:26 AM
Should move this to reverse engineering/open source as it's not limited to Starcraft.

Other than that, good work.

zonemikel
11-27-2008, 03:22 PM
Should move this to reverse engineering/open source as it's not limited to Starcraft.

Other than that, good work.

good idea i was just about to put it in "user downloads" ill put it in there. Since this is just a tut it kinda fits in here, ill release the code in that forum

homegrownpeas
11-27-2008, 04:56 PM
yeah this is a mix between a tut and a user download.

you know ASM and reversing alot better than i do. I do believe we should put ours together.