Showing results 1 to 14 of 14

Thread: [tutorial] How to Use ModTools.h Class

  1. #1

    Default [tutorial] How to Use ModTools.h Class



    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

    1. Create a new VS project
    2. Set up the ModTools class and includes
    3. Call the constructor with the right variables
    4. Create a function for our code cave
    5. Setup our code cave using the class and nop out the garbage
    6. 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


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

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

    1. Download ModTools.h
    2. Right click on header files
    3. Add -> Existing Item
    4. Navagate to where you put Modtools.h, select it
    5. Click add
    6. (IMPORTANT) also copy the file ModTools.h to your UnitAlert\UnitAlert directory

    You must now add all the includes that I used

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

    PHP Code:
    #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


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

    PHP Code:
    #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

    PHP Code:
    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.

    PHP 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.

    PHP Code:
    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;

    PHP Code:
    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

    PHP Code:
    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


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

    PHP Code:
        mt.stripJmpPatch(&myCodeCave1, (PBYTE)0x004A02B6); 
        
    mt.nopIt((PBYTE)0x004A02BB2); // 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.

    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.

    PHP Code:
                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 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 Project
    After 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.

    This is what your unitalert.cpp should look like
    PHP Code:
    // 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)0x004A02BB2); // 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 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)
    Attached Images Attached Images  
    Attached Files Attached Files
    Last edited by zonemikel : 11-23-2008 at 07:33 AM
    Go to the Beginning . . . Continue till the end . . . when you get to the end, stop.

    "Socrates concluded he was indeed the wisest man, if only because he knew he was ignorant. Then as now, this is the cardinal rule of intelligence analysis: we take from it what we bring to it: our fears and hopes, selfish biases and selfless concerns, our insight and blindness."




  2. #2

    Default

    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.

    Code:
    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");
            }
    }
    Go to the Beginning . . . Continue till the end . . . when you get to the end, stop.

    "Socrates concluded he was indeed the wisest man, if only because he knew he was ignorant. Then as now, this is the cardinal rule of intelligence analysis: we take from it what we bring to it: our fears and hopes, selfish biases and selfless concerns, our insight and blindness."




  3. #3

    Default

    Looks very nice zone you make me wanna make a tut of my own.


  4. #4

    Default

    This is a very nice tutorial, thankyou very much for making it.

  5. #5

    Default

    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.
    Go to the Beginning . . . Continue till the end . . . when you get to the end, stop.

    "Socrates concluded he was indeed the wisest man, if only because he knew he was ignorant. Then as now, this is the cardinal rule of intelligence analysis: we take from it what we bring to it: our fears and hopes, selfish biases and selfless concerns, our insight and blindness."




  6. #6

    Default

    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.

  7. #7

    Default

    Quote Originally Posted by homegrownpeas View Post
    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.
    Go to the Beginning . . . Continue till the end . . . when you get to the end, stop.

    "Socrates concluded he was indeed the wisest man, if only because he knew he was ignorant. Then as now, this is the cardinal rule of intelligence analysis: we take from it what we bring to it: our fears and hopes, selfish biases and selfless concerns, our insight and blindness."




  8. #8

    Default

    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.

  9. #9

    Default

    Quote Originally Posted by homegrownpeas View Post
    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
    Go to the Beginning . . . Continue till the end . . . when you get to the end, stop.

    "Socrates concluded he was indeed the wisest man, if only because he knew he was ignorant. Then as now, this is the cardinal rule of intelligence analysis: we take from it what we bring to it: our fears and hopes, selfish biases and selfless concerns, our insight and blindness."




  10. #10

    Default

    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.

  11. #11

    Default

    Quote Originally Posted by homegrownpeas View Post
    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.
    Go to the Beginning . . . Continue till the end . . . when you get to the end, stop.

    "Socrates concluded he was indeed the wisest man, if only because he knew he was ignorant. Then as now, this is the cardinal rule of intelligence analysis: we take from it what we bring to it: our fears and hopes, selfish biases and selfless concerns, our insight and blindness."




  12. #12

    Default

    Should move this to reverse engineering/open source as it's not limited to Starcraft.

    Other than that, good work.

  13. #13

    Default

    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
    Go to the Beginning . . . Continue till the end . . . when you get to the end, stop.

    "Socrates concluded he was indeed the wisest man, if only because he knew he was ignorant. Then as now, this is the cardinal rule of intelligence analysis: we take from it what we bring to it: our fears and hopes, selfish biases and selfless concerns, our insight and blindness."




  14. #14

    Default

    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.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. [Poll] What is your class?
    By Irene in forum World of Warcraft
    Replies: 18
    Last Post: 09-28-2008, 10:17 AM
  2. Wrote a story for a class
    By Calaspawn in forum General Chat
    Replies: 10
    Last Post: 09-19-2008, 11:29 AM
  3. Warcraft3 Global Class ???
    By Offset(h) in forum Warcraft
    Replies: 8
    Last Post: 08-18-2008, 02:09 PM
  4. [C++/CLI] Registry Configurator Class
    By Dyndrilliac in forum Software Development
    Replies: 0
    Last Post: 02-07-2008, 08:56 PM

Posting Rules

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •