将值分配给特定地址 [英] Assign a value to a specific address

查看:101
本文介绍了将值分配给特定地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个采访问题,我在采访中遇到一本书,后来在一次采访中遇到.

It is an interview question, which I came across at a book for interviews, and later in an interview.

问题是

如何将值(例如0)分配给地址(例如0x12345678).

How to assign value (say 0) to an address (say 0x12345678).

(在面试很长时间之后)我对这个问题的最佳尝试是

My best try for this question (after a long time after the interview) is

地址是可以存储在指针中的数字,我们可以通过指针为该地址分配一个值,该指针的值就是该地址,例如:

An address is a number which can be stored in a pointer, and we can assign a value to the address by a pointer, the value of which is the address, like:

         int* p = 0x12345678;
         *p = 0;

但是,在具有内存管理的系统上是不可能的,因为该程序没有对特定地址的特权.

However, it is not possible on a system with memory management, because the program does not have privilege to the specific address.

根据我自己的经验,这种操作唯一有效的时间是在没有任何操作系统的8086芯片上进行的实验,而我当时使用的语言是汇编语言.

According to my own experience, the only time this kind of operation was valid was the experiment on an 8086 chip without any operation system, and the language I used that time was assembly.

请帮助我纠正,改善和完善我的答案.谢谢.

Please help me correct, improve and complete my answer. Thanks.

推荐答案

您的代码正确,但是如果操作系统将0x12345678定义为只读,则代码可能会在运行时崩溃.

Your code is correct but might crush on runtime if the OS defines 0x12345678 as read-only.

常规"操作系统可以做到这一点,而轻巧"操作系统则不能.

While a "regular" OS does that, "lighter" ones do not.

您要编写一个内核空间黑客程序来做到这一点.

You want to write a kernel-space hacking program to do it.

如果您想看一下,我已经为Linux解决了该问题:

I solved it for linux if you like to take a look:

1)构建此模块(example.ko):

1) build this module (example.ko):

#include <linux/module.h>
#include <linux/fs.h>       /* for file_operations  */
#include <linux/uaccess.h>  /* copy_from & copy_to  */

char*   g_value=0;
size_t  size =0; 

int driver_open(struct inode *inode, struct file *filp)
{
    printk("open driver");
    return 0;
}

int driver_write(struct file*,          /*ignored*/
                const char __user *umem,/*source in user-space's address*/
                size_t size,            /*max size to be writen*/
                loff_t*)                /*offset - ignored*/
{
    unsigned long ret = 0;

    g_value = (char*) kmalloc(size, GFP_KERNEL);

    if (!g_value)
    {
        printk("ERROR:allocation failure\n");
        return -ENOMEM;
    }

    ret = copy_from_user(g_value,   /*destination*/
                        umem,       /*source*/
                        size);      /*size*/

    if (ret<0)
    {
        printk("ERROR:copy failure\n");
        return -EACCES;
    }

    return g_size = size;;
}

int driver_read(struct file*,       /*ignored*/
                 char __user *umem, /*destination in user-space's address*/
                 size_t size,       /*max size to be read*/
                 loff_t*)           /*offset - ignored*/
{

    /*  don't use copy_to_user(umem,    &value, size)!!
        we want to do exectly what it is made to protect from */

    int i = ((g_size>size)?size:g_size)-1; /*MIN(g_size,size)-1*/
    for (; i>=0; --i)
    {
        umem[i]=g_value[i]; /*can be done more effectively, thats not the point*/
    }

    return size;
}

int driver_close(struct inode *inode, struct file *filp)
{
    if (g_value)
        free(g_value);
    g_value = 0;
    printk("close driver");
    return 0;
}

/***interface***/

struct file_operations driver_ops = {
    open: driver_open,
    write: driver_write,
    read:  driver_read,
    release: driver_close
};

/***implementation***/

static int g_driver_fd = 0;

static void driver_cleanup(void) 
{
    printk("ERROR:driver exit\n");
    unregister_chrdev(g_driver_fd, "driver");
}

static int driver_init(void)
{

    printk("driver init\n");
    g_driver_fd =  register_chrdev(0,"ROM-bypass", &driver_ops);
    if (g_driver_fd<0)
    {
        printk("ERROR:failed to register char driver\n");
        return -1;
    }
    return 0;
}

module_init(driver_init);
module_exit(driver_cleanup);

/***documentation***/

MODULE_DESCRIPTION("write on OS's \"read only\" segment");
MODULE_AUTHOR("Elkana Bronstein");
MODULE_LICENSE("GPL");

2)将其添加到内核模块:

2) add it to kernels modules:

$insmod example.ko

3)在列表中找到模块的主要":

3) find the module's 'major' in the list:

$cat /proc/devices

4)使节点与设备关联:

4) make node associated with the device:

$mknod /dev/rom_bypass  c <major> <minor>

'c'用于字符设备,'minor'可以是0-255中的任何一个

'c' is for character device and 'minor' can be any of 0-255

5)将代码中的设备用作文件:

5) use the device in your code as a file:

int main()
{

    int fd;
    int value = 0;

    fd = open("/dev/rom_bypass",O_RDWR);    
    if (fd<0)
    {
        fprintf(stderr,"open failed");
        return -1;
    }

    /*write the desirable value into the device's buffer*/
    write(fd,&value,sizeof(value));
    /*read the device's buffer into the desirable object - without checking*/
    read(fd,0x12345678,sizeof(value));

    close(fd);
}

这篇关于将值分配给特定地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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