[c++ injecting]Simple detouring (no need for extra libraries)[2.4.3 example] menu

User Tag List

Results 1 to 14 of 14
  1. #1
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [c++ injecting]Simple detouring (no need for extra libraries)[2.4.3 example]

    So, I was inspired by the Jansi's thread ([2.4.3] [C++] Autologin) about injecting stuff.

    Here is an example for his case (2.4.3).

    The detour class I made, (I was inspired by Apoc's Gray Magic) I think it can be very useful, because of it's simplicity (54 lines) and easy to understand (I hope). That simple kind of c++ detour class I searched for long time, but I never found one until I had to make one by myself.
    So for example, creating a detour is easy like this :
    Code:
    detours["NetClientProcess"] = new Detour(0x0055F440, (int)NetClientProcessDetour);
    and the detour handler could be written like this:
    Code:
    //it's a a thiscall
    int __fastcall NetClientProcessDetour(int connection, int edx, int tickCount, CDataStore* data)
    {
    	auto ds = DataStore(data);
    	auto opcode = ds.Peek<unsigned short>();
    
    	if (opcode == SMSG_ATTACKSTART)
    	{
    		chat("dude, SMSG_ATTACKSTART");
    	}
    
    	//---------------- return to the original function ----------------	
    	return detours["NetClientProcess"]->Call<decltype(NetClientProcessDetour)>(connection, edx, tickCount, data);
    }
    Thanks.
    Last edited by tutrakan; 08-24-2017 at 05:14 AM.

    [c++ injecting]Simple detouring (no need for extra libraries)[2.4.3 example]
  2. Thanks CrazyCo, Willy (2 members gave Thanks to tutrakan for this useful post)
  3. #2
    DarkLinux's Avatar Former Staff
    CoreCoins Purchaser Authenticator enabled
    Reputation
    1584
    Join Date
    May 2010
    Posts
    1,827
    Thanks G/R
    188/531
    Trade Feedback
    16 (100%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Wow has a good number of vtables you can hook that gets called every frame, but I would still watch out for warden. I don't really see a need to patch code when it takes 1 simple write, and no page types need to be changed. Unless you cant find a vtable related to the function you want to hook, but overall a good method for executing genaric code in the main thread. I would also recommend looking into using HDE, then your hook can be way more dynamic.
    Last edited by DarkLinux; 08-24-2017 at 02:01 PM.

  4. #3
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by DarkLinux View Post
    Wow has a good number of vtables you can hook that gets called every frame, but I would still watch out for warden. I don't really see a need to patch code when it takes 1 simple write, and no page types need to be changed. Unless you cant find a vtable related to the function you want to hook, but overall a good method for executing genaric code in the main thread.
    It's not patching, but detouring functions. I prefer hooking static functions because of the simplicity. Warden concerned memory scans can be bypassed (PAGE_CHECK not included here) as follows:
    Code:
    int WardenScanDetour(int buffer, int to_compare, int len)
    {
    	std::map<int, byte> old_bytes_map{};
    
    	for (auto& detour_pair : detours)
    	{
    		auto detour = detour_pair.second;
    		for (int i = 0; i != detour->original_bytes.size(); ++i)
    			old_bytes_map[(int)(detour->target) + i] = detour->original_bytes[i];
    	}
    
    	for (int i = 0; i != len; ++i)
    		if (old_bytes_map.find(to_compare + i) == old_bytes_map.end())
    			*(byte*)(buffer + i) = *(byte*)(to_compare + i);
    		else
    			//bypass MEM_CHECK for detoured functions
    			*(byte*)(buffer + i) = old_bytes_map[to_compare + i];
    	return 0;
    }
    Originally Posted by DarkLinux View Post
    I would also recommend looking into using HDE, then your hook can be way more dynamic.
    I said "no need for extra libraries" and really, I don't see the dynamic advantage here against the simplicity of my detour class.
    Last edited by tutrakan; 08-24-2017 at 03:02 PM.

  5. #4
    DarkLinux's Avatar Former Staff
    CoreCoins Purchaser Authenticator enabled
    Reputation
    1584
    Join Date
    May 2010
    Posts
    1,827
    Thanks G/R
    188/531
    Trade Feedback
    16 (100%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    HDE is made up of like 2 or 3 files, it's really simple to setup. I recommend using that so you only patch 1x. Your method reapplies the hook every call, not very efficient. On top of that, you're not even setting the page type back. And if I can remember correctly at some point warden did detect that. None of that really matters I guess if you're only working on an old emulator, I just like my code to be portable, so its good for multiply projects.

  6. #5
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by DarkLinux View Post
    HDE is made up of like 2 or 3 files, it's really simple to setup. I recommend using that so you only patch 1x. Your method reapplies the hook every call, not very efficient.
    You recommend me that I should use some third-party library that relies on guessing processor dependent machine code’s next instruction size, addressing type and operand type? You can try this old one and you'll find out that not all opcodes are handled.
    Efficiency? I rather prefer clearly defined principles against the messy look of the trampoline spaghetti (complications added - congratulations!).
    At least, this is another way of hooking and is widely used in gray and white magic .
    Originally Posted by DarkLinux View Post
    On top of that, you're not even setting the page type back. And if I can remember correctly at some point warden did detect that. None of that really matters I guess if you're only working on an old emulator, I just like my code to be portable, so its good for multiply projects.
    Thanks for pointing the restoring page type back, I had always ignored this part, but I’ll fix it just to stop further comments like the above. For the portability, refer to the “guessing processor dependent machine code’s…” part.
    Last edited by tutrakan; 08-24-2017 at 09:38 PM.

  7. #6
    lolp1's Avatar Site Donator CoreCoins Purchaser
    Reputation
    190
    Join Date
    Feb 2013
    Posts
    210
    Thanks G/R
    43/77
    Trade Feedback
    3 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Why need to detour anything? There is countless examples if invoking code in a thread-safe manner from WndProc by intercepting custom messages. Simply detour the d3d device for the pure intention of frame counting if you want to observe ever frame.

  8. Thanks tutrakan (1 members gave Thanks to lolp1 for this useful post)
  9. #7
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can you give an example of the "thread-safe manner from WndProc" please? Consider that I'm not a pro like you guys and I always try to learn something new. For sure, I will do my research for this WndProc thingy to see if I can use it. In fact, I used it already in order to implement the imgui library window handling, but that was the only encounter I had with till now.
    Last edited by tutrakan; 08-25-2017 at 04:14 AM.

  10. #8
    namreeb's Avatar Legendary

    Reputation
    658
    Join Date
    Sep 2008
    Posts
    1,023
    Thanks G/R
    7/215
    Trade Feedback
    0 (0%)
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    It is worth mentioning that this method of detour is not thread safe. What if you toggle your patch while that code is executing?

  11. #9
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can you give me a specific example and then what should be the best way to do it so it should be thread safe?

  12. #10
    namreeb's Avatar Legendary

    Reputation
    658
    Join Date
    Sep 2008
    Posts
    1,023
    Thanks G/R
    7/215
    Trade Feedback
    0 (0%)
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    To do it in a generic and fully thread safe manner is very complicated. It may technically even be impossible. By that I mean there are potential (read: never-going-to-happen) scenarios to defeat any approach that I am aware of, no matter how robust. That being said, you can do a much better job than this.

    Instead of writing a JMP at the start of the function you want to detour leading to your hook, lead it instead to a trampoline which will a) call your hook and b) execute the first instructions of the original function.

    Consider the following first few instructions as the start of a function you want to detour:

    Code:
    mov eax, 0
    mov ebx, 0
    mov ecx, 0
    mov edx, 0
    Then when you write your JMP, it turns into:

    Code:
    JMP 0xFEEDFACE
    mov ecx, 0
    mov edx, 0
    Note: I am hand-waving a bit at the length of these instructions, but I don't think it matters for purposes of this discussion.

    When your function is called, it will eventually try and call the original function. It does that by removing the JMP patch and then calling (read: JMPing) to the original function. The reason this is not thread safe is consider that the eip of some thread is on the second instruction (mov ebx, 0) while you write your JMP. It will end up attempting to execute the second half of the JMP instruction, which will likely be catastrophic. I believe that the MS detours library will side-step this problem by pausing all threads and examining them to make sure that no thread is executing the to-be-patched bytes.

    Instead of writing a simple JMP, consider instead allocating (or locating in alignment space of an existing executable memory page, preferably the same one as we're working with) enough space to write this:

    Code:
    mov eax, 0
    mov ebx, 0
    JMP 0xDEADBEEF
    And when you want to call the original function from within your hook, call this trampoline instead. In this example, 0xDEADBEEF is the location of the 'mov ecx, 0' instruction in the original function.

    Using this method will avoid having to grant write access to the executable page, write your patch, and restore normal flags. It is still vulnerable to the dilemma of what to do if a thread is executing in the space of the patch you will write, but because you're no longer constantly toggling that patch, it is far less likely to be a problem. You could always implement something like what I mentioned that MS detours above will do, but it may be overkill, especially in WoW which isn't highly paralleled -- unless it is these days I don't know.

    There is another problem with this method. It may seem unlikely but I have actually seen it in DirectX (read: endscene hooks). What if the 'mov eax, 0' or 'mov ebx, 0' instructions are actually relative jumps like 'JMP +0x10'? Then when that executes you will jump into no-mans-land and poof. The only solution for this is to disassemble the instructions and make sure that doesn't happen. And if it does, rewrite in some intelligent way.

    Now, my point here isn't actually to get you to do all this. In fact, I just want to make a shameless plug for Cypher's hadesmem library, which will take care of most/all of these things for you. It can be found here: GitHub - RaptorFactor/hadesmem: HadesMem is a C++-based memory editing library for Windows based applications, with the goal of providing a safe, generic, powerful, and efficient API.

  13. Thanks tutrakan (1 members gave Thanks to namreeb for this useful post)
  14. #11
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    While i don't understand yet some parts of your examples like "What if the 'mov eax, 0' or 'mov ebx, 0' instructions are actually relative jumps like 'JMP +0x10'?", I am aware of Joshua's hadesmem library (which I find too complicate for my simple-minded brain) and i know that you like it. I think I know how to make trampolines, after all I did many of them when I used Black Magic and out of process hooking back in time. I just didn't like the added complication.
    Thanks to you, I understand now that if two (or more) different threads are about to execute the same function that I detour, this can lead to crashing the client. BTW that I don't remember if such a crash happened yet and the fact that I detour the same way as Apoc does it in Grey Magic.

    P.S. GreyMagic - The best of both worlds, and then some
    Last edited by tutrakan; 08-28-2017 at 07:16 PM.

  15. #12
    DarkLinux's Avatar Former Staff
    CoreCoins Purchaser Authenticator enabled
    Reputation
    1584
    Join Date
    May 2010
    Posts
    1,827
    Thanks G/R
    188/531
    Trade Feedback
    16 (100%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    You could loop all threads and suspend them when hooking/unhooking, and then check each thread context (check eip address). I would add a check to see what thread you are in before executing your hook. I would also recommend saving your flags, currently you're nuking them. Look up PUSHFD/POPFD. Also I would free up some stack space to be safe. I dont really see a big problem between a ret hook or jmp hook to be honest, I dont think that was namreeb point eather, but I could be wrong.
    Last edited by DarkLinux; 08-26-2017 at 02:01 AM.

  16. Thanks tutrakan (1 members gave Thanks to DarkLinux for this useful post)
  17. #13
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by DarkLinux View Post
    You could loop all threads and suspend them when hooking/unhooking, and then check each thread context (check eip address). I would add a check to see what thread you are in before executing your hook.
    Thanks for the hint, I never tried that before.
    Originally Posted by DarkLinux View Post
    I would also recommend saving your flags, currently you're nuking them. Look up PUSHFD/POPFD. Also I would free up some stack space to be safe. I dont really see a big problem between a ret hook or jmp hook to be honest, I dont think that was namreeb point eather, but I could be wrong.
    I agree that jmp/push&ret do the same thing, I never argued about.
    You may want to take a look here and see the same principle that I am using: IceFlake_qk/DetourManager.cs at master * qkdefus/IceFlake_qk * GitHub.

    Edit: GreyMagic - The best of both worlds, and then some
    I didn't see somebody telling Apoc - "look dude your toggling detour method sucks bad" etc. On the contrary, peoples are thankful (it worth mentioning that CleanCore/CleanLayer <4.3.4>, IceFlake <3.3.5> and VWOW <1.12.1> e.t.c. bots used that same toggling function start address detour).
    And the strange thing is that, actually, you was participating on the very same thread: http://www.ownedcore.com/forums/worl...ml#post2564196
    Last edited by tutrakan; 09-01-2017 at 07:43 PM.

  18. #14
    namreeb's Avatar Legendary

    Reputation
    658
    Join Date
    Sep 2008
    Posts
    1,023
    Thanks G/R
    7/215
    Trade Feedback
    0 (0%)
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by tutrakan View Post
    While i don't understand yet some parts of your examples like "What if the 'mov eax, 0' or 'mov ebx, 0' instructions are actually relative jumps like 'JMP +0x10'?", I am aware of Joshua's hadesmem library (which I find too complicate for my simple-minded brain) and i know that you like it. I think I know how to make trampolines, after all I did many of them when I used Black Magic and out of process hooking back in time. I just didn't like the added complication.
    Thanks to you, I understand now that if two (or more) different threads are about to execute the same function that I detour, this can lead to crashing the client. BTW that I don't remember if such a crash happened yet and the fact that I detour the same way as Apoc does it in Grey Magic.
    My point was that generating a robust trampoline with the purpose of avoiding the constant toggling of your patch is not a trivial matter. In my example, such a trampoline would look like this:

    Code:
    mov eax, 0
    mov ebx, 0
    JMP 0xDEADBEEF
    Where 0xDEADBEEF is the ea of the third instruction in the function. It may seem like a reasonable heuristic to have merely copied the first n instructions (by byte size) to generate that trampoline. But what if the very first instruction in the function is a relative JMP, i.e. JMP +0x100? Your trampoline would look like this:

    Code:
    JMP +0x1000
    mov ebx, 0
    JMP 0xDEADBEEF
    Note that the jump to 0xDEADBEEF would never happen, and execution would go +100 bytes after your trampoline, and who knows what that would be.

    Originally Posted by DarkLinux View Post
    I dont think that was namreeb point eather, but I could be wrong.
    My point was merely to make it clear that this type of detour is not thread safe. I'm not too familiar with how retail wow runs these days, but in the old days it wouldn't really matter because almost everything ran in one main thread anyway.

  19. Thanks tutrakan (1 members gave Thanks to namreeb for this useful post)

Similar Threads

  1. No need for attunement Q for MC ;P
    By dkcas11 in forum World of Warcraft Exploits
    Replies: 10
    Last Post: 05-25-2010, 01:09 PM
  2. Legit Renting & Buying accounts with 80's (No need for epic flying!)
    By Nikentic in forum Members Only Accounts And CD Keys Buy Sell
    Replies: 26
    Last Post: 02-03-2010, 01:29 PM
  3. OMG - Alot of space! No need for bank spots!
    By Leketid in forum World of Warcraft Guides
    Replies: 16
    Last Post: 12-25-2007, 04:32 PM
  4. Replies: 5
    Last Post: 10-28-2007, 01:50 PM
All times are GMT -5. The time now is 05:44 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search