However, it is not possible on a system with memory management, because the program does not have privilege to the specific address. 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. 23.4k 18 18 gold badges 72 72 silver badges 115 115 bronze badges asked Mar 23, 2011 at 1:56 Dante May Code Dante May Code 11.2k 9 9 gold badges 50 50 silver badges 82 82 bronze badges
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.
I solved it for linux if you like to take a look:
1) build this module (example.ko):
#include #include /* for file_operations */ #include /* 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) add it to kernels modules:
$insmod example.ko
3) find the module's 'major' in the list:
$cat /proc/devices
4) make node associated with the device:
$mknod /dev/rom_bypass c'c' is for character device and 'minor' can be any of 0-255
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); >