LunaHook-mirror/LunaHook/stackoffset.hpp
2024-05-10 14:07:26 +08:00

129 lines
2.4 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
}