【问题标题】:how to change value in a specific memory address?如何更改特定内存地址中的值?
【发布时间】:2021-03-02 13:34:06
【问题描述】:

我是 c 编程新手。有一个用例:我需要更改特定内存地址中的值。

int main(){

    int *p;
    p = 0x111;
    *p = 100;
    return 0; 
}

但是,我无法编译上述代码。它显示了以下问题。

test.c:10:7: warning: incompatible integer to pointer conversion assigning to 'int *' from 'int' [-Wint-conversion]
    p = 0x111;
      ^ ~~~~~
1 warning generated.

我尝试过如下投射:

int main(){

    int *p;
    p = (int *) 0x111;
    *p = 100;
    return 0; 
}

它可以编译,但是,当我运行它时,它显示segmentation fault

我的问题:

  1. 有没有办法强制编译和运行这段代码?我知道有野指针问题。但是,操作内存是一个常见的用例。例如,当我玩本地游戏时。不知何故,我知道游戏运行时我的玩家健康点的具体内存地址,例如地址 = 0x123。如何只更改 0x123 中的值?

  2. 如果我不能使用上述方式来操作任何特定内存地址中的值,还有其他标准方式来实现我的用例吗?

PS: 顺便说一句,我找到了实现我的用例的示例方法。

可以参考源码:https://github.com/haseeb-heaven/GTLibc/

How do game trainers change an address in memory that's dynamic?

https://www.youtube.com/watch?v=cRCnN987gd8&ab_channel=HaseebMir

【问题讨论】:

  • 您需要将其转换为指针。但是,请注意,如果该地址在您的应用程序范围“之外”。然后,您将收到一个尝试访问和不允许访问的地址的段错误。
  • 您不能在具有受保护内存寻址的操作系统中执行此操作,现在基本上都是这样。除此之外,一个进程的地址空间与另一个进程完全不同,它们甚至不在同一个星球上。当直接在另一个进程中使用时,来自一个进程的指针完全没有意义。除非这是 DOS 之类的代码,否则它不会工作。
  • 你的平台是什么?
  • @maplemaple 那么你不能那样做。你实际上想要达到什么目的?
  • 这能回答你的问题吗? Reading Other Process' Memory in OS X?

标签: c pointers


【解决方案1】:

让我让你了解应用程序如何读取另一个应用程序或自身的地址。

  1. 自我地址。

您正在读取的地址高于基地址0x0040000executable image,所以它应该看起来像这样0x0040000 + 0x0040 其中0x0040 是基地址的偏移量。 如果您访问 .text(只读)以外的区域,则必须首先使用 VirtualProtect 方法更改区域的权限,如 here 所示

  1. 外部应用地址。

如果您想从外部应用程序读取地址,比如说您的游戏,那么首先您必须获得应用程序Handle,它只是您的应用程序的标识符,然后使用ReadProcessMemory,如here 所示,类似地您可以编写也使用WriteProcessMemory 如图here

请始终确保您在不更改其权限区域的情况下不要访问除 .text 以外的部分,否则您的程序可能会崩溃。

【讨论】:

    【解决方案2】:

    给定一个指向内存地址中对象的有效指针,通过指针间接赋值:

    int health_points = 1337;  // an object in some memory address
    int* ptr = &a;             // pointer to the value in that memory address
    *ptr = 0;                  // the value is modified
    

    有没有办法强制编译和运行这段代码?

    您的程序格式不正确。如果编译器提供相关的语言扩展,可能有一种方法可以让编译器成功编译它,但依赖此类扩展通常是个坏主意,因为它会诱使您使用那个编译器。

    我建议修复程序,而不是试图强制编译器接受损坏的程序。

    如何改变特定内存地址的值?

    首先,必须分配该地址中的内存。语言实现负责分配所有内存,没有标准方法来指定分配的地址。

    但是,某些语言实现可能会将某些地址指定为可访问。这在嵌入式系统上很典型。如果是这种情况,那么您可以使用强制转换将整数值转换为指针:

    std::uintptr_t address = 0x111; // see documentation whether this is a valid address
    int* ptr = reinterpret_cast<int*>(address);
    

    如果您的语言实现未指定该地址可访问,则无法保证访问该地址。在管理虚拟内存的现代操作系统上,最好的情况是段错误。

    【讨论】:

    • 注意 OP 在文本中询问了 C 并且 C++ 标记已被删除,因此该答案中的 C++ 现在适用于 C++ 示例代码和关于格式错误的断言,这不适用于 C。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2022-08-17
    • 2012-09-22
    • 1970-01-01
    • 2012-08-31
    • 2011-07-02
    • 2015-08-22
    相关资源
    最近更新 更多