2024-11-06 06:46:35 +08:00

164 lines
2.5 KiB
C++

#pragma once
enum class regs
{
_flags,
#ifndef _WIN64
eax,
ecx,
edx,
ebx,
esp,
ebp,
esi,
edi,
flags,
#else
rax,
rbx,
rcx,
rdx,
rsp,
rbp,
rsi,
rdi,
r8,
r9,
r10,
r11,
r12,
r13,
r14,
r15,
#endif
invalid
};
inline int get_stack(int s)
{
#ifdef _WIN64
return s * 8;
#else
return s * 4;
#endif
}
inline int get_reg(regs reg)
{
#ifdef _WIN64
return -8 * (int)reg - 8;
#else
return -4 - (int)reg * 4;
#endif
}
inline uintptr_t regof(regs reg, hook_stack *stack)
{
switch (reg)
{
#ifndef _WIN64
case regs::eax:
return stack->eax;
case regs::ecx:
return stack->ecx;
case regs::edx:
return stack->edx;
case regs::ebx:
return stack->ebx;
case regs::esp:
return stack->esp;
case regs::ebp:
return stack->ebp;
case regs::esi:
return stack->esi;
case regs::edi:
return stack->edi;
#else
case regs::rax:
return stack->rax;
case regs::rbx:
return stack->rbx;
case regs::rcx:
return stack->rcx;
case regs::rdx:
return stack->rdx;
case regs::rsp:
return stack->rsp;
case regs::rbp:
return stack->rbp;
case regs::rsi:
return stack->rsi;
case regs::rdi:
return stack->rdi;
case regs::r8:
return stack->r8;
case regs::r9:
return stack->r9;
case regs::r10:
return stack->r10;
case regs::r11:
return stack->r11;
case regs::r12:
return stack->r12;
case regs::r13:
return stack->r13;
case regs::r14:
return stack->r14;
case regs::r15:
return stack->r15;
#endif
}
return 0;
}
#ifndef _WIN64
#define ARG1 stack[1]
#define ARG2 stack[2]
#define ARG3 stack[3]
#define LASTRETVAL eax
#define THISCALL __thiscall
#define THISCALLTHIS ecx
#define THISCALLARG1 stack[1]
#define GETARG1 get_stack(1)
#define GETARG2 get_stack(2)
#define GETARG3 get_stack(3)
#define GETARG4 get_stack(4)
#else
#define ARG1 rcx
#define ARG2 rdx
#define ARG3 r8
#define LASTRETVAL rax
#define THISCALLTHIS rcx
#define THISCALLARG1 rdx
#define THISCALL
#define GETARG1 get_reg(regs::rcx)
#define GETARG2 get_reg(regs::rdx)
#define GETARG3 get_reg(regs::r8)
#define GETARG4 get_reg(regs::r9)
#endif
inline uintptr_t *argidx(hook_stack *stack, int idx)
{
#ifdef _WIN64
auto offset = 0;
switch (idx)
{
case 1:
offset = get_reg(regs::rcx);
break;
case 2:
offset = get_reg(regs::rdx);
break;
case 3:
offset = get_reg(regs::r8);
break;
case 4:
offset = get_reg(regs::r9);
break;
default:
offset = get_stack(idx);
}
return (uintptr_t *)((uintptr_t)stack + sizeof(hook_stack) - sizeof(uintptr_t) + offset);
#else
return (uintptr_t *)((uintptr_t)stack + sizeof(hook_stack) - sizeof(uintptr_t) + get_stack(idx));
#endif
}