一起谈.NET技术,C#不为人知的秘密-缓冲区溢出

  开场白

  各位朋友们,当你们看到网上传播关于微软windows、IE对黑客利用“缓冲区溢出”、0day漏洞攻击的新闻,是否有过自己也想试试身手,可惜无从下手的感慨?本文将完全使用C#语言,探索那些不为人知的秘密。

  1.本文讲述在C#中利用堆栈缓冲区溢出动态修改内存,达到改变应用程序执行流程的目的。

  2.如果你是高手,请指出本文的不足。

  3.为了让本文通俗易懂,代码将极尽精简。

  现在开始

  我们知道,当数组下标越界时,.NET会自动抛出StackOverflowException,这样便让我们可以安全的读写内存,那么我们有没有逾越这个自动检测的屏障,达到我们非常操作的目的呢?答案是有的,而且我们可以修改一些关键变量如if、switch的判断值,for循环变量i值,甚至方法返回值,当然理论上还可以注入代码、转移代码执行区块,前提是必须在unsafe代码里。

  方法在被调用时,系统会进行以下几项操作:将该方法入栈、参数入栈、返回地址入栈、控制代码区入栈(EIP入栈)。我们想要访问方法的栈内地址,常规的托管代码是不行的,只能使用unsafe代码,但也并不是说你非要精通C/C++语言和指针操作,本文的例子都非常简单,完全可以将指针就认为是简版C#数组。

  改变临时变量的值

  先给出一段代码,然后再详细解释原理。

 代码

static  unsafe void Main(string[] args)
        {
            //在栈上申请一个只能保存一个int32的内存段
            int* p = stackalloc int[1];

            for (var i = 0; i < 30; i++)
            {
                System.Threading.Thread.Sleep(200);

                Console.WriteLine("{0}\n", i);
                p[i] = 0;
            }
           
            Console.ReadLine();
        }

  这是一个既简单,但是对于从没有尝试这样写过代码的开发者来说,又颇耐人寻味,C#(包括C/C++)不会去检查指针p的偏移量是否越界,那么这段代码将会顺利编译并运行,那么for循环会顺利执行30次吗?还是......

  结论是,这将是一个死循环,因为p不断的递增1偏移,并将附近的内存的值全改为0,而局部变量i是靠p最近的变量,所有当p[i]的偏移地址等于i的地址时,代码p[i]=0就等价于i=0,实际上我在测试中i=6的时候i的值就被覆盖为0了,我在代码中添加了Thread.Sleep(200)和Console.WriteLine("{0}\n", i)就是让大家能更直观的看到程序的执行过程,当然这里也可以改为p[i]=1,p[i]=2等数字

  搜索内存值并修改

  还是先给出代码

代码

static  unsafe void Main(string[] args)
        {
            Console.WriteLine(Change_Result());
            Console.ReadLine();
        }

        static unsafe int Change_Result()
        {
           
            int i = 0;
            //变量result,默认的返回值
            int result = 123;
            //申请一段栈内存,大小可随意设置
            int* p = stackalloc int[1];
            //从当前栈地址开始向下查找与函数返回值相匹配的地址,一旦匹配则修改为10000
            while (true)
            {
                if (p[++i] == 123)
                {
                    p[i] = 10000;
                    break;
                }
            };
            return result;
        }

  变量result作为方法的返回值默认为123,并且没有任何显式修改其值的代码,关键在这里


while (true)
{
if (p[++i] == 123)
{
p[i] = 10000;
break;
}
}

  这段代码找到值为123的内存地址(也就可能是变量result的地址),然后将其值修改为10000,当然,函数返回值就肯定不会再是原先的123咯

  这就是经典的StackOverFlow的两个例子,希望通俗易懂能让大家所接受,另外缓冲区溢出并不只是改变内存的值,在高手的手里,他还可以执行任意代码,因为方法执行的时候总会有一个指针指向方法即将执行的下一条指令,如果控制了这个指针,就控制了进程。

时间: 2024-08-02 09:55:32

一起谈.NET技术,C#不为人知的秘密-缓冲区溢出的相关文章

C#不为人知的秘密-缓冲区溢出

开场白 各位朋友们,当你们看到网上传播关于微软windows.IE对黑客利用"缓冲区溢出".0day漏洞攻击的新闻,是否有过自己也想试试身手,可惜无从下手的感慨?本文将完全使用C#语言,探索那些不为人知的秘密. 1.本文讲述在C#中利用堆栈缓冲区溢出动态修改内存,达到改变应用程序执行流程的目的. 2.如果你是高手,请指出本文的不足. 3.为了让本文通俗易懂,代码将极尽精简. 现在开始 我们知道,当数组下标越界时,.NET会自动抛出StackOverflowException,这样便让我

浅谈缓冲区溢出之栈溢出&lt;上&gt;

有段时间没有用windows了,刚一开机又是系统补丁更新.匆匆瞥了一眼看到了"内核缓冲区溢出漏洞补丁"几个字眼.靠,又是内核补丁.打完这个补丁后MD的内核符号文件又得更新了.于是抱怨了几句,一旁的兄弟问什么是缓冲区溢出.这个-三两句话还真说不清楚.解释这个问题用C语言比较方便,但是单从C代码是看不出来什么的,具体原理要分析机器级代码才能说清楚.既然是浅谈原理,那就从最基本的开始吧. 本文的定位是对此方面一无所知的读者,所以大牛们可以直接飘过- 缓冲区溢出这个名词想必大家并不陌生吧,在微

浅谈缓冲区溢出之栈溢出&lt;下&gt;

上回我们简单的介绍了缓冲区溢出的基本原理和机器级代码的解释,对此类问题的分析和研究都必须建立在对程序的机器级表示有一定的了解的基础上.记得有句话是这样说的,"真正了不起的程序员是对自己代码的每一个字节都了如指掌的程序员."我们也许做不到每一字节,但至少得明晰机器级程序的组成结构和执行流程. 言归正传,我们今天在上回的基础上继续探索缓冲区溢出.之前的例子都是简单的通过越界访问来实现对程序执行流程的变动,而且执行的函数都是编译前写入的,那么如何对一个发行版的可执行程序进行缓冲区溢出呢? 首

探索Windows 7那些不为人知的秘密功能

Win7系统已经上市两年,凭借其出色的性能与良好的口碑目前已经成为最流行的操作系统,占据了大量电脑用户的桌面.而且,无论是通过升级Win7还是购买Win7电脑的方式,我们都能以较为实惠的办法使用上正版Windows7系统,这的确是Win7发布之前很难想象的改变.Win7功能强大且操作便捷,虽然很多电脑用户已经使用Win7系统很长一段时间了,但其中一些较为隐藏或是并不常用的功能依然未能了解,这里想要分享两三个这样的小功能给大家,希望能在需要使用的时候助Win7用户一臂之力. Screen Cali

linux下so动态库一些不为人知的秘密(中)

上一篇(linux下so动态库一些不为人知的秘密(上))介绍了linux下so一些依赖问题,本篇将介绍linux的so路径搜索问题.      我们知道linux链接so有两种途径:显示和隐式.所谓显示就是程序主动调用dlopen打开相关so;这里需要补充的是,如果使用显示链接,上篇文章讨论的那些问题都不存在.首先,dlopen的so使用ldd是查看不到的.其次,使用dlopen打开的so并不是在进程启动时候加载映射的,而是当进程运行到调用dlopen代码地方才加载该so,也就是说,如果每个进程

linux下so动态库一些不为人知的秘密(中二)

继续上一篇< linux下so动态库一些不为人知的秘密(中) >介绍so搜索路径,还有一个类似于-path,叫LD_RUN_PATH环境变量, 它也是把路径编译进可执行文件内,不同的是它只设置RPATH.  [stevenrao] $ g++ -o demo -L /tmp/  -ltmp main.cpp  [stevenrao] $ readelf -d demo  Dynamic section at offset 0xb98 contains 25 entries:   Tag    

告诉你淘宝和雅虎中国不为人知的“秘密”

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断淘宝客 站长团购 云主机 技术大厅 昨晚,由于要用淘宝的支付宝收点货款,在打开淘宝后,不经意间居然让我发现了马云的一点不为人知的"秘密"-- 打开淘宝首页后,由于机子已属"更年期"型,鼠标被卡了下,在按下鼠标的一刹那,我听到了一些蛮搞怪而且蛮好笑的声音,怪了,打开淘宝网站以前是没有声音的吖,呵呵.这点激起了我的好奇之心,为了查清声

《创业家》牛文文:少谈点模式多谈点技术

"模式"如同当年的"主义",流行于各种创业大赛.创业励志节目.论坛的"街头"式秀场 文/创业家 牛文文 "美国某某公司你知道吧?就是刚被戴尔.惠普.思科十几亿美元抢购的那家.我们的模式和它的一样,现在还没赢利,可将来起码有十几亿人民币的市值." "我开了小煤矿,但煤运不出去,上商学院之后受到启发,想搞模式创新,具体讲就是想在铁路边上搞个煤炭物流开发区,建一个大的物流和信息流平台,把分散的煤炭集中在我这个园区,这样和铁

ViewPager不为人知的秘密

ViewPager不为人知的秘密 ViewPager翻页控制 关于控制ViewPager的翻页,在网上已经有很多解决方法了,我们一个个来看看. setScanScroll() 我们先来看一下具体实现: public class CustomViewPager extends ViewPager { private boolean isCanScroll = true; public CustomViewPager(Context context) { super(context); } publ