muted 0 Posted November 16, 2009 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.1const 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...! Share this post Link to post
muted 0 Posted November 19, 2009 (edited) 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: 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? Like... How would you make it so the message has a longer viewing time (I assume that's the compare they all use)? Edited November 19, 2009 by muted Share this post Link to post
muted 0 Posted November 22, 2009 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! 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
Union1 33 Posted November 23, 2009 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
muted 0 Posted November 25, 2009 (edited) 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 November 25, 2009 by muted Share this post Link to post
Union1 33 Posted November 25, 2009 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/ Share this post Link to post
muted 0 Posted November 25, 2009 (edited) 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 November 25, 2009 by muted Share this post Link to post
Union1 33 Posted November 25, 2009 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
muted 0 Posted November 26, 2009 (edited) 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 November 26, 2009 by muted Share this post Link to post
Union1 33 Posted November 26, 2009 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
muted 0 Posted November 26, 2009 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
Union1 33 Posted November 26, 2009 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
muted 0 Posted November 28, 2009 (edited) 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 November 28, 2009 by muted Share this post Link to post
Union1 33 Posted November 28, 2009 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
muted 0 Posted November 28, 2009 (edited) 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 November 28, 2009 by muted Share this post Link to post
Union1 33 Posted November 28, 2009 thats whats jmppatch is for. it auto makes it jmp to an address in the program Share this post Link to post
muted 0 Posted November 28, 2009 (edited) 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 November 28, 2009 by muted Share this post Link to post
muted 0 Posted December 9, 2009 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
Union1 33 Posted December 9, 2009 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
muted 0 Posted December 11, 2009 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! 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. Share this post Link to post
Union1 33 Posted December 11, 2009 You could've also tried to download Zynastor's multi-command and use that. Share this post Link to post
muted 0 Posted December 13, 2009 (edited) 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 December 13, 2009 by muted Share this post Link to post
Union1 33 Posted December 13, 2009 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
muted 0 Posted December 14, 2009 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
muted 0 Posted December 14, 2009 (edited) 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! Edited December 14, 2009 by muted Share this post Link to post