Code:
public static uint StringToInt = 0x6A6F10;
public static uint ObjectByGuid = 0x46DB20;
public static uint UpdateModel = 0x6806D0;
public static uint StringToFloat = 0; // ?
/// <summary>
/// Function that will be called once the user enters 'morph [arg]'.
/// Morphs the localplayer's target.
/// TODO: Get ObjectByGuid to work via ASM, find a StringToFloat function.
/// </summary>
/// <param name="w"></param>
/// <returns></returns>
public static uint MorphFunctionASM(BlackMagic w)
{
// Codecave + offsets that'll hold certain values for further use
uint dwCodeCaveMorphF = 0;
uint dwMorphId = 0x2500;
uint dwMorphScale = 0x2600;
uint dwMorphTargetBase = 0x2700;
uint dwLocalPlayer = 0x2800;
if (Program.I(w)) // wrapper for 'bool OpenProcessAndThread(..)'
{
dwCodeCaveMorphF = w.AllocateMemory(0x3000); // teh bigz
dwMorphId += dwCodeCaveMorphF;
dwMorphScale += dwCodeCaveMorphF;
dwMorphTargetBase += dwCodeCaveMorphF;
dwLocalPlayer += dwCodeCaveMorphF;
w.Asm.Clear();
// get the 2 arguments
w.Asm.AddLine("push esi");
w.Asm.AddLine("call {0}", StringToInt); // ret 4
w.Asm.AddLine("mov [{0}], eax", dwMorphId); // <- 1st arg, ID; TODO: cmp eax, 0 -> je to end
w.Asm.AddLine("add edx, 1");
w.Asm.AddLine("push edx");
w.Asm.AddLine("call {0}", StringToInt);
w.Asm.AddLine("mov [{0}], eax", dwMorphScale); // <- 2nd arg, Scale, currently an int
// s_curMgr
w.Asm.AddLine("mov eax, [0x11CB310]");
w.Asm.AddLine("mov eax, [eax+0x28A4]");
w.Asm.AddLine("mov edx, eax");
// TIB
w.Asm.AddLine("xor eax, eax");
w.Asm.AddLine("fs mov eax, [0x2C]");
w.Asm.AddLine("mov eax, [eax]");
w.Asm.AddLine("add eax, 8");
w.Asm.AddLine("mov dword [eax], edx");
// get the local player
w.Asm.AddLine("mov eax, [0x127F13C]");
w.Asm.AddLine("mov eax, [eax+0x30]");
w.Asm.AddLine("mov eax, [eax+0x28]");
w.Asm.AddLine("mov [{0}], eax", dwLocalPlayer);
w.Asm.AddLine("mov ecx, eax");
// get targetguid of local player
w.Asm.AddLine("mov ecx, [ecx+0x8]");
w.Asm.AddLine("mov ebx, dword [ecx+0x13*4]"); // high
w.Asm.AddLine("mov edx, dword [ecx+0x12*4]"); // low
// objectbyguid
w.Asm.AddLine("xor eax, eax");
w.Asm.AddLine("push 0x86");
w.Asm.AddLine("push 0x92F3B0");
w.Asm.AddLine("push 0x10");
w.Asm.AddLine("push ebx"); // high
w.Asm.AddLine("push edx"); // low
w.Asm.AddLine("call {0}", ObjectByGuid);
w.Asm.AddLine("add esp, 0x14");
w.Asm.AddLine("mov [{0}], eax", dwMorphTargetBase);
// change target id
w.Asm.AddLine("mov eax, [eax+0x8]");
w.Asm.AddLine("add eax, 0x108");
w.Asm.AddLine("mov ebx, [{0}]", dwMorphId);
w.Asm.AddLine("mov dword [eax], ebx");
// call updateModel
w.Asm.AddLine("push 1");
w.Asm.AddLine("push 1");
w.Asm.AddLine("mov ecx, [{0}]", dwMorphTargetBase);
w.Asm.AddLine("call {0}", UpdateModel); // ret 8
// goodbye
w.Asm.AddLine("retn");
w.Asm.Inject(dwCodeCaveMorphF);
}
return dwCodeCaveMorphF;
}
I know it's a pain to even read it, guess how much fun debugging was.