All-
So I've been following the UsePower wrapper thread (usepower wrapper) and was hoping to get some help on OS X. I feel like I'm 90% there thanks to everyone's contributions.
Overall (given it's a usercall vs. stdcall) it sounds like you just need to set up the registers before calling UsePower. Sounds pretty simple, and of course I'm running into problems.
On OS X this is how the function call is set up (4 different ways): [ASM (NASM)] // call 1 mov edx, [ebx+4] add edx, 7F44h lea eax, [ebp+var_1C] - Pastebin.com
Here is a summary of what registers should be set to before the call (to my knowledge):
Code:
eax = ptr to RActor struct
ebx = edx
ecx = 1
edx = pointer to UsePowerStruct = ebx (by chance?)
esp = unk
ebp = unk
esi = world id
edi = ptr to string (ex: ActorCommonData)
Here is how I'm attempting to do a wrapper. I have a feeling I'm doing something wrong with the stack pointer (I should push 2 arguments onto it I believe, especially given the user call shows 5 arguments in IDA, even though the first 3 are in registers):
Note: It's AT&T assembly syntax, yay GCC :/ It goes opcode src, dest
Code:
//signed int __usercall UsePower<eax>(int a1<eax>, int a2<edx>, int a3<ecx>, int a4, int a5)
__declspec(naked) void _use_power(int SpellID);
__declspec(naked) void _use_power(int SpellID){
const char *model = "Demonhunter_Female-5";
int ptr = 0;
// create our spell struct
UsePowerStruct MyStruct;
MyStruct.SpellToCast = SpellID; // spell we are trying to cast
MyStruct.SpellActual = SpellID; // actual spell that is cast (ex: if you are out of arcane power, it would cast the wand spell...)
MyStruct.guid = 0x2; // hard coding to test
MyStruct.unk = -1;
MyStruct.x = 3110.821533; // hard coding to test
MyStruct.y = 2832.733643;
MyStruct.z = 59.075588;
MyStruct.WorldID = 0x772E0000; // worldid
MyStruct.unk3 = -1;
MyStruct.Type = 0;
// create our RActor struct
RActor RActorStruct;
RActorStruct.RActorGuid = 0x77E21234; // hard coding to test
RActorStruct.ACDGuid = 0x77BC0000; // hard coding to test
memcpy(&RActorStruct.Name, model, sizeof(RActorStruct.Name));
RActorStruct.Name[20] = '\0';
// Step 1: Copy a ptr to -1 into eax
//lea eax, [ebp+var_1C]
int value = -1;
ptr = (int)&value;
//__asm__ __volatile__("movl %0, %%eax" : "=g" (ptr));
// Step 2: Move eax ptr (to -1) into [esp+4]
//mov [esp+4], eax
ptr = (int)&value;
//__asm__ __volatile__("movl 4(%esp), %eax");
// Step 3: Move 1 into eax
//mov eax, [ebp+var_B0]
__asm__ __volatile__("movl $1,%eax");
// Step 4: Move ptr to 1 into esp
//mov [esp], eax
ptr = (int)&value;
//__asm__ __volatile__("movl %0, %%esp" : "=g" (ptr));
// Step 5: Move 1 into ecx
//mov ecx, eax
__asm__ __volatile__("movl $1,%ecx");
// Step 6: Move spell struct into edx and ebx
//mov edx, ebx
ptr = (int)&MyStruct;
__asm__ __volatile__("movl %0, %%edx" : "=g" (ptr));
__asm__ __volatile__("movl %0, %%ebx" : "=g" (ptr));
// Step 7: Copy RActor struct ptr into eax
//mov eax, [ebp+var_AC]
ptr = (int)&RActorStruct;
__asm__ __volatile__("movl %0, %%eax" : "=g" (ptr));
//call UsePower
__asm__ __volatile__("movl $0x7028f0,%ebx"); // call the real UsePower
__asm__ __volatile__("call *%ebx");
}
And the structs:
Code:
struct RActor{
int RActorGuid;
int ACDGuid;
char Name[128];
};
struct UsePowerStruct{
int SpellToCast; // 0x777C = walk
int SpellActual; // 0x777C = walk
int guid; // like 2
int unk; // -1 (TargetACDId)
float x;
float y;
float z;
int WorldID; // 0x772E0000;
int unk3; // -1
int Type; // 1 for skill , 0 for walk/interact
};
I've hardcoded the structs just to get 1 call working, as I haven't been able to get that far. Oddly enough if I comment out the statements around esp UsePower will be called but eventually errors out when it gets further into the function (probably due to me corrupting the stack in some way).
Anyone have any ideas on how I can correct this? And if you'd like to see the pseudocode for UsePower: http://pastebin.com/wPXVgq2J
Thanks in advance!
~ Tanaris