首页
社区
课程
招聘
[旧帖] [分享]OllySSEH的一个小bug 0.00雪花
2012-7-20 15:42 1077

[旧帖] [分享]OllySSEH的一个小bug 0.00雪花

2012-7-20 15:42
1077
     使用OllySSEH的过程中发现一个小小的bug。看了一下源码后发现,程序在使用堆内存的时候,出现重复释放的错误。

     没有什么技术含量,大牛飘过。

int CheckSafeSEH(t_module *module, t_sseh * ssm)
{
  LPBYTE    lpHead;  
  int       retval = SAFESEH_OFF;
  t_handler handler;
  DWORD    i;  
  
  // Check bounds .. 

  if ( !(module->headersize > sizeof (IMAGE_DOS_HEADER)) ||
    [COLOR="red"] !(lpHead = malloc(module->headersize)) )//分配内存[/COLOR]
  {
    return ERROR_READING_SEH;
  }

  // Read Module Headers 

  if ( Readmemory(lpHead,module->base,module->headersize, MM_RESTORE | MM_SILENT ) )
  {
    PIMAGE_DOS_HEADER              lpDOSh;
    PIMAGE_NT_HEADERS              lpNTh;
    PIMAGE_DATA_DIRECTORY          lpDD;
    PIMAGE_LOAD_CONFIG_DIRECTORY32 lpLCD;
    DWORD               *lpHTable;


    // Get NT header 

    lpDOSh = (PIMAGE_DOS_HEADER) lpHead;
    lpNTh  = (PIMAGE_NT_HEADERS) ( (LPBYTE)(lpDOSh) + lpDOSh->e_lfanew );
    
    // Check bounds ..

    if  (!IS_CONTAINED(lpNTh,sizeof(IMAGE_NT_HEADERS),lpHead,module->headersize) )
    {
      free(lpHead);
      return ERROR_READING_SEH;
    }
    
    // Check DllCharacteristics, is SEH enabled for this image?

    if ( lpNTh->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_SEH )
    {
      free(lpHead);
      return NOSEH;
    }
  
    // Get Data directory 

    [COLOR="Red"]lpDD   = (PIMAGE_DATA_DIRECTORY) &lpNTh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];//lpDD指向堆内存[/COLOR]

    // Check bounds ..
    
    if (!IS_CONTAINED(lpDD,sizeof(IMAGE_DATA_DIRECTORY),lpHead,module->headersize) )
    {
      free(lpHead);
      return ERROR_READING_SEH;
    }

    [COLOR="red"]// We don't need the header anymore[/COLOR]

    [COLOR="red"]free(lpHead);//第一次释放[/COLOR]

    // Allocate memory for Load Config Directory

    if (! ( lpLCD = malloc(sizeof(IMAGE_LOAD_CONFIG_DIRECTORY)) ) )
    {
      PluginError();
    }

    // Read Load Config Directory 

    if ([COLOR="Red"]lpDD->Size[/COLOR] && Readmemory (lpLCD, //[COLOR="red"]这里还在引用lpDD[/COLOR]
             module->base + lpDD->VirtualAddress,
             sizeof(IMAGE_LOAD_CONFIG_DIRECTORY), MM_RESTORE | MM_SILENT )  )
    {      
      
      // Do we have a SEH handler table? ;-)

      if ( lpLCD->SEHandlerTable  )
      {
        // Allocate memory for SEHandler Table

        if (! (lpHTable = (DWORD *) malloc( lpLCD->SEHandlerCount * sizeof(DWORD) ) ) )
        {
          free(lpLCD);
          PluginError();
        }                

        // Read SEHandler Table

        if ( ! Readmemory (lpHTable,
                     lpLCD->SEHandlerTable,
                   lpLCD->SEHandlerCount * sizeof(DWORD), MM_RESTORE | MM_SILENT ) )
        {      
          
          free(lpHTable);
          free(lpLCD);
          return ERROR_READING_SEH;
        }

        // Allocate memory for handler's table 

        
        if ( (!ssm->handlers) && (!(ssm->handlers = malloc(sizeof(t_table)) )) )
        {
          free(lpHTable);
          free(lpLCD);
          PluginError();
        }
        
        // Zeroing memory  

        memset(ssm->handlers,0,sizeof(t_table));
  
        // Just create a new sorted data for handler addresses.
        
        if ( Createsorteddata(&ssm->handlers->data,
          "handlers",
          sizeof(t_handler),
          10,
          (SORTFUNC *)handlersortfunc,
          NULL ) != 0 )
        {          
          free(lpHTable);
          free(lpLCD);
          PluginError();
        }

        // Add handlers to sorted data
        
        for ( i = 0; i < lpLCD->SEHandlerCount ; i++  )
        {
          handler.index = i;
          handler.size  = 1;
          handler.type  = 0;          
          handler.address = module->base + lpHTable[i];          
          Addsorteddata(&ssm->handlers->data,&handler);
        }

        // Free memory and return success
        
        free(lpHTable );
        free(lpLCD);
        retval = SAFESEH_ON;
      }
    }
    [COLOR="red"]free(lpDD);//这里又释放了一次[/COLOR]
  }
  else
  {
    free(lpHead);
    retval = ERROR_READING_SEH;
  }
  return retval;
}

看红色标记的代码,lpDD 引用的内存是lpHead 指向的堆内存,后面在最后一次使用lpDD之前,lpHead指向的

堆内存就被释放了,最后程序又来释放lpDD,。。。。虽然概率不大,但是还是会造成崩溃的。

这应该是作者不小心留下的!不过问题也不大,所谓瑕不掩瑜嘛。最后还是要感谢作者的共享精神。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回