【问题标题】:Access voilation exception when trying to rewrite jmp尝试重写 jmp 时出现访问冲突异常
【发布时间】:2014-03-08 15:54:54
【问题描述】:

我有一个游戏,我将它分解并找到了一个我想重写的跳转,

但每当我尝试写入该地址时,我都会遇到访问冲突异常,即使我使用 VirtualProtect 并设置了 READWRITE 权限。

0x0042BD5F 上的指令是这样的:

0x0046AACF E9 FF FF 89 FC |在这里jmp一些地址

现在,当我尝试写入 0x0042BD5F 以更改相对跳转地址时,我得到了访问破坏异常。

如何更改该地址的跳转?

请求了代码,所以这里是:

#define AddVar(Type,Name,Address) Type& Name = *reinterpret_cast<Type*>(Address)
/*
Hooker
1b 0x0042BD5F == E9 <relative jmp>
4b 0x0042BD60 - relative jump offset (always the value 0xFFFF89FC)
*/
AddVar(uqbyte, jump_hook_bytes, 0x0042BD60);
//the user tick function
void(*tick)(void);
void SetTick(void(*passed)(void))
{
    tick = passed;
}
void Ticker();
void OnDLLLoad(void(*passed)(void) = nullptr)
{
    tick = passed;
    //point the game loop end to Ticker()
    //replace the jump address
    //jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)])
    DWORD old;
    VirtualProtect(
        (LPVOID)0x0042BD5F,
        0x05,
        PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE,
        &old
        );
    jump_hook_bytes = (((uqbyte)((uqbyte*)&Ticker) - (uqbyte)0x0042BD5F) - (uqbyte)0x0000005);
}
void Ticker()
{
    if (tick != nullptr)
    {
        tick();
    }
    __asm
    { 
        MOV EAX, 0x0042B9EA;//old address
        JMP EAX;
    }
}

uqbyte 是一个unsigned long

调用 getlasterror 时,代码似乎返回十进制错误 87 (INVALID_PARAMETERS)。

【问题讨论】:

  • 你可以编写一个程序来复制地址之前的所有二进制数据,更改地址并复制之后的所有内容。这会给你一个新的二进制文件:如果没有校验和,否则它会将你的二进制文件标记为无效。
  • 你试过什么?显示您的代码。请记住,每次运行程序时,现代版本的 Windows 都会将程序代码加载到不同的地址。
  • 不用担心,函数的地址始终保持不变。至少在这个二进制文件中。
  • 你永远不会检查 VirtualProtect 是否成功。
  • hm 失败但 GetLastError 返回 0

标签: c++ windows exception assembly hook


【解决方案1】:

内存保护常量的documentation 表示:

以下是内存保护选项;在内存中分配或保护页面时,您必须指定以下值之一。

然后它会列出一些值,包括您组合在一起的三个值。当文档说“指定以下值之一”时,它的意思就是一个。您不能将它们组合在一起。

您需要单独使用PAGE_EXECUTE_READWRITE

我建议您围绕所有 API 调用添加错误检查。我还认为您可以避免对地址进行硬编码。

【讨论】:

    【解决方案2】:

    您需要使用调试器或启用调试器模式的进程令牌特权的程序(如培训师)。我认为这不是用于在线作弊(离线不重要)。

    【讨论】:

    • 以及如何启用该进程令牌?如果我正在制作的是多人游戏,那么在线有点困难:P(所以我正在编辑“离线”的东西)。游戏没有 TCP/IP 多人游戏
    • 如果目标只是修改跳跃,那么为什么不使用训练器或训练器制造商套件呢?启用进程令牌需要获取当前进程 ID,然后获取令牌并循环查找调试器的令牌,然后启用它。然后,您需要确定您尝试修改的进程的进程 ID。
    • @rcgldr 他正试图在自己的进程中修改代码。这是一个弯路。
    【解决方案3】:

    传递PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE 是错误的,您只需将PAGE_EXECUTE_READWRITE 传递给Virtual Protect。现在可以了。

    【讨论】:

      猜你喜欢
      • 2021-07-12
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2021-07-02
      • 2021-06-04
      • 2017-01-27
      相关资源
      最近更新 更多