Page 1 of 3 123 LastLast
Showing results 1 to 20 of 46

Thread: My little coding thread

  1. #1
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default My little coding thread

    Let me know how I can improve this.

    I'm working on a VB based injector and a C++ mineral hack now.

    Edit: A description is probably useful. This grabs the names of each player. My intention was to do more with it, but now I'm going to shift into C, which should allow me to write to the screen in game.

    Code:
    Public Class Form1
        Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As Integer
    
        Private Declare Function WriteProcessMemory1 Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
        Private Declare Function WriteProcessMemory2 Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Single, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Single
        Private Declare Function WriteProcessMemory3 Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Long, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Long
    
        Private Declare Function ReadProcessMemory1 Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Integer
        Private Declare Function ReadProcessMemory2 Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Single, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Single
        Private Declare Function ReadProcessMemory3 Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Long, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Long
    
        Const PROCESS_ALL_ACCESS = &H1F0FF
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim P11 As Integer = ReadInteger("StarCraft", &H57F0E4)
            MsgBox(P11)
        End Sub
        Public Sub Player_Score()
            Dim P11 As Integer = ReadInteger("StarCraft", &H59A32C)
            P6S.Text = P11.ToString
        End Sub
        Public Sub Player_Name()
            Dim P11 As Integer = ReadInteger("StarCraft", &H57EE9C)
            Dim P12 As Integer = ReadInteger("StarCraft", &H57EEA0)
            Dim P13 As Integer = ReadInteger("StarCraft", &H57EEA4)
            Dim P14 As Integer = ReadInteger("StarCraft", &H57EEA8)
    
            Dim P21 As Integer = ReadInteger("StarCraft", &H57EEEB)
            Dim P22 As Integer = ReadInteger("StarCraft", &H57EEEF)
            Dim P23 As Integer = ReadInteger("StarCraft", &H57EEF3)
            Dim P24 As Integer = ReadInteger("StarCraft", &H57EEF7)
    
            Dim P31 As Integer = ReadInteger("StarCraft", &H57EF0F)
            Dim P32 As Integer = ReadInteger("StarCraft", &H57EF13)
            Dim P33 As Integer = ReadInteger("StarCraft", &H57EF17)
            Dim P34 As Integer = ReadInteger("StarCraft", &H57EF1C)
    
            Dim P41 As Integer = ReadInteger("StarCraft", &H57EF33)
            Dim P42 As Integer = ReadInteger("StarCraft", &H57EF37)
            Dim P43 As Integer = ReadInteger("StarCraft", &H57EF3C)
            Dim P44 As Integer = ReadInteger("StarCraft", &H57EF40)
    
            Dim P51 As Integer = ReadInteger("StarCraft", &H57EF57)
            Dim P52 As Integer = ReadInteger("StarCraft", &H57EF5C)
            Dim P53 As Integer = ReadInteger("StarCraft", &H57EF60)
            Dim P54 As Integer = ReadInteger("StarCraft", &H57EF64)
    
            Dim P61 As Integer = ReadInteger("StarCraft", &H57EF7B)
            Dim P62 As Integer = ReadInteger("StarCraft", &H57EF7F)
            Dim P63 As Integer = ReadInteger("StarCraft", &H57EF83)
            Dim P64 As Integer = ReadInteger("StarCraft", &H57EF87)
    
            Dim P71 As Integer = ReadInteger("StarCraft", &H57EF9F)
            Dim P72 As Integer = ReadInteger("StarCraft", &H57EFA3)
            Dim P73 As Integer = ReadInteger("StarCraft", &H57EFA7)
            Dim P74 As Integer = ReadInteger("StarCraft", &H57EFAC)
    
            Dim P81 As Integer = ReadInteger("StarCraft", &H57EFC3)
            Dim P82 As Integer = ReadInteger("StarCraft", &H57EFC7)
            Dim P83 As Integer = ReadInteger("StarCraft", &H57EFCC)
            Dim P84 As Integer = ReadInteger("StarCraft", &H57EFCF)
    
            Dim HexS As String = Nothing
    
            HexS = Hex(P14) & Hex(P13) & Hex(P12) & Hex(P11)
            P1T.Text = HexToString(HexS)
    
            HexS = Hex(P24) & Hex(P23) & Hex(P22) & Hex(P21)
            P2T.Text = HexToString(HexS)
    
            HexS = Hex(P34) & Hex(P33) & Hex(P32) & Hex(P31)
            P3T.Text = HexToString(HexS)
    
            HexS = Hex(P44) & Hex(P43) & Hex(P42) & Hex(P41)
            P4T.Text = HexToString(HexS)
    
            HexS = Hex(P54) & Hex(P53) & Hex(P52) & Hex(P51)
            P5T.Text = HexToString(HexS)
    
            HexS = Hex(P64) & Hex(P63) & Hex(P62) & Hex(P61)
            P6T.Text = HexToString(HexS)
    
            HexS = Hex(P74) & Hex(P73) & Hex(P72) & Hex(P71)
            P7T.Text = HexToString(HexS)
    
            HexS = Hex(P84) & Hex(P83) & Hex(P82) & Hex(P81)
            P8T.Text = HexToString(HexS)
        End Sub
        Function HexToString(ByVal hex As String) As String
            Dim text As New System.Text.StringBuilder(hex.Length \ 2)
            For i As Integer = hex.Length - 2 To 0 Step -2
                text.Append(Chr(Convert.ToByte(hex.Substring(i, 2), 16)))
            Next
            Return text.ToString
        End Function
        Public Function ReadInteger(ByVal ProcessName As String, ByVal Address As Integer, Optional ByVal nsize As Integer = 16) As Integer
            If ProcessName.EndsWith(".exe") Then
                ProcessName = ProcessName.Replace(".exe", "")
            End If
            Dim MyP As Process() = Process.GetProcessesByName(ProcessName)
            If MyP.Length = 0 Then
                MessageBox.Show(ProcessName & " isn't open!")
                Exit Function
            End If
            Dim hProcess As IntPtr = OpenProcess(PROCESS_ALL_ACCESS, 0, MyP(0).Id)
            If hProcess = IntPtr.Zero Then
                MessageBox.Show("Failed to open " & ProcessName & "!")
                Exit Function
            End If
    
            Dim hAddress As Integer
            Dim vBuffer As Integer
    
            hAddress = Address
            ReadProcessMemory1(hProcess, hAddress, vBuffer, nsize, 16)
            Return vBuffer
        End Function
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Player_Name()
            Player_Score()
        End Sub
    Last edited by Zaund : 01-19-2020 at 08:01 AM

  2. #2

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    Looks cool, how's it going?

  3. #3
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    Goin good! I am trying to find out how to call functions in Starcraft, specifically write text on the screen. I was able to resurrect Yonder's tutorial from the waybackmachine, but its either incomplete or I am missing something.

    My injector, coded in VB and uses a class written in C++

    Code:
    Public Class Form1
        Private Declare Function main Lib "C:\Users\Ulfric\source\repos\Zaund\Debug\Zaund-Inj.dll" () As Integer
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim loadStatus As Integer = main()
            If loadStatus = 19 Then
                MsgBox("Brood War is not open!")
            ElseIf loadStatus = 1 Then
                MsgBox("Success")
            ElseIf loadStatus = 2 Then
                MsgBox("Could not open process")
            ElseIf loadStatus = 3 Then
                MsgBox("Failed to allocate memory")
            ElseIf loadStatus = 4 Then
                MsgBox("Failed to write to memory")
            ElseIf loadStatus = 5 Then
                MsgBox("Failed to create thread")
            ElseIf loadStatus = 6 Then
                MsgBox("Something went wrong!")
            End If
        End Sub
    End Class
    The class

    Code:
    #include <iostream>
    #include <windows.h>
    #include "pch.h"
    #include <stdio.h>
    
    #pragma comment(lib, "user32.lib")
    #pragma comment(lib, "advapi32.lib")
    
    using namespace::std;
    
    int Inject(HWND windowHandle, char* dll);
    
    BOOLEAN tokenAdjuster();
    
    int main()
    {
        char dllLocation[] = "C:\\Users\\Ulfric\\source\\repos\Zaund\\Debug\\Zaund.dll";
        if (tokenAdjuster == FALSE) { return 7; } //Failed to change access token
        HWND broodHandle = FindWindowA(NULL, "Brood War");
        int diagPort = Inject(broodHandle, dllLocation);
        if (broodHandle == NULL) { return 19; }
        if (diagPort) { return 1; }
        if (diagPort == 0) { return 2; } // Could not open process
        if (diagPort == 1) { return 3; } // Failed to allocate memory
        if (diagPort == 2) { return 4; } // Failed to write to memory
        if (diagPort == 3) { return 5; } // Failed to create thread
        else { return 6; }
    }
    
    
    int Inject(HWND windowHandle, char* dll)
    {
        DWORD processID;
        HANDLE    broodHandle, threadHandle;
        DWORD   bytesWritten;
        LPVOID    memory;
    
        GetWindowThreadProcessId(windowHandle, &processID);
        broodHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
    
        if (broodHandle == NULL) { return 0; }
        memory = VirtualAllocEx(broodHandle, NULL, strlen(dll), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    
        if (memory == NULL) { CloseHandle(broodHandle); return 1; }
        if (WriteProcessMemory(broodHandle, memory, (LPVOID)dll, strlen(dll), &bytesWritten))
        {
            threadHandle = CreateRemoteThread(broodHandle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"KERNEL32.DLL"), "LoadLibraryA"), memory, 0, NULL);
            if (threadHandle == NULL) { VirtualFreeEx(broodHandle, NULL, strlen(dll), MEM_RESERVE | MEM_COMMIT); CloseHandle(broodHandle); return 3; }
    
            VirtualFreeEx(broodHandle, NULL, strlen(dll), MEM_RESERVE | MEM_COMMIT);
            CloseHandle(threadHandle);
            CloseHandle(broodHandle);
            return 1;
        }
        VirtualFreeEx(broodHandle, NULL, strlen(dll), MEM_RESERVE | MEM_COMMIT);
        CloseHandle(broodHandle);
        return 2;
    }
    BOOLEAN tokenAdjuster()
    {
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp;
    
        // Get a token for this process. 
    
        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
            return(FALSE);
    
        // Get the LUID for the shutdown privilege. 
    
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME,
            &tkp.Privileges[0].Luid);
    
        tkp.PrivilegeCount = 1;  // one privilege to set    
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
        // Get the shutdown privilege for this process. 
    
        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
            (PTOKEN_PRIVILEGES)NULL, 0);
    
        if (GetLastError() != ERROR_SUCCESS)
            return FALSE;
    
        //successful
        return TRUE;
    }
    And the hack

    Code:
    #include "pch.h"
    #include "windows.h"
    
    DWORD processID;
    HANDLE    broodHandle;
    HWND broodWindow;
    char broodMsg[32];
    
    
    void readMsg()
    {
        broodWindow = FindWindowA(NULL, "Brood War");
        if (GetWindowThreadProcessId(broodWindow, &processID))
    
        {
            if (broodHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID))
    
            {
                ReadProcessMemory(broodHandle, (LPVOID)0x06B80088, broodMsg, 32, 0);
                CloseHandle(broodHandle);
    
                MessageBoxA(0, broodMsg, NULL, MB_ICONEXCLAMATION | MB_OK);
            }
            else
            {
                MessageBoxA(0, "Unable to open process", NULL, MB_ICONEXCLAMATION | MB_OK);
            }
        }
        else
        {
            MessageBoxA(0, "Unable to obtain process ID", NULL, MB_ICONEXCLAMATION | MB_OK);
        }
    
    }
    
    void writeMem()
    {
    
        broodWindow = FindWindowA(NULL, "Brood War");
        INT miner = 5000;
    
        if (GetWindowThreadProcessId(broodWindow, &processID))
    
        {
            if (broodHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID))
    
            {
                WriteProcessMemory(broodHandle, (LPVOID)0x508718, &miner, sizeof(miner), 0);
                CloseHandle(broodHandle);
            }
            else
            {
                MessageBoxA(0, "Unable to open process", NULL, MB_ICONEXCLAMATION | MB_OK);
            }
        }
        else
        {
            MessageBoxA(0, "Unable to obtain process ID", NULL, MB_ICONEXCLAMATION | MB_OK);
        }
    
    }
    Hack doesn't do much yet, just messing around at this point.

  4. #4

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    Looks good!

    Yonder's tutorial is very dated and used an even older version of the game, so everything will be kinda different. Suteki I think had more up to date tutorials, but I don't remember specifics.

    Is the hack portion internal? If so, try using the handle from GetCurrentProcess() as the handle for ReadProcessMemory/WriteProcessMemory, it should shorten your code a lot.

    BWAPI is also a very good resource. For instance, if you found where this struct is in BW's memory, you would have access to quite a lot of useful data:
    https://github.com/bwapi/bwapi/blob/...ce/BW/BWGame.h

    Cheers.

  5. #5
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    Jiggie, thanks for the link!

    I've been stumbling around the internet looking for tutorials for weeks now lol.

    I'm not sure what you mean by 'is the hack portion internal?', can you elaborate?

  6. #6

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    Internal as in, a DLL style hack? I assume you are injecting a DLL, then all further hacky stuff happens in the DLL.
    External would be if you were doing all the reading/writing from another process somewhere.

  7. #7
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    Yes I am Jiggie and I know exactly what you mean now!

    I am also pleased to discover assembly in c++

    Thanks again for the link

  8. #8

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    Quote Originally Posted by Zaund View Post
    Yes I am Jiggie and I know exactly what you mean now!

    I am also pleased to discover assembly in c++

    Thanks again for the link
    Ya np! I'll be around

  9. #9
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    Jiggie, I am making progress!

    Code:
    void displayText(char* txtMsg)
    {
        static int textFunc = 0x46DD20; //1.09 Player Text Function
    
            __asm
            {
                PUSH txtMsg
                POP EDI
                MOV ECX, EDI
                CALL DWORD PTR [textFunc]
            }
    }
    Now, I am going to locate the function that prints text anywhere

    Edit:

    So I am pretty sure I found the draw text anywhere function, but I am confused about calling the refresh function (how do I find this in BW?) and why do I need to jump back to another function? (And how do I find the function to jump to?)

    This is the code I have been studying:

    Code:
    const int BWFXN_HUD = 0x04202B0;
    const int BWFXN_RetHud = 0x048CF85;
    
    const int BWFXN_Refresh = 0x41E0D0; // I found this!
    const int BWFXN_RetRefresh = 0x041E28D; // I was told this (and I'm STILL confused as to how to find it..)
    
     
    
    - My functions in C++
    
    void BW_RefreshScreen(int TopY, int LeftX, int BottomY, int RightX) {
    
    __asm {
    	pushad
    		push RightX
    		mov eax, TopY
    		mov edx, BottomY
    		mov ecx, LeftX
    		call dword ptr cs:[BWFXN_Refresh]
    	popad
    }
    }
    
    void __declspec(naked) BW_RefreshScreenHook() {
    
    __asm {
    	MOV EDI,DWORD PTR DS:[6CEFF4h]
    	jmp BWFXN_RetRefresh
    }
    }
    
    void BW_DrawHudText(int x, int y, const char *szText) {
    
    __asm {
    	pushad
    		push y;
    		mov esi, x;
    		mov eax, szText;
    		call DWORD PTR [BWFXN_HUD]
    	popad
    }
    }
    
    void __declspec(naked) BW_DrawHudTextHook() {
    
    BW_RefreshScreen(0, 0, 0x480, 0x640); // Refresh the WHOLE screen!
    BW_DrawHudText(50, 50, "x6Hello World!");
    
    __asm {
    	mov dword ptr ss:[ebp-4h],0Bh
    	jmp BWFXN_RetHud
    }
    }
    Last edited by Zaund : 02-10-2020 at 08:49 AM

  10. #10

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    Nice!

    I'm going to break your quote up,

    Quote Originally Posted by Zaund View Post
    So I am pretty sure I found the draw text anywhere function
    I am confused about calling the refresh function (how do I find this in BW?)
    Typically it's probably right beside the place you found text draw. Here's some shit code for clarity:
    Code:
    ...code...
    CALL TextDrawBlah
    ...code...
    CALL RefreshStuff
    ...code...
    The refresh function could be hiding inside RefreshStuff, for instance. You must test functions by replacing the first asm instruction (usually "PUSH EBP") with RETN or RETN #, and seeing if screen refreshing stops. If so, then you know this function relates to refresh.

    From there, you either call it in your hook, OR, hack the refresh bounds to fit the entire screen (edit the asm so that the refresh rect covers 0,0,640,480), then whenever it refreshes anything, the entire screen refreshes.

    and why do I need to jump back to another function? (And how do I find the function to jump to?)
    The jump back is where you want the code to resume, since it needs a direction to go when you are done with it.
    Jump back is needed for Hooks. Hooks being ways to hijack code at specific points. Do you know where your hook offset is?

  11. #11
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    I think I need to back track a little.

    To find a breakpoint for the draw text anywhere function, I made a custom map with a leader board, labeled 'Minerals'. I found an address for 'Minerals' and set an on access memory breakpoint. The debugger pops, and I dissect from there.

    Does that sound like I am even starting on the right path? The registers have already been loaded with the ASCII string when Olly pauses.

    I will say that when I step into the function that I suspect is the HUD draw function and replace the first PUSH with a RETN, the leader board numbers and text disappear and the game crashes shortly after.

    Is my hook the thread I created when my DLL was attached to the process?

    Thanks for hangin with me Jiggie. I am out of coffee and I have to go back to work tomorrow for a day. If I don't respond for a little while, I haven't given up!
    Last edited by Zaund : 02-11-2020 at 01:42 AM

  12. #12

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    Quote Originally Posted by Zaund View Post
    I think I need to back track a little.
    ...
    Thanks for hangin with me Jiggie. I am out of coffee and I have to go back to work tomorrow for a day. If I don't respond for a little while, I haven't given up!
    Np, but I should backtrack too. This is complicated by game hacking standards, so it's a lot of trial and error.

    Is my hook the thread I created when my DLL was attached to the process?
    In drawing text to XY, hooks are the most important thing, and they're extremely sensitive.

    Draw XY needs to be called in a very small window of opportunity (after the game has chosen font and drawing region and such). Call it at the wrong time and it will either crash or fail to draw.

    To circumvent this, you will need a hook. A hook is just a tool that lets you take any line of the game and redirect it to your DLL code. So if you have a hook at 0x12345678 that redirects to void boobies(), then boobies() will get executed every time offset 0x12345678 executes. You'll need to read up on this elsewhere, they're commonly called JmpPatch or CallPatch.

    So you'll need to use that tool to have your code execute whenever SC draws it's minerals (or whatever). Then any time SC draws the mineral count in the HUD, boobies() goes too.

    To find a breakpoint for the draw text anywhere function, I made a custom map with a leader board, labeled 'Minerals'. I found an address for 'Minerals' and set an on access memory breakpoint. The debugger pops, and I dissect from there.

    Does that sound like I am even starting on the right path? The registers have already been loaded with the ASCII string when Olly pauses.
    Yea kinda, you can find the function that way but you will not be able to get a very good hook. You might get wonky results down the line (like your text not drawing unless you are in a custom game or w/e).

    I will say that when I step into the function that I suspect is the HUD draw function and replace the first PUSH with a RETN, the leader board numbers and text disappear and the game crashes shortly after.
    Try RETN 4 instead of RETN. (If you scroll down to the bottom of the HUD draw function, you will see RETN or RETN #, that determines which type of RETN you do.)

    Good luck, lotta trial and error and such. I should also say, drawing from an external source is probably easier, but you won't get any hacker street cred.

  13. #13
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    Jig, great info as usual!

    I read up on calling hooks, but wasn't able to really find articles relating to game hacking. Ill keep focusing on this for now. I am assuming I will write the jump using writeprocessmemory at whatever address, then redirect it back to the following line of code once mine has ran?

    Ill try the RETN #. I did find a function called within the function I thought was the draw function, which if I change the first PUSH to RETN, the HUD stops updating and the game doesn't freeze!

    Its all about the street cred

  14. #14
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    I am pretty sure I came across the tutorial that the guy used in the code I posted previously from ghoztcraft...

    http://www.rohitab.com/discuss/topic...l-for-newbies/

    Which helps a lot!

    Still a little unclear about how the JmpPatch function works

    Code:
    void JmpPatch(void *pDest, void *pSrc, int nNops = 0) {
     
        DWORD OldProt;
     
        VirtualProtect(pSrc, 5 + nNops, PAGE_EXECUTE_READWRITE, &OldProt);
     
        *(char*)pSrc = (char)0xE9;
        *(DWORD*)((DWORD)pSrc + 1) = (DWORD)pDest - (DWORD)pSrc - 5;
     
        for (int i = 0; i < nNops; ++i) { *(BYTE*)((DWORD)pSrc + 5 + i) = 0x90; }
     
        VirtualProtect(pSrc, 5 + nNops, OldProt, &OldProt);
    }
    Code:
    if (reason == DLL_PROCESS_ATTACH) {
        JmpPatch(&FindMe, (PBYTE)0x0401006, 0);
    }

    For the params pDest and pSrc, pDest is the address of my function (do I need to find the function address, once loaded into BW?), and pSrc is where I want to jump from?

    Just for an example, lets say the function is at the address 0x4DCFD0C. Would pSrc be this address, or the address right before it?

    Out of time for now, I will get back at it tonight.

    Edit:

    Ok making a little progress tonight.

    I have successfully written a jump patch into BW's memory!! I am still thinking I am not at the right function address. I can't get anything to print without causing an exception and BW to crash. I also tried changing my version to 1.15.1, like used in the example code I posted previously, and wasn't able to replicate results using his addresses

    Jig, any pointers on finding the HUD draw function? I am trying to search for a string value of '50' (my mineral count), then setting a memory access break point, but Olly never pauses. I can get it to pause when I use the address of the leader board title "Minerals", but I am thinking this is where I am stuck at.

    Edit 2:

    Alright, I wrote a jump patch to my function, which replaced a pointer in the ECX register with the address of my player name, then executed a draw function and jumped back right after my jump patch. The result was everything replaced with 'Tyrone', resource values and all the menu options. I think I am close!
    Last edited by Zaund : 02-14-2020 at 03:23 PM

  15. #15

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    Quote Originally Posted by Zaund View Post
    Jig, great info as usual!

    I read up on calling hooks, but wasn't able to really find articles relating to game hacking. Ill keep focusing on this for now. I am assuming I will write the jump using writeprocessmemory at whatever address, then redirect it back to the following line of code once mine has ran?

    Ill try the RETN #. I did find a function called within the function I thought was the draw function, which if I change the first PUSH to RETN, the HUD stops updating and the game doesn't freeze!

    Its all about the street cred
    Yes, great comprehension skills, that is exactly what you do!

    Quote Originally Posted by Zaund View Post
    I have successfully written a jump patch into BW's memory!! I am still thinking I am not at the right function address. I can't get anything to print without causing an exception and BW to crash. I also tried changing my version to 1.15.1, like used in the example code I posted previously, and wasn't able to replicate results using his addresses

    Jig, any pointers on finding the HUD draw function? I am trying to search for a string value of '50' (my mineral count), then setting a memory access break point, but Olly never pauses. I can get it to pause when I use the address of the leader board title "Minerals", but I am thinking this is where I am stuck at.

    Edit 2:

    Alright, I wrote a jump patch to my function, which replaced a pointer in the ECX register with the address of my player name, then executed a draw function and jumped back right after my jump patch. The result was everything replaced with 'Tyrone', resource values and all the menu options. I think I am close!
    That's excellent progress!

    I'll assume you have figured out how JmpPatch works and no longer need tips on that. The only thing I'll add is, a Jmp/Call Patch is 5 bytes, and so sometimes you must overwrite multiple lines of asm, which you may have figured out by now.

    As for finding a HUD draw function, are we talking about a spot to hook or a function to call to print a message to XY?

    If it's a spot to hook you are looking for... Immediately after any call to DrawXY is a "valid" spot, so long as it gets called once per frame. In Olly you can find every call to a function by selecting the first line of the function (often PUSH EBP), then right clicking -> Find References to selected command, or whatever it was, which will give you a list of all the places that call it... Then in a single player game with as LITTLE text on the screen as possible, set breakpoints on all the calls. The ones that pop will likely be called once every HUD draw, which make for decent hooking spots.

    Let's pretend 0x12345678 is the drawXY function. You would go to 0x12345678 in olly, select the first line, find references to selected commands. You'll get a big list, and setting breakpoints on these offsets will tell you which are being used. Some are better than others (different draw areas, different fonts, etc), but they should all be valid hook locations.

    Example:
    Code:
    PUSH BLAH
    PUSH BLAH
    MOV BLAH, BLAH
    CALL 0x12345678       ; draw XY function
    MOV BLAH, BLAH        ; maybe a hook here would do you good?
    Also, beware registers C++ may use for your DLL code. Wrapping your code in
    Code:
    _asm pushad
    //code here
    _asm popad
    might stop some crashes.

    Keep me posted, great progress so far! I wasn't able to address everything you mentioned, so re-ask if it's still relevant.

    Cheers, Zaund!
    Last edited by Jiggie=#1 : 02-15-2020 at 03:27 PM

  16. #16
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    Thanks jig! Without your help, I would be absolutely lost!

    I haven't played with the draw anywhere function since my last post, but your advice will definitely help finding the line that calls the function.

    I decided to step back from the Draw anywhere and work on the unit alert portion of the hack, since I was feeling stuck.

    I can get it to flawless execution with the name of the unit drawn to the chat/message area!

    I am working on the nitty gritty now of forming the string with all the data of the player name and the amount they command of that particular unit. I used a online C++ assemble to write the code while I was at work last night (hehe), but it unfortunately is not working out as planned!

    To form the string, I am using sprintf_s to combine the color code with the player name, some text, the unit created, and the amount commanded of that unit followed by some text.

    It really jacks the registers up and I can't seem to pop all the data I need gone off the stack.

    Let me play some more and I can come up with something meaningful that you can help me with :D

    Needless to say, c++ has challenges when trying to manipulate at the assembly level, but I will work through it. I am well over 30 hours into it since I started back into it at the end of January and years ago I spent many hours trying to make this stuff work with no success.

    When I finish and polish my code, I plan on writing WELL written tutorials and leaving them here. I know the game is ancient, but I still love it and I love taking it apart and making it do what I want!

    YOU THE MAN JIG!!! HAVE SOME FREE BOOBIES (. Y .)

  17. #17
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    so yea when I do all my string and int conversions to char, the registry goes wild!

    I am going to mess around with pushad and popad,


    I wrote that and thought, man in the time it took me to write that I could have coded it. So I stopped there and tried, I am getting somewhere!

    Name:  AuC5NHd.png
Views: 79
Size:  984.2 KB

  18. #18

    Disciple
    Jiggie=#1's Avatar
    Join Date
    Jul 2006
    Location
    Cream
    Posts
    389

    Default

    (. Y .)

    Unit alert looks nice, good work! Motivation is the true enemy.

    I miss SC, maybe I'll do something if I get the time. Hacking is always fun, just always busy or tired.

    Tutorials would be interesting. You ever gonna touch remastered?

    Fun fact, if you tell a pylon to place a rally point on a probe, the probe gets a power field around it. It worked online since the dawn of time (rally point struct overlaps with pylon power field). Worked on remastered last I checked, but that might not be the case anymore. Definitely works on every version pre-remastered though.

  19. #19
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    Yes, working nightshift gets me off kid duty on my days off, so I have a lot of free time when Im awake during the night.

    I cant figure outnhow to get past the anti cheat in the newer versions v.v

    I will try the pylon trick that sounds cool!

  20. #20
    Bee Double You Hacks Senior Member
    Retired Staff Member

    Enlightened
    Zaund's Avatar
    Join Date
    May 2005
    Posts
    2,647

    Default

    I think I am done with unit alert! I want to clean the code up a bit and was thinking I would move it into it's own file, outside of the dllmain file.

    I have found the refresh function, and I think I know the parameters, but sometimes my centertext function doesn't update correctly.

    There has to be a better way to do this:

    Code:
    // Terran buildings
                if (unitType == 0x6A) { buildMsg(commandCenter, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xD6 && unitAlertstate == 2) { buildMsg(supplyDepot, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xBC && unitAlertstate == 2) { buildMsg(extractor, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x6F) { buildMsg(barracks, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x7A && unitAlertstate == 2) { buildMsg(engineeringBay, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x7C && unitAlertstate == 2) { buildMsg(missleTurret, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x70) { buildMsg(academy, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x7D) { buildMsg(bunker, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x71 && unitAlertstate == 2) { buildMsg(factory, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x78) { buildMsg(machineShop, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x72) { buildMsg(stargate, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x73 && unitAlertstate == 2) { buildMsg(controlTower, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x74 && unitAlertstate == 2) { buildMsg(scienceFacility, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x75) { buildMsg(covertOps, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x76) { buildMsg(physicsLab, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x7B && unitAlertstate == 2) { buildMsg(armory, totalUnit, buildingPlayernumb); }
    
                // Terran units
                else if (unitType == 0x07) { buildMsg(SCV, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x00) { buildMsg(marine, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x20) { buildMsg(firebat, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x01) { buildMsg(ghost, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x22 && unitAlertstate == 2) { buildMsg(medic, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x02 && unitAlertstate == 2) { buildMsg(vulture, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x1E) { buildMsg(stSiege, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x03) { buildMsg(goliath, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x08 && unitAlertstate == 2) { buildMsg(wraith, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x0B && unitAlertstate == 2) { buildMsg(dropship, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x09 && unitAlertstate == 2) { buildMsg(scienceVessel, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x05) { buildMsg(stTank, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x0C) { buildMsg(battleCruiser, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x3A && unitAlertstate == 2) { buildMsg(vulcan, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x0E) { buildMsg(nuke, totalUnit, buildingPlayernumb); }
    
                // Protoss buildings
                else if (unitType == 0x9A) { buildMsg(nexus, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x9C && unitAlertstate == 2) { buildMsg(pylon, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x9D && unitAlertstate == 2) { buildMsg(assimilator, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA0) { buildMsg(gateway, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA6 && unitAlertstate == 2) { buildMsg(forge, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA2 && unitAlertstate == 2) { buildMsg(cannon, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA4 && unitAlertstate == 2) { buildMsg(cyberneticsCore, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xAC && unitAlertstate == 2) { buildMsg(shieldBattery, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x9B) { buildMsg(roboticsFacility, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA7) { buildMsg(stargate, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA3 && unitAlertstate == 2) { buildMsg(citadelofAdun, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xAB && unitAlertstate == 2) { buildMsg(roboticsSupportbay, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA9 && unitAlertstate == 2) { buildMsg(fleetBeacon, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xA5) { buildMsg(templarArchives, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x9F && unitAlertstate == 2) { buildMsg(observatory, totalUnit, buildingPlayernumb); }
                else if (unitType == 0xAA) { buildMsg(arbiterTribunal, totalUnit, buildingPlayernumb); }
    
                // Protoss units
                else if (unitType == 0x40) { buildMsg(probe, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x41) { buildMsg(zealot, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x42) { buildMsg(dragoon, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x43) { buildMsg(highTemplar, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x3D) { buildMsg(darkTemplar, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x53) { buildMsg(reaver, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x45 && unitAlertstate == 2) { buildMsg(shuttle, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x54) { buildMsg(observer, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x46 && unitAlertstate == 2) { buildMsg(scout, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x47) { buildMsg(arbiter, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x48) { buildMsg(carrier, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x3C && unitAlertstate == 2) { buildMsg(corsair, totalUnit, buildingPlayernumb); }
    
                // Zerg buildings
                else if (unitType == 0x82) { buildMsg(infestedCC, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x83) { buildMsg(hatchery, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x84) { buildMsg(lair, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x85) { buildMsg(hive, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x8B && unitAlertstate == 2) { buildMsg(evolutionChamber, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x8E) { buildMsg(spawningPool, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x87) { buildMsg(hydraliskDen, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x8D) { buildMsg(spire, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x89) { buildMsg(greaterSpire, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x8A) { buildMsg(queensLair, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x86) { buildMsg(ultraliskCavern, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x8C) { buildMsg(nydusCanal, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x88) { buildMsg(defilerMound, totalUnit, buildingPlayernumb); }
    
                // Zerg units
                else if (unitType == 0x29) { buildMsg(drone, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x25) { buildMsg(zergling, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x26) { buildMsg(hydralisk, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x67) { buildMsg(lurker, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x2D) { buildMsg(mutalisk, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x2C) { buildMsg(guardian, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x53) { buildMsg(reaver, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x2D) { buildMsg(queen, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x27) { buildMsg(ultralisk, totalUnit, buildingPlayernumb); }
                else if (unitType == 0x2E) { buildMsg(defiler, totalUnit, buildingPlayernumb); }
            }
    Because the sprintf function only take pointers, I have all these:

    Code:
    // Terran buildings
    char commandCenter[] = "Command Center";
    char supplyDepot[] = "Supply Depot";
    char extractor[] = "Extractor";
    char barracks[] = "Barracks";
    char engineeringBay[] = "Engineering Bay";
    char missleTurret[] = "Missle Turret";
    char academy[] = "Academy";
    char bunker[] = "Bunker";
    char factory[] = "Factory";
    char machineShop[] = "Machine Shop";
    char controlTower[] = "Control Tower";
    char scienceFacility[] = "Science Facility";
    char covertOps[] = "Covert Ops";
    char physicsLab[] = "Physics Lab";
    char armory[] = "Armory";
    
    // Terran units
    char SCV[] = "SCV";
    char marine[] = "Marine";
    char firebat[] = "Firebat";
    char ghost[] = "Ghost";
    char medic[] = "Medic";
    char vulture[] = "Vulture";
    char stSiege[] = "Siege Tank(Siege Mode)";
    char stTank[] = "Siege Tank(Tank mode)";
    char goliath[] = "Goliath";
    char wraith[] = "Wraith";
    char dropship[] = "Dropship";
    char scienceVessel[] = "Science Vessel";
    char battleCruiser[] = "Battlecruiser";
    char vulcan[] = "Vulcan";
    char nuke[] = "Nuke";
    
    // Protoss buildings
    char nexus[] = "Nexus";
    char pylon[] = "Pylon";
    char assimilator[] = "Assimilator";
    char gateway[] = "Gateway";
    char forge[] = "Forge";
    char cannon[] = "Cannon";
    char cyberneticsCore[] = "Cybernetics Core";
    char shieldBattery[] = "Shield Battery";
    char roboticsFacility[] = "Robotics Facility";
    char stargate[] = "Stargate";
    char citadelofAdun[] = "Citadel of Adun";
    char roboticsSupportbay[] = "Robotics Support Bay";
    char fleetBeacon[] = "Fleet Beacon";
    char templarArchives[] = "Templar Archives";
    char observatory[] = "Observatory";
    char arbiterTribunal[] = "Arbiter Tribunal";
    
    // Protoss units
    char probe[] = "Probe";
    char zealot[] = "Zealot";
    char dragoon[] = "Dragoon";
    char highTemplar[] = "High Templar";
    char darkTemplar[] = "Dark Templar";
    char reaver[] = "Reaver";
    char shuttle[] = "Shuttle";
    char observer[] = "Observer";
    char scout[] = "Scout";
    char arbiter[] = "Arbiter";
    char carrier[] = "Carrier";
    char corsair[] = "Corsair";
    
    // Zerg buildings
    char hatchery[] = "Hatchery";
    char lair[] = "Lair";
    char hive[] = "Hive";
    char infestedCC[] = "infested Command Center";
    char evolutionChamber[] = "Evolution Chamber";
    char spawningPool[] = "Spawning Pool";
    char hydraliskDen[] = "Hydralisk Den";
    char spire[] = "Spire";
    char greaterSpire[] = "Greater Spire";
    char queensLair[] = "Queens Lair";
    char nydusCanal[] = "Nydus Canal";
    char ultraliskCavern[] = "Ultralisk Cavern";
    char defilerMound[] = "Defiler Mound";
    
    // Zerg units
    char drone[] = "Drone";
    char zergling[] = "Zergling";
    char hydralisk[] = "Hydralisk";
    char lurker[] = "Lurker";
    char mutalisk[] = "Mutalisk";
    char guardian[] = "Guardian";
    char ultralisk[] = "Ultralisk";
    char queen[] = "Queen";
    char defiler[] = "Defiler";
    Name:  XkhAv4u.png
Views: 67
Size:  806.0 KB

Thread Information

Users Browsing this Thread

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

Similar Threads

  1. problem in coding hack program
    By MarniTto in forum Starcraft/Brood War
    Replies: 13
    Last Post: 11-29-2009, 08:04 AM
  2. [Starcraft/VB] Cobra Spoofer v2.0 Source Coding
    By ViperSRT3g in forum Open Source and Tutorials
    Replies: 3
    Last Post: 01-23-2009, 10:55 PM
  3. Questions About Coding DLL's
    By overwhelmed in forum Starcraft/Brood War
    Replies: 7
    Last Post: 06-28-2007, 08:19 PM
  4. How did u learn each coding language?
    By SmashedPumpkins in forum Software Development
    Replies: 35
    Last Post: 03-06-2006, 08:50 AM

Posting Rules

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