Code:
void __declspec(naked) RunScriptAsm()
{
__asm {
mov eax, dword ptr FS:[0x2c]
mov eax, [eax]
add eax, 8
mov dword ptr [eax], 0xDEADBEE0 // patch with Mgr
push 0xDEADBEE3 // address of ""
push 0xDEADBEE2 // address of "DoEmote(\"dance\")"
push 0xDEADBEE1 // address of "DoEmote(\"dance\")"
mov eax, 0x0077DEF0 // lua_RunScript
call eax
add esp, 12 // cleanup my args off the stack
retn
}
}
void Monkey()
{
BYTE DanceString[] = "DoEmote(\"dance\")";
int DanceStringLength = sizeof(DanceString) + sizeof(DanceString) % 4;
BYTE AsmBuffer[0x100];
int AsmBufferLength = sizeof(AsmBuffer);
int TotalBufferLength = AsmBufferLength + DanceStringLength;
// Alloc some mem in their space
void *pvBase = VirtualAllocEx(hProcess, 0, TotalBufferLength, MEM_COMMIT, PAGE_READWRITE );
// Unprotect the page
DWORD old;
VirtualProtectEx(hProcess, pvBase, TotalBufferLength, PAGE_EXECUTE_READWRITE, &old);
// Write out DoEmote("dance") in their space. 17 bytes in including the null.
WriteProcessMemory(hProcess, pvBase, DanceString, sizeof(DanceString), NULL);
BYTE *pvAsm = (BYTE*)pvBase + DanceStringLength;
// Copy assembly in a local buffer
memcpy(AsmBuffer, RunScriptAsm, sizeof(AsmBuffer));
// Patch up the local buffer withour params
DWORD db = 0xDEADBEE0;
PatchMem(AsmBuffer, sizeof(AsmBuffer), &db, sizeof(db), &Mgr);
db = 0xDEADBEE1;
PatchMem(AsmBuffer, sizeof(AsmBuffer), &db, sizeof(db), &pvBase);
db = 0xDEADBEE2;
PatchMem(AsmBuffer, sizeof(AsmBuffer), &db, sizeof(db), &pvBase);
db = 0xDEADBEE3;
DWORD tmp = (DWORD) pvBase + sizeof(DanceString) - 1; // point to the null term
PatchMem(AsmBuffer, sizeof(AsmBuffer), &db, sizeof(db), &tmp);
// Jam the local buffer into their space
WriteProcessMemory(hProcess, pvAsm, AsmBuffer, sizeof(AsmBuffer), NULL);
DWORD ThreadId;
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) (BYTE*)pvAsm, NULL, NULL, &ThreadId);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProcess, pvBase, TotalBufferLength, MEM_RELEASE);
}