Valhalla Legends Forums Archive | Battle.net Bot Development | In Game Messaging

AuthorMessageTime
LockesRabb
Is there a way to do in-game messaging for Starcraft, like BWCoach does? In the game, it displays messages using SC's text engine- as if someone on bnet had typed a message to you ingame. If you download BWCoach, and try it- you'll see what I mean. You can get it at www.bwchart.com.

I've searched this site's forums, and haven't found anything in reference to this as of yet, so any input would be appreciated.
June 15, 2005, 8:27 PM
QwertyMonster
Yes you can do it.

COnnect to battle.net, send the correct packets to join the game, and then send more correct packets to send a message, and just have it be displayed.

Try looking on Bnetdocs for all the correct packets and information.
June 15, 2005, 8:34 PM
LockesRabb
I'm referring to outside of bnet, in single player.
June 15, 2005, 8:43 PM
QwertyMonster
Oh sorry, you didnt say that.

Sending text to single player, try asking Adron he does that kind of stuff.
June 15, 2005, 8:44 PM
KkBlazekK
Hes not building a bot that connects to the game, hes building a program that displays messages ingame.  I was working on one last night.
June 15, 2005, 8:46 PM
LockesRabb
Ah, and did you get it to work, Blaze? Hopefully Adron will read this thread and reply... :-P
June 15, 2005, 9:21 PM
hismajesty
What's the point?
June 15, 2005, 10:29 PM
Quarantine
You can use DirectDraw and find a pointer to the backbuffer then just blit whatever you need to the screen afaik
June 15, 2005, 10:45 PM
Myndfyr
[quote author=Warrior link=topic=11842.msg115905#msg115905 date=1118875552]
You can use DirectDraw and find a pointer to the backbuffer then just blit whatever you need to the screen afaik
[/quote]

But then Starcraft would draw over it, most likely.

Easiest way would be to disassemble and try to find the offset of the function that displays text.
June 15, 2005, 11:38 PM
KkBlazekK
I did that last night, the only function I saw that looked like it had something to do with drawing was DrawTextA in storm.dll.  Its also in your user32.dll.

[code]
Public Declare Function DrawText Lib "user32.dll" Alias "DrawTextA" (hDC As Long, lpString As String, nCount As Integer, lpRect As RECT, uFormat As Long) As Long

Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
[/code]
June 16, 2005, 12:33 AM
Quarantine
Does it work :p.
June 16, 2005, 12:44 AM
KkBlazekK
No, but thats not the point. :P  I was hoping somebody would correct me on something.
June 16, 2005, 12:54 AM
Myndfyr
[quote author=Blaze link=topic=11842.msg115932#msg115932 date=1118881981]
I did that last night, the only function I saw that looked like it had something to do with drawing was DrawTextA in storm.dll.  Its also in your user32.dll.

[code]
Public Declare Function DrawText Lib "user32.dll" Alias "DrawTextA" (hDC As Long, lpString As String, nCount As Integer, lpRect As RECT, uFormat As Long) As Long

Public Type RECT
     Left As Long
     Top As Long
     Right As Long
     Bottom As Long
End Type
[/code]
[/quote]

DrawTextA is an imported function.  Storm's own exported functions will not be named with a name that would say what they do.
June 16, 2005, 1:01 AM
LockesRabb
BWCoach's text display works pretty well by interfacing with SC- so I think the program author solved that issue already. Maybe if someone downloaded BWCoach, and had it run- that someone'd be able to break (bp) the second BWCoach told SC to display something. Personally, I have no experience in reverse engineering, so I'd not be able to look into this potential venue... But perhaps someone else with the experience can?
June 16, 2005, 1:05 AM
Quarantine
It might be easier to reverse BWCoach as opposed to Starcraft.exe
June 16, 2005, 1:40 AM
LockesRabb
I agree-- that's why I suggested it. Is anyone up to it?
June 16, 2005, 1:56 AM
KkBlazekK
I thought of that too.  StarBoxViewer a program that displays ingame stats uses the api:

[code]
Public Declare Function TextOut Lib "gdi32.dll" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
[/code]


Heres the program I made to display ingame text and its source.

http://blazenet.servebeer.com/site/Downloads/StarcraftText.zip
June 16, 2005, 2:14 AM
Quarantine
Ugh that flicker is horrible :p
June 16, 2005, 2:28 AM
KkBlazekK
Well, thats the re-drawing of my vb app and starcraft.
June 16, 2005, 2:29 AM
LockesRabb
Mmm. BWCoach doesn't use that- they use SC's text display directly, and SC even dings when it displays the text. So I don't think they're using that API... I think they most likely figured out the internal function SC uses to display the text, so it'd be a matter of reverse-engineering BWCoach to find out what internal function BWCoach calls upon in order to pull it off.

I'm thinking maybe set up a program to monitor when BWCoach accesses any file inside the SC directory, and if the program catches BWCoach accessing those files (for API, or whatever), trap what location it's accessing from, and also trap the incoming/outgoing data transfer between BWCoach and the file. This would enable one to determine what internal function of SC BWCoach uses, and how to use it also.
June 16, 2005, 2:38 AM
Kp
Not intending to offend, but that's a rather silly (and probably ineffective) way of approaching this.  There is a function in Starcraft which posts new text to the internal ring buffer; the ring buffer is rendered by Starcraft's draw loop as visible text.  BWCoach merely needs to call the appending function with appropriate arguments, and Starcraft will do the rest.  IIRC, the function takes a timeout, a color, and a char*.  That should be enough to get you started. :)
June 16, 2005, 3:00 AM
Quarantine
Heh theres hope yet! :o
June 16, 2005, 3:23 AM
KkBlazekK
Thank Kp, that should help a lot. :)  Yeah, my method is ineffective.
June 16, 2005, 3:42 AM
NicoQwertyu
I suck too much to debug Starcraft. Everytime a bp triggers, I get stuck in SC and can't even view the disassembly.  :(
June 16, 2005, 5:21 AM
UserLoser.
[quote author=NicoQwertyu link=topic=11842.msg115988#msg115988 date=1118899301]
I suck too much to debug Starcraft. Everytime a bp triggers, I get stuck in SC and can't even view the disassembly.  :(
[/quote]

Couldn't you run Starcraft in a window, or run multiple desktops at once?
June 16, 2005, 2:33 PM
NicoQwertyu
[quote author=UserLoser link=topic=11842.msg116007#msg116007 date=1118932386]
[quote author=NicoQwertyu link=topic=11842.msg115988#msg115988 date=1118899301]
I suck too much to debug Starcraft. Everytime a bp triggers, I get stuck in SC and can't even view the disassembly.  :(
[/quote]

... or run multiple desktops at once?
[/quote]

Never thought of that.  :-\
June 16, 2005, 5:54 PM
KkBlazekK
http://www.valhallalegends.com/skywing/files/DxWnd/DxWnd.zip
June 16, 2005, 6:11 PM
NicoQwertyu
What can I use to run multiple desktops? I went and got VMware, but that doesn't seem like it's what I want.
June 16, 2005, 6:48 PM
LockesRabb
[quote author=Blaze link=topic=11842.msg116061#msg116061 date=1118945511]
http://www.valhallalegends.com/skywing/files/DxWnd/DxWnd.zip
[/quote]

can you give a screen shot of sc in a window? i'm curious as to what it looks like. im not home right now, still at work, but I plan on trying that- it'd be very benefitical if i could get sc to run in a window- it'd allow me to multitask much easier...
June 16, 2005, 8:41 PM
R.a.B.B.i.T
It's big, so clicky.
June 16, 2005, 9:33 PM
Kp
[quote author=Kyro link=topic=11842.msg116092#msg116092 date=1118954512]can you give a screen shot of sc in a window? i'm curious as to what it looks like. im not home right now, still at work, but I plan on trying that- it'd be very benefitical if i could get sc to run in a window- it'd allow me to multitask much easier...[/quote]

It looks pretty much like you'd expect: (mostly) correct, but smaller.  battle.snp's GUI code is an absolute mess, and doesn't interact with ScWnd well at all.  In game looks ok, but the window-izing hacks make it run slower, and of course everything is scaled down.  IMO, it's not generally useful if you want to play, but it can be handy if you want to debug, or hang out in a game and lag it up while watching IM clients (I've had people do this to me; it's quite irritating).
June 17, 2005, 3:06 AM
LockesRabb
I've been scanning Storm.dll via IDA for the function you mentioned... Could it be this one:

[code].text:15001960 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:15001960
.text:15001960
.text:15001960 sub_15001960    proc near              ; CODE XREF: sub_150013F0+225p
.text:15001960                                        ; sub_150013F0+287p
.text:15001960
.text:15001960 arg_0          = dword ptr  4
.text:15001960 arg_4          = dword ptr  8
.text:15001960 arg_8          = dword ptr  0Ch
.text:15001960
.text:15001960                test    ecx, 80000000h
.text:15001966                jz      short locret_1500197C
.text:15001968                mov    eax, [esp+arg_8]
.text:1500196C                mov    ecx, [esp+arg_4]
.text:15001970                push    eax
.text:15001971                mov    eax, [esp+4+arg_0]
.text:15001975                push    ecx
.text:15001976                push    eax
.text:15001977                call    edx
.text:15001979                add    esp, 0Ch
.text:1500197C
.text:1500197C locret_1500197C:                        ; CODE XREF: sub_15001960+6j
.text:1500197C                retn    0Ch
.text:1500197C sub_15001960    endp
.text:1500197C
.text:1500197C ; ---------------------------------------------------------------------------[/code]

I'm hoping that's the one- because it has three arguements, and the third arguement seems to be a char*... I could be wrong tho. If I'm wrong, can I have a hint? LOL...
June 17, 2005, 3:56 AM
KkBlazekK
I'll look at it tomorrow and try it out.  You like IDA Kyro?
June 17, 2005, 4:11 AM
LockesRabb
Yea, IDA's pretty cool- I just wish I could understand assembly, and the code itself...
June 17, 2005, 4:50 AM
NicoQwertyu
Userloser, or anyone, how can I "run multiple desktops at once?"  I'd like to be able to do this without relying on Skywing's program.
June 17, 2005, 5:17 AM
Ringo
[quote author=NicoQwertyu link=topic=11842.msg116179#msg116179 date=1118985478]
Userloser, or anyone, how can I "run multiple desktops at once?"  I'd like to be able to do this without relying on Skywing's program.
[/quote]

hmm, i had somthing like this ages ago, witch would let you install multiple os's on the desctop, but it used to lag like hell when the host and virtual PC where on the net, and i only ever remember installing window 98's on it.
It sounds abit like what your after, but i dunno where you would find a cracked/trail copy :(
June 17, 2005, 5:32 AM
Quarantine
They released some sort of tweak for allowing multiple desktops. That's multiple OS's. Isn't that overcomplicating it :P
June 17, 2005, 5:33 AM
KkBlazekK
My videocard has multiple desktop software, but its crappy.  Go ATI!
June 17, 2005, 5:53 AM
LockesRabb
Okay, I just attempted to use function 607... And guess what happened? It CRASHED Visual Basic... I didn't know using Storm.dll would do that... If testing involves rebooting VB constantly, so be it. ;-p

I also tried function 613... Also resulted in VB crashing.

Anyway, this is my Main.frm code so far:

[code]Private Sub cmdDisplay_Click()
    STextOut 5000, 16777215, Text1.Text
End Sub[/code]

And this is my Storm.bas code:

[code]Option Explicit

'Storm declarations

Public Declare Function STextOut Lib "Storm.dll" Alias "#607" (ByVal Arg1 As Long, ByVal Arg2 As Long, ByRef Arg3 As String) As Long[/code]

Where in the STextOut function (STextOut 5000, 16777215, Text1.Text), 5000 is 5 seconds (5000 milliseconds) of display, 16777215 is the color white (as converted from hex to deca), and Text1.text is the text to display (as obtained from a text box.

Now, this was coded by purely guesswork- I don't even know if I have the right function, or what the timeout argument is (I presumed it was how long to display text?), or what color format should be used, or how the values should be passed to the function. Any input would be appreciated...
June 17, 2005, 6:26 AM
NicoQwertyu
I believe what you want to do is inject a .dll, into Starcraft, which calls the function from within the process.  In which case VB wouldn't be the language of choice.

And as far as multiple desktops go:

1.) I have VMware, but havn't been able to test it yet.

2.) I've tried Virtual Desk which allows "virtual desktops," but is completely useless because I still get stuck in SC when a bp triggers.
June 17, 2005, 7:44 AM
Quarantine
your best bet would be to run in a window. Maybe if you program and compile using the same compiler SC used you might be able to call functions directly after you inject *shrug*
June 17, 2005, 8:04 AM
warz
Tutorial: Starcraft Screen Messages
Author: Drakken
Date: 4/24/03
Site: http://www.gamethreat.com/
Game: Starcraft/Broodwar version 1.10
_____________________________________

Intro:
In this tutorial I'm going to show you a way to send client side messages to the screen in starcraft. This is not the same method that the current Ally Alert uses. I did use this method in Ally Alert before version 3.0. You'll only need to use three windows API (ReadProcessMemory, WriteProcessMemory, GetTickCount) to do this so even if you're programming in visual basic this shouldn't be too hard for you. This will not work with TMK. I'll go through the whole process of developing this method so that hopefully you will follow along and learn some new techniques that you can use in the future. Try to resist skimming through this tutorial.
_____________________________________

What you will need:
Softice - I highly reccomend you get softice. It is the BEST and most valuable tool EVER. Trust me. You could try to use the autohack in TSearch instead, but that's about as silly as trying to hack starcraft on a mac.

Memory Searcher/Editor - I use Winhack. It's decent and easy to use but it is shareware and requires registration to use all the features. You can use another program if you like. As long as it can do ascii memory searches and view hex/ascii memory it will be fine. TSearch and Artmoney are good programs.

W32Dasm - This is a disassembler. You can also use IDA which is more advanced but I prefer w32 because I'm used to it.

You should be able to find these tools pretty easily on the net. Search on google.com or check Gamehacking.com or protools.cjb.net.

Some knowledge of assembly will really be helpful but not totally necessary. Hopefully you'll learn a little bit while reading this.

_____________________________________

Let's begin:
Start up starcraft and load a game. Do not start a single player campaign game because you can't type and send text to the screen. Either get on battle.net or load up a lan game.

First we want to find where starcraft stores the text that is displayed on screen. If you type a bunch of messages quickly you can see that there are eleven lines of text that can fit on the screen at one time. So we can assume that starcraft has eleven offsets for these. Now let's find them.

Open the text box and type "Drakken is my hero" and press enter. hehe . Now open Winhack or your favorite memory editor and select the starcraft process. Now we want to do an ascii search. In Winhack select the edit memory tab and make sure "Ascii String" is selected next to the search box. Do an ascii search for "Drakken". For me it lands at the offset 651535. If you got a different offset don't worry about that, remember there's eleven offsets for the screen text. Now scroll up through the memory and you can see the whole string that was displayed on screen. "yourname: Drakken is my hero". It begins at offset 65152C. Notice that the first byte of yourname is 00. This is how starcraft removes the messages from the screen. It nulls (null=00) the first byte of the message to remove it from the screen.

Now go through and find all eleven offsets for the screen text. Write a different message for every search so you don't find the same offset again. And make sure to use a word that is unique that you won't find somewhere else in starcraft's memory space. For instance, use a message like "GameThreat.com ownz" then search for "GameThreat". Write down the offsets for the beginning of each of the text spots.

When finished you should have found these eleven offsets:
650CA8
650D82
650E5C
650F36
651010
6510EA
6511C4
65129E
651378
651452
65152C

Now we've got all eleven offsets. (there's actually a couple more but don't worry about those.) You're probably thinking we're done now. Try writing a string to one of those offsets. Then maximize starcraft to see your message on screen. What?!? It's not there? Look at the string you just wrote. Starcraft has nulled the first byte of it immediately after you wrote it to memory. Why? Starcraft creates a timer value for each message so that it knows when to remove it from the screen. So the next thing we want to do is find where starcraft writes the null byte to the message to remove it.

Why don't we just search for the timer value?
Because we have no idea what that value might be and since the messages only stay on screen for a few seconds we would have little time to find it.

Why do we want to find where it writes the null byte?
Because shortly before it writes the null byte starcraft will check the timer to see if it's time to write the null byte. We can find a reference to the timer there.

We will have to set a breakpoint in softice on one of the offsets to find where starcraft writes the null byte. Let's use the first offset on that list. 650CA8. It is already null but starcraft is constantly checking those offsets to see if anything is there. Maximize starcraft and press ctrl-D to bring up softice. Look to the bottom right corner of softice to make sure you are in the starcraft process. If not press ctrl-D a couple times until you are. Then type:

BPM 650CA8

Press enter to set the breakpoint. Then press ctrl-D to exit softice. Softice will immediately pop again at this offset: 46B825. Press ctrl-D a few more times to see if starcraft accesses that offset anywhere else. It doesn't. Now type "bc *" in softice to clear your breakpoints then press ctrl-D one last time to exit softice.

Now let's look at the disassembly so we can see what's going on at 46B825. Open W32Dasm, select Disassembler, Open file to Disassemble. Then find starcraft.exe. It will take a few minutes to disassemble. Now is a good time for a break. Go grab a snack, get a drink, take a leak, or have a smoke.

When it's done you can click disassembler and save the disassembly to a project file so that you don't have to disassemble starcraft.exe every time you open w32dasm. This is optional but it saves time.

Now click Goto, then Goto Code Location. In the code offset box enter the offset we want to look at. 46B825. I've written down some of the important code and made some comments to show you what it's doing.


ASM Code:
:0046B812 Call dword ptr [004E61A0]
:0046B818 mov edi, eax
:0046B81A xor esi, esi

:0046B81C lea eax, dword ptr [esi+2*esi]
:0046B81F lea eax, dword ptr [eax+8*eax]
:0046B822 lea eax, dword ptr [esi+4*eax]
:0046B825 mov cl, byte ptr [2*eax+00650CA8]
:0046B82C test cl, cl
:0046B82E je 0046B8D9
:0046B834 mov edx, dword ptr [4*esi+006517BC]
:0046B83B mov ecx, edi
:0046B83D sub ecx, edx
:0046B83F js 0046B8D9
:0046B845 cmp esi, 0000000C
:0046B848 mov byte ptr [2*eax+00650CA8], 00
:0046B850 jne 0046B86C


Comments:
:0046B812 calls GetTickCount (result ends up in eax)
:0046B818 moves the tick count from eax to edi for use below
:0046B81A clears esi

:0046B81C sets up eax for the pointer to the message offset
:0046B81F " "
:0046B822 " "
:0046B825 moves the first byte of the message offset into cl
:0046B82C tests cl against itself
:0046B82E if cl is null (00) it jumps to 46B8D9
:0046B834 moves the message timer value into edx
:0046B83B moves the current tick count from edi into ecx
:0046B83D subtracts the message timer from the current tick count
:0046B83F depending on the result it will jump to 46B8D9
:0046B845 compares esi to 0C
:0046B848 writes the null byte to the message offset
:0046B850 jumps to 46B86C if esi isn't 0C


You may still be confused by all that. I'll try to sum it up. First it calls GetTickCount and stores that value. Then it sets up the pointer to the message offset. Next it reads the first byte of the message offset and checks if it's null. If it's already null it jumps over the following code since there is no message there. If it isn't zero it then continues and reads the timer value for that message. Then it subtracts the timer from the tick count that was called above. This is where it determines if it is time to remove the message from the screen. If it isn't time it jumps over the following code. If it is time to remove the message it continues and writes the null byte to the message offset.

Now we know that it's using GetTickCount to check the message timer. So we also know that it must be using GetTickCount to set the timer. So if you look at code at 46B834 we can determine what the offsets are for the timers. [4*esi+006517BC]. Four times the value in esi plus 6517BC is the offset for the current message offset. With this info we can determine this:

Message - Timer
650CA8 - 6517BC
650D82 - 6517C0
650E5C - 6517C4
650F36 - 6517C8
651010 - 6517CC
6510EA - 6517D0
6511C4 - 6517D4
65129E - 6517D8
651378 - 6517DC
651452 - 6517E0
65152C - 6517E4

Now that you know the timers for each message offset you can write a timer value there and a message to the appropriate message offset. For fun let's test this out. Write the following to memory then switch to starcraft.

6517BC 0F 0F 0F 0F
650CA8 44 72 61 6B 6B 65 6E 20 72 75 6C 65 73 21 00

Neat eh? But there are two problems. That message will stay on screen for a really really long time or until it is scrolled off screen. Also it probably isn't at the bottom message position on screen.

To solve the timer problem, in your program make a call to GetTickCount. To determine how long you want it to display add to the result. I found that adding 2000 to the tick count seemed to make the messages stay on screen about as long as they normally do. Then write that to the timer offset then write your message to the appropriate message offset.

Now let's figure out how to tell which message offset is the bottom one. Look back at the disassembly in w32dasm. Hopefully the asm is starting to look a little more friendly to you now. You can see an offset reference to the message offset at 46B825. You can also see a reference to the timer offset at 46B834. And again you can see another reference to the message offset at 46B848.

:0046B825 mov cl, byte ptr [2*eax+00650CA8]
:0046B834 mov edx, dword ptr [4*esi+006517BC]
:0046B848 mov byte ptr [2*eax+00650CA8], 00

Now look down just below these offsets and you'll see another offset sticking out in the asm:

:0046B852 mov edx, dword ptr [006517F4]

Hrm what could this be? Let's take a look. First notice that it's pointing to a dword value. Now take a look at 6517F4 in your memory editor. Now go back to starcraft and type in a message and hit enter. Then take a look back at 6517F4 to see if it's changed at all. 6517F4 hasn't changed but 6517F0 has. Remember that it was pointing to a dword value so 6517F0 is still part of it. Send some more messages in starcraft and take notice of how 6517F0 changes. Now document how this offset refers to which message offset is being used. So with the following info you can determine which text spot to write to to make the message appear at the bottom of the screen.

Text spot pointer
6517F0

Spot Message Timer
01 - 650CA8 - 6517BC
02 - 650D82 - 6517C0
03 - 650E5C - 6517C4
04 - 650F36 - 6517C8
05 - 651010 - 6517CC
06 - 6510EA - 6517D0
07 - 6511C4 - 6517D4
08 - 65129E - 6517D8
09 - 651378 - 6517DC
0A - 651452 - 6517E0
00 - 65152C - 6517E4

Now we have all the info we need.

_____________________________________

Summary:
Now to put all this info to good use in your program. First you want to use ReadProcessMemory to read one byte at 6517F0 to determine which message offset you want to write to. Once you've determined that then you want to use GetTickCount to get the current tick count on your system. Then add the amount of time you want your message to stay on screen. I suggest trying 2000 or 2100. Next write that value to the timer offset. And finally write your message to the message offset. Starcraft will automatically remove your message from the screen when your timer expires.

Update:
Use these hex bytes in your messages to add colors.
0x02 default White/dull blue
0x03 Yellow
0x04 Bright White
0x05 Grey
0x06 Red
0x07 Green

_____________________________________

Conclusion:
Remember that these are client side messages only. No one else will see them but you. You will notice that these messages don't always appear on screen right away. This is because they don't actually get drawn until starcraft updates the screen. It's an unfortunate side effect of writing messages this way but at least it works.

I'm sure some of you are going to want to go and make an ally detector program right away. While that will be a good learning experience, I suggest that you try to make something new. How about a unit detector? A program that alerts you when someone has Dark Templars or Lurkers would be very useful and hasn't been done yet... as far as I know. There are offsets in starcraft that store units counts of each unit type for each player. All you have to do is find them.

I hope you learned something new from this tutorial. If not, at least you know how to write messages on screen now. I hope you appreciate the time I've taken to develope this method and write up this tutorial. All I ask is that if you use this method in your program just give me a little thanks somewhere in your credits. 

Feel free to post this tutorial on your own site as long as it remains unmodified.
_____________________________________

Drakken
©GameThreat.com 2003
June 17, 2005, 12:41 PM
LockesRabb
Thanks for the tutorial! I was able to find the strings I typed in Starcraft, and now I'm trying to write to the offsets I found the strings at. But I keep getting a type mismatch error... Here's my code so far:

Main.frm code:

[code]Private Sub cmdDisplay_Click()
   
    Dim lPid As Long
    lPid = FindProcessId("Starcraft.exe")
   
    If lPid > -1 Then
        wHandle = lPid
        Address = &H650CA8 'Memory Segment to write to...
        display$ = "This is a test..." 'String to display
        WriteProcessMemory wHandle, Address, StrPtr(display$), LenB(display$), 0&
        Text1.Text = "String displayed."
    Else
        MsgBox "Please activate Starcraft.", vbInformation, "Error"
        DoEvents
    End If

End Sub[/code]

And this is the functions.bas module code:

[code]Option Explicit

'Process Function Management Declarations
'---------------------------------------------------
'Used to read and write to memory. Memory Writing must be enabled
'For this to work.

Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function EnumProcesses Lib "PSAPI.DLL" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function GetModuleFileNameExA Lib "PSAPI.DLL" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Private Declare Function EnumProcessModules Lib "PSAPI.DLL" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long

Public Function FindProcessId(ByVal sExeName As String, Optional lStartFromPID = -1) As Long
   
    'FindProcessId function code obtained from VBUSERS.COM
   
    Const clInitNumProcesses As Long = 500
    Const MAX_PATH = 260, PROCESS_QUERY_INFORMATION = 1024, PROCESS_VM_READ = 16
    Dim sModuleName As String * MAX_PATH, sProcessNamePath As String, sProcessName As String
    Dim alMatchingProcessIDs() As Long
    Dim alModules(1 To 400) As Long
    Dim lBytesReturned As Long, lNumMatching As Long, lArraySize As Long
    Dim lNumProcesses As Long, lBytesNeeded As Long, alProcIDs() As Long
    Dim lHwndProcess As Long, lThisProcess As Long, lRet As Long
    Dim bPastLastMatch As Boolean
   
    On Error GoTo ErrFailed
    FindProcessId = -1
    sExeName = UCase$(Trim$(sExeName))
   
    'Get the list of processes
    Do
        If lArraySize = 0 Then
            lArraySize = clInitNumProcesses
        Else
            lArraySize = lArraySize + clInitNumProcesses
        End If
        'Size array to hold process IDs
        ReDim alProcIDs(lArraySize * 4) As Long
        'Populate an array containing all process ID's
        lRet = EnumProcesses(alProcIDs(1), lArraySize * 4, lBytesReturned)
        'Count number of processes returned
        lNumProcesses = lBytesReturned / 4
        'Resize the array containing all the processes
        ReDim Preserve alProcIDs(lNumProcesses)
        'Resize the array to contain all the matching processes
        ReDim alMatchingProcessIDs(1 To lNumProcesses)
    Loop While lArraySize <= lBytesReturned

    For lThisProcess = 1 To lNumProcesses
        'Open the process
        lHwndProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, alProcIDs(lThisProcess))
       
        If lHwndProcess <> 0 Then
            'Get an array of the module handles for the specified process
            lRet = EnumProcessModules(lHwndProcess, alModules(1), 200&, lBytesNeeded)
           
            If lRet <> 0 Then
                'Get Process Path and Name
                lRet = GetModuleFileNameExA(lHwndProcess, alModules(1), sModuleName, MAX_PATH)
                sProcessNamePath = Trim$(UCase$(Left$(sModuleName, lRet)))
                'Get the Process Name
                sProcessName = Mid$(sProcessNamePath, InStrRev(sProcessNamePath, "\") + 1)
               
                If sProcessName = sExeName Then
                    'Found a matching process ID
                    If lStartFromPID = -1 Then
                        'Return the first matching Id
                        FindProcessId = alProcIDs(lThisProcess)
                    Else
                        If bPastLastMatch Then
                            'Return the next matching process Id
                            FindProcessId = alProcIDs(lThisProcess)
                        End If
                        If alProcIDs(lThisProcess) = lStartFromPID Then
                            'Start the search for the previous matching PID
                            bPastLastMatch = True
                        End If
                    End If
                End If
            End If
        End If
        'Close the handle to this process
        lRet = CloseHandle(lHwndProcess)
        If FindProcessId > -1 Then
            Exit For
        End If
    Next

    Exit Function

ErrFailed:
    Debug.Print "Error in FindProcessId: " & Err.Description
    FindProcessId = -1
End Function[/code]

When I execute the program, I get a type mismatch error with the Address variable... Any idea what I'm doing wrong?
June 17, 2005, 10:36 PM
Quarantine
warz, you're my hero
June 17, 2005, 10:50 PM
R.a.B.B.i.T
Kyro, you never declare it.  Variant isn't an acceptable "Any" type (stupid VB).  I put the address value right in and it didn't give an error...but it didn't work either.
June 18, 2005, 12:20 AM
KkBlazekK
I tried the code and I from lastdll error I get error 6.  I can't seem to find what that is in google so :-\.
June 18, 2005, 12:24 AM
Kp
[quote author=Kyro link=topic=11842.msg116165#msg116165 date=1118980575]I've been scanning Storm.dll via IDA for the function you mentioned... Could it be this one:[/quote]

It could.
June 18, 2005, 4:07 AM
tA-Kane
By the way, in case you still haven't resolved the issue of how to get "multiple desktops", there's two ways that I know of. There may be (and most likely are) other ways.

1) Either get a second graphics card (a PCI one will work fine since you shouldn't be doing much gaming on it) or swap your current graphics card with a new card that has dual output. Then, aquire a second screen and hook it up.

2) Get desktop drivers that support desktop "switching" (kinda like how Linux does desktops). nVidia's nView apparently is able to do this, but I'm not sure how to get it set up.

Of course, if you aren't able to do either of those, it is also possible to work on two computers (side-by-side will save a lot of time, I might add) and use a remote debugger.
June 18, 2005, 8:24 AM
LockesRabb
[quote]Now we know that it's using GetTickCount to check the message timer. So we also know that it must be using GetTickCount to set the timer. So if you look at code at 46B834 we can determine what the offsets are for the timers. [4*esi+006517BC]. Four times the value in esi plus 6517BC is the offset for the current message offset. With this info we can determine this:

Message - Timer
650CA8 - 6517BC
650D82 - 6517C0
650E5C - 6517C4
650F36 - 6517C8
651010 - 6517CC
6510EA - 6517D0
6511C4 - 6517D4
65129E - 6517D8
651378 - 6517DC
651452 - 6517E0
65152C - 6517E4 [/quote]

I got stuck at that part... [4*esi+006517BC]?!? How do I find out the value in esi, and where do I find esi? I got this far before getting stuck... and how do you multiply 65152C with whatever is in esi, and add it with 006517BC, to come up with 6517E4? Input, as always, would be appreciated!
June 18, 2005, 9:01 AM
Kp
[quote author=Kyro link=topic=11842.msg116353#msg116353 date=1119085314]where do I find esi?[/quote]

It's in your CPU. ;)  esi is the Extended Source Index (oppose edi - Extended Destination Index)
June 18, 2005, 3:38 PM
LockesRabb
Right, I know that much. I just don't know where to locate the value in esi. Is the value of esi the same for the entire program, meaning I can just press ctrl d and look at the value of esi for the starcraft process, or does esi differ as per each offset section it's at?

Do I use SoftIce to determine what the value in esi is? Or do I use some other software? I have IDA, WinHack, SoftIce, and Win32DASM. I finally figured out that in:

[4*esi+006517BC]

The 006517BC in above is the timer in the following in the tutorial:

Message - Timer
650CA8 - 6517BC
658D1C - 659160
The timer offset is different from mine when I step into the code though. Instead of [4*esi+006517BC], I have:

[4*esi+00659160]

The timer offset is obviously not in the list that Drakken has- I presume it's because of a starcraft update patch change. In any case, it's obvious 659160 is the timer offset. So I'd think it means I'd have to:

1. Find out the value of esi (how do I do this?!?)
2. Multiply 4 with esi (how do I do that using MS calculator?)
3. Add result with 00659160


End result is the location of the message offset...

I know I already have the message offset and timer offset, but I'd like to know the above, so I can apply the math for the other offsets.

Also, in this:

          6517BC 0F 0F 0F 0F

What is 0F 0F 0F 0F?

I wrote 0F 0F 0F 0F at the offset of 659160 using WinHack (since I don't know how to write 0F 0F 0F 0F to that offset using vb...) and TESTSTRING to the offset of 658D1C using VB. This caused SC to crash and SoftIce to emit blood-curling screams of horrors, terrors and errors galore... So what am I doing wrong?
June 18, 2005, 7:46 PM
KkBlazekK
Would all those offsets be in the same place 3 patches later?
June 18, 2005, 8:46 PM
UserLoser.
[quote author=Blaze link=topic=11842.msg116404#msg116404 date=1119127605]
Would all those offsets be in the same place 3 patches later?
[/quote]

Most likely, no.
June 18, 2005, 8:51 PM
LockesRabb
No. Patches are modification of code, which means, code gets shifted around. So chances are, the offsets most likely would be different. So every time a patch came out, you'd have to update your program to reflect the changes.
June 18, 2005, 9:50 PM
NicoQwertyu
Or devise a clever way to have your program get the offsets itself!

[list]
1.) A command line option that the user can specify to have your program send "thisisamessage" 10-15 times while the SC screen is active, and then have it scan for those values to find the different offsets.

2.) Or include an extra program that does this.

3.) Or perhaps have your program, upon execution, download offsets.txt from a certain website which you can personally alter every time a patch comes out.
[/list]
June 18, 2005, 11:14 PM
tA-Kane
[quote author=Kyro link=topic=11842.msg116398#msg116398 date=1119123977]1. Find out the value of esi (how do I do this?!?)
2. Multiply 4 with esi (how do I do that using MS calculator?)
3. Add result with 00659160[/quote]1. Find out the value of esi (using a debugger)
2. Multiply 4 with esi (manually)
3. Add result with 00659160

Note that some debuggers may present the result of the math (including ESI's contents) for you.

[quote author=Kyro link=topic=11842.msg116398#msg116398 date=1119123977]I wrote 0F 0F 0F 0F at the offset of 659160 using WinHack (since I don't know how to write 0F 0F 0F 0F to that offset using vb...) and TESTSTRING to the offset of 658D1C using VB. This caused SC to crash and SoftIce to emit blood-curling screams of horrors, terrors and errors galore... So what am I doing wrong?
[/quote]I am not familiar with the tutorial that you are working with (laziness) nor with StarCraft's inner-workings, but is it possible that the "timer offset" either refers to code or a pointer instead of a text message? If such is the case, then it is especially likely that overwriting the memory with 0x0F0F0F0F will result in a crash.


Edit:
I might add that you should try only one of the two things (in regards to writing 0x0F0F0F0F and TESTSTRING) and see if it's one or the other or both things that's causing StarCraft to crash.
June 19, 2005, 4:58 AM
EpicOfTimeWasted
Wouldn't it just be easier to type a message like "findme", NOT send the message, use SoftICE to search the memory for "findme", bpm the results, and then send the message?  There should only be about two results, and only one of them should be in Starcraft's address space.  SoftICE will break every time the memory is accessed, and with a little back tracing, you'll find SC's text message handling function, as well as the parameters.  Just seems cleaner than trying to throw a message into one of the buffers and hoping you did everything right.
June 19, 2005, 6:33 AM
LockesRabb
EpicOfTimeWasted-

Probably would be easier-- providing I understood ASM, which I don't. Let's say I find the function. I'd be seeing it in ASM, but I'd not know what the parameters were, and how the function wanted the parameters to be phrased.

In any case, I got Starcraft to display messages, so I figured out the first half of the tutorial, now I'm on the timer part.

Here's my problem:

[code]
    Dim LOD As String
   
    'Get Tick Count and add 8 seconds to it.
    LOD = CStr(GetTickCount() + 8000)
   
    'Write to the timer offset to set timer
    WriteProcessMemory pHandle, &H659180, LOD, Len(LOD), Len(LOD)
[/code]

That should make sure the message stays on screen for only 8 seconds. I used WinHack to check the timer memory offset, and it shows what I wrote to it. However, it doesn't stay on the screen for eight seconds: it stays on screen permanently. If I do 0f 0f 0f 0f (whatever that means), the message obviously stays on screen permanently... If I try to do the timer mod, it still stays on screen... Any idea what I'm doing wrong?
June 19, 2005, 12:55 PM
Adron
Dim LOD As Long
   
    'Get Tick Count and add 8 seconds to it.
    LOD = GetTickCount() + 8000
June 19, 2005, 4:23 PM
R.a.B.B.i.T
SoftICE is being evil for me!  Particularly: it will not break.  ever.  It refuses to break even when I set breakpoints at the memory addresses I found for the text.  Any ideas?
June 20, 2005, 4:30 AM
tA-Kane
Try a different debugger?
June 20, 2005, 4:34 AM
LockesRabb
[quote author=rabbit link=topic=11842.msg116594#msg116594 date=1119241850]
SoftICE is being evil for me!  Particularly: it will not break.  ever.  It refuses to break even when I set breakpoints at the memory addresses I found for the text.  Any ideas?
[/quote]

That means you put BPM at the wrong offset. What offset are you trying to put BPM at, and how did you get that offset?
June 20, 2005, 4:52 AM
R.a.B.B.i.T
659EDD, (among others, my list is on my other computer), which I found by searching the memory (as the tutorial said).

I also tried the old offsets (listed in the tutorial), but they didn't work either.
June 20, 2005, 5:09 PM
Okee
Hey guys, where did everyone download SoftICE for WinXP and IDA? I've been searching, and they're all broken links, etc.

Thanks.
June 20, 2005, 5:29 PM
NicoQwertyu
Rabbit, do you use SP2 on the machine that uses SoftICE?
June 20, 2005, 6:47 PM
R.a.B.B.i.T
Yes, but I also installed the patch that Blaze(?) posted.
June 20, 2005, 8:57 PM
LockesRabb
[quote author=rabbit link=topic=11842.msg116634#msg116634 date=1119287363]
659EDD, (among others, my list is on my other computer), which I found by searching the memory (as the tutorial said).

I also tried the old offsets (listed in the tutorial), but they didn't work either.
[/quote]

Those offsets in the tutorial are worthless. They are completely inaccurate- they might have been accurate before, but they aren't now because of the patches Blizzard released since that.

In any case, let me tell you what to do... My apologies in advance if I'm explaining this in layman's terms- I'm trying to keep it easy for anyone else who needs it to be... :-P Also, keep in mind I haven't solved the timer offset problem- so I'm just going to give you what I got. So yeah, I'm writing my own tutorial for ya guys. Heh. You'll need SoftIce, IDA, WinHack, and a calculator capable of doing HEX mathematics. You'll also need a paper and a pen. Or whatever writing implement you use... To get the software I mentioned, just google it. It's how I got my copies. Be wary though, most sites are disreputable.

Once you have obtained **AND INSTALLED** all of the software you'll need, go ahead with the tutorial. SoftIce also must be already running in the background.

Boot up starcraft, start a game on battle.net. When you're actively in the game- not just the game lobby, but IN the game-- press enter, type "TESTSTRING" and press enter again.

Now, open WinHack, select the starcraft process, then click the Edit Memory tab.

Now, in the text box to the right of the Search Now button, type: TESTSTRING, then click search now.

Now, what the tutorial failed to clairfy on is, in the memory offset it takes you to-- it is **NOT** the start of that specific memory offset. Remember, in the game, when you pressed enter after typing the string, it said:

YourName: TESTSTRING

YourName being your battle.net name that you were using when you sent that string. The 'YourName: ' is also part of that string-- so we don't want the start of TESTSTRING-- we want the start of YourName. In WinHack, using the ^ button, scroll up one line. You'll see:

ourName: TESTSTRING

in my case, my battle.net name is Kyro[sK], and it showed:

yro[sK]: TESTSTRING

In any case, the first letter of the string will be missing. The reason why it's missing is because if the first letter is NULL (empty), Starcraft knows not to print the string. Now, we want the offset that the string first starts at. Look at the left side of WinHack-- you'll notice alot of zeros (00 00 00 00).  Keep that in mind. Now, in the right side of the window, you'll see your string. Click on that place (in your bnet name) where the first letter is missing (Like for example, in mine, the place where there should have been a K, in Kyro, but yet K is missing).

That's the message offset. Now, look at the left side of the window- you'll notice a 00 that got selected too. Look at the far left side- the list of offsets. In my case, it was:

658D10

Okay, you've got the first part of the offset- you need a more specific offset. Now, look at the top row of buttons- the ones saying 0123456789ABCDEF... Look at the button that's in the same row as the offset that was selected. In my case, it was the C button.

Now, you replace the last character on the right of 658D10 with that letter/number.

658D10 turns into 658D1C.

That's the message offset. Now, we need to find out where the timer offset is...

Press Ctrl D to get into SoftIce. Look in the bottom right corner of SoftIce. That's the process it is looking at. Is it Starcraft? If not, close SoftIce by pressing Ctrl D again. Open it again, it'll be displaying a different process. If it's not Starcraft, close and re-open. Repeat until it is showing the Starcraft process.

Score! Now we got it showing the Starcraft process! Now, type:

BPM #######

#### being the message offset. For example, in mine, it was:

BPM 658D1C

Now the breakpoint is set. Press ctrl d to close SoftIce. SoftIce should immediately pop back up. See the line that it outlined in grey? That's where it broke at. Now, look to the left of that green line. The offset will be selected. Write it down. In mine, it was 46E63C. To the right, see the ASM line saying: TEST CL, CL? Keep that in mind. Look at the top right part of SoftIce. You'll see a part that says ESI =. Write the value of ESI. In mine, it was 00000008. Or to sum it up, 8.

Now, in SoftIce, type BC *. That clears all breakpoints. Press Ctrl D to exit SoftIce.

Now, open IDA. Disassemble the Starcraft Process. For those who don't know how, click the New button in the Welcome to IDA! window. Browse to where your Starcraft.exe is (usually in c:\program files\starcraft\). Select the Starcraft.exe file. Click open. It'll take a moment for the next window to pop up. When it does, just click OK. It'll take a moment while it disassembles the file. When it's done, in the top left menu, click Jump, then click Jump to Address. Type in that offset you found from SoftIce. Aha! See Test CL, CL on that line it selects (jumps to)? That confirms we're on the right line/offset. Now, this is the tricky part: it's **NOT** the timer offset.

!!!WARNING!!!! Up to this point, I'm completely sure the information above is correct, but past this point, I'm not sure if the information I have is correct- feel free to keep following what I explain-- but keep in mind, it may not be correct, as I am still having problems with using the Timer function. Maybe Kp will finally enlighten me on how to use the Timer function, but seeing how he's keeping his lips tightly sealed, we'll have to figure it out for ourselves... PM Kp-- maybe you'll have better luck than I did-- at least he did give some advice regarding why I shouldn't be doing this in VB.

Now, back to the tutorial. In IDA, you should be on the TEST CL, CL line. Or to be specific, the 46E63C offset (that's the offset I found in SoftIce to the left of Test CL, CL when SoftIce broke).  Look two lines below that. You should see:

.text:0046E644                 mov     edx, dword_659160[esi*4]

Now, open calculator. Microsoft Calculator. If you have a better software to use, fine. But in this, we'll use MSCalc. If you're not a windows user-- well then, use whatever calculator comes with the OS, and hope like heck it comes with advanced functions.

To open MSCalc for windows, just click start (bottom left corner of the screen...), click run, then type Calc, then press enter.

In MSCalc, if you're not already in Scientific Mode, click on View, then click on Scientific.

Now, below the text box and to the left, you'll see a couple of options; Hex, Dec, Oct, Bin. Select Hex. Multiply 4 by whatever the value of ESI you got. Since my value was 8, I got 20 (for those who're going what the-- it should be 32!, it didn't multiply decimal style, it multiplied HEX style, so it's 20).

.text:0046E644                 mov     edx, dword_659160[esi*4]

Remember this line? Look at the between of dword_ and [esi*4]. In that line, it's 659160. In MSCalc, it should still be at the number you got after multiplying ESI with 4. Click add. Then put in that number you got from between dword_ and [esi*4] (in this case, 20 + 659160).

Here's a fact: did you know HTML colors are usually in HEX? Cool.

Back to the tutorial. Now, when I added the results of ESI * 4 to the offset between dword and esi * 4, I got 659180.

(4 * ESI) + 659160 = 659180.

659180, is what I think is the timer offset. I could be wrong, but I suspect it is. Now, switch back to WinHack. See the Go To Address button? In the textbox to the immediate right of it, type the final result you got in MSCalc (in my case, 659180). Click on the Go To Address button. You're now at what I suspect is the timer offset. Click on what is selected, edit it to say:

0F

Repeat for the next three boxes to the right of that one. It should look like: 0F 0F 0F 0F. Now save changes right after you put in the 0F 0F 0F 0F, by clicking on the "Save Changes" button to the right middle of the window of WinHack.

Almost done! Now, write your message to the message offset- for example: Valhalla Legends rules!

If you scroll up, you'll see code that lets you write messages to message offsets. Or if you want to do it manually, just using WinHack, jump to the message offset (in my case, 658D1C). Then in the right side window pane, you should see your TESTSTRING part. Click at that first letter of your string (in my case, the missing letter part of Kyro[sK]: TESTSTRING, in WinHack, says yro[sK]: TESTSTRING)- IT MUST BE THAT EMPTY (NULL) FIRST LETTER PART! In my case, the C column at offset 658D10. Now, using the right side window pane, put in your message. For example, the C column would say V, D column would say a, E would say l, and so on. If you reach the end of the columns (F is the last column), just go down one row, and continue from column #1. When you finish your message, click save changes.

If you used a compiler like VB or C++ (As per due Kp's recommendation, I'll pass this on: use C++, just ignore the fact I chose to stick with VB), just make code that writes the message to the offset. There's code for that if you scroll up.

Now, once you've written the message to the offset, switch back to StarCraft. You should see the message being displayed.

Only one problem: the message won't go away, unless you scroll up by entering several text messages (or you get several text messages) using StarCraft. To make it go away, just change the first letter of your message to a NULL character (in VB, the null character is obtained using CHR$(0). In VB, you could just write a single NULL character to the message offset (in my case, 658D1C). This will result in Starcraft no longer displaying the message.

That's the end of my tutorial! Now I can start packing for the move to my apartment- I won't be online for three days (hopefully less), so if you need any help, others will assist you until then!

Take care!
June 20, 2005, 9:53 PM
LockesRabb
Oh, and if you manage to solve the timer problem, or manage to finish Drakken's tutorial, please let me know how you got the timer function to work! Thanks!!!

Also, there is more than one message offset-- the timer offsets are different for each message offset, so you will want to write down (or record using whatever method you use) each message offset you find, and the corresponding timer offset. Kudos for getting this far!
June 20, 2005, 9:55 PM
hismajesty
In reference to the multiple desktops question, I'm not sure if this is what you want, but get Virtual Desktop Manager here.
June 21, 2005, 12:48 AM
NicoQwertyu
Already said I tried that -- it's useless.  I fixed my problem by switching to SoftICE.
June 21, 2005, 2:44 AM
R.a.B.B.i.T
O shit!  I forgot about the name part!  Well...that explains it :\
June 21, 2005, 3:18 AM
warz
Just update the offsets, and the old tutorial works. Don't take it literally. Read it and get the idea of what he's doing, and re-do it.
June 21, 2005, 3:34 AM
LockesRabb
Actually, warz- the message writing works-- writing to the timer function DOES NOT work... If you want my source code, I'd be happy to send it. A friend of mine who's very good at this kind of stuff tried to assist, and also got stumped. Maybe you'll have better luck. If you want to message me, just AIM me. My screen name is in my profile- be sure to PM me what your screen name is so I can verify it's you. :-)

I'm on dial up by the way- finished moving to the apartment. Won't have DSL up until wednesday. Fun, fun.
June 21, 2005, 9:23 AM
LivedKrad
If anyone ever tried, I disassembled BWCoach. Apparently it uses a DLL that utilizes the SetWindowsHook* API to hook different functions inside of starcraft. I didn't look any further.
July 8, 2005, 1:18 AM
dRAgoN
[quote author=Blaze link=topic=11842.msg115957#msg115957 date=1118888094]
I thought of that too.  StarBoxViewer a program that displays ingame stats uses the api:

[code]
Public Declare Function TextOut Lib "gdi32.dll" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
[/code]


Heres the program I made to display ingame text and its source.

http://blazenet.servebeer.com/site/Downloads/StarcraftText.zip
[/quote]

[code]Private Sub Timer1_Timer()
Dim hWnd As Long
Dim DCHdl As Long
Dim rEctR As RECT

    hWnd = FindWindow(vbNullString, "Brood War")
    DCHdl = GetDC(hWnd)
   
    SetRect rEctR, 5, 5, 256, 20

    'DrawTextA "USER32"
    DrawText DCHdl, "l)ragon was here!", Len("l)ragon was here!"), rEctR, DT_LEFT

    Call ReleaseDC(hWnd, DCHdl)
End Sub[/code]
could do that this way to ;p
July 8, 2005, 4:30 AM
LockesRabb
No way- flickers too much. Thanks for the idea though.
July 8, 2005, 4:38 AM
dRAgoN
Never said that it wasent going to lol.
July 8, 2005, 4:44 AM

Search