WoW Memory EditingWoW Memory Editing for learning purposes only.
This section is more advanced than others on MMOwnedRead the section specific rules, infractions will be given out if u break them!That is including the expectations! - If you don't meet them then don't post
If you're using C++, is there ANY reason to be out of process? Anyway, I would say make an inline function and put an asm block in it. Much nicer. Then you can just copy the bytes out of that function into the process and execute it. I don't really see any problem with that asm, but you never know when it's in shellcode...
Is there a reliable way to determine the length of a C/C++-function?
Another problem is that most compilers will create a stackframe etc even if your function is just something like this
Code:
void nothing()
{
asm {"mov eax, 1"}
}
Donate to remove ads, get your "DONATOR title, and get access to the MMOwned community's elite Shoutbawx.
I don't think they do if you do __declspec(naked). I don't remember exactly how to do it, but there's a DLL injection tutorial on edgeofnowhere.cc and it shows how it's done. It's not really C++, more C-like.
Still don't have lua_DoString() working. Had to change my shellcode and source too few times, but didn't help(((
New code with debug inlines (just to check there's no mess with addresses ):
Code:
int Lua_DoString(char *luastr)
{
FILE* f;
int res;
char olo1[50];
char olo2[50];
void* strmem;
DWORD codemem;
char shellcode[]=
"\x8B\x15\xB0\x05\x27\x01\x8B\x92\x94\x2D\x00\x00" //MOV EDX,DWORD PTR DS:[12705B0]; MOV EDX,DWORD PTR DS:[EDX+2D94]
"\x64\xA1\x2C\x00\x00\x00\x8B\x00\x83\xC0\x08" //MOV EAX,DWORD PTR FS:[2C]; MOV EAX,DWORD PTR DS:[EAX],ADD EAX,8
"\x89\x10\x6A\x00\xB8\x78\x56\x34\x12" //MOV DWORD PTR DS:[EAX],EDX,PUSH 0; MOV EAX,12345678 - luastr addr
"\x50\x50\xE8\x89\xF6\x7C\x00\x83\xC4\x0C" //PUSH EAX,PUSH EAX,CALL 007CF6B0,ADD ESP,0C
"\xC3";//retn
f=fopen("D:\\crack\\hiew\\code.txt","wb");
ReadProcessMemory( hProc, (LPVOID)(0x0133D5B0), (LPVOID)&res, sizeof(res), NULL );
while (res!=0)
{
ReadProcessMemory( hProc, (LPVOID)(0x0133D5B0), (LPVOID)&res, sizeof(res), NULL );
Sleep(0);
}
SuspendThread(mThread);
strmem=VirtualAllocEx(hProc,NULL,1024,MEM_COMMIT,PAGE_READWRITE);
if (strmem==NULL)
ShowMessage("Can't alloc some mem");
ShowMessage(HexToStr((DWORD)strmem));// showing me luastr addr
WriteProcessMemory(hProc, strmem,&luastr[0],100,NULL);
codemem=(DWORD)VirtualAllocEx(hProc,NULL,1024,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (codemem==NULL)
ShowMessage("Can't alloc some mem");
WriteProcessMemory(hProc, (LPVOID)codemem,&shellcode[0],sizeof(shellcode),NULL);
WriteProcessMemory(hProc, (LPVOID)(codemem+28),&strmem,sizeof(codemem),NULL);// fixing luastr addr
ReadProcessMemory( hProc, (LPVOID)(codemem), (LPVOID)&olo1[0], 50, NULL );//check if code is written
ReadProcessMemory( hProc, (LPVOID)(strmem), (LPVOID)&olo2[0], 50, NULL );// check if luastr is written
fwrite(&olo1[0],1,50,f);//writing shellcode from wow to file
fwrite(&olo2[0],1,50,f);//writing luastr from wow to file
HANDLE rThread=CreateRemoteThread(hProc,NULL,0,(PTHREAD_START_ROUTINE)codemem,NULL,0,NULL);
WaitForSingleObject(rThread, 10000);
CloseHandle(rThread);
ResumeThread(mThread);
if(!VirtualFreeEx(hProc,(LPVOID)strmem,NULL,MEM_RELEASE)) ShowMessage ("Can't free mem");
if(!VirtualFreeEx(hProc,(LPVOID)codemem,NULL,MEM_RELEASE)) ShowMessage ("Can't free mem");
fclose(f);
return 0;
}
And here's code.txt 0xA040000 is the luastr's address
And here's what was read from 0x0A040000
As you can see luastr is really there.
But anyway i get this
and this
If anyone has an idea what's wrong with my code please share your thoughts. I'd be very grateful. guaranteed!
how do you get this "100"? The lua string isn't that big. Couldn't it be that the random values which are lying in the memory after the luastr array make it crash?
you have allocated 1024 bytes for codemem. however, you write sizeof(codemem) = 1024 starting from offset 28. You overwrite the following 28 bytes in memory. My opinion is that the length has to be sizeof((DWORD)codemem) //Edit
args. forget about it. codemem is just a longpointer... so sizeof(codemem) = 8 bytes, not 1024. i'm letting it here that some other beginner may use it...
please correct me if i'm wrong since I want to improve my knowledge in this area :-)
This 100 is taken for debugging only. PoC luastr is less.
As you can see it in hiew screen luastr is terminated by zero byte. So it doesn't matter what comes next.
codemem is a pointer to the begining of allocated memory. So sizeof codemem is 4 because codemem is DWORD. So i overwrite 4 bytes starting 28 bytes from the begining.
Look at my code and hiew screens. It shows that shellcode and luastr are written alright and that pointer to luastr is fixed in shellcode. But fjr the reason i don't know wow crashes((
this is the code which remains when removing/combining all stuff into a minimum.
my questions:
- what is the purpose of overwriting global data in the wow address space to call a function oO? why do we need this g_clientConnection + s_curMgrOffset here?
- sure that it is TLS[2] that you have to overwrite? In the post from qjlex on page one of the thread, he overwrites TLS[4], so TLS + 16
what is the purpose of overwriting global data in the wow address space to call a function oO?
And what i overwrite? I allocate some free memory in wow, write there code and data, fixing pointer to data, execute code, free memory. Nothing's overwritten.
We need g_clientConnection + s_curMgrOffset to get TLS. And have you read all topic?
Look at it [Only registered and activated users can see links. ]
and this
you are right. seems that i've missed some part on page 1 since it all looks similar and i've lost the overview.
my guess about "overwriting" was that you read TLS base pointer via "FS mov EAX, [0x2C]", dereference via "mov EAX, [EAX]" and jump to offset 2 via "add EAX, 8". then you write edx = g_clientConnection + s_curMgrOffset to the location where EAX currently points to (which is [TLS[2 * 4]] ), thus overwriting what stood there before.
well, now that i've seen qjlex's second post it's clear that the asm cannot be the problem source since he got the same one except that he has allocated a 0x2048 block ( = 8264 bytes) for the code AND the string (which shouldn't make a difference) instead of taking two 1024 byte ones. (i think that he forgot that he wants to use decimal numbers and put the 0x before by accident)
your writeprocessmemory's cannot be the problem source either since they are stored properly. (maybe, the MEM_RESERVE flag should be also set with the MEM_COMMIT flag?)
one other possible thing could maybe be that you don't immediately suspend the wow thread when the lua lock gets released. instead, you yield with sleep(0) and check afterwards, if the outdated value of the lock states "lock was released". the wow thread could acquire it again in the meantime, ****ing it up and crashing.
ps: to the "We need g_clientConnection + s_curMgrOffset to get TLS." Sorry for bothering, but don't we get the TLS via "FS mov eax, [0x2C]" regardless of what we have computed in edx?
pps: why is the realm IP intact in the wowerror message, but the whole rest not... strange
ppps: what is it exactly which causes the crash? does it also crash if you don't call luaDoString actually? does it crash as soon as there is some assembler code you execute? does it crash even if you don't ever execute your assembler code?
I've searched in Google. [Only registered and activated users can see links. ]
All have similar code. [Only registered and activated users can see links. ]
But i can't understand what's wrong in my case. Gonna view BM's sources to undrstand what's the source of my problem. And check if lua lock is released when calling DoString.
10x for ideas.
found another difference between yours and the working ones:
you don't have set the PAGE_EXECUTE_READWRITE flag to the luastr memory. instead, you just set PAGE_READWRITE. don't think that it makes the difference since the luastr isn't executed anyways. but trying cannot make it worse.
pps: why is the realm IP intact in the wowerror message, but the whole rest not... strange
All that data is safe. I play on Russian server and the rest is unicode strings in ascii mode.
Quote:
ppps: what is it exactly which causes the crash? does it also crash if you don't call luaDoString actually? does it crash as soon as there is some assembler code you execute? does it crash even if you don't ever execute your assembler code?
No. It crashes only when i call lua_DoString(). I click the button (that calls lua_DoString) and in few seconds i have err. I tried to inject another shellcode. It was
It's a NOP line with retn in the end. It does nothing. With this shellcode this function works fine, no crashes. So i suppose the source of the evil is my shellcode.
I also checked lua lock. It's always released (0) when i inject and call my code.
Now gonna debug it with int 3 (CC opcode). And how should i call function. I looked at opcode table. opcode for call is E8. But also FF 15. First is near call, second is far (as i understand). But don't understand waht should i use.
This makes absolutly no sense. You are attempting to load the Object-Manager address (incorrectly) and then you overwrite it...
WoW does it like this:
Code:
.text:00476580 mov ecx, large fs:2Ch // fs points to TEB, 0x2C is the offset to the storage-pointer
.text:00476587 mov eax, TlsIndex // Index of the storage is loaded
.text:0047658C mov edx, [ecx+eax*4]
.text:0047658F mov ecx, [edx+8]
But qjlex here [Only registered and activated users can see links. ] says that this works for him. My code's the same. And everywhere on forum it looks similar [Only registered and activated users can see links. ]
that's what i've meant with "overwriting". gave the idea up after i saw that the other implementation does the same thing with success. However, I don't understand why you have to patch those addresses even... just taking it as given that it is necessary.
This doesn't crash wow now. Hm.... so call was the source of problems?
But i don't understand what is wrong. How to fix it? And maybe should i allocate 1 block of memory for both code and luastr?