zoukankan      html  css  js  c++  java
  • 字符串常量区读写属性强制修改为可写

    常见的0xC0000005错误,往往是程序尝试对不可写内存区域写入数据导致的,这是使用指针的时候的常见错误。不过字符串常量区(也叫数据区,确切的说,字符串常量区是数据区的一部分)、代码区、堆、栈都是系统临时分配的一段内存而已,他们本质上没有区别。通过修改PE文件,我们可以修改对应内存的读写属性,从而规避0xC0000005错误(程序成功地把数据写入字符串常量区)。示例程序:

    #include "stdafx.h"
    #include <stdlib.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
      char *p = "hello world";
    
      system("pause");
    
      *(p + 2) = 'm';    //此处触发C05错误
    
      printf("%s
    ", p);
    
      system("pause");
      return 0;
    }
    

    如图所示,这个程序是可以编译通过并运行的:

    但是当我们把程序运行到*(p + 2) = 'm'这一行,程序会因为我们尝试对字符串常量区进行写入而触发C05错误,如图所示:

    现在我们对字符串常量区的读写属性进行修改。停止VS中的调试,用文本编辑器打开刚才编译链接生成的可执行文件,如图所示:

    可以看到里面有各种区域,我们关心的是rdata区,也就是只读数据区。这个区域的读写属性被编码成了一个字节,位于段落开始后的两行半处(习惯上每行看16字节,两行半就是40字节,十六进制偏移为0x28)。把它从原来的40修改成和data区一样的C0,如图所示:

    保存文件,再次运行(注意不要用VS重新编译源代码。重新编译的话,链接器会把rdata区域的读写属性重新置为默认的只读)。可以发现,我们成功地执行了程序的意图,把“hello”里的字母l改成了m,如图所示:

    PE文件中各个区域的读写属性是通过位来编码的,前四位二进制数(0000)分别代表写、读、执行、共享(英文缩写为WRES)。所以原来的40(4的二进制0100)代表的只读,被我们修改成了C0(C的二进制1100),也就是可写可读。

  • 相关阅读:
    eclipse下配置hadoop环境
    eclipse下安装hadoop伪分布式集群
    ubuntu安装eclipse步骤
    Fiddler修改抓包请求
    Fiddler抓包(以谷歌浏览器、安卓手机为例)
    whistle抓包-数据包分析
    whistle手机抓包(以安卓手机为例)
    whistle浏览器抓包(以火狐浏览器为例)
    whistle安装
    Jmeter结构体系及运行原理
  • 原文地址:https://www.cnblogs.com/zhugehq/p/6555881.html
Copyright © 2011-2022 走看看