百度空间 | 百度首页 
 
查看文章
 
定位可执行文件中不安全函数
2009年11月08日 星期日 12:37

今天写了一半的程序,写不下去了,目前缓冲区溢出还是比较热门的,说到底是程序写代码没安全意识造成。在处理字符串上或者数组,整数上,造成了栈溢出,堆溢出或者整数溢出。当然有时候还有逻辑上的问题。下面的代码主要是想搜索PE文件中的不安全函数,来帮助发现程序中是否有不安全的函数存在。 这实现了对STRNCPY的例子。还不是很完善,没时间写了。

#include "windows.h"
#include <stdio.h>

//
//一般是可执行节,我们不能仅根据 .TEXT / .CODE来确定。
//
typedef struct __section_info
{
unsigned int uistart; //// map
unsigned int uiend; // map
}section_info;

#define MAX_SECTION 4

typedef struct __mapfile_info
{
unsigned int uisection_num;
section_info arr_sectioninfo[MAX_SECTION];

HANDLE hFile;
HANDLE hMapping;
PVOID lpMapbase;
}mapfile_info,*pmapfile_info;

BOOLEAN   MAPFILE_INIT(LPCSTR szFileName, pmapfile_info lpMapFileInfo)
{

if( lpMapFileInfo == NULL)
{
return FALSE;
}

ZeroMemory( lpMapFileInfo, sizeof( mapfile_info ));

if (( lpMapFileInfo->hFile = CreateFile(szFileName, GENERIC_READ,
                              FILE_SHARE_READ,0,OPEN_EXISTING,
         FILE_FLAG_SEQUENTIAL_SCAN,0 )) == INVALID_HANDLE_VALUE)
{

        printf("Can't open file ! err 0x%08x \n",GetLastError() );

return FALSE;
}

if (!( lpMapFileInfo->hMapping = CreateFileMapping( lpMapFileInfo->hFile ,0,PAGE_READONLY|SEC_COMMIT, 0,0,0)))
{
printf("Mapping failed.\n");

CloseHandle( lpMapFileInfo->hFile );

return FALSE;
}

    if (!( lpMapFileInfo->lpMapbase = MapViewOfFile( lpMapFileInfo->hMapping ,FILE_MAP_READ,0,0,0)))

    {
printf("View failed.\n");

CloseHandle( lpMapFileInfo->hMapping );

CloseHandle( lpMapFileInfo->hFile );

return FALSE;
}


IMAGE_DOS_HEADER *dosHeader;
   
IMAGE_NT_HEADERS *ntHeader;
   
IMAGE_SECTION_HEADER *SectionHeader;

    int NumOfSections,test=0;


dosHeader=(IMAGE_DOS_HEADER*)lpMapFileInfo->lpMapbase;
   
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpMapFileInfo->lpMapbase+dosHeader->e_lfanew);
   
NumOfSections=ntHeader->FileHeader.NumberOfSections;

SectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpMapFileInfo->lpMapbase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS));

lpMapFileInfo->uisection_num = 0;

for (int i=0;i<NumOfSections;i++)
{
        SectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpMapFileInfo->lpMapbase+
   dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;

if( (SectionHeader->Characteristics&0x20000020)!=0 ) /// executable section
{
   if( lpMapFileInfo->uisection_num < MAX_SECTION )
   {
    //
    //RVA相对虚地址,VirtualAddress 本节的RVA(相对虚拟地址)。
    //
   
    lpMapFileInfo->arr_sectioninfo[lpMapFileInfo->uisection_num].uistart =
     SectionHeader->VirtualAddress;

    //
    // SizeOfRawData >=VirtualSize   ,VirtualSize   是节在内存中的长度
    // SizeOfRawData   则是VirtualSize经文件对齐后的尺寸。
    // 你的.text的代码段长是0x110但是文件对齐尺寸是0x400,那.text的SizeOfRawData   就是0x400,
    // 而virtualSize就是0x110
    //

    lpMapFileInfo->arr_sectioninfo[lpMapFileInfo->uisection_num].uiend =
     SectionHeader->SizeOfRawData;
   
    lpMapFileInfo->uisection_num++;
   
    printf("-%s 0x%x\n",SectionHeader->Name,SectionHeader->VirtualAddress);
   }
   
  
}
}

return TRUE;

}


void MAPFILE_CLEANUP( pmapfile_info lpMapFileInfo )
{
UnmapViewOfFile( lpMapFileInfo->lpMapbase );

CloseHandle( lpMapFileInfo->hMapping );

CloseHandle( lpMapFileInfo->hFile );
}

unsigned int Find_strncpy(unsigned int start , unsigned int end) ///// VC 6 sp6
{
unsigned char *ucptr = (unsigned char *)start ;
unsigned int uic = end - start;

if( end < start)
{
return 0;
}

while( uic != 0)
{
if( ((unsigned char*)ucptr)[0] == 0x8b &&
   ((unsigned char*)ucptr)[1] == 0x4c &&
   ((unsigned char*)ucptr)[2] == 0x24 &&
   ((unsigned char*)ucptr)[3] == 0x0c &&
   ((unsigned char*)( (int)ucptr+0xd ))[0] == 0x8b &&
   ((unsigned char*)( (int)ucptr+0xd ))[1] == 0x74 &&
   ((unsigned char*)( (int)ucptr+0xd ))[2] == 0x24 &&
   ((unsigned char*)( (int)ucptr+0xd ))[3] == 0x14 )
  

{
   printf("--find xx 0x%x\n",ucptr);
   return (unsigned int)ucptr ;
}
ucptr++;
uic--;
}

return 0;
}

BOOLEAN IsCallMatch( unsigned int uiAddress, unsigned int uiNorAddress)
/*
测试 uiAddress 地址 的指令是不是 call uiNorAddress
*/
{
__try
{
*(unsigned char*)uiAddress;

}__except(1)
{
return FALSE;
}

if( *(unsigned char*)uiAddress != 0xe8 ) ///// now just sp e8
{
return FALSE;
}

unsigned int uiasc = 0;
unsigned int uiTmpptr = *(unsigned int*)( (unsigned char*)uiAddress+1);


if( uiTmpptr & 0x10000000 )
{
uiasc = uiTmpptr + uiAddress -0xFFFFFFFB;
}else
{
uiasc = uiTmpptr+ uiAddress +5;
}

return uiasc == uiNorAddress ? TRUE : FALSE ;


}

unsigned int FucAddress(unsigned int uiAddress, unsigned int uimaylen)
{
unsigned char *ucptr = (unsigned char *)uiAddress;

if( uimaylen != 0)
{
while( uimaylen != 0 )
{
   if( IsBadReadPtr( ucptr+5, 5) == 0 &&
    ( ucptr[0] == 0xcc && ucptr[1] == 0xcc && ucptr[2] == 0xcc &&
      ucptr[3] == 0xcc && ucptr[4] == 0xcc ))
   {
   
    return (unsigned int)( ucptr+5 );
   }
   ucptr--;
   uimaylen--;
}
}

return 0;

}


void ________test()
{
char cbuf[16];

ZeroMemory( cbuf, 16 );

//ENABLE_L __asm int 3
char* testpath = "F:\\SysFilter\\.sys\\i386\\YasBoxFilter.sys";
//"C:\\溢出测试\\Debug\\溢出测试.exe";


if( strncpy( cbuf, "hello" , 6) == NULL )
{

}

/*
//// E8 C8 85 FF FF
///E8 D2 7B FF FF 0x39BEE9 0x393ac0
unsigned int xxx = Find_strncpy( (unsigned int)0x400000 ,(unsigned int)0x404005);

printf("--%d\n",IsCallMatch( 0x40bbd3 ,xxx) );

printf("--%x\n",FucAddress);

printf("--%x\n",FucAddress(0x40bbd3,0x1000));
*/
unsigned int xxx = 0;

mapfile_info mapfilexfo;

MAPFILE_INIT( testpath , &mapfilexfo);


for( unsigned int i=0; i<mapfilexfo.uisection_num; i++)
{
xxx = Find_strncpy( (unsigned int)mapfilexfo.lpMapbase+(unsigned int)mapfilexfo.arr_sectioninfo[i].uistart ,
   (unsigned int)mapfilexfo.lpMapbase+ (unsigned int)mapfilexfo.arr_sectioninfo[i].uiend);
if( xxx != 0x0)
{
   break;
}
}

//xxx-=(unsigned int)mapfilexfo.lpMapbase;

printf("--0x%x\n",mapfilexfo.lpMapbase);

unsigned int uissize = (unsigned int)mapfilexfo.arr_sectioninfo[i].uiend -
(unsigned int)mapfilexfo.arr_sectioninfo[i].uistart;

printf("s --0x%x\n",(unsigned int)mapfilexfo.lpMapbase+(unsigned int)mapfilexfo.arr_sectioninfo[i].uistart);

for( unsigned int j = (unsigned int)mapfilexfo.lpMapbase+(unsigned int)mapfilexfo.arr_sectioninfo[i].uistart ;
      uissize-->0 ; j++ )
{
    if( IsCallMatch( j ,xxx) != 0 )
printf("RVA--%x\n", j - (unsigned int)mapfilexfo.lpMapbase);
}

//printf("e --0x%x\n",)


}

/*
---------------------------------------------------
*/
DWORD RVAToOffset(LPVOID lpBase,DWORD VirtualAddress)
{
    IMAGE_DOS_HEADER *dosHeader;
    IMAGE_NT_HEADERS *ntHeader;
    IMAGE_SECTION_HEADER *SectionHeader;
    int NumOfSections;
    dosHeader=(IMAGE_DOS_HEADER*)lpBase;
    ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
    NumOfSections=ntHeader->FileHeader.NumberOfSections;
    for (int i=0;i<NumOfSections;i++)
    {
        SectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;
        if(VirtualAddress>=SectionHeader->VirtualAddress&&VirtualAddress<=SectionHeader->VirtualAddress+SectionHeader->SizeOfRawData)
        {
            DWORD AposRAV=VirtualAddress-SectionHeader->VirtualAddress;
            DWORD Offset=SectionHeader->PointerToRawData+AposRAV;
            return Offset;
        }
    }
return 0;
   
}

unsigned int getiat_funcaddress(unsigned int lpmap_base,
         const char* szfucname,
         const char* szModuleName)
{

    PIMAGE_DOS_HEADER       dosHeader;
    PIMAGE_NT_HEADERS       ntHeader;
    PIMAGE_IMPORT_BY_NAME   ImportName;
PIMAGE_THUNK_DATA       pThunk;
PIMAGE_IMPORT_DESCRIPTOR ImportDec;
char* pDllName = NULL;
unsigned int i = 0;

dosHeader=(IMAGE_DOS_HEADER*)lpmap_base;
   
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpmap_base+dosHeader->e_lfanew);

ImportDec=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpmap_base+
RVAToOffset((LPVOID)lpmap_base,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
   
while(ImportDec->FirstThunk)
    {
   
pDllName=(char*)((BYTE*)lpmap_base+RVAToOffset((LPVOID)lpmap_base,ImportDec->Name));

if (strcmpi(pDllName,szModuleName)==0)
{
   if(ImportDec->OriginalFirstThunk)
   {
    pThunk=(PIMAGE_THUNK_DATA)((BYTE*)lpmap_base+
     RVAToOffset((LPVOID)lpmap_base,ImportDec->OriginalFirstThunk));

   }
   else
   {
    pThunk=(PIMAGE_THUNK_DATA)((BYTE*)lpmap_base+
     RVAToOffset((LPVOID)lpmap_base,ImportDec->FirstThunk));

   }
       
   while(pThunk->u1.Function)
   {
    if(pThunk->u1.Ordinal& IMAGE_ORDINAL_FLAG32)
    {
     //printf("EX_number:%x\n",pThunk->u1.Ordinal&0xFFFF);
    }
    else
    {

     ImportName=(IMAGE_IMPORT_BY_NAME*)((BYTE*)lpmap_base+
      RVAToOffset((LPVOID)lpmap_base,(DWORD)pThunk->u1.AddressOfData));

     if( strcmpi( (const char *)ImportName->Name,szfucname )==0 )
     {
      return (unsigned int)(ImportDec->FirstThunk + i*4);
     }
    
     //printf("--%s 0x%x \n",ImportName->Name, ImportDec->FirstThunk + i*4);
     i++;
    }
   
    pThunk++;
   }
}

ImportDec++;

}
   
return 0;


}
/*
text:000111F5                 call    ds:__imp__strncpy

FF 15 20 C0 01 00

text:00014D40                 call    ds:__imp__strncpy
FF 15 20 C0 01 00

.idata:0001C020 ; char *__cdecl _strncpy(char *, const char *, size_t)
.idata:0001C020                 extrn __imp__strncpy:dword


*/

BOOLEAN IsCallMatch_IAT( unsigned int uiAddress, unsigned int uiNorAddress)
{
__try
{
*(unsigned char*)uiAddress;

}__except(1)
{
return FALSE;
}

if( *(unsigned char*)uiAddress != 0xff || *(unsigned char*)( (unsigned char*)uiAddress + 1) != 0x15)
{
return FALSE;
}

return ( *(unsigned int*)( (unsigned char*)uiAddress + 2) == uiNorAddress ) ? TRUE : FALSE;

}

void _____testIMPORT()
{
char* testpath = "F:\\SysFilter\\.sys\\i386\\YasBoxFilter.sys";

mapfile_info mapfilexfo;

MAPFILE_INIT( testpath , &mapfilexfo);

unsigned int ui_strncpy_addr =
getiat_funcaddress( (unsigned long)mapfilexfo.lpMapbase,
(const char*)"strncpy",(const char*)"ntoskrnl.exe" );

printf("--0x%x\n",ui_strncpy_addr);
}
void main()
{
// ________test();
_____testIMPORT();

printf("xxxxxxxxx");

}


类别:默认分类 | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu