Jump to content
Sign in to follow this  

Sending game text to all users

Recommended Posts

Currently, I'm using SendMessage() to send messages - and it works fast, but! It has a down-side:

If you're typing a message, it'll hit "Enter" on you, sending that message, then typing to air, and not sending the desired text, and hitting enter again, making an empty text-box pop up, which is extremely aggravating at times.

 

I'm planning on modifying how I do that in the near future, if I can't find a better (non-packet based) method of doing it.

Here's my idea (which has nothing to do with this thread) of a better way, than SendMessage():

Step 1: Save the current text buffer (if it has anything in it)

Step 2: Replace the text buffer with the desired text, and append it with a null

Step 3: Send the text by hitting enter

Step 4: Re-open the text box by hitting enter

Step 5: Reapply the users text he/she was typing (if any)

 

Down-falls:

- It would be annoying

- The blinking caret wouldn't be at the end of where you were typing (maybe?)

 

But anyways, that's pretty much my current objective at this point!

I've googled around plenty, and am using the Code::Blocks IDE, with a GNU GCC compiler.

I cannot use the inline Intel ASM syntax, I have to use inline GCC ASM, which is annoying to convert.

 

There are a few potential "print Brood War to screen" functions, and only one thread where I saw it saying printing to ALL USERS.

 

const int BWPrintText = 0x48CE60; // Print Text Function 1.15.1

const int BWGameText = 0x4F2EC0; // Send Messages 1.15.1

 

 

BWFXN_PrintText - 48CE60

BWFXN_PrintAnywhere - 4202A0

BWFXN_FontSize - 41FB20

Small - 6CE0DC

Normal - 6CE0E0

Large - 6CE0E4

Huge - 6CE0E8

 

420201 = BWFXN_PrintXY

 

char *abc;

int BWFXN_PubTextOut = 0x4F2EA0;

 

void BWPubTextOut(char *text) {

 

abc = text;

 

asm(".intel_syntax noprefix");

asm("pushad");

asm("lea %eax, _abc");

asm("call dword ptr [_BWFXN_PubTextOut]");

asm("popad");

asm(".att_syntax noprefix");

 

return;

}

 

The last one I converted to AT&T inline ASM, because GCC compiler uses it.

Preferably, I would use WriteProcessMemory over injecting *.dll files, but I'm not sure how that goes against dynamic variable addresses.

 

Thanks in advance for any help...! T_T

Share this post


Link to post
Share on other sites

Hello, I was reading a tutorial on how to print text to anywhere on the screen, and I'm not all that familiar with OllyDbg, although I have tried to use it, in the past, I've always had extreme frustration when trying to understand the simple little concepts, so if anybody wouldn't mind answering me...?

 

I can't really 'verbally,' explain this, so here's a screen shot and I'll try to make this as easy to understand as possible! :D

 

This is the image:

orne9t.jpg

 

I'm using StarCraft version 1.16.1 currently, and the current offset for the first "message" is: 0057EE9C

I don't know how I'm supposed to "Search" for that specific offset, or value.

I don't know what "004B2727" is!

What's it supposed to mean? I assume it's an offset (a value in memory), but it has no use to me.

Is it mathematically based on the value 0057EE9C?

 

In OllyDbg, is it possible for me to go directly to that offset, 0057EE9C?

I'm not extremely familiar with Assembly, but I can sort of follow, because I know what the stack is, how push/pop work, what ECX, and EDX are ('registers' that hold numerical data (yes, it's all digits, but whatever)). LEA's for multiplying offsets, but a quicker way than using mul..? nop is "No operation" (0x90).

 

Thanks, in advance. :(

-----------------------------------------------------

 

I think I found what I was looking for, and I learned how to do the breakpoints! ;)

But! I have a new question... How are you supposed to edit what it's comparing against?

 

zmh1r9.jpg

 

Like... How would you make it so the message has a longer viewing time (I assume that's the compare they all use)?

Edited by muted

Share this post


Link to post
Share on other sites

Well, nobody replied apparently, but the good news is: I found what I was looking for...! :)

It wasn't quite what I thought, and it was in the same function (do-while loop? in C?), but anyways, here it is!

 

2d9ycs9.jpg

 

I highlighted what I think is a do-while loop, with a "call" in it, that I have no clue is/does.

But anyways! The timer that gets compared against, is the CMP ESI, 0 command I modified to 0; Initially it was 0x0D (14 seconds?).

 

I also found a rather peculiar method of changing where user messages are displayed (making them spread apart/closer together).

Here's the source code I threw together:

#include <iostream>
#include <windows.h>

using namespace std;

HWND hwnd = FindWindow(0, "Brood War");
HANDLE handle;
DWORD pid;


int main() {

GetWindowThreadProcessId(hwnd, &pid);
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

unsigned MessageAddress = 0x0640B20;
int Value = 10;

if (FindWindow(0, "Brood War")) {
	do {

		Sleep(5);

		if (GetAsyncKeyState(VK_ADD)) {
			Value++;
			Sleep(25);

			WriteProcessMemory(handle, (LPVOID)MessageAddress, &Value, sizeof(Value), NULL);
		}

		if (GetAsyncKeyState(VK_SUBTRACT)) {
			Value--;
			Sleep(25);

			WriteProcessMemory(handle, (LPVOID)MessageAddress, &Value, sizeof(Value), NULL);
		}
	} while (!GetAsyncKeyState(VK_END));
} else { cout << "StarCraft: Brood War, not foundn"; }

cout << "Press return to exit";
getchar();

return 0;
}

 

You need to either use VirtualProtect(), or set it to debug mode, to do that to StarCraft v1.16.1.

 

Again: If anybody knows how to print text to X, Y on the screen, or send messages to all users (without using the enter key/packet sending), please let me know! Thanks... :(

 

I'll keep searching on my own, I know there has to be a function somewhere!

Share this post


Link to post
Share on other sites

Play with these.

 

DispText_BWFXN 48D1C0h

PrintText_BWFXN 4202B0h

Refresh_BWFXN 41E0D0h

Draw_BWFXN 4E1C70h

 

All for patch 1.16.1

Share this post


Link to post
Share on other sites
Play with these.

 

DispText_BWFXN 48D1C0h

PrintText_BWFXN 4202B0h

Refresh_BWFXN 41E0D0h

Draw_BWFXN 4E1C70h

 

Two words: Thank-you, so-very-much. ;)

 

I overlooked the ASCII text that said, "%s: %s" which is obviously a message (unformatted).

I nop'd out the entire function, and then specific calls until I found which is actually causing the text to be sent.

 

I can't seem to get a *.dll to load into StarCraft, and have it work (EG: when I press the HOME key, do something).

 

I am so freaking excited right now! I haven't ever gotten a *.dll injection to work, and from the looks of it... Injecting a *.dll and directly editing the memory would be a lot 'faster,' AND easier. :D

 

It keeps crashing on me though, so, I'm gonna have to study how it does this.... :(

I don't even know where to jump in at, or how! But this is fun anyways!!

 

Thanks again! :(

Edited by muted

Share this post


Link to post
Share on other sites
Here is something quick I wipped up showing text to the screen.

 

There are probly some bugs. I am releasing this under GPL v3.

A link to GPLv3 is http://www.gnu.org/licenses/gpl-3.0.txt

 

printtoscreen.zip

 

You'll need masm32 to compile this. Link: http://www.masm32.com/

 

I was extremely close! :( It keeps popping an error in my thread, saying it can't access the memory...

At 0x00064B or something. But that doesn't make sense, because that should be accessable!

 

#include "stdafx.h"

int *FXN_TextToPlayers = (int*)0x048D461;
void SC_TextToPlayers(char *szText) {

_asm {
	pushad
	mov eax, szText
	call dword ptr [FXN_TextToPlayers]
	popad
	ret
}

return;
}

DWORD ThreadID;

DWORD WINAPI SendText(LPVOID lParam) {

while(1) {
	Sleep(50);

	if (GetAsyncKeyState(VK_HOME)) {
		PrintXY("Hello world! :( i R Muted!");
	}
}

ExitThread(0);
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {

if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&SendText, 0, 0, &ThreadID);
}

return TRUE;
}

 

Umm, thank you very much! For the Assembly project... Except I don't program in Assembly...

or even have an Assembler on my machine, let alone MASM (yes, I know where to get one). :P

 

I tried to convert it all to C++ but I'm a little confused on how to convert "invoke" and...

what exactly.. or how to even 'convert' it, or whatever. I don't know how you'd phrase that.

...Translate?

 

int *BWFXN_HUD = (int*)0x04202B0;
void PrintXY(char *Text) {

_asm {
	pushad
	mov eax, Text
	mov edx, 14h
	push edx
	mov esi, 1B0h
	call dword ptr [BWFXN_HUD]
	popad
	leave
	retn
}

return;
}

...

void JmpPatch(int a, int b) {

_asm {
//		mov	ebx, to
//		mov	ecx, from
	add	ecx, 05h
	sub	ebx, ecx
//		lea	ecx, lgJmp
	mov	byte ptr [ecx], 0E9h
	mov	dword ptr [ecx+1], ebx
//		invoke WriteMem, from, addr lgJmp, 5
	ret
}

return;

}

 

I'm not even sure what that's doing.

It's moving 0048CF7E into ebx, and PrintXY's memory address into ecx, and then what?

What exactly does the "WriteMem" function do?

It looks as if it enables debugging but, it doesn't DO anything.

 

Thanks again, sorry for being such a hassle. :(

 

Oh also, this person gave me this snippet in February, but I never checked the forum until today:

SC_TextToPlayers proc

szText:DWORD

	.data
	FXN_TextToPlayers		  dd 004F2EC0h

	.code
	pushad
	   mov eax, szText
	   call dword ptr [FXN_TextToPlayers]
	popad
	ret

SC_TextToPlayers endp

 

He said the offset is for v1.15.1, but I don't know how to get it to work either... I THINK the offset is:

0x048D463 - because if you nop that call, no text goes out!

 

But when I try using the code, it doesn't work or do anything, it just crashes StarCraft:

int *FXN_TextToPlayers = (int*)0x048D463;
void SC_TextToPlayers(char *szText) {

_asm {
	pushad
	mov eax, szText
	call dword ptr [FXN_TextToPlayers]
	popad
	ret
}

return;
}

 

PS: I'd love to be able to print text to any X, Y coordinate client side, but I also wanted...!

To be able to send text, to ALL users, without having to hit enter/edit the buffers/all that. :D

 

-------------------

This actually printed text (garbage only ("$B'|-")), but it was client side only.

 

void DisplayMessage(char *strMessage, int intDurationInSeconds) {

int intDisplayUntil = GetTickCount() + (intDurationInSeconds * 1000);
int fcnDisplayMessage = 0x048D460;

__asm
{
	push 0
	push intDisplayUntil
	mov  edx, 0
	mov  ecx, strMessage
	call fcnDisplayMessage
}
}

Edited by muted

Share this post


Link to post
Share on other sites

Just noticed I included a shitty bug in my code. here is the updated version.

Now it should print normally.

 

 

printtoscreen.zip

 

 

I can convert the asm to pseudo code if you wish.

 

Also just as a side note most functions end in 0. i would try your FXN_TexttoPlayers as 004707D0h. I didn't even check out that address but it looks better.

 

EDIT: changed address to 4707D0h

Share this post


Link to post
Share on other sites
Just noticed I included a shitty bug in my code. here is the updated version.

Now it should print normally.

 

 

printtoscreen.zip

 

 

I can convert the asm to pseudo code if you wish.

 

Also just as a side note most functions end in 0. i would try your FXN_TexttoPlayers as 004707D0h. I didn't even check out that address but it looks better.

 

EDIT: changed address to 4707D0h

 

0x4707D0 gives an "access violation" just like before.

The debugger takes you to: 0101FFEC add byte ptr [eax],al

 

What exactly does the "patch" do? Because if I could manually do it, it'd make a lot more sense.

I'm using OllyDbg, so I can't everything, but I can do some things...

 

In this googled site, is this what your "JmpPatch" is doing (but with Assembly)?

http://www.skullsecurity.org/wiki/index.ph...on_and_Patching

Edited by muted

Share this post


Link to post
Share on other sites

JmpPatch all it does is the following.

 

You know when in olly you can click on space while selecting a command and changing that command in memory?

 

Well JmpPatch all it does is at a certain offset which is the first argument it tells the program to jmp to the second argument and execute code from there. anyway if you would like i can probly make pseudo-code for all of this. and i recommend in starting to make hacks in asm firstly because if you do so you'll have a much better feel of making hacks and how the PE environment works.

 

Anyway I gtg for today ill reply tomorrow.

Share this post


Link to post
Share on other sites
JmpPatch all it does is the following.

 

You know when in olly you can click on space while selecting a command and changing that command in memory?

 

Well JmpPatch all it does is at a certain offset which is the first argument it tells the program to jmp to the second argument and execute code from there. anyway if you would like i can probly make pseudo-code for all of this. and i recommend in starting to make hacks in asm firstly because if you do so you'll have a much better feel of making hacks and how the PE environment works.

 

Anyway I gtg for today ill reply tomorrow.

 

When I say this to people, it usually comes off as being arrogant, and mis leading:

I can and do program, and hack, and have for a long time (hack is a general term).

I've never really been, "good," at it, but I do understand a lot of the terminology/theory behind it.

I understand the main algorithms to finding, and cracking programs, and how to find what you're looking for.

 

But I don't program in Assembly, and I've tried to teach myself on multiple occasions, and get extremely confused, and frusterated, and lost without guidance, because there's one too many variables for me to even try and comprehend... I have a lacking knowledge about hardware, other than the basics, which doesn't help, although now, I understand EXACTLY what an x86 is, and why there are different "instruction sets" for Assembly languages.

 

The fact there are so MANY Assembly languages, makes it rather confusing, and honestly, I think a lot of people try to give their biased opinions, rather than solid facts (letting "you" (me) make a decision for yourself), which really clouds a lot of personal thought, and judgement.

 

A language is a tool, it's designed with a purpose in mind, and I really am extremely familiar with C/C++, although I get the two confused from time to time, I primarily use C (technically when you "use C++" such as cout, it IS C++, although I still refer to it as "C").

 

I've never programmed with, or learned the Win32 API, I've attempted to learn other APIs and I really get--

Yeah, confused, lost, etc, and there is lots of information on the web, and forums, but I usually end up getting banned because of personal disagreements with other users, or 'quarrels,' if you want to call it that. Which makes it rather hard, and difficult to find a forum with a 'community,' that I like, and respect, that's actually active.

 

Um, and yes, I've attempted to learn MASM, and A89? And also HLA (High Level Assembly)! I've read a few "x86 Assembly Tutorials" that were quick run-throughs on the basics, I've read longer tutorials that try to explain (in a non-professional manner?) what Assembly is, what the specifics of it are (such as registers, and how they correlate with RAM, and the instructions themselves, and other misc. crap that isn't required, but is considered helpful - such as understand how pressing a gas pedal makes a car move, rather than simply knowing it will make a car move.

 

I've read "The Art of Assembly," or at least parts of it before, and I'm so spoiled, and used to having an IDE, trying to use the commandline after years of having a GUI is hard to readjust to, because it 'doesn't fit' into my 'real life,' or daily life, and I consider programming a habit, and I understand that a lot of people would say you must put fourth effort, to learn programming, and newer languages, and I also understand that people say it's harder to go from a high level language (common ones: Delphi, C/C++, Java) to a lower level language (PASCAL (not so much), SmallTalk, Assembly, Macro Assembly, etc).

 

I've always been resistant to learning new ideas when it comes to programming, and as of this past year, I've been trying to be more open than before, and it hasn't shown much (classes in C++ for one), although trying to use a debugger (at least a disassembler such as OllyDbg), has proved to be more useful than simply hex editing something, because that isn't modifying the RAM real-time. Also using RAM searchers such as ArtMoney (very popular, and effective)! :)

 

If you would be willing to take the time, to coherently teach me, and instruct me, and be patient with me - because I am a slow learner - I would be more than willing to listen. I know how I learn, and I know the better methods I learn by, although people consider it 'spoon-feeding,' that's just me. I have a hard time creating ideas from thin air, but when I see that idea on paper, I can articulate it, manipulate it, and do whatever I want with it, build on it, and that's where I'm getting stuck with this idea in particular.

 

I managed to find a few of those offsets on my own, without the help of anybodies tutorial, or advice, or experience, knowledge, etc. I actually used what little I know to find them, and I made some whack-o assumptions, and decided it was a "function" written in Assembly, and if not that, at least a "do-while loop," of some sort, which now after having spent many hours on google trying to find answers, I find posts from 2007 that say exactly that (they ARE do-while loops)!

 

The fact that the tutorials are for different patch versions, have different offsets, and the op-codes change makes it extremely discouraging, and if nothing else, frusterating, because I don't have any one person I can consult in case of questions, or troubles, or if something doesn't turn out the way I expect or hope.

 

I'm sorry for the extremely long post, I'd go on more but... I think it'll say I have "too much text." :(

Share this post


Link to post
Share on other sites

Well anyway I read your post, I'll make you some pseudo-code functions for the print text.

 

void TextAnywhere(char *printme, int wherex, int wherey) {

//This function will print text anywhere and can be used to print static text.
static int BWFXN_HUD = 0x4202B0;

__asm
{
pushad
push wherey
mov esi, wherex
mov eax, printme
call BWFXN_HUD
popad
mov dword ptr ss:[ebp-4h],0Bh
jmp BWFXN_RetHud
}
}

 

void CenterText(char *printme) {

 //this function should print center text and it should go away.
 static int DispText_BWFXN = 0x48D1C0;
 __asm
 {
mov eax, -1
mov esi, printme
push esi
call dword ptr [DispText_BWFXN] 
ret 
 }
}

 

Edit: I'll get back to you with sending text to all users in the game.

 

Edit 2:

void SendTexttoUsers(char *sendtext) {

//this should send text to users. you will not see the text it sends

static int BWFXN_SendText = 0x4C2310;
__asm{
mov edi, sendtext
add esi, 6
call [BWFXN_SendToUsers]
retn
}
}

Share this post


Link to post
Share on other sites

0048CF60   55			   PUSH EBP
0048CF61   8BEC			 MOV EBP,ESP
0048CF63   51			   PUSH ECX
0048CF64   8B0D F8E06C00	MOV ECX,DWORD PTR DS:[6CE0F8]
0048CF6A   53			   PUSH EBX
0048CF6B   56			   PUSH ESI
0048CF6C   57			   PUSH EDI
0048CF6D   E8 BE2BF9FF	  CALL StarCraf.0041FB30
0048CF72   0FB61D 580B6400  MOVZX EBX,BYTE PTR DS:[640B58]
0048CF79   BF 70000000	  MOV EDI,70							 ; 00 to 9F - Y coordinate of text
0048CF7E   C745 FC 0B000000 MOV DWORD PTR SS:[EBP-4],0B			; Controls the loop of text?? ('text wrap')
0048CF85   BE 0A000000	  MOV ESI,0A							 ; 00 to 9F - X coordinate of text
0048CF8A   8D9B 00000000	LEA EBX,DWORD PTR DS:[EBX]

 

This is the only 'function,' that I've been able to find X, Y coordinates on, for displaying text.

This affects not only user text (pressing enter & typing), but also the "Not enough minerals/supply" text.

 

Every single code snippet you've posted only results in StarCraft crashing when it's run.

My only guess is, it has something to do with there being no "jump patch..." and I don't even know what that is.

 

You gave a very brief, and incoherent (from my perspective) explanation of what it is; This is how I understood it:

You make a jump from one offset to another <-- That doesn't help me at all, or make any sense at all.

 

The code you have does this (which isn't simply "jmp <offset>"):

JmpPatch proc	uses ecx ebx	from:DWORD, to:DWORD

mov	ebx, to
mov	ecx, from
add	ecx, 05h
sub	ebx, ecx
lea	ecx, lgJmp
mov	byte ptr [ecx], 0E9h
mov	dword ptr [ecx+1], ebx
invoke WriteMem, from, addr lgJmp, 5
ret

JmpPatch endp

 

and WriteMem is:

 

WriteMem proc	MemOffset:DWORD, DataPtr:DWORD, dataLen:DWORD

LOCAL OldProt:DWORD

invoke VirtualProtect, MemOffset, dataLen, PAGE_EXECUTE_READWRITE, addr OldProt
invoke RtlMoveMemory, MemOffset, DataPtr, dataLen
invoke VirtualProtect, MemOffset, dataLen, OldProt, addr OldProt
ret

WriteMem endp

 

What does that DO exactly? If it's something I'm able to manually do with OllyDbg, please explain!

From the looks of it, I SHOULD be able to do that with OllyDbg manually.. but I don't know.

 

How does it even work? It replaces (where and why) a single line of ASM code, with a "call <offset>?"

Then the call is directed to your OWN user-defined *.dll file, and the first thing it does is replaces

the call you overwrote? And then it returns back to the StarCraft *.dll or whatever?

 

EDIT: This site (http://www.skullsecurity.org/wiki/index.php/.dll_Injection_and_Patching) explains it, but I can't get v1.05 patch to see for myself.

Edited by muted

Share this post


Link to post
Share on other sites

yes jmppatch tells one it to make this offset to be modded to jump to this offset.

 

i tried making c functions try using them.

if they don't work then try fixing them youself. remember I dont own you anything so don't get too grumpy, most ppl will just tell you fuck off while im actually replying. seriously go dl Zynastor's multicommand source on http://gamethreat.net

 

lastly this functions i gave you work in asm and i program in MASM so plus adapt to it or use c++ but don't be annoyed when something fails.

Also if you get errors please give more info about them and also try some troubleshooting.

 

Good Luck! :P fixing all your shit.

Share this post


Link to post
Share on other sites
yes jmppatch tells one it to make this offset to be modded to jump to this offset.

 

...

 

lastly this functions i gave you work in asm and i program in MASM

 

Yes, I know they work in ASM!

I downloaded a MASM compiler just to see. :)

 

I can easily create stuff like that, but I don't want to cheat, and steal somebody elses work.

Aside from that, I don't understand what it's doing, which is what I'm trying to learn.

 

I tried commenting (I think that's ASM comments anyways) what I think it's doing.

And sorry if I seemed "grumpy," didn't mean to come off that way. :|

 

;0048CF7E = "from" initial value
;addr PrintXY = "to" initial value

JmpPatch proc	uses ecx ebx	from:DWORD, to:DWORD

mov	ebx, to;store "to" in EBX
mov	ecx, from;store "from" in ECX
add	ecx, 05h;add 0x05 into ECX
sub	ebx, ecx;subtract ECX from EBX (why?)
lea	ecx, lgJmp;Load Effective Address of "lgJmp" into ECX (therefore undoing all previous math?)
mov	byte ptr [ecx], 0E9h;move 0xE9 into ECX (what for??)
mov	dword ptr [ecx+1], ebx;move (ecx + 1) into EBX
invoke WriteMem, from, addr lgJmp, 5; Call the "WriteMem" function, passing these values to 'patch?'
ret

JmpPatch endp

 

Also: OK! I'll download it but, I don't know how much help it'll be to me...

And thanks again for the help, and actually replying without saying "fuck off" :D

------------------

 

OK! I looked at StarCraft with OllyDbg, before AND after the *.dll (example.dll) was loaded.

This is it (that small section) AFTER your *.dll was uploaded, and SC's memory was altered:

0048CF60   55			   PUSH EBP
0048CF61   8BEC			 MOV EBP,ESP
0048CF63   51			   PUSH ECX
0048CF64   8B0D F8E06C00	MOV ECX,DWORD PTR DS:[6CE0F8]
0048CF6A   53			   PUSH EBX
0048CF6B   56			   PUSH ESI
0048CF6C   57			   PUSH EDI
0048CF6D   E8 BE2BF9FF	  CALL StarCraf.0041FB30
0048CF72   0FB61D 580B6400  MOVZX EBX,BYTE PTR DS:[640B58]
0048CF79   BF 70000000	  MOV EDI,70							 ; 00 to 9F - Y coordinate of text
0048CF7E  -E9 F040B805	  JMP example.06011073				; Controls the loop of text?? ('text wrap')
0048CF83   90			   NOP
0048CF84   90			   NOP
0048CF85   BE 0A000000	  MOV ESI,0A							 ; 00 to 9F - X coordinate of text
0048CF8A   8D9B 00000000	LEA EBX,DWORD PTR DS:[EBX]

 

How does it know where to jump at, in example.dll? :shout:

Edited by muted

Share this post


Link to post
Share on other sites
thats whats jmppatch is for. it auto makes it jmp to an address in the program

 

Well, I sort of get that now. :)

 

How does it know where to jump to in example.dll?

Unless that's what all that Assembly code is for, mathematically calculating it.

 

EDIT: I just had a really weird idea...

If all you're doing, is jumping in/out of another *.dll, wouldn't it be possible to like...

NOP out an entire function - say the /whisper and /ignore commands - and then!

Write all the code there, and simply jump back "up" to where it was originally at?

-------------------------------------------------

 

EDIT #2: Hey um, I fixed the lag with your *.dll (it made SC: BW lag really bad) with Sleep...

Anyways! Oh, I also used GetTickCount(), but anyways! How do you add like...

A digit from X offset into a db (database?) message? So I can make a quickie "stat hack?" :)

 

I wouldn't use it on the internet; I mean, if I wanted a stat hack, there's plenty of them...

I just wanted to do this for learning purposes, and all I'm asking is how to do it in Assembly...!

I know the offset I want to use, and I don't know how to append data from an offset to a message.

 

What I want -> Add "50" (numerical value) from offset XXXXXX to message "P1 Minerals: "

 

Sorry for asking for so much, I don't know what to google even (I'm still trying). :(

 

This is my code (I modified yours, in MASM32!!) :D

 

.Data

BWFXN_HUD 			dd 004202B0h;1.16.1
BWFXN_RetHud			dd 0048CF85h;1.16.1
P1_Minerals			db "P1 Min: ", 00h
Credits				db 06h,"Hello (red) World!", 00h



.Code

PrintXY proc

pushad
push 32h
mov esi, 0FAh
mov eax, offset Credits
call BWFXN_HUD

push 14h
mov esi, 1B0h
mov eax, offset P1_Minerals
call BWFXN_HUD

popad
mov dword ptr ss:[ebp-4h],0Bh
jmp BWFXN_RetHud

PrintXY endp

........

DLLLoop proc

GetCurrentTime:
invoke GetTickCount
mov edx, eax;copy time from eax to edx
add edx, 5000;add a 5 second delay (so it isn't super laggy/flashy)

Events:
invoke GetTickCount
cmp eax,edx
jle ShowText
jmp DontShowText

ShowText:
call DLLStartup
jmp GetCurrentTime

DontShowText:
invoke Sleep, 50
jmp Events

DLLLoop endp

 

-------------------------------

EDIT #3: OK! I'm sorry for all the edits, but I just had yet ANOTHER way to express this...!

What I'm wanting to do (put in simpler terms in C), is append an integer to a char *!

In C, what you'd use to do what I want is sprintf()!

 

Example code would be:

char *MyDBMessage = "P1 Minerals: ";
int P1Mineral_Offset = 0x0405000; /* random offset, just for example */
char *buffer; /* the end result is stored here */

sprintf(buffer, "%s %d", MyDBMessage, P1Mineral_Offset);

 

If the integer value, at the offset was like, 75, the message would read: P1 Minerals: 75

 

Hope that makes it clearer to understand :D

Edited by muted

Share this post


Link to post
Share on other sites
Well anyway I read your post, I'll make you some pseudo-code functions for the print text.

 

void CenterText(char *printme) {

 //this function should print center text and it should go away.
 static int DispText_BWFXN = 0x48D1C0;
 __asm
 {
mov eax, -1
mov esi, printme
push esi
call dword ptr [DispText_BWFXN] 
ret 
 }
}

 

Hey, thank you very much for the effort, responses, and everything else, but I have another question:

Why is it, that this code works, and it doesn't use esi, but eax (v1.16.1 SC: BW)?

 

DWORD MessageOffset = 0x48D1C0;

__asm {
	push Message
	mov eax, -1
	call dword ptr [MessageOffset]
	ret
}

 

It has 100% no issues with StarCraft. It displays it in the center/white (a "cheat code").

eax is the "player" -> -1 is "cheat", 0 is no player, 1-8 is the players in the game

 

How do you use "sprintf()" function, in MASM32?

 

Thanks in advance! :)

Share this post


Link to post
Share on other sites
Hey, thank you very much for the effort, responses, and everything else, but I have another question:

Why is it, that this code works, and it doesn't use esi, but eax (v1.16.1 SC: BW)?

DWORD MessageOffset = 0x48D1C0;

__asm {
	push Message
	mov eax, -1
	call dword ptr [MessageOffset]
	ret
}

Load up olly, load up the dll, set a breakpoint on that function and test it with it being eax or esi :). And test how its normally accessed ie without the dll.

 

 

it is because both are printed eax is ment to be the player name and esi the actual text. If you look at SC's code further you can actually see that eax becomes the message if it was firstly -1

 

 

It has 100% no issues with StarCraft. It displays it in the center/white (a "cheat code").

eax is the "player" -> -1 is "cheat", 0 is no player, 1-8 is the players in the game

 

How do you use "sprintf()" function, in MASM32?

 

Thanks in advance! :)

I use wsprintf.

Share this post


Link to post
Share on other sites
Load up olly, load up the dll, set a breakpoint on that function and test it with it being eax or esi :). And test how its normally accessed ie without the dll.

 

 

it is because both are printed eax is ment to be the player name and esi the actual text. If you look at SC's code further you can actually see that eax becomes the message if it was firstly -1

 

 

Thank you, very much for the replies! T_T

 

I have converted it to C code with the slight aid of one other person.

He helped put the MASM code for JmpPatch into English, so I took English and turned it into C. :)

 

bool APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {

LPVOID MyFuncAddr = &MyFunction; // Address to jump to (in my own *.dll file)
DWORD AddressToPatch = 0x048CF83;   // Address to patch over
DWORD MyAddress = reinterpret_cast<DWORD>(MyFuncAddr); // Convert 'cause void* can't hold data
DWORD Idea = (MyAddress - AddressToPatch); // Find the difference!

BYTE JmpOP = 0xE9;
BYTE NOPs[] = { 0x90, 0x90 };

if (dwReason == DLL_PROCESS_ATTACH) {
	WriteProcessMemory(GetCurrentProcess(), (LPVOID)0x048CF7E, &JmpOP, sizeof(JmpOP), NULL);
	WriteProcessMemory(GetCurrentProcess(), (LPVOID)0x048CF7F, (LPVOID)&Idea, 4, NULL);
	WriteProcessMemory(GetCurrentProcess(), (LPVOID)0x048CF83, &NOPs, sizeof(NOPs) / sizeof(NOPs[0]), NULL);
}

return true;
}

 

Thanks again for the help, and the spoiler alert being blacked out. T_T

Share this post


Link to post
Share on other sites

How do you make it so you can pass X, Y arguments to the PrintXY function...?

Whenever I attempt to pass arguments, it crashes on me (I'll post the offset OllyDbg pops on):

 

__declspec(naked) void PrintXY() {

__asm {
	pushad
	push y
	mov esi, x
	mov eax, Message
	call BWFXN_HUD
	popad

	mov dword ptr ss:[ebp-4h],0Bh
	jmp BWFXN_RetHud
}
}

void MainLoop() {

PrintXY();

return;
}

 

OllyDbg pops (when using DWORD y, DWORD x, char *Message as arguments) on:

0041E3A3 8066 FD F8 |AND BYTE PTR DS:[ESI-3],0F8

 

Please help, because I do not understand why it's crashing.

 

EDIT #1: Hey! I actually got it to pass an argument... But it makes the screen not refresh?

What does that AND BYTE statement do exactly? I'm guessing it has to do something with refreshing the screen! :D

 

char *Message = "x06Hello world!"; // Red text, "Hello World!"

__declspec(naked) void PrintXY(const int &X, const int &Y) {

__asm {
	pushad
	push X
	mov esi, Y
	mov eax, Message
	call BWFXN_HUD
	popad

	mov dword ptr ss:[ebp-4h],0Bh
	jmp BWFXN_RetHud
}
}

void MainLoop() {

PrintXY(0x32, 0x0FA);

return;
}

 

Thanks again. :suicide:

Edited by muted

Share this post


Link to post
Share on other sites

PrintXY prints static messages. Also if you want to not inject dlls you'll need to make your program attain debug privledges everytime and to do so u'll need to be admin on that computer

Share this post


Link to post
Share on other sites
PrintXY prints static messages. Also if you want to not inject dlls you'll need to make your program attain debug privledges everytime and to do so u'll need to be admin on that computer

 

There's no way to make it so you can pass PrintXY arguments to print text on X, Y coordinates...?

 

No no no! I'm using an injected *.dll and I have created my own jump patch (with some help).

I'm just wondering how you're supposed to call the PrintXY routine AND pass arguments...

I mean, if "push comes to shove," I can use a pair of global X, Y coordinates, and a global char * but...

I don't want to have to specifically change the X, Y everytime then call the PrintXY function!

I'd much rather prefer doing something more on the lines of: PrintXY(0x15, 0x15, "Hello World!");

 

... Why does it not refresh the StarCraft screen at all? Only where I move the mouse/drag "squares" with the mouse?

Does it have something to do with "the stack" and not "being balanced..?" Do you know anything about that?

Is that the actual offset (region?) where the "Refresh" function for v1.16.1 lives at or...? Thanks. :D

Share this post


Link to post
Share on other sites

This actually works, but it doesn't display the text where the arguments are (32h, and FAh):

 

const int BWFXN_HUD = 0x04202B0;
const int BWFXN_RetHud = 0x048CF85;

char *Message = "x06Hello world!";
DWORD x = 0x0FA;
DWORD y = 0x32;

__declspec(naked) void PrintXY(const int &X, const int &Y) {

__asm {
	pushad
	push X
	mov esi, Y
	mov eax, Message
	call BWFXN_HUD
	popad
	ret
}
}

__declspec(naked) void MainLoop() {

		// These arguments are being "ignored" but I know why now!!
PrintXY(0x32, 0x0FA);

__asm {
	mov dword ptr ss:[ebp-4h],0Bh
	jmp BWFXN_RetHud
}

//return;
}

 

I stared at OllyDbg, and I tried doing that "breaking" thing (int 3 interruption for debugging?), and!

I stared at it long enough, and I started using "Step into" and "Step over" (F7 and F8), and...

This is what I discovered (I'll just write it one per line so it's easier to read)...

Well actually, this is my understanding, of what the Assembly code is for, and does:

 

- pushad

pushad stores all registers on the stack, it's there to preserve any possible messages being sent!

Messages such as: Not enough minerals, or You cannot build there, or You require more supplies

- push X

Pushes the "starting" (left) horizontal position of the text, on the stack!

- mov esi, Y

Stores the top-most? vertical position of the text, on the stack

- mov eax, Message

Stores the message in the "dump...?" (I don't understand what "the dump" is)

- call BWFXN_HUD

Executes the function (and nothing else!) at that location (offset.. memory address?)

- popad

Restores all variables on the stack to normal, so nothing bugs up! So like...

If "You require more Vespene Gas" WAS on the stack before it detoured to your *.dll file...

it won't be overwritten, rather preserved with this "popad" and "pushad" commands :)

- ret

This simply returns to the "caller" (if there was one)

------------------------------------------------------------

 

If I was wrong, or incorrect about ANYTHING, please point it out! :(

I'm trying to learn here, and having zero feedback doesn't help very much.

 

Like I said before: I don't want to download somebody elses game hack, 'cause... that won't help.

I don't want somebody ELSES game hack, I want to be able to make my OWN game hacks!

I want to be able to find game-functions on my own without much (if any) help.

 

This way, I'm by far more independent, and best of all: I can help somebody else if it happens. :D

 

Thanks again, for the replies, it's very....... encouraging. ;)

Here's a link to a screen shot of my *.dll in OllyDbg (look please): http://i50.tinypic.com/15s06t2.jpg

I didn't post an image, 'cause I had a lot more questions about stuff/wanted to show that...

I'm actually learning about stuff I've never even been able to use ('cause I use C, not MASM!).

 

Also, I've never used a debugger before but, now I know why people like them so much! ^_^

 

Thank you, so much, Union1! v4w5c5.gif

Edited by muted

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

×