Hello Ownedcore!
One of the main issues with my bot is that I sadly have to ask for the user to set ALL the keys, such as, Interact with MouseOver, /cast Fishing, mount key, combat keys, etc. In order to avoid this, I decided once and for all to learn about this "function calling", where you simply call WoW function that does all the work for you. In this case, the function I want to call is the Lua_DoString() which, well, can be used to do everything, including interacting with targets, casting spells, etc. After reading a bunch of posts here in Ownedcore, I saw that most people were using the famous Blackmagic to manage memory along with C#. Since I use C++ and I don't know how to use Blackmagic nor I like to use managed libraries (not in this case, as my only purpose is learning), I decided to call this Lua_DoString() only by using CreateRemoteThread and WriteProcessMemory, which is the method greatly explained in this link.
So after a lot of tries and simulations into smaller projects, I finally managed to get it working. The main C++ code is the one below:
Code:
typedef struct {
DWORD funcptr;
char command[255];
} INJDATA;
__declspec( naked ) DWORD codeasm(){
__asm{
nop
push ebx //here we have address of funcptr, but I want the address of command on EAX so...
pop eax // remove from stack and pass it to EAX
add eax, 4 // add 4 to the address, therefore, now we have the address of char command[255]
push 0
push eax
push eax
mov edx, [ebx] //grab the content of EBX which is funcptr and pass to EDX
call edx // call Lua_doString()
add esp, 0xC //probably just "fixing" the stack pointer
nop
ret
};
//return 0;
}
static void after_codeasm (void) {
}
void convertToASCII(string letter, char x[255])
{
for(int j = 0; j <= 255; j++){
x[j] = 0x0;
}
for (int i = 0; i < letter.size(); i++)
{
x[i] = letter.at(i);
}
}
void Lua_DoString(string cmd){
void* Handle = ::Handle2;
DWORD func = reinterpret_cast<unsigned int>(module.modBaseAddr) + Framescript_ExecuteBuffer;
DWORD cbCodeSize = ((PBYTE) after_codeasm - (PBYTE) codeasm);
cbCodeSize = 200; // meh, I should actually check the size of codeasm() but whatever...
INJDATA mydata;
convertToASCII(cmd,mydata.command);
mydata.funcptr = func;
LPVOID pData = VirtualAllocEx( Handle, NULL, sizeof(func), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
LPVOID pLibRemote = VirtualAllocEx( Handle, NULL, cbCodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
WriteProcessMemory( Handle, pData, &mydata, sizeof(mydata), NULL);
WriteProcessMemory( Handle, pLibRemote, &codeasm, cbCodeSize, NULL);
HANDLE hThread = CreateRemoteThread(Handle, NULL, 0,(LPTHREAD_START_ROUTINE) pLibRemote, pData, 0, NULL );
if(hThread != 0){
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
VirtualFreeEx( Handle, pLibRemote, cbCodeSize, MEM_RELEASE );
VirtualFreeEx( Handle, pData, sizeof(func), MEM_RELEASE );
}
}
As you guys can see, it isn't that complicated the way I did it. I basically allocated 2 memory spaces, one to receive my ASM and another one to receive my 2 parameters: one holding the address of where my ASM code was injected and another holding the string converted to ASCII. The parameters and the ASM code are then written with WriteProcessMemory into WoW's thread. After that, I'm good to start the CreateRemoteThread(). This function will then open a new thread on WoW that will run my injected ASM which will then call Lua_DoString(). I copied most of the ASM from Vandra, who made this post here. However, in my case, I had to modify his ASM a little. I noticed with CheatEngine that when you do a simple /script DoEmote("dance") in WoW, the command is converted to ASCII and the register EAX receives the address where the command is. So when I was running the "call eax" from Vandra's code, it would call Lua_DoString() but EAX would be pointing to Lua_DoString(). This is why I had to use another register, EDX, while the EAX register I left with the address that points to my LUA command.
Anyways, I guess my method is quite complicated afterall and has a bunch of useless codes, but hey, it works so far. Although it's working, I've got a couple questions:
1 - Do I really need to allocate 2 memory spaces or is there a more intelligent/cleaner way of doing it?
2 - In the ASM code, there are 3 instructions that I didn't understand at all why they are there:
Code:
push 0
push eax
push eax
I didn't try yet with one single push eax, which for me, is enough, because I would probably be lost later on what I should "add" to later to the ESP. So is it really needed to have 3 "push" instructions like that?
3 - My knowledge about Warden is practically ZERO. The idea I have of it is: don't mess with the addresses that it scans. Since I'm allocating memory and then injecting code, I think I'm running a huge risk of writing something where Warden scans. So I take that, although Injection is quite risky, if I don't mess with the scanned addresses, I should be fine, correct? And for that, I should implement some sort of protection in my bot to avoid memory allocation or code injection in forbidden addresses, correct? Oooor... should I just leave this away and call Lua_DoString() without worrying too much?
4 - What would be a nice way of checking that my VirtualFreeEx() is actually working? It basically frees the allocated memory... so should I just open WoW, run my fishing bot and monitor WoW's memory in the Task Manager to see if it gets bigger and bigger over time? Or I could just check the return of VirtualFreeEx()?
Well, that's basically it, guys... As you probably noticed, I'm quite new to ASM, injection and I'm terrible at OOP. And yeah, I'm having a hard ****ing time to learn all of it, but it's been fun so far. Sometimes it's quite frustrating and others I just think it's impossible to do something... but damn, this is what I study at my college and what I want to work with in the future (not that I want to live making bots -_-... which wouldn't be a bad idea either considering the popularity of Honorbuddy haha, but anyways...).
Finally, feel free to post your comments and criticize whatever I did wrong or whatever could be done in a much simpler way. I'll see if I can answer my own questions right now by testing some stuff, but I'm mainly worried about Warden. I'm ready to replace all my "PostMessage()" in my bot... but I don't know if it's a good idea to just do it right away without having some sort of Warden protection...
Thanks a lot for your attention! And a special thanks to:
Vandra - for the ASM
TOM_RUS - Framescript_ExecuteBuffer offset
To whoever made CheatEngine <3 Damn, the way it shows what's inside each register is just... amazing!
And well, all the posts I read from googling "call interact site: ownedcore.com" and "call lua do string site: ownedcore.com"!