Jump to content
Heads Up! This website is no longer maintained, if your a member from our era, consider joining the discord to say hello.
Sign in to follow this  

A Starcraft DLLTutorial Coded In MASM32

Recommended Posts

A Starcraft DLLTutorial Coded In MASM32

By: Suteki

 

This tutorial is aimed at beginners who have probably never worked with much outside of a memory searcher. Thus that type of attitude should be taken when reading this.

 

Tools that are required:

Masm32; http://www.masm32.com

Ollydbg; http://www.ollydbg.de

Jiggie's Basic Hack Template; http://upload.Ghoztcraft.net/files/178/Bas...%20Template.rar (http:// must be included)

A memory searcher, I'm going to use Cheat Engine for this tutorial; http://www.cheatengine.org/

Starcraft in window mode; http://rapidshare.com/files/70636634/scloa..._wmode.zip.html

 

*INSTRUCTIONS*

-Download from rapidshare with the link above

-Save to a spot where you have easy access to the zip

-Extract the contents of the zip into your Starcraft directory

-Right click on scloader2b, and create a shortcut

-Right click on the shortcut of scloader2b, and hit properties

-In the shortcut tab where it says target. You will see a pathway and " at the end of it. click at the end of the " and make a space after it.

-Now add -xmod wmode.xmod (It should look like this when your done "C:Program FilesStarcraftscloader2b.exe" -xmod wmode.xmod)

-Hit apply, and then Ok

 

Okay now that you have all the required tools, let's get into it! We are going to be making the classical offline mineral/gas hack.

 

The hack will do these things:

Pressing a hotkey will give Player 0 (Player 1) a set amount of minerals/gas if you are, indeed that player

Pressing a hotkey will give Player 1 (Player 2) a set amount of minerals/gas if you are, indeed that player

 

What you will learn (hopefully):

Memory searcher useage

Some very basic Ollydbg useage

What it takes to create a DLL in MASM32

How do determine what player you are, and thus be able to only give the desired hack features to yourself

How hotkeys work useing MASM32

A little bit of Hex

And hopefully you will better understand how Starcraft as a game functions

 

The Beginning

After installing/downloading all the required files/tools, start by creating a folder and extracting the DLL template files into that folder. The template should include the BasicHack ASM file, Calls.INC, Events.INC, Functions.INC, the DLL compiler (the Batch file), and the DLL injector (the exe titled "load") along with the load text document. If your computer doesn't reconize the ASM file or INC files, just browse and open them with Notepad.

Start Starcraft using the scloader2b, and then start up cheat engine. Click the glowing computer in the top left, scroll down and then select Starcraft.exe. Then start a new single player game on the Astral Balance.scm map. As always your minerals start at 50, so go to cheat engine and search for the Exact 4 Byte value of 50 and click First Scan. Screenshot1.JPG

many addys will pop up in the left corner, now go back to Starcraft and build 1 worker, your minerals will then drop to 0, as the worker is building switch to cheat engine and change the 50 into 0 and click "Next Scan" You should only have a few addys on the left now. Now open up Ollydbg, select File>Attach, and then scroll until you see "Brood War" in the Window section Screenshot2.JPG

click it and click "Attach". Now the debugger will attach to Starcraft and then Pause. (Bottom right corner will tell you it's Paused) To resume the game, press the VCR looking play button. Take a look at the first addy that is on the top left of cheat engine (mine was 0057F0DC) remember that address and go back to Olly, and click somewhere in the bottom left corner (this window is called the Hex dump)and press Ctrl+G put in the address you had into the window that pops up and press OK Screenshot3.JPG

Do the same thing again. If you did it correctly the top left byte in that bottom window should either be 0 if you have no minerals, or 32 if you have 50 minerals. To make sure it's the right address click on that top left byte and press Ctrl+E Screenshot4.JPG

and change either the 00 or 32 into FF. Go back to Starcraft, and if it was the right address your minerals should now be 255. In Hex FF is the largest you can go, which in Decimal is equivalent to 255. FF Hex = 255 Decimal. If your minerals did not change, start the game over, and start a new scan in cheat engine and repeat what I said to do before.

So now that you know you have the right address for your minerals, we need to find our Gas address, so start a new scan in CE (cheat engine) and search for 0 (you should have 0 gas) now build a gas building for whatever race you are. allow your worker to only bring in 1 thing of gas (which should then make your gas be at 8 ) now scan 8 for your Next Scan, allow the worker to bring in 1 more thing of gas (gas should now be at 16) and search 16. You should only have a few addresses now, so pick the first one, and again in the Hex dump of Olly click somewhere and press Ctrl+G and put in the new address you found for the gas. (Mine was 0057F10C) assuming you stopped at 16 gas your top left byte should be 10. Check to make sure this is the right addy by clicking on the 10 and pressing Ctrl+E and change the 10 to FF. Go back to Starcraft and your gas should now be 255. Okay so now we have both the Mineral address and Gas address. Now look at where you are on the map. If you are on the bottom you are Player0 (Player1) if you are on the top right you are Player 1 (Player 2) Starcraft starts off player numbers at 0, so that means Player 1 is really Player 0, and Player 2 is really Player 1, etc. So whatever addresses you found will only work for that particuler Player # What does that mean? That means you have to do what we just did to find our Minerals/Gas all over again for the opposite side of where you are! I know your probably thinking "UGH Do I really have too!?" Yes, yes you do. So put down in your notes (You are keeping notes right?) the Mineral and Gas address you found, clear those searches out in CE and keep restarting Starcraft until you are on the opposite side of where you first were, and start searching away!

Okay you finally got all the addresses! Good Job! I know it might of been annoying, but it had to be done because starcraft has a seperate address for Minerals/Gas respectivly for each Player on the map! So for Player 0 (Again Player 0 is Player 1) The addresses I got were:

Minerals - 57F0D8

Gas - 57F108

And Player 1 (Again Player 1 is Player 2) I got:

Minerals - 57F0DC

Gas - 57F10C

 

Now we need to find the hex dump addy that holds what Player we are. So start a game on the Astral Balance.scm map if you aren't already in it. Look and see where you are, if you are on the bottom left, go into CE and start a new search and put in 0. If you are on the top left put in 1. You'll get a lot of addresses. Now restart the game, and search for 0 or 1 again if you are in the same spot. But if you aren't search the opposite. Keep doing this until you have 20 or so addys. A lot of the addresses hold the same info, I got 00512678 So once you have around 20 just pick the top left one, and search for it in the Hex dump of Olly. It should say 0 if you are at the bottom, and 01 if you are at the top. Now click on that Byte (00, or 01 pending on where you are) and right click on it, go to Breakpoint, and then select "Memory, on Access"

Screenshot5.JPG

Olly should then pop (Pause) and you should be on the address

00486C43 MOV DWORD PTR DS:[512678],ECX

Screenshot6.JPG

Let's take a look at what this is doing. If you look in the top right corner of Olly (the Registers window) You should see in the ECX register either 00000000 if you are on the bottom, or 00000001 if you are on top. If you remember that's our Player #! Again look at the line of code:

MOV DWORD PTR DS:[512678],ECX

It is moving whatever is in ECX into the Pointer 512678...wait a minute that was my Hex dump addy! Yup, and that is how you saw what you saw. It's taking ECX (either 0 or 1) and putting that value into the address 512678. Okay this is what we need to do now, right click and go to Breakpoint>Remove memory breakpoint. And press play until the game unpauses. Go back to Olly and above the line we were on, go to 00486C00 (PUSH EBX) and double click on that line of code until it turns red. Screenshot7.JPG

Now once that happens it should pop right away. Double click it again to remove the red line, then press Ctrl+F9 (Execute till return) you should land at 00486D15 (RETN) Screenshot8.JPG

once there, press Enter on that line, which should take you down to 00486D72 (JMP SHORT starcraf.00486D79) Screenshot9.JPG

if you look above that line you should see CALL starcraf.00486C00 if you click that line and press Enter, you will see we get taken right back to 00486C00 (PUSH EBX) ! What we just did is landed on a line of code in a function ( 00486C43 MOV DWORD PTR DS:[512678],ECX ) then we ran until the RETurN and left the function, RETurNing to the one before it. Then pressing enter on that Call, took us right back into the CALLed function that we just left. Get it? I hope so. Right now your probably wondering "Why/How does any of this even freaken matter!?" Well what we were doing is finding what function handled our Player #, and what register it was put into, remember ECX was 00000000 if we were on the bottom, and 00000001 if we were on top? The reason for all that and how we will use it you will soon see.

 

Codeing Our DLL!

First what we are going to do is create a Jump Patch (JmpPatch) I think Drakken said it best inside of his Template "JmpPatch works like code injection only easier. :D It dynamically patches a jmp to your function. You must have it execute any code you've overwritten and have it jump back or return to the appropriate memory location. Use "jmp dword ptr [variablename]" if you need to have it jump back instead of ret It will write 5 bytes at the offset you specify for the jump. JmpPatch, from offset, to offset" What that means is we are going to use it on the CALL that took us to the function that handled our Player #. We will place our JmpPatch on that Call, and have it take us into our own function that we are going to make. It will then execute the code we tell it to execute. Then finally we will have it jump back to the appropriate code location-that being the same addy that the RETN took us to.

 

Okay so open up Basic Hack.ASM and scroll until you see DLLStartup proc Press enter to go right below that, and put this in:

invoke JmpPatch, 486D6Dh, addr PlayersChecker;Our JmpPatch, it's the Call that leads to the Player# function, but we are using it to Jump to our PlayersChecker function instead

That's all we need to do with that, so save and close. It should look like this:

DLLStartup proc
invoke JmpPatch, 486D6Dh, addr PlayersChecker;Our JmpPatch, it's the Call that leads to the Player# function, but we are using it to Jump to our PlayersChecker function instead
ret
DLLStartup endp

 

Now open up Functions.INC Now what we must do is:

Define Player0's Mineral/Gas address

Define Player1's Mineral/Gas address

Define the first address that we should be taken to inside of the JmpPatch

Create our Toggle

and Define the our Jump Back address

 

To each of these do this; at the top of Functions.INC is .Data This is where we are going to define all of those things mentioned above, we will do that in this manner.

Under .Data put

Player0Min db 61h, 1Eh ;Player0's Minerals

Player0Gas db 61h, 1Eh ;Player0's Gas

Player1Min db 61h, 1Eh ;Player1's Minerals

Player1Gas db 61h, 1Eh ;Player1's Gas

Player dd 486C00h ;Address taken to inside the Call

Hack dd 0 ;Our toggle

JmpBack dd 486D72h ;The Jumpback (The code ran After it returns from the Call)

 

What we did is define the variables (Player0Min, Player0Gas, Etc.) and then gave them either a value (db =Data Byte) Or gave them and address (dd = Define Doubleword) We will use these inside of the procedure that we are going to make. Everything has an h at the end because that is how MASM know that you mean Hex.0-9 do not need h because 0-9 in Hex is 0-9 in Decimal, but once you hit 10 in Decimal, 10 in Decimal is translates into A for Hex. Why we did the 61h, 1Eh part is because in Hex that = 7777 in Decimal...Actually it's really 1E61 = 7777 but starcraft reads Bytes Backwards! So that means we have to put it backwards in order for it to put it the correct way. Try it, open up windows calculator, go to View>Scientific, make sure the Dec bubble is checked, and put in 7777 then click the Hex bubble. See in Hex 7777 = 1E61 But since Starcraft reads the Bytes backwards if we were do to that it would end up being 611E, put that in for Hex and then switch to Dec. See now we would get 24862 instead of our neat 7777. Anyways there is your Hex lesson for the day (See I didn't lie, I told you in the begining that you would learn a little bit of Hex!) So you should have:

.Data
Player0Min	 db	61h, 1Eh;Player0's Minerals
Player0Gas	db	61h, 1Eh;Player0's Gas
Player1Min	 db		61h, 1Eh;Player1's Minerals
Player1Gas	db	61h, 1Eh;Player1's Gas
Player		dd			486C00h;Address taken to inside the Call 
Hack			 dd			0		   ;Our toggle
JmpBack	   dd			486D72h;The Jumpback (The code ran After it returns from the Call)

 

Now under .Code is where we are going to create our proc. Remember back in the ASM file when we created our JmpPatch we named our Proc PlayersChecker, so under .Code put PlayersChecker proc ;Start our PlayersChecker Proc

If your wondering why I am putting all of these ";" in with sentences afterwords it's because these are "Comments" Anything put after a ; is not read by the program and is only created for visualization purposes for the programmer to read. It's a way to make notes inside of the Program/DLL that the programmer is creating basically. You can get kinda lost in 500 lines of code if you don't have any comments, or "notes" to refer to. Anyways after creating the proc, we first need to put the first line of code that will be ran when it jumps to this proc. If you go back into Olly and go to that Call again and press enter, you will land on 486C00 and as you can see we defined 486C00 as Player back up in the .Data section. So how do we get it to go; or "Call" this address. Well there is the key word, we are going to "Call" it! do this:

Call dword ptr [Player] ;Go to the Player Function

That means call the dword pointer "Player" which as I already said is address 486C00 It just means "goto address 486C00" but when coding in MASM you need to create the name of the Pointer (ptr) you are Calling/define it's address.

Now what are we going to do? Well remember when we first popped and landed on that line of code that put ECX into that Hex dump Address? (If you don't you may want to scroll up and refresh your memory) Well 2 lines above that ECX is still being messed with so if you get in Olly and go to the address again (00486C43) You can see what I mean. (Screenshot) So double click on the line of code that is 2 lines above 00486C43 and copy the code that comes up in the little Assemble window. Now go back into Functions.INC and Paste that line of code under Call dword ptr [Player]

So now you should have:

PlayersChecker proc;Start our PlayersChecker Proc
Call dword ptr [Player];Go to the Player Function
MOV ECX,DWORD PTR DS:[EAX*4+57EEC0h];Move Player # into ECX

Note: that inside of the Pointer the address 57EEC0 is a Hex address, which means it too needs the h after it.

Now copy the code we popped on (Addy 00486C43) and paste it right under the last code you pasted. What we did is when our JmpPatch is activated it will Jmp to our proc, Call the Player # Function, move our player # into ECX, and then move ECX into the hex dump address 512678. Now to put our Toggle to use, under what you just pasted put:

.if ecx == 0;If Player # = 0
mov Hack, 0 ;Make Hack 0
.elseif ecx == 1;But if Player # = 1
mov Hack, 1 ;Make Hack 1
.endif

 

What we just did is important, and you need to understand it. We moved our Player # into ECX in the previous lines correct? Well now what we are saying is "If ecx = 0 that means I am Player 0 (Player 1)" "otherwise if ecx = 1 that means I am Player 1 (Player 2)" What we are doing with "Hack" is if ecx = 0 we are player 0 so move the value of 0 into Hack, but if ecx = 1 then we are Player 1 so move the value of 1 into Hack.What we are going to do with this is next when we make our hotkey, we are going to have it give the mineral/gas increase to US ONLY!. We are going to do that by checking whether or not Hack = 1 or 0. If Hack = 0 then give the minerals/gas to Player 0, but if Hack = 1 then give the minerals/gas to Player 1 Remember Player 0 and Player 1 have their own mineral/gas addresses, so we can mess with each one individually, otherwise if we were to skip this step and just hand out minerals/gas no matter what, then not only would we recieve the mineral/gas increase, but the Computer would gain them too, which kind of defies the whole point. It's kind of a proof of concept for later when you create harder hacks and you only want whatever you are doing to affect a particuler player. I hope you understand what I've said, if not, re-read it over and over until you do.

Now for the last line of code, can you guess what it is? The Jumpback! Remember, like Drakken said, we have to jump back to the appropriate code location after we are done executing what we want done in our proc. And if you remember I said the JmpBack is the address the RETN took us to. (We went through the whole process with the return, and going back into the Call) So head on down to the RETN and follow it. You'll land on 486D72. If you noticed, under the .Data section we have already created the JmpBack, the way you use it is:

jmp dword ptr[JmpBack] ;Jump back to the address that the RETN took us to (We must have this!)

And finally end the proc by typing in under the Jmpback line we just put it, PlayersChecker endp ;End our PlayersChecker proc. So the finished Functions.INC should look like this:

.Data
Player0Min			db	61h, 1Eh;Player0's Minerals
Player0Gas	db	61h, 1Eh;Player0's Gas
Player1Min			db	61h, 1Eh;Player1's Minerals
Player1Gas	db	61h, 1Eh;Player1's Gas
Player		dd	486C00h;Address taken to inside the Call
Hack				dd	0		   ;Our toggle
JmpBack		dd	486D72h;The Jumpback (The code ran After it returns from the Call)



.Data?

.Code
PlayersChecker proc;Start our PlayersChecker Proc
Call dword ptr [Player];Go to the Player Function
MOV ECX,DWORD PTR DS:[EAX*4+57EEC0h];Move Player # into ECX
MOV DWORD PTR DS:[512678h],ECX;Move ECX (Player #) into the hexdump address 512678
.if ecx == 0;If Player # = 0
mov Hack, 0 ;Make Hack 0
.elseif ecx == 1;But if Player # = 1
mov Hack, 1 ;Make Hack 1
.endif
jmp dword ptr[JmpBack];Jump back to the address that the RETN took us to (We must have this!)
PlayersChecker endp;End our PlayersChecker proc

 

Almost done! Save and close Functions.INC and open up Events.INC

 

If you scroll down you will see a line of code that says ".if wParam == VK_F5 ;If F5 key is pressed" That is the Hotkey. I'm leaving mine as F5 but you can change it to whatever you want. Careful though as I have had problems (as have others) with certain keys like Delete. I suggest you leave it as F5 for now. Now under .if wParam == VK_F5 put:

.if Hack == 0 ;If our Hack Toggle = 0 (which means We are Player0)

invoke WriteMem, 57F0D8h, addr Player0Min, 2 ;Add Minerals to Player0 Only

 

WriteMem as described by Drakken "WriteMem works similar to WriteProcessMemory. WriteMem, offset, data pointer, number of bytes to write"

What we did is (if you couldn't figure it out) remember the 61h, 1Eh we had? well a one byte is 2 of those numbers (61) or (1E), so 4 of those numbers = 2 Bytes. (61 1E) = 2 Bytes. So what we did was "if Hack = 0 that means we are Player0 so write 2 bytes of code to the address Player0Min" The 2 Bytes we wrote were 61 1E and since Starcraft reads bytes backwards (remember?) 61 1E = 7777, and we wrote those bytes to that Player0 address that we found in the beginning, AND we made sure to only do it if Hack = 0 for US! Now we need to make it give us the gas for Player0 too!

invoke WriteMem, 57F108h, addr Player0Gas, 2 ;Add Gas to Player0 Only

Same thing with the minerals, but this time we put in gas with the gas offset we found for Player0 in the beginning. Now we have to do this for Player 1 so do the same thing, but make it if Hack = 1 for Player 1

.elseif Hack == 1 ;But if our Hack Toggle = 1 (which means We are Player1)

invoke WriteMem, 57F0DCh, addr Player1Min, 2 ;Add Minerals to Player1 Only

invoke WriteMem, 57F10Ch, addr Player1Gas, 2 ;Add Gas to Player1 Only

.endif

.endif

So you should have:

.if wParam == VK_F5;If F5 key is pressed
	.if Hack == 0;If our Hack Toggle = 0 (which means We are Player0)
	invoke WriteMem, 57F0D8h, addr Player0Min, 2;Add Minerals to Player0 Only
	invoke WriteMem, 57F108h, addr Player0Gas, 2;Add Gas to Player0 Only
	.elseif Hack == 1;But if our Hack Toggle = 1 (which means We are Player1)
	invoke WriteMem, 57F0DCh, addr Player1Min, 2;Add Minerals to Player1 Only
	invoke WriteMem, 57F10Ch, addr Player1Gas, 2;Add Gas to Player1 Only
	.endif

.endif

 

Guess what? We Are Done! Save Events.INC and close all of them. Now go to the folder (or wherever you saved the Basic Hack Template) and double click on Compile (Batch file) If all goes well it should say a few lines of stuff but the only thing you need to look for is "Assembling: BasicHack.asm" if it says that, and you don't see anything that says "error" then it compiled fine! You should now see a BasicHack.dll in your folder along with BasicHack.OBJ (don't worry about this one)

Now load up starcraft, and click on the load.exe and it should say the DLL was injected successfully! Now go into the Astral Balance.scm map and press F5 and if all went right you should recieve your minerals/gas while the computer doesn't! If you started on bottom, restart until you start on top, if you started on top, restart until you start on bottom to make sure the hack works for both Player 0 (Player 1) and Player 1 (Player 2)

 

If you wanted you could go through and find all the other players minerals/gas addys and make sure it only will give the minerals/gas to you! The hack will work on other maps, but it will only work as-is if you are Player 0 or Player 1.

 

I hope you have enjoyed this tutorial, and were able to follow it and understand it without too much trouble. But most importantly, I hope you learned something!! If you need help you can PM @ http://www.Ghoztcraft.net I also welcome both positive comments and constructive criticism. I would love to know if my tutorial helped you in any way, so please let me know! All code was found and written by me excluding the skeleton for the Basic Hack Template made by Jiggie.

Loader by SC_Modder

 

I am including the source. But please try to make it own your own, or try to fix your own errors before looking at the source. And if you do use it for your own projects, please give proper credit.

Source; http://upload.Ghoztcraft.net/files/178/Min...ck%20Source.rar (http:// must be included)

Share this post


Link to post

You could use a lot less [ CENTER], it doesn't really help when you're reading indented code.

 

It's useful when you want to emphasize a topic, or special conditions. But any large chunk of text becomes annoying to read, I personally just skip it.

Edited by Gamepin126

Share this post


Link to post

This looks really well written. It will teach me alot about this since i am fairly new to ASM (ironic how i have to use ASM in my OS and i barely know ASM, im learning as i go)

Share this post


Link to post

I appreciate the feedback, I personally thought it would make it easier to read this way, however if it isn't I'll try to format it in another way!

 

I hope you do learn some things tjtrickdog, as that was my goal. :)

Share this post


Link to post

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×