所以我正在为一个程序写一个'扩展'(确切地说是游戏)。这更像是一场黑客攻击。 无论如何,我正在扭转一些类,如角色,项目等。我想做出好的方法。
所以我做了这样的事情:
class CHARACTER
{
public:
int hp;
int level;
//....
int GetLevel(void);
void SetLevel(int lv);
};
#include "character.hpp"
int CHARACTER::GetLevel(void)
{
return ((int(*)(CHARACTER*))0xADDR)(this);
}
void CHARACTER::SetLevel(int lv)
{
((void(*)(CHARACTER*,int))0xADDR)(this,lv);
}
void hook1(CHARACTER* pc)
{
pc->SetLevel(99);
}
问题是,代码执行两次。你在hook1中推送参数 然后你再次在CHARACTER :: SetLevel(下面的伪asm)中推送它们: //////////////
hook1:
push 99
call CHARACTER__SetLevel
CHARACTER__SetLevel:
push arg
call 0xADDR
所以我试图跳转,因为你已经在堆栈上有所有参数,你可以跳转到该函数。问题是,'asm'添加了
push ebp
mov ebp, esp
void CHARACTER::SetLevel(int lv)
{
asm(".intel_syntax\n"
"mov eax, 0xADDR\n"
"jmp eax\n"
);
}
at the beginning. So I have to execute this code at address + 3
(If I'm making hook in only asm, I do something like this)
void hook_asm(void)
{
asm(".intel_syntax noprefix\n"
".whatever\n"
);
}
void MAIN_HOOK(void)
{
JmpPatch(0xADDR, &hook_asm+3); // Skip push ebp and mov ebp, esp
}
////////////////////
所以,我看到的唯一解决方案就是让它像
void asm_SetLevel(void)
{
asm(".intel_syntax noprefix\n"
"mov eax, 0xADDR\n"
"jmp eax\n"
);
}
CHARACTER::SetLevel(int lv)
{
((void(*)(void))&asm_SetLevel+3)();
}
但这不是我想要做的,除了每个方法都有2x函数。
有没有办法让它变得更好?
对不起我的英语和烂摊子,我尽力解释我的问题。 希望你能理解我的意思。
答案 0 :(得分:0)
将CHARACTER::SetLevel()
的定义移到头文件中,并将其标记为内联。