php加壳,文件加壳实现(三) —— ZwUnmapViewOfSection

还不完整, 继续整理中

// TestShell.cpp : Defines the entry point for the application.

//

#include "stdafx.h"

#include

#include

#include

#include "PEOperate.h"

/*

以挂起的形式创建进程,

获取Context

*/

#define KEY 0x56

#pragma pack(push, 1)

typedef struct{

unsigned long VirtualAddress;

unsigned long SizeOfBlock;

} *PImageBaseRelocation;

#pragma pack(pop)

// 重定向PE用到的地址

void DoRelocation(PIMAGE_NT_HEADERS peH, void *OldBase, void *NewBase)

{

unsigned long Delta = (unsigned long)NewBase - peH->OptionalHeader.ImageBase;

PImageBaseRelocation p = (PImageBaseRelocation)((unsigned long)OldBase

+ peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);

while(p->VirtualAddress + p->SizeOfBlock)

{

unsigned short *pw = (unsigned short *)((int)p + sizeof(*p));

for(unsigned int i=1; i <= (p->SizeOfBlock - sizeof(*p)) / 2; ++i)

{

if((*pw) & 0xF000 == 0x3000){

unsigned long *t = (unsigned long *)((unsigned long)(OldBase) + p->VirtualAddress + ((*pw) & 0x0FFF));

*t += Delta;

}

++pw;

}

p = (PImageBaseRelocation)pw;

}

}

//在指定位置分配空间

BOOL AllocShellSize()

{

typedef void *(__stdcall *pfVirtualAllocEx)(unsigned long, void *, unsigned long, unsigned long, unsigned long);

pfVirtualAllocEx MyVirtualAllocEx = NULL;

MyVirtualAllocEx = (pfVirtualAllocEx)GetProcAddress(GetModuleHandle("Kernel32.dll"), "VirtualAllocEx");

//p = MyVirtualAllocEx((unsigned long)res, (void *)peH->OptionalHeader.ImageBase, ImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

//p = MyVirtualAllocEx((unsigned long)res, NULL, ImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

return FALSE;

}

// 卸载原外壳占用内存

BOOL UnloadShell(HANDLE ProcHnd, unsigned long BaseAddr)

{

typedef unsigned long (__stdcall *pfZwUnmapViewOfSection)(unsigned long, unsigned long);

pfZwUnmapViewOfSection ZwUnmapViewOfSection = NULL;

BOOL res = FALSE;

HMODULE m = LoadLibrary("ntdll.dll");

if(m){

ZwUnmapViewOfSection = (pfZwUnmapViewOfSection)GetProcAddress(m, "ZwUnmapViewOfSection");

//MessageBox(0,"1111",0,0);

if(ZwUnmapViewOfSection)

res = (ZwUnmapViewOfSection((unsigned long)ProcHnd, BaseAddr) == 0);

FreeLibrary(m);

}

return res;

}

LPVOID GetLastSecData(LPSTR lpszFile,DWORD &fileSize)

{

LPVOID pFileBuffer = NULL;

pFileBuffer= ReadPEFile(lpszFile);

if(!pFileBuffer)

{

printf("文件读取失败\n");

return NULL;

}

PIMAGE_DOS_HEADER pDosHeader = NULL;

PIMAGE_NT_HEADERS pNTHeader = NULL;

PIMAGE_FILE_HEADER pPEHeader = NULL;

PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;

PIMAGE_SECTION_HEADER pSectionHeader = NULL;

PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

//Header信息

pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;

pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);

pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);

pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);

pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);

int fileLength = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;

//判断是否已经加壳

if(strcmp((char*)pSectionHeader_LAST->Name,".enSec")!=0)

{

MessageBox(0,"没有加壳","错误",0);

return NULL;

}

fileSize = pSectionHeader_LAST->SizeOfRawData;

LPVOID pEncryptBuffer = malloc(fileSize);

memset(pEncryptBuffer,0,fileSize);

CHAR* pNew = (CHAR*)pEncryptBuffer;

CHAR* pOld = (CHAR*)((DWORD)pFileBuffer+pSectionHeader_LAST->PointerToRawData);

//将最后一个段的数据拷贝到pEncryptBuffer中,并解密

for(int i=0;i

{

pNew[i] = pOld[i]^KEY;

}

//关闭文件

free(pFileBuffer);

return pEncryptBuffer;

}

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

// TODO: Place code here.

TCHAR shellDirectory[256]={0};

GetModuleFileName(NULL,shellDirectory,256);

//MessageBox(0,shellDirectory,0,0);

DWORD encryptSize = 0;

LPVOID encryptFileBuffer = NULL;

encryptFileBuffer = GetLastSecData(shellDirectory,encryptSize);

//失败则结束

if(encryptFileBuffer == NULL)

{

MessageBox(0,"解密失败","失败",0);

//return 0;

}

//成功,goon

//WirteToFile(encryptFileBuffer,encryptSize,"C:\\aaa.exe");

//MessageBox(0,"结束","写出完成",MB_OK);

//以挂起的形式创建进程

STARTUPINFO si={0};

si.cb = sizeof(STARTUPINFO);

PROCESS_INFORMATION pi;

CreateProcess(shellDirectory,

NULL,

NULL,

NULL,

FALSE,

CREATE_SUSPENDED,

NULL,

NULL,

&si,&pi);

TCHAR szTempStr[256]={0};

sprintf(szTempStr,"进程消息: %x , %x \n",pi.hProcess,pi.hThread);

CONTEXT contx;

contx.ContextFlags = CONTEXT_FULL;

GetThreadContext(pi.hThread,&contx);

DWORD shellOEP = contx.Eax;

//获取IMAGE_BASE的信息

char* baseAddress = (CHAR*)contx.Ebx+8;

TCHAR szBuffer[4]={0};

ReadProcessMemory(pi.hProcess,baseAddress,szBuffer,4,NULL);

int* fileImageBase;

fileImageBase = (int*)szBuffer;

DWORD shellImageBase = *fileImageBase;

//卸载外壳程序

BOOL isUnload = UnloadShell(pi.hProcess,shellImageBase);

/*

if(isUnload)

{

MessageBox(0,"成功","1",0);

}else

{

MessageBox(0,"失败","0",0);

}

*/

//在指定位置分配空间

//位置: Src的ImageBase

//大小: Src的SizeOfImage

BOOL isAlloc = AllocShellSize();

//ResumeThread(pi.hThread);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值