0

所以我正在为一个程序(确切地说是游戏)编写一个“扩展”。这更像是一种黑客行为。无论如何,我正在反转一些类,比如角色、项目等。我想做好的方法。

所以我做了这样的事情:

字符.hpp

class CHARACTER
{
public:

int hp;
int level;
//....



int GetLevel(void);
void SetLevel(int lv);

};

字符.cpp

#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 函数。

有没有办法让它变得更好?

对不起我的英语和混乱,我已尽力解释我的问题。希望你能明白我的意思。

4

1 回答 1

0

将 的定义移动CHARACTER::SetLevel()到头文件中并将其标记为内联。

于 2013-10-22T21:11:52.340 回答