直接运行内存中的程序

2020-04-17 20:03

直接运行内存中的程序

Windows的PE加载器在启动程序的时候,会将磁盘上的文件加载到内存,然后做很多操作,如函数导入表重定位,变量预处理之类的。这位仁兄等于是自己写了一个PE加载器。直接将内存中的程序启动。记得以前的“红色代码”病毒也有相同的特性。

直接启动内存中的程序相当于加了一个壳,可以把程序加密保存,运行时解密到内存,然后启动,不过对于增加破解难度还要稍微复杂点。否则人家把内存中的进程DUMP出来然后修复导入表就被拖出来了。

#include \

typedef IMAGE_SECTION_HEADER (*PIMAGE_SECTION_HEADERS)[1];

// 计算对齐后的大小

unsigned long GetAlignedSize(unsigned long Origin, unsigned long Alignment) {

return (Origin + Alignment - 1) / Alignment * Alignment; }

// 计算加载pe并对齐需要占用多少内存

// 未直接使用OptionalHeader.SizeOfImage作为结果是因为据说有的编译器生成的exe这个值会填0 unsigned long CalcTotalImageSize(PIMAGE_DOS_HEADER MzH , unsigned long FileLen , PIMAGE_NT_HEADERS peH

, PIMAGE_SECTION_HEADERS peSecH) {

unsigned long res; // 计算pe头的大小

res = GetAlignedSize( peH->OptionalHeader.SizeOfHeaders , peH->OptionalHeader.SectionAlignment );

// 计算所有节的大小

for( int i = 0; i < peH->FileHeader.NumberOfSections; ++i) {

// 超出文件范围

if(peSecH[i]->PointerToRawData + peSecH[i]->SizeOfRawData > FileLen) return 0;

else if(peSecH[i]->VirtualAddress)//计算对齐后某节的大小 {

if(peSecH[i]->Misc.VirtualSize) {

res = GetAlignedSize( peSecH[i]->VirtualAddress + peSecH[i]->Misc.VirtualSize , peH->OptionalHeader.SectionAlignment ); } else {

res = GetAlignedSize( peSecH[i]->VirtualAddress + peSecH[i]->SizeOfRawData , peH->OptionalHeader.SectionAlignment ); } }

else if( peSecH[i]->Misc.VirtualSize < peSecH[i]->SizeOfRawData ) {

res += GetAlignedSize( peSecH[i]->SizeOfRawData , peH->OptionalHeader.SectionAlignment ); } else {

res += GetAlignedSize( peSecH[i]->Misc.VirtualSize , peH->OptionalHeader.SectionAlignment ); }// if_else }// for

return res; }

// 加载pe到内存并对齐所有节 BOOL AlignPEToMem( void *Buf , long Len

, PIMAGE_NT_HEADERS &peH

, PIMAGE_SECTION_HEADERS &peSecH , void *&Mem

, unsigned long &ImageSize) {

PIMAGE_DOS_HEADER SrcMz;// DOS头 PIMAGE_NT_HEADERS SrcPeH;// PE头

PIMAGE_SECTION_HEADERS SrcPeSecH;// 节表

SrcMz = (PIMAGE_DOS_HEADER)Buf;

if( Len < sizeof(IMAGE_DOS_HEADER) ) return FALSE;

if( SrcMz->e_magic != IMAGE_DOS_SIGNATURE ) return FALSE;

if( Len < SrcMz->e_lfanew + (long)sizeof(IMAGE_NT_HEADERS) ) return FALSE;

SrcPeH = (PIMAGE_NT_HEADERS)((int)SrcMz + SrcMz->e_lfanew); if( SrcPeH->Signature != IMAGE_NT_SIGNATURE ) return FALSE;

if( (SrcPeH->FileHeader.Characteristics & IMAGE_FILE_DLL) ||

(SrcPeH->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE == 0) ||

(SrcPeH->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER)) ) {

return FALSE; }

SrcPeSecH = (PIMAGE_SECTION_HEADERS)((int)SrcPeH + sizeof(IMAGE_NT_HEADERS)); ImageSize = CalcTotalImageSize( SrcMz, Len, SrcPeH, SrcPeSecH);

if( ImageSize == 0 ) return FALSE;

Mem = VirtualAlloc( NULL, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // 分配内存 if( Mem != NULL ) {

// 计算需要复制的PE头字节数

unsigned long l = SrcPeH->OptionalHeader.SizeOfHeaders; for( int i = 0; i < SrcPeH->FileHeader.NumberOfSections; ++i) {

if( (SrcPeSecH[i]->PointerToRawData) && (SrcPeSecH[i]->PointerToRawData < l) ) {

l = SrcPeSecH[i]->PointerToRawData; } }

memmove( Mem, SrcMz, l);

peH = (PIMAGE_NT_HEADERS)((int)Mem + ((PIMAGE_DOS_HEADER)Mem)->e_lfanew); peSecH = (PIMAGE_SECTION_HEADERS)((int)peH + sizeof(IMAGE_NT_HEADERS));

void *Pt = (void *)((unsigned long)Mem

+ GetAlignedSize( peH->OptionalHeader.SizeOfHeaders , peH->OptionalHeader.SectionAlignment) );

for( i = 0; i < peH->FileHeader.NumberOfSections; ++i) {

// 定位该节在内存中的位置 if(peSecH[i]->VirtualAddress)

Pt = (void *)((unsigned long)Mem + peSecH[i]->VirtualAddress);

if(peSecH[i]->SizeOfRawData) {

// 复制数据到内存

memmove(Pt, (const void *)((unsigned long)(SrcMz) + peSecH[i]->PointerToRawData), peSecH[i]->SizeOfRawData); if(peSecH[i]->Misc.VirtualSize < peSecH[i]->SizeOfRawData)

Pt = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->SizeOfRawData, peH->OptionalHeader.SectionAlignment)); else // pt 定位到下一节开始位置

Pt = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->Misc.VirtualSize, peH->OptionalHeader.SectionAlignment)); } else {

Pt = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->Misc.VirtualSize, peH->OptionalHeader.SectionAlignment)); } } }

return TRUE; }

typedef void *(__stdcall *pfVirtualAllocEx)(unsigned long, void *, unsigned long, unsigned long, unsigned long); pfVirtualAllocEx MyVirtualAllocEx = NULL;

BOOL IsNT() {

return MyVirtualAllocEx!=NULL;


直接运行内存中的程序.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:新疆九年级上册综合实践活动教师用书

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: