今天写了一半的程序,写不下去了,目前缓冲区溢出还是比较热门的,说到底是程序写代码没安全意识造成。在处理字符串上或者数组,整数上,造成了栈溢出,堆溢出或者整数溢出。当然有时候还有逻辑上的问题。下面的代码主要是想搜索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");
}