2010年12月27日

 

开场白

 

各位朋友们,当你们看到网上传播关于微软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的两个例子,希望通俗易懂能让大家所接受,另外缓冲区溢出并不只是改变内存的值,在高手的手里,他还可以执行任意代码,因为方法执行的时候总会有一个指针指向方法即将执行的下一条指令,如果控制了这个指针,就控制了进程。

posted @ 2010-12-27 08:58 bidaas 阅读(10680) 评论(42) 编辑

2008年12月30日

首先说明的是,我不懂VSTO,而是直接引用的 MS Word 的 COM组件,但是对象模型好像跟VSTO差不多,嘿嘿。

首先看一下代码:

搜索红色的文字

关键的就app.ActiveDocument.Content.Find.Font属性,它可以设置要搜索的各种字体格式,然后就是app.ActiveDocument.Content.Find.Format = true ;

如果设置为True,才可以应用格式搜索。

但是奇怪的是,有时候我设置app.ActiveDocument.Content.Find.Format属性的时候总是设置不了,

执行了下列代码

 

Code

 

但是app.ActiveDocument.Content.Find.Format依然为False,不知道是为什么,希望有经验的高手能为我解答,谢谢!
posted @ 2008-12-30 17:59 bidaas 阅读(1820) 评论(2) 编辑

2008年7月30日

这个函数实现如下

function TimerStart(func,delay)
{
    
var TimerID = window.setInterval(
                                    
function()
                                    {
                                        
if(!func())
                                        {
                                            window.clearInterval(TimerID);
                                        };
                                    },
                                    delay
                                    );
}

调用例子:

//状态栏效果

window.onload=function()
{
    
var i=0;
    
//调用函数
    TimerStart(
            
function()
            {
                window.status 
= i++;//状态栏显示数据
            },
            
50 //速度
            );
}

//跑马灯效果
window.onload =function()
{
    
var str1="   公告:本站属于个人博客,用于收藏本人喜好的原创作品及网络资源,如果您不喜欢千万不要勉强。谢谢合作!~ ";
    
var str2="";
    
var length = str1.length-1;
    
var index = 0;
    TimerStart(
            
function()
            {
                str2 
= str1.substring(index,length)+str1.substring(0,index);
                
                index
++;
                
                
if(index==length-1
                {
                    index
=3;
                }
               
        
                document.title
=str2;
              
                
return true;
            },
            
130
            );
}
posted @ 2008-07-30 15:00 bidaas 阅读(4330) 评论(0) 编辑

2008年4月29日

刚一上班就碰到个问题,要我把任意时间段的数据按年、月、日、小时、分种任意格式来汇总,搞了半天终于写出来了,奉献给新手们看看还行吗

SELECT CONVERT(CHAR(10),[OrderTime],120)[time],USD,EUR,GBP,CAD,AUD,HKD
INTO #F
FROM Paypal
WHERE DATEDIFF(DAY,OrderTime,@date)=0 AND PaypalState='Completed'

这个查询是用来把指定那天的所有记录查询到临时表#F中,最关键就是SELECT语句里面的Convert函数,你把CHAR的值设多长,比如说你想基于YYYY-MM月查询
就应该写成CHAR(7),为什么呢?因为当你把Datetime转化成字符串的过程中,CHAR(7)把后面多余的字符截取掉了,得到了你想要的日期格式。这样再GROUP BY
这个新生成的列,就是按月的汇总,按此推理YYYY-MM-DD就是CHAR(10),YYYY-MM-DD HH就是CHAR(13),YYYY-MM-DD HH:mi就是CHAR(16)

SELECT [time],'USD'=SUM(USD)*@USD,'EUR'=SUM(EUR)*@EUR,'GBP'=SUM(GBP)*@GBP,'CAD'=SUM(CAD)*@CAD,'AUD'=SUM(AUD)*@AUD,SUM(HKD)*@HKD[HKD],'Quantity'=Count(*),
(
SUM(USD)*@USD+SUM(EUR)*@EUR+SUM(GBP)*@GBP+SUM(CAD)*@CD+SUM(AUD)*@AUD+SUM(HKD)*@HKD)[CNY]
FROM #F
GROUP BY [time]

DROP TABLE #F

你看我基于每天的每小时的汇总,就是这样实现的,假如你有更好的办法,赶快给我拍砖啊
posted @ 2008-04-29 20:38 bidaas 阅读(2544) 评论(0) 编辑
 
工作以前不懂什么是正则表达式,现在常常要到网上去采集数据,不懂这玩意很麻烦。
可是想好一个还要试验行不行也很麻烦,就干脆自己搞一个页面来保存工作中写的正则表达式。

匹配URL最后的网页名称:
C#: /[^( |\\>|/|\"|']+
查找搜索框: /[^( |>|/|"|']+

匹配FORM表单的ACTION:
C# : action=[^( |\\>)]+

匹配INPUT标签:
C# : \\<input[^>]*\\>

匹配NAME属性:
C# : name=[^( |\\>)]+


posted @ 2008-04-29 14:26 bidaas 阅读(724) 评论(0) 编辑

2007年11月17日

怎么启用GridView多行编辑?还有就是我用GridView1.Rows[rowIndex].Cells[cellIndex].FindControl()方法找到的CheckBox无论如何Checked属性都返回False,怎么办呢?郁闷
posted @ 2007-11-17 23:17 bidaas 阅读(250) 评论(3) 编辑

2007年11月14日

摘要: Microsoft.Web,System.Net.NetworkInfomation,System.Management.这3个命名空间分别在三个DLL里,你直接引用就可以用了,Microsoft.Web允许你操作IIS网站和虚拟目录等等以及查看一些你想知道的信息,System.Net.NetworkInfomation允许你查询服务器的网络状况等等System.Management就是真正的服务...阅读全文
posted @ 2007-11-14 17:09 bidaas 阅读(100) 评论(1) 编辑

2007年11月9日

摘要: 一直在找一个爽的WEB网格控件,但总是让我很失望,最终还是重拾JS自己写。这代码需要你先在页面做一个Table,然后就可以用这个代码在页面给你添加行了。1function$(id)2{3returndocument.getElementById(id);4}56varcount=1;78varGrid={910Id:"table",//网格的客户端ID,1112CellCount:0,//单元格数...阅读全文
posted @ 2007-11-09 12:17 bidaas 阅读(378) 评论(1) 编辑

2007年10月29日

摘要: 怎么用NH实现分页操作?阅读全文
posted @ 2007-10-29 23:24 bidaas 阅读(132) 评论(3) 编辑