Windows的PE加载器在启动程序的时候,会将磁盘上的文件加载到内存,然后做很多操作,如函数导入表重定位,变量预处理之类的。这位仁兄等于是自己写了一接将内存中的程序启动。记得以前的“红色代码”病毒也有相同的特性。直接启动内存中的程序相当于加了一个壳,可以把程序加密保存,运行时解密到内存,然后启动,不过对于增加破解难度还要稍微复杂点。否则人家把内存中的进后修复导入表就被拖出来了。#includestdafx.htypedefIMAGE_SECTION_HEADER(*PIMAGE_SECTION_HEADERS)[1];//计算对齐后的大小unsignedlongGetAlignedSize(unsignedlongOrigin,unsignedlongAlignment){return(Origin+Alignment-1)/Alignment*Alignment;}//计算加载pe并对齐需要占用多少内存//未直接使用OptionalHeader.SizeOfImage作为结果是因为据说有的编译器生成的exe这个值会填0unsignedlongCalcTotalImageSize(PIMAGE_DOS_HEADERMzH,unsignedlongFileLen,PIMAGE_NT_HEADERSpeH,PIMAGE_SECTION_HEADERSpeSecH){unsignedlongres;//计算pe头的大小res=GetAlignedSize(peH-OptionalHeader.SizeOfHeaders,peH-OptionalHeader.SectionAlignment);//计算所有节的大小for(inti=0;ipeH-FileHeader.NumberOfSections;++i){//超出文件范围if(peSecH[i]-PointerToRawData+peSecH[i]-SizeOfRawDataFileLen)return0;elseif(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);}}elseif(peSecH[i]-Misc.VirtualSizepeSecH[i]-SizeOfRawData){res+=GetAlignedSize(peSecH[i]-SizeOfRawData,peH-OptionalHeader.SectionAlignment);}else{res+=GetAlignedSize(peSecH[i]-Misc.VirtualSize,peH-OptionalHeader.SectionAlignment);}//if_else}//forreturnres;}//加载pe到内存并对齐所有节BOOLAlignPEToMem(void*Buf,longLen,PIMAGE_NT_HEADERS&peH,PIMAGE_SECTION_HEADERS&peSecH,void*&Mem,unsignedlong&ImageSize){PIMAGE_DOS_HEADERSrcMz;//DOS头PIMAGE_NT_HEADERSSrcPeH;//PE头PIMAGE_SECTION_HEADERSSrcPeSecH;//节表SrcMz=(PIMAGE_DOS_HEADER)Buf;if(Lensizeof(IMAGE_DOS_HEADER))returnFALSE;if(SrcMz-e_magic!=IMAGE_DOS_SIGNATURE)returnFALSE;if(LenSrcMz-e_lfanew+(long)sizeof(IMAGE_NT_HEADERS))returnFALSE;SrcPeH=(PIMAGE_NT_HEADERS)((int)SrcMz+SrcMz-e_lfanew);if(SrcPeH-Signature!=IMAGE_NT_SIGNATURE)returnFALSE;if((SrcPeH-FileHeader.Characteristics&IMAGE_FILE_DLL)||(SrcPeH-FileHeader.Characteristics&IMAGE_FILE_EXECUTABLE_IMAGE==0)||(SrcPeH-FileHeader.SizeOfOptionalHeader!=sizeof(IMAGE_OPTIONAL_HEADER))){returnFALSE;}SrcPeSecH=(PIMAGE_SECTION_HEADERS)((int)SrcPeH+sizeof(IMAGE_NT_HEADERS));ImageSize=CalcTotalImageSize(SrcMz,Len,SrcPeH,SrcPeSecH);if(ImageSize==0)returnFALSE;Mem=VirtualAlloc(NULL,ImageSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);//分配内存if(Mem!=NULL){//计算需要复制的PE头字节数unsignedlongl=SrcPeH-OptionalHeader.SizeOfHeaders;for(inti=0;iSrcPeH-FileHeader.NumberOfSections;++i){if((SrcPeSecH[i]-PointerToRawData)&&(SrcPeSecH[i]-PointerToRawDatal)){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*)((unsignedlong)Mem+GetAlignedSize(peH-OptionalHeader.SizeOfHeaders,peH-OptionalHeader.SectionAlignment));for(i=0;ipeH-FileHeader.NumberOfSections;++i){//定位该节在内存中的位置if(peSecH[i]-VirtualAddress)Pt=(void*)((unsignedlong)Mem+peSecH[i]-VirtualAddress);if(peSecH[i]-SizeOfRawData){//复制数据到内存memmove(Pt,(constvoid*)((unsignedlong)(SrcMz)+peSecH[i]-PointerToRawData),peSecH[i]-SizeOfRawData);if(peSecH[i]-Misc.VirtualSizepeSecH[i]-SizeOfRawData)Pt=(void*)((unsignedlong)Pt+GetAlignedSize(peSecH[i]-SizeOfRawData,peH-OptionalHeader.SectionAlignment));else//pt定位到下一节开始位置Pt=(void*)((unsignedlong)Pt+GetAlignedSize(peSecH[i]-Misc.VirtualSize,peH-OptionalHeader.SectionAlignment));}else{Pt=(void*)((unsignedlong)Pt+GetAlignedSize(peSecH[i]-Misc.VirtualSize,peH-OptionalHeader.SectionAlignment));}}}returnTRUE;}typedefvoid*(__stdcall*pfVirtualAllocEx)(unsignedlong,void*,unsignedlong,unsignedlong,unsignedlong);pfVirtualAllocExMyVirtualAllocEx=NULL;BOOLIsNT(){returnMyVirtualAllocEx!=NULL;}//生成外壳程序命令行char*PrepareShellExe(char*CmdParam,unsignedlongBaseAddr,unsignedlongImageSize){if(IsNT()){char*Buf=newchar[256];memset(Buf,0,256);GetModuleFileName(0,Buf,256);strcat(Buf,CmdParam);returnBuf;//请记得释放内存;-)}else{//Win98下的处理请参考原文;-)//=8.709133E-03returnNULL;}}//是否包含可重定向列表BOOLHasRelocationTable(PIMAGE_NT_HEADERSpeH){return(peH-OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)&&(peH-OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);}#pragmapack(push,1)typedefstruct{unsignedlongVirtualAddress;unsignedlongSizeOfBlock;}*PImageBaseRelocation;#pragmapack(pop)//重定向PE用到的地址voidDoRelocation(PIMAGE_NT_HEADERSpeH,void*OldBase,void*NewBase){unsignedlongDelta=(unsignedlong)NewBase-peH-OptionalHeader.ImageBase;PImageBaseRelocationp=(PImageBaseRelocation)((unsignedlong)OldBase+peH-OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);while(p-VirtualAddress+p-SizeOfBlock){unsignedshort*pw=(unsignedshort*)((int)p+sizeof(*p));for(unsignedinti=1;i=(p-SizeOfBlock-sizeof(*p))/2;++i){if((*pw)&0xF000==0x3000){unsignedlong*t=(unsignedlong*)((unsignedlong)(OldBase)+p-Virt