[C++] [Help] Different methods of calling Wow functions (DLL Injection, Hooking, etc) menu

User Tag List

Results 1 to 9 of 9
  1. #1
    reliasn's Avatar Legendary Authenticator enabled
    Reputation
    774
    Join Date
    Jan 2009
    Posts
    136
    Thanks G/R
    24/215
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [C++] [Help] Different methods of calling Wow functions (DLL Injection, Hooking, etc)

    Hello, Ownedcore!

    After reading a lot about injection and hooking and facing tons of problems, I come here to share the C++ method I'm currently using (not actually share... more like asking for help, but anyways...). Before anything, let me just point out a couple problems I found "along the road":
    1 - CreateRemoteThread
    I made this thread (Lua_DoString() in C++ w/ CreateRemoteThread/WriteProcessMemory + Security questions) once and it was the first method I tried. It worked sometimes, but it would crash others. I think the crashes happened due to sometimes having two threads executing the same code and somehow one would affect the other and, therefore, a crash would happen.

    In order to solve this problem, as most of you know, I had to learn about Hooking to make Wow's thread run the code that I want.

    2 - Hooking - The one I'm currently using
    The idea behind it is great and comprehensible. However, I found it a little hard to implement, because, well, it's Assembly. Indeed, there are other great methods and libraries out there to help and ease hooking, but I'm one of those guys that like to learn and suffer a little. My bot was made with that purpose: learning. So I left behind everything (Detours, EasyHook, BlackMagic and other stuff...) and decided to implement my own method, described below:



    In order to pass the parameters, I used the code:
    Code:
    call dummy
    dummy: pop edx
    sub edx, 0x114
    So, EDX+0x4 contains the address of the to-be-called function (offset + Wow base address), EDX+0x8 contains the "flag" (if 0, it runs the code), EDX+0xC contains the parameters, for example, "DoEmote("dance")" for LuaDoString() or the Player Address, etc. In the case of UnitReaction, I move the return value to EDX+0x14 which is later read.

    As you guys can see, whenever I need to call a function, I just inject its calling structure in that "NOP Region". The parameters are all written on the "green area" of the picture. The function parameters are located in the BYTE command[255], so, sometimes, I write a sequence os chars for Lua_DoString, others I write the Player Base Pointer for UpdateDisplayInfo and so on. The address of these functions are written in the "function_to_be_called_pointer" and passed into EBX register. Therefore, all the calls must be like "call ebx", as seen on the right side of the picture. The flag is just a parameter to control the execution so that it doesn't call UpdateDisplayInfo infinitely.

    Below is the code on what I have to do to call each of these functions. Notice that UnitReaction() is the only function that I really read the EAX after calling the function because that's where the value (1-Hated, 2-Hostile, etc) is returned. And that "loop" to detect if the result was changed meaning that the function was called and returned something... is, at least for me, a little ugly, but it was the first idea that came to my mind...
    Code:
    void Lua_DoString(string cmd){
    	char comando[255];
    	if(loaded == 0){
    		InjectHooking();
    	}
    	convertToASCII(cmd,comando);
    	mainThread = OpenThread(THREAD_ALL_ACCESS,false,mainThreadID);
    	SuspendThread(mainThread);
    	func = reinterpret_cast<unsigned int>(module.modBaseAddr) + Framescript_ExecuteBuffer;
    	mydata.funcptr = func;
    	mydata.flag = 0;
    	WriteProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + FunctionASMOffset), &ASMLua, 15, NULL);
    	WriteProcessMemory( Handle2, pLibRemote, &mydata, sizeof(mydata), NULL);
    	WriteProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + 0xC), &comando, sizeof(comando), NULL);
    	ResumeThread(mainThread);    
    }
    
    
    void UpdateDisplay(DWORD pTarget){
    	if(loaded == 0){
    		InjectHooking();
    	}
    	if(pTarget != 0){
    		mainThread = OpenThread(THREAD_ALL_ACCESS,false,mainThreadID);
    		SuspendThread(mainThread);
    		func = reinterpret_cast<unsigned int>(module.modBaseAddr) + UpdateDisplayInfo;
    		mydata.funcptr = func;
    		mydata.flag = 0;
    		WriteProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + FunctionASMOffset), &ASMUpdate, 20, NULL);
    		WriteProcessMemory( Handle2, pLibRemote, &mydata, sizeof(mydata), NULL);
    		WriteProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + 0xC), &pTarget, 4, NULL);
    		ResumeThread(mainThread);    
    	}
    }
    
    int UnitReaction(DWORD player, DWORD pTarget){
    	int wait = 0, waitf = 0;
    	ReadProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + 0x14), &wait, sizeof(wait), NULL);
    	wait = waitf;
    	if(loaded == 0){
    		InjectHooking();
    	}
    	if(pTarget != 0){
    		mainThread = OpenThread(THREAD_ALL_ACCESS,false,mainThreadID);
    		SuspendThread(mainThread);
    		func = reinterpret_cast<unsigned int>(module.modBaseAddr) + GetUnitReaction;
    		mydata.funcptr = func;
    		mydata.flag = 0;
    		WriteProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + FunctionASMOffset), &ASMUnitReaction, 20, NULL);
    		WriteProcessMemory( Handle2, pLibRemote, &mydata, sizeof(mydata), NULL);
    		WriteProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + 0xC), &player, 4, NULL);
    		WriteProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + 0x10), &pTarget, 4, NULL);
    		ResumeThread(mainThread);   
    	}
    	while(wait == waitf){
    		ReadProcessMemory( Handle2, reinterpret_cast<void*>(reinterpret_cast<unsigned int>(pLibRemote) + 0x14), &waitf, sizeof(waitf), NULL);
    		Sleep(1);
    	}
    	return waitf+1;
    }
    The good thing about this method is that... it works! Even if I call Lua_DoString() and then UpdateDisplayInfo() right after, no crashes happen and everything works just fine since Wow's thread is doing the work.

    Although everything is working, dealing with Assembly like this is a headache.
    - For every new function that I decide to call, I will have to reverse it and look at how the parameters are passed and WriteProcessMemory() the parameters on the BYTE cmd[255].
    - My code is filled with NOPs to reserve space and overwrite a previous injected function, afterall, their sizes are different. So yeah, if you look at my code, it's ugly, at least for me.

    So I decided to learn more about DLL Injection, since I could create function pointers that would do all the Assembly work for me.

    3 - DLL Injection without Hooking
    In this method, I just injected a DLL that would call a certain function. No assembly was needed, but, for example, in order to call UpdateDisplayInfo(), I had to put in the DLL all the ObjectManager functions to iterate through all objects and find the player. Besides that, I couldn't change the UpdateDisplayInfo() parameter, for example, if I decide to pass some Unit's address. When I say "I couldn't" it's not because it isn't something possible, but because I really don't know how to do it, if there's a way.

    And although it worked sometimes, others it would crash like the CreateRemoteThread() method, for reasons that I think that are the same.

    4 - DLL Injection with Hooking
    On the previous method, I just injected a DLL and ran its function which would call UpdateDisplayInfo(). In this one, I actually allocated memory and injected ASM similar to the 2nd method I described, but now, in a more managed way, like below:
    Code:
    typedef void (__thiscall * UpdateDisplayInfo)(DWORD arg1, DWORD arg2);
    typedef int (__cdecl * DoString)(const char *arg1, const char *arg2, int arg3);
    __declspec(naked) void codeasm(){
    	DWORD player_base;
    	int flag;
    	__asm{
    		nop
    		pushad
    		pushfd
    		push ebp
    		mov ebp, esp
    		sub esp, __LOCAL_SIZE
    		mov player_base, 0x0
    		mov flag, 0x2
    	}
    	
    	if(flag == 1){
    		UpdateDisplayInfo(base + 0x3f7390)(player_base,1);
    	}else if(flag == 2){
    		DoString(base + 0x54ee6)(cmd,cmd,0); // yeah, it's a variable located in the DLL
    	}
    	flag = 0;
    
    	__asm{
    		mov esp, ebp
    		pop ebp
    ab:             popfd
    		popad
    		nop
    		mov		eax, edi
    		pop		edi
    		pop		esi
    		pop		ebp
    		ret
    		nop
    	}
    }
    With this method, I don't need to worry about writing an Assembly structure for each function that I want to call since I'm using fuction pointers and I just need to change the flag to the desired function. I did a bunch of modifications in the above function, for example, setting "flag" and "player_base" as global variables and it would work just fine. The above code isn't totally accurate because I was experimenting some stuff, but I think you guys got the idea of "calling in a managed way" the functions. The issues with this method that I found are:
    - Again, what if I want to call UpdateDisplayInfo() on another Unit instead of the Player? How will I change that parameter from my executable (the one that injected the DLL)?
    - The DLL will be loaded on Wow's process, which, for me, isn't something safe. Not to mention that all the exported functions are shown, which is something that, as of now, I don't know how to hide.
    - Ok, I'm calling the functions in a "managed way", but, it's still quite ugly if I have to add a bunch of "if's" for every function that I decide to call. And how about their parameters? Ok if they are in the DLL, but what if I want to unload the DLL?

    What I tried to accomplish with this method is:
    1 - Inject my DLL
    2 - The DLL injects my codeasm() function which has little ASM and calls Wow functions with function pointers
    3 - Unload the DLL but with the code already injected
    4 - Pass different parameters easily to the functions in the stub. Therefore, the variables must not refer the DLL at any point.

    1, 2 and 3 are ok... but 4, I have no idea on how to do it, not even if that's possible.

    Anyways, this post got bigger than I expected so I'm ending it soon. As you guys can notice, I'm quite lost and having a hard time to find the best way to do what I want. If you read until now and have some light to share with me, I'd appreciate it a lot! Feel free to criticize the methods I've tried and even my behaviour in "not wanting to use something that is already done" like Detours, BlackMagic, etc (although I barely know what they do exactly or even how to use them). I think that most of my problems would be solved and I would have learned a lot more if I had opened the source of my code and had someone else to help me out with this stuff. But I haven't done this yet, because my code is ugly and poorly object-oriented. But if you guys need more details to help me out, I will do my best to provide them.

    Finally, I didn't touch the "security" subject, because I think I'm quite behind on other basic principles. What I can say is just that I hook where I think Warden doesn't scan, but I don't know exactly how to protect against it. I also don't know what the safest method is among all of these that I tried... so yeah, I don't have much to say about security. Maybe some other time...

    Aaaand that's basically it. Thanks a lot for your attention and I apologize for the long post

    PS: I probably forgot to add or explain something somewhere... but I guess this is enough to get a general idea of what I want...
    PS2: Again, feel free to bash this post if needed. I'm open to any feedback... Even a "Yo, learn C#" will be considered...
    Last edited by reliasn; 12-17-2013 at 04:28 PM.

    [C++] [Help] Different methods of calling Wow functions (DLL Injection, Hooking, etc)
  2. #2
    migtron's Avatar Corporal
    Reputation
    18
    Join Date
    Jun 2010
    Posts
    22
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by reliasn View Post
    1 - Inject my DLL
    2 - The DLL injects my codeasm() function which has little ASM and calls Wow functions with function pointers
    3 - Unload the DLL but with the code already injected
    4 - Pass different parameters easily to the functions in the stub. Therefore, the variables must not refer the DLL at any point.
    So this is what you are doing:
    1. Inject code into the WoW process (in the form of a DLL)
    2. Inject more code, which is injected by the code you injected in step 1
    3. Remove the code which injected the code in step 2

    My advice: Stop after step 1. As you have full control over your own DLL, it should already contain all the code you ever need, which you direct your hooks to.
    How you get information to your code (in your case which unit to process) is less a question about code injection and more a question about general software architecture. You could have a whole GUI loaded with your DLL. Or inject your own LUA functions to communicate with it. Or you use a network connection. Shared mapped memory. The file system. The choice is yours!

  3. #3
    573737534947's Avatar Corporal
    Reputation
    38
    Join Date
    Jul 2013
    Posts
    20
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Regarding your point 4, your basically in the need of some IPC mechanism. In your 2nd approach you (ab)use WriteProcessMemory as such if I understand you right. If you're using a compiled language you can consider to go all injected which saves you some hassle. The size of your code blob doesn't limit your ability to hide. If not something like your second approach is probably the most straightforward. Just allocate a piece of memory or find a code cave, write your code there, it should basically check some part of your code cave as flag that you can set from outside through WPM, and jump to another part of the code cave, if the flag is set, where you can write arbitrary instructions via WPM, hook a function to your code cave and you're done. If you need return values your 2nd stage payload can drop them at a reserved place in your code cave where you can read them via RPM. There's your poor man's IPC, but it's gonna work. Just write your code, set the flag, wait for the return buffer to be filled.

  4. #4
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can inject your code without either DLL injection or hooking.
    You can simply modify EIP using SetThreadContext: [C#] ASM Injection (SetThreadContext)

  5. #5
    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)
    Originally Posted by Xartrick View Post
    You can inject your code without either DLL injection or hooking.
    You can simply modify EIP using SetThreadContext: [C#] ASM Injection (SetThreadContext)
    Or just write the string "plz crash" to (char*)0 to get more reliable crash behavior.

  6. #6
    573737534947's Avatar Corporal
    Reputation
    38
    Join Date
    Jul 2013
    Posts
    20
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Xartrick View Post
    You can inject your code without either DLL injection or hooking.
    You can simply modify EIP using SetThreadContext: [C#] ASM Injection (SetThreadContext)
    Did you even try that? Bananenbrot is right, you can execute code without side effects (read: useless code) that way. If you're going to steal the pc, you better know from where.

  7. #7
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I already used DLL injection in past, and I compared both methods.
    I prefer the current I explained, just my point of view.

  8. #8
    573737534947's Avatar Corporal
    Reputation
    38
    Join Date
    Jul 2013
    Posts
    20
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Xartrick View Post
    I already used DLL injection in past, and I compared both methods.
    I prefer the current I explained, just my point of view.
    The method will crash when it calls a function that's not reentrance safe which is almost always the case. In most functions lots of state is involved, which will be altered through your reinvocation setting it up for a crash as soon as you resume normal execution. If you have no control from where you pick up execution but invoke stateful functions that are called by the victim process, too, you will have state collision at some point. This is no theoretical issue but can be experienced almost immediately by anyone who tries it.

  9. #9
    Jadd's Avatar 🐸 Premium Seller
    Reputation
    1511
    Join Date
    May 2008
    Posts
    2,432
    Thanks G/R
    81/333
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Xartrick View Post
    You can inject your code without either DLL injection or hooking.
    You can simply modify EIP using SetThreadContext: [C#] ASM Injection (SetThreadContext)
    This is a seriously unsafe and slow method to execute from the main thread. Not to mention redundant; there's no real reason to avoid in-process hooking.

Similar Threads

  1. Cant access any wow function from injected dll
    By Kwapuzzi in forum WoW Memory Editing
    Replies: 8
    Last Post: 11-01-2012, 01:58 PM
  2. Calling WoW functions C++
    By f3lix in forum WoW Memory Editing
    Replies: 3
    Last Post: 03-20-2010, 10:00 AM
  3. Need a little help for free time of WoW =(
    By Pwnnned in forum World of Warcraft General
    Replies: 3
    Last Post: 06-09-2007, 11:40 AM
  4. Can someone help me get onto a WoW private server?
    By hyacary in forum Gaming Chat
    Replies: 1
    Last Post: 01-25-2007, 03:14 PM
All times are GMT -5. The time now is 07:38 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