为什么在任意存储位置设置值不起作用? [英] Why does setting a value at an arbitrary memory location not work?

查看:87
本文介绍了为什么在任意存储位置设置值不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有此代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>

int main (int argc, char** argv) {

   *(volatile uint8_t*)0x12345678u = 1;
   int var = *(volatile uint8_t*)0x12345678;
   printf("%i", var);
   printf("%i", &var);

   return (EXIT_SUCCESS);
}

我想看到一个1以及我先前指定的那个int的地址.但是,当由gcc在bash中编译时,将仅显示命令终止",而不会出现任何错误.有人知道为什么吗?

I want to see a 1 and the address of that int, which i specified previously. But when compiled by gcc in bash, only "command terminated" without any error will be shown. Does anyone know why so?

PS:我是C的新手,所以只需尝试一下即可.

PS: I am newbie to C, so just experimenting.

推荐答案

您正在做什么:

*(volatile uint8_t*)0x12345678u = 1;
int var = *(volatile uint8_t*)0x12345678;

完全错误.

您不能保证程序可以访问诸如0x12345678之类的任意地址,更不用说可写了.换句话说,您不能将值设置为任意地址,并希望它可以正常工作.至少可以说这是未定义的行为,并且很可能会由于操作系统阻止您接触您不拥有的内存而使程序崩溃.

You have no guarantee whatsoever that an arbitrary address like 0x12345678 will be accessible, not to mention writable by your program. In other words, you cannot set a value to an arbitrary address and expect it to work. It's undefined behavior to say the least, and will most likely crash your program due to the operating system stopping you from touching memory you don't own.

您试图运行程序时得到的命令终止"恰好是因为操作系统阻止您的程序访问不允许访问的内存位置.您的程序在执行任何操作之前都会被杀死.

The "command terminated" that you get when trying to run your program happens exactly because the operating system is preventing your program from accessing a memory location it is not allowed to access. Your program gets killed before it can do anything.

如果您使用的是Linux,则可以使用mmap函数请求在(几乎)任意地址访问之前访问该内存页(请参见 man mmap ).这是一个实现所需功能的示例程序:

If you are on Linux, you can use the mmap function to request a memory page at an (almost) arbitrary address before accessing it (see man mmap). Here's an example program which achieves what you want:

#include <sys/mman.h>
#include <stdio.h>

#define WANTED_ADDRESS (void *)0x12345000
#define WANTED_OFFSET 0x678 // 0x12345000 + 0x678 = 0x12345678

int main(void) {
    // Request a memory page starting at 0x12345000 of 0x1000 (4096) bytes.
    unsigned char *mem = mmap(WANTED_ADDRESS, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    // Check if the OS correctly granted your program the requested page.
    if (mem != WANTED_ADDRESS) {
        perror("mmap failed");
        return 1;
    }

    // Get a pointer inside that page.
    int *ptr = (int *)(mem + WANTED_OFFSET); // 0x12345678

    // Write to it.
    *ptr = 123;

    // Inspect the results.
    printf("Value  : %d\n", *ptr);
    printf("Address: %p\n", ptr);

    return 0;
}

这篇关于为什么在任意存储位置设置值不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆