【问题标题】:examining and modifying memory addresses in C在 C 中检查和修改内存地址
【发布时间】:2012-03-16 02:33:41
【问题描述】:

我想基本上做以下事情(这可能是危险的,什么不是)只是为了它的见鬼:

int main() {

    int x = 0x00ff00ff;

    printf("Value at addr x: %x\n",*x);


    return 0;
}

基本看一下我机器中某个地址的内容。也许写信给它。我猜我不允许做后者。

我得到的错误是error: invalid type argument of 'unary *'

有什么办法吗?

【问题讨论】:

  • 不一定,@L7ColWinters,这取决于实现。即使在 Linux 或其他受保护内存的操作系统中,也可能有人将实际内存映射到该地址。或者,您可能正在运行的系统提供对物理内存的无限制访问。
  • 由于虚拟寻址,这不太可能做任何太有趣的事情,除非这恰好是嵌入式环境等。如果你真的想偷看系统内存,你需要像 Linux 上的 /dev/mem 这样的东西

标签: c pointers memory-address


【解决方案1】:

你需要一个指针:

int *x = (int*)0x00ff00ff;

您是对的,这可能不是一个好主意,除非您知道0x00ff00ff 是某种有效地址。这实际上不是未定义的行为,因为标准说您不能取消引用 非法 地址,但随后声明“非法”包括以下内容:

  • 已释放堆对象的地址。
  • 空指针。
  • 对齐错误。

但没有明确列出任意指针值,因为这会使嵌入式系统中的内存映射 I/O 出现问题。

例如,您可以通过读取或写入已知的内存映射 I/O 地址来控制嵌入式系统中的 UART(通用异步接收器/发送器,基本上是串行端口设备):

#define UART_READ_READY  ((char*)0xff00)
#define UART_READ_CLEAR  ((char*)0xff01)
#define UART_DATA        ((char*)0xff02)

char getUartCharWithWait (unsigned int tries) {
    char retChar;
    unsigned int limit;

    // Keep looping until character available, at least for a while.

    limit = tries;
    while (*UART_READ_READY == 0)
        if (limit-- == 0)
            return '\0';

    // Get character, tell UART to clear it, then return it.

    retChar = *UART_DATA;
    *UART_CLEAR = 1;

    return retChar;
}

在本例中,您的代码如下:

retChar = *UART_DATA;

它将从“内存”地址0xff02中读取一个字节(Cchar),这实际上是来自监控地址总线并拦截特定地址的设备。

【讨论】:

  • 谢谢。我在这个例子中只尝试“int”的原因(我在键盘上做了)是因为我正在使用一个小型操作系统并且我正在处理一种名为“paddr_t”(物理地址)的数据类型。使用这种数据类型,我很确定我可以执行 *paddr = 0x11223344 并且通常遵循我在 OP 中尝试过的相同模式。
  • 也是使用 C 实现内存映射 I/O 的绝佳示例。
【解决方案2】:

您收到前面提到的错误,因为无法取消引用 int,将x 设为pointer-to-int 将产生“正确”的结果(即它将能够编译)。

int * x = (int*)0x00ff00ff;

“它可以工作,它可以工作!或者,我的意思是,它可以编译。现在,什么是段错误?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 2010-10-09
    • 2022-01-15
    • 2013-10-11
    相关资源
    最近更新 更多