[code snippet]Pass GUID to UnitXXXX functions as argument menu

User Tag List

Results 1 to 5 of 5
  1. #1
    demonguy's Avatar Member
    Reputation
    2
    Join Date
    Feb 2012
    Posts
    111
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [code snippet]Pass GUID to UnitXXXX functions as argument

    Despite you can get information about all units from descriptors...But still it's trouble-some to write codes about all descriptors
    So i write this,i noticed that most UnitXXX functions will call GetGUIDByKeyWord function ,transforming UID to GUID, So i hook it ...
    After hooking... you can pass UID directly to UnitXXX functions...which means UnitHealth("target") and UnitHealth(UnitGUID("target")) return the same value


    By the way,I need to abreact...... local varibles allocation on stack by myself is really annoyed

    All offsets you need is in dump threads, So i won't list them here

    Attention:All Asm codes will vary from Wow Version..You need to go into IDA and check them.. How to analyst IDA is beyond our discussion.So go to look it up in IDA-related books

    Then Codes below:
    Code:
    	// GetGuidByKeyWord Hook , Jump to my own function
    	Memory::Write<byte>(WoWBase + GetGUIDByKeyWord , 0xE9);
    	Memory::Write<int>(WoWBase + GetGUIDByKeyWord  + 1, reinterpret_cast<unsigned int>(Lua::GetGuidByKeyHook) - (WoWBase + GetGUIDByKeyWord  + 4 + 1));
    Code:
    __declspec(naked) unsigned int __cdecl CHack::Lua::GetGuidByKeyHook ()
    {
    	__asm
    	{
    		pushad  //esp will decrease by 32
    	}
    
    	char *s;
    	__int64* guid;
    
    	__asm
    	{
    		mov ebp,esp
    		sub esp,24  //make enough memory for local varibles
    		mov ecx,[ebp+36]  //first argument of GetGuidByKeyWord ,since esp decreased 32, so you need plus 36 instead of 4
    		mov edx,[ebp+40]  //second argument of GetGuidByKeyWord
    		mov s,ecx
    		mov guid,edx
    	}
    
    	if(IsBadReadPtr(s,100) || !checkGUID(s))  //Sometimes the caller will pass a invalid pointer....Damn it....
    	{
    		static unsigned int Address = WoWBase + GetGUIDByKeyWord  + 0x5;
    		__asm
    		{
    			mov esp,ebp
    			popad
    			push ebp
    			mov ebp,esp
    			push ecx
    			push edi
    			jmp Address  //argument is not a GUID , so does nothing and  jump back
    		}
    	}
    	else
    	{
    		sscanf_s(s, "%llx", guid);
    
    		unsigned int ObjPtr = reinterpret_cast<unsigned int (__cdecl*)(__int64 guid,char mask,char * file,int line)>(CHack::WoWBase + ClntObjMgrObjectPtr)(guid,(char)0xFF,".\\ScriptEvents.cpp",348);
    
    		if (*(char *)(ObjPtr + ObjectType) != Type_Player && *(char *)(ObjPtr + ObjectType) != Type_NPC)  //Since All UnitIDs such as "target" "focus" represent NPC or Player.. So i check here to avoid crash
    		{
    			static unsigned int Address = WoWBase + GetGUIDByKeyWord + 0x5;
    			__asm
    			{
    				mov esp,ebp
    				popad
    				push ebp
    				mov ebp,esp
    				push ecx
    				push edi
    				jmp Address   //GUID doesn't represent a NPC or Player, so does nothing and jump back
    			}
    		}
    		else
    		{
    			static unsigned int Address = WoWBase + GetGUIDByKeyWord + 0x474;
    			__asm
    			{
    				mov esp,ebp
    				popad
    				mov al, 1
    				jmp Address
    			}
    		}
    	}
    
    }
    Last edited by demonguy; 05-09-2012 at 02:02 AM.

    [code snippet]Pass GUID to UnitXXXX functions as argument
  2. #2
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Woah, I don't think I've been this confused by something posted here in a long time now.. No offence, but that code is quite the mess
    I understand that you might be trying to help others by posting this, but you really need to write a decent hooking framework first imo. Naked functions, manual stack management and explicit 'jmp's is just asking for trouble.
    Compare your function to mine which does the same thing.. (at least I think it does, your's is kinda hard to grasp)
    Code:
    Real_GetGUIDFromToken = reinterpret_cast<tGetGUIDFromToken>(Hook(Offsets::GetGUIDFromToken, reinterpret_cast<HookTarget>(&Hook_GetGUIDFromToken)));
    ...
    bool Hook_GetGUIDFromToken(const char* keyword, Guid& guid, bool b1, bool b2)
    {
    	try
    	{
    		guid = Guid::FromString(keyword);
    		return true;
    	}
    	catch(const std::bad_cast&)
    	{
    		return Real_GetGUIDFromToken(keyword, guid, b1, b2);
    	}
    }
    I wrote that several patches ago and haven't needed to touch it ever since. Which one do you think is easier to maintain?

    I'm not going to post the full hooking lib for C&P, but if you have specific questions I wouldn't mind helping you writing your own.

  3. #3
    demonguy's Avatar Member
    Reputation
    2
    Join Date
    Feb 2012
    Posts
    111
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Generally speaking, i like your codes , they are surely brief...
    Framework will make your codes brief, that's true,but it will also make it hard to understand..Those who want to study will need to learn what your framework does first...
    For experienced programmers, they will know what your codes do immediately, But what i want to do is to show newbs what a hook should do , after all, experienced programmers don't need my code snippets at all ,right?

    When i want to publish my program, I will pay attention to write a framework. anyway thanks....

    By the way ,I now still have trouble to know how to get a "spell object" position (i don't know if it's called spell object...).And weeks went by, I still even don't know where to start .... Since you seem to be good at Wow Memory Editing. would you please take a look at this ?
    http://www.ownedcore.com/forums/worl...ts-target.html
    Last edited by demonguy; 05-09-2012 at 10:37 AM.

  4. #4
    Bananenbrot's Avatar Contributor
    Reputation
    153
    Join Date
    Nov 2009
    Posts
    384
    Thanks G/R
    1/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code listings should always be brief. Next to no class file should be longer than 200 lines in current software engineering techniques. You should keep yourself focused in code listings and ensure that you are only doing one thing at a time. Your code is some hooking code intertwined with your actual poc. I would even say that your actual "point" in that snippet is only 1/4 of that listing, the rest is boilerplate or just orthogonal concepts which have nothing to do with "passing a GUID to UnitXXX functions". For that case, there are refactorings like Refactoring: Extract Method and design patterns that help you to stay focused.
    Extract method is one of the most essential refactorings. See A Java "extract method" refactoring example | Refactoring examples series | devdaily.com . It's kind of a "binary search for code" (group related behavior and give it a meaningful name, so that you can always know where to continue search for your actual code block by tracing method calls). The huge benefit is that you know in a second what your method does (see the second link for more insight).
    When your extractions outline different concepts in a class, it is time to split that class up to accomodate the Single Responsibility Principle.

    Mike's code is more informative than yours, because of TL;DR ofc and his code is condensed and focused. Only a simple prologue to set some preconditions (GetGUIDFromToken is hooked and the name of the hook function) and a short and meaningful listing of that hook function which "tells" what and not how to do.

    There is no "I'll clean it up later" because you almost never will (granted, in this case everyone would ) until you realize that your framework is bullshit and you begin a complete rewrite. That framework is the essence of what you want to do, your tool box with some distinct tools.
    There is just no place for a hammer with an attached wrench and a hammer with a voltmeter attached in a toolbox. It should rather be like hammer, voltmeter, wrench as seperate concepts. By being able to name a concept unambigously you can communicate on that in a so called ubiquotious language (actually there's more to it). If somebody talks to you to use a hammer to get your nails into the wall, you instantly know what he means. He can give you a much shorter and more precise description of what to do. Imagine how he would explain that without you knowing the concept hammer... Think that's enough of far-fetched examples

    So I wasn't really focused in this post, the odds are you won't be reading this bottom line, but I hope I could prove to you why doing clean and focused work is so important when releasing code. I hope you don't feel offended, I just wanted to give some constructive criticism and explain why I favor Mike's snippet.
    Last edited by Bananenbrot; 05-09-2012 at 04:57 PM. Reason: langauge

  5. #5
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    At least someone got my point. Bananenbrot <3

    Generally speaking, i like your codes , they are surely brief...
    Framework will make your codes brief, that's true,but it will also make it hard to understand..Those who want to study will need to learn what your framework does first...
    For experienced programmers, they will know what your codes do immediately, But what i want to do is to show newbs what a hook should do , after all, experienced programmers don't need my code snippets at all ,right?
    I was just trying to prove a point that sometimes, less is more.
    Maybe it is harder to understand. I don't know. Personally I'd like to believe that the function name Hook() is clear enough to explain what it does, and that a "newb" (I really hate that word) would have a much easier time figuring out what it does compared to a few lines of inline assembler.
    But anyways; The details of how it does it is not important for the context of this thread, which is getting the hooked function to accept guids as well as unit tokens. What matters is the logic of the hook itself.
    Consider the following text:

    The function Script_GetGUIDFromToken (also sometimes referred to as GetGUIDByKeyword) is a function that takes a unit token, such as "player" or "target", and converts it to a GUID that other functions can use to reference players and npcs.

    It takes 4 parameters:
    [in] char* (the keyword to look up)
    [out] guid* (the resulting guid that matches the above keyword)
    [in] bool, bool (irrelevant to us at this time. Just know they are there so you can build a proper function prototype)
    The return value is a bool where true means the conversion succeeded and false means it failed for some reason.

    So how do we get this function to accept a guid? Well, it's actually not that hard.
    After we've hooked the function we can test the keyword parameter to see if it is a numerical string. If it is we parse the string to get the number and write it to the guid pointer, and then we return true for success.
    And if it isn't a number then we assume it is a keyword and pass it off to the original function and let it check if the keyword is valid or not.
    And then we're done..
    Those few lines of text, without including a single line of code, says much much more about how to solve the issue than the code in the OP. And does it matter that I didn't explain in detail how to write the actual hooking code, or how to parse a numerical string? No, it doesn't. Because those kinds of libraries can be found all over the internet. All you need is a little time on google.

    So what was the point of this whole rant then? The point is that for your personal projects you can write your code however you want using whatever technique you want and I couldn't care less. If it works then good for you. But when you post code with the intent of teaching others, please don't post stuff that will leave people more confused than before they even read it
    And please don't take this as a personal insult as I've got nothing against you. In fact I think it's great that we've seen some new people here recently that are genuinely trying to learn and to help others to learn as well. Just, maybe, ask yourself "hey, if I hadn't written this myself.. would I be able to understand it?" every once in a while.

Similar Threads

  1. MW2 - Code snippets, tutorials
    By Ket in forum FPS Game Discussions
    Replies: 1
    Last Post: 08-08-2011, 04:04 PM
  2. [Code] Snippets from WoWBasic
    By bigtimt in forum WoW Memory Editing
    Replies: 5
    Last Post: 10-01-2008, 02:44 PM
  3. [guide] alt code/characters
    By *TraPStaR* in forum Community Chat
    Replies: 2
    Last Post: 01-30-2008, 09:45 PM
  4. Codes for creating own vendor place, and taking away the arena points costs[Guide]
    By chanceless in forum World of Warcraft Emulator Servers
    Replies: 7
    Last Post: 11-03-2007, 01:22 PM
  5. Ultimate Gold Guide <User and Pass>
    By janzi9 in forum World of Warcraft General
    Replies: 16
    Last Post: 12-16-2006, 07:58 PM
All times are GMT -5. The time now is 09:04 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search