版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、Windows的PE加載器在啟動程序的時候,會將磁盤上的文件加載到內存,然后做很多操作,如函數(shù)導入表重定位,變量預處理之類的。這位仁兄等于是自己寫了一個PE加載器。直接將內存中的程序啟動。記得以前的“紅色代碼”病毒也有相同的特性。 直接啟動內存中的程序相當于加了一個殼,可以把程序加密保存,運行時解密到內存,然后啟動,不過對于增加破解難度還要稍微復雜點。否則人家把內存中的進程DUMP出來然后修復導入表就被拖出來了。 #includestdafx.htypedefIMAGE_SECTION_HEADER(*PIMAGE_SECTION_HEADERS)1;/計算對齊后的大小unsignedlong
2、GetAlignedSize(unsignedlongOrigin,unsignedlongAlignment)return(Origin+Alignment- 1)/Alignment*Alignment;/計算加載pe并對齊需要占用多少內存/未直接使用OptionalHeader.SizeOfImage作為結果是因為據(jù)說有的編譯器生成的exe這個值會填0unsignedlongCalcTotalImageSize(PIMAGE_DOS_HEADERMzH,unsignedlongFileLen,PIMAGE_NT_HEADERSpeH,PIMAGE_SECTION_HEADERSpeSec
3、H)unsignedlongres;/計算pe頭的大小res=GetAlignedSize(peH-OptionalHeader.SizeOfHeaders,peH-OptionalHeader.SectionAlignment);/計算所有節(jié)的大小for(inti= 0;iFileHeader.NumberOfSections;+i)/超出文件范圍if(peSecHi-PointerToRawData+peSecHi-SizeOfRawDataFileLen)return 0;else if(peSecHi-VirtualAddress)/計算對齊后某節(jié)的大小if(peSecHi-Misc.
4、VirtualSize)res=GetAlignedSize(peSecHi-VirtualAddress+peSecHi-Misc.VirtualSize,peH-OptionalHeader.SectionAlignment);elseres=GetAlignedSize(peSecHi-VirtualAddress+peSecHi-SizeOfRawData,peH-OptionalHeader.SectionAlignment);else if(peSecHi-Misc.VirtualSizeSizeOfRawData)res+=GetAlignedSize(peSecHi-SizeO
5、fRawData,peH-OptionalHeader.SectionAlignment);elseres+=GetAlignedSize(peSecHi-Misc.VirtualSize,peH-OptionalHeader.SectionAlignment);/if_else/forreturnres;/加載pe到內存并對齊所有節(jié)BOOLAlignPEToMem(void *Buf,longLen,PIMAGE_NT_HEADERS&peH,PIMAGE_SECTION_HEADERS&peSecH,void *&Mem,unsignedlong &ImageSize)PIMAGE_DOS
6、_HEADERSrcMz;/DOS頭PIMAGE_NT_HEADERSSrcPeH;/PE頭PIMAGE_SECTION_HEADERSSrcPeSecH;/節(jié)表SrcMz=(PIMAGE_DOS_HEADER)Buf;if(Lene_magic!=IMAGE_DOS_SIGNATURE)returnFALSE;if(Lene_lfanew+(long)sizeof(IMAGE_NT_HEADERS)returnFALSE;SrcPeH=(PIMAGE_NT_HEADERS)(int)SrcMz+SrcMz-e_lfanew);if(SrcPeH-Signature!=IMAGE_NT_SIG
7、NATURE)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);ImageSiz
8、e=CalcTotalImageSize(SrcMz,Len,SrcPeH,SrcPeSecH);if(ImageSize= 0)returnFALSE;Mem=VirtualAlloc(NULL,ImageSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);/分配內存if(Mem!=NULL)/計算需要復制的PE頭字節(jié)數(shù)unsignedlongl=SrcPeH-OptionalHeader.SizeOfHeaders;for(inti= 0;iFileHeader.NumberOfSections;+i)if(SrcPeSecHi-PointerToRawData
9、)&(SrcPeSecHi-PointerToRawDataPointerToRawData;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
10、.SectionAlignment);for(i= 0;iFileHeader.NumberOfSections;+i)/定位該節(jié)在內存中的位置if(peSecHi-VirtualAddress)Pt=(void *)(unsignedlong)Mem+peSecHi-VirtualAddress);if(peSecHi-SizeOfRawData)/復制數(shù)據(jù)到內存memmove(Pt,(constvoid *)(unsignedlong)(SrcMz)+peSecHi-PointerToRawData),peSecHi-SizeOfRawData);if(peSecHi-Misc.Virtu
11、alSizeSizeOfRawData)Pt=(void *)(unsignedlong)Pt+GetAlignedSize(peSecHi-SizeOfRawData,peH-OptionalHeader.SectionAlignment);else /pt定位到下一節(jié)開始位置Pt=(void *)(unsignedlong)Pt+GetAlignedSize(peSecHi-Misc.VirtualSize,peH-OptionalHeader.SectionAlignment);elsePt=(void *)(unsignedlong)Pt+GetAlignedSize(peSecHi-
12、Misc.VirtualSize,peH-OptionalHeader.SectionAlignment);returnTRUE;typedefvoid *(_stdcall*pfVirtualAllocEx)(unsignedlong,void *,unsignedlong,unsignedlong,unsignedlong);pfVirtualAllocExMyVirtualAllocEx=NULL;BOOLIsNT()returnMyVirtualAllocEx!=NULL;/生成外殼程序命令行char *PrepareShellExe(char *CmdParam,unsignedlo
13、ngBaseAddr,unsignedlongImageSize)if(IsNT()char *Buf= new char256;memset(Buf,0,256);GetModuleFileName(0,Buf,256);strcat(Buf,CmdParam);returnBuf;/請記得釋放內存;-)else/Win98下的處理請參考原文;-)/ :/ *PImageBaseRelocation;#pragmapack(pop)/重定向PE用到的地址voidDoRelocation(PIMAGE_NT_HEADERSpeH,void *OldBase,void *NewBase)unsi
14、gnedlongDelta=(unsignedlong)NewBase-peH-OptionalHeader.ImageBase;PImageBaseRelocationp=(PImageBaseRelocation)(unsignedlong)OldBase+peH-OptionalHeader.DataDirectoryIMAGE_DIRECTORY_ENTRY_BASERELOC.VirtualAddress);while(p-VirtualAddress+p-SizeOfBlock)unsignedshort *pw=(unsignedshort *)(int)p+sizeof(*p)
15、;for(unsignedinti=1;iSizeOfBlock-sizeof(*p)/ 2;+i)if(*pw)& 0 xF000 = 0 x3000)unsignedlong *t=(unsignedlong *)(unsignedlong)(OldBase)+p-VirtualAddress+(*pw)& 0 x0FFF);*t+=Delta;+pw;p=(PImageBaseRelocation)pw;/卸載原外殼占用內存BOOLUnloadShell(HANDLEProcHnd,unsignedlongBaseAddr)typedefunsignedlong(_stdcall*pfZ
16、wUnmapViewOfSection)(unsignedlong,unsignedlong);pfZwUnmapViewOfSectionZwUnmapViewOfSection=NULL;BOOLres=FALSE;HMODULEm=LoadLibrary(ntdll.dll);if(m)ZwUnmapViewOfSection=(pfZwUnmapViewOfSection)GetProcAddress(m,ZwUnmapViewOfSection);if(ZwUnmapViewOfSection)res=(ZwUnmapViewOfSection(unsignedlong)ProcHn
17、d,BaseAddr)= 0);FreeLibrary(m);returnres;/創(chuàng)建外殼進程并獲取其基址、大小和當前運行狀態(tài)BOOLCreateChild(char *Cmd,CONTEXT&Ctx,HANDLE&ProcHnd,HANDLE&ThrdHnd,unsignedlong &ProcId,unsignedlong &BaseAddr,unsignedlong &ImageSize)STARTUPINFOAsi;PROCESS_INFORMATIONpi;unsignedlongold;MEMORY_BASIC_INFORMATIONMemInfo;memset(&si,0,si
18、zeof(si);memset(&pi,0,sizeof(pi);si.cb=sizeof(si);BOOLres=CreateProcess(NULL,Cmd,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi);/以掛起方式運行進程;if(res)ProcHnd=pi.hProcess;ThrdHnd=pi.hThread;ProcId=pi.dwProcessId;/獲取外殼進程運行狀態(tài),ctx.Ebx+8內存處存的是外殼進程的加載基址,ctx.Eax存放有外殼進程的入口地址Ctx.ContextFlags=CONTEXT_FULL;Ge
19、tThreadContext(ThrdHnd,&Ctx);ReadProcessMemory(ProcHnd,(void *)(Ctx.Ebx+8),&BaseAddr,sizeof(unsignedlong),&old);/讀取加載基址void *p=(void *)BaseAddr;/計算外殼進程占有的內存while(VirtualQueryEx(ProcHnd,p,&MemInfo,sizeof(MemInfo)if(MemInfo.State=MEM_FREE)break;p=(void *)(unsignedlong)p+MemInfo.RegionSize);ImageSize=(
20、unsignedlong)p-(unsignedlong)BaseAddr;returnres;/創(chuàng)建外殼進程并用目標進程替換它然后執(zhí)行HANDLEAttachPE(char *CmdParam,PIMAGE_NT_HEADERSpeH,PIMAGE_SECTION_HEADERSpeSecH,void *Ptr,unsignedlongImageSize,unsignedlong &ProcId)HANDLEres=INVALID_HANDLE_VALUE;CONTEXTCtx;HANDLEThrd;unsignedlongAddr,Size;char *s=PrepareShellExe(
21、CmdParam,peH-OptionalHeader.ImageBase,ImageSize);if(s=NULL)returnres;if(CreateChild(s,Ctx,res,Thrd,ProcId,Addr,Size)void *p=NULL;unsignedlongold;if(peH-OptionalHeader.ImageBase=Addr)&(Size=ImageSize)/外殼進程可以容納目標進程并且加載地址一致p=(void *)Addr;VirtualProtectEx(res,p,Size,PAGE_EXECUTE_READWRITE,&old);else if(
22、IsNT()if(UnloadShell(res,Addr)/卸載外殼進程占有內存p=MyVirtualAllocEx(unsignedlong)res,(void *)peH-OptionalHeader.ImageBase,ImageSize,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);if(p=NULL)&HasRelocationTable(peH)/分配內存失敗并且目標進程支持重定向p=MyVirtualAllocEx(unsignedlong)res,NULL,ImageSize,MEM_RESERVE|MEM_COMMIT,PAG
23、E_EXECUTE_READWRITE);if(p)DoRelocation(peH,Ptr,p);/重定向if(p)WriteProcessMemory(res,(void *)(Ctx.Ebx+8),&p,sizeof(DWORD),&old);/重置目標進程運行環(huán)境中的基址peH-OptionalHeader.ImageBase=(unsignedlong)p;if(WriteProcessMemory(res,p,Ptr,ImageSize,&old)/復制PE數(shù)據(jù)到目標進程Ctx.ContextFlags=CONTEXT_FULL;if(unsignedlong)p=Addr)Ctx
24、.Eax=peH-OptionalHeader.ImageBase+peH-OptionalHeader.AddressOfEntryPoint;/重置運行環(huán)境中的入口地址elseCtx.Eax=(unsignedlong)p+peH-OptionalHeader.AddressOfEntryPoint;SetThreadContext(Thrd,&Ctx);/更新運行環(huán)境ResumeThread(Thrd);/執(zhí)行CloseHandle(Thrd);else/加載失敗,殺掉外殼進程TerminateProcess(res,0);CloseHandle(Thrd);CloseHandle(re
25、s);res=INVALID_HANDLE_VALUE;else/加載失敗,殺掉外殼進程TerminateProcess(res,0);CloseHandle(Thrd);CloseHandle(res);res=INVALID_HANDLE_VALUE;deletes;returnres;/*/*從內存中加載并運行exe*參數(shù):*Buffer:內存中的exe地址*Len:內存中exe占用長度*CmdParam:命令行參數(shù)(不包含exe文件名的剩余命令行參數(shù))*ProcessId:返回的進程Id*返回值:如果成功則返回進程的Handle(ProcessHandle),如果失敗則返回INVALI
26、D_HANDLE_VALUE*/HANDLEMemExecute(void *ABuffer,longLen,char *CmdParam,unsignedlong *ProcessId)HANDLEres=INVALID_HANDLE_VALUE;PIMAGE_NT_HEADERSpeH;PIMAGE_SECTION_HEADERSpeSecH;void *Ptr;unsignedlongpeSz;if(AlignPEToMem(ABuffer,Len,peH,peSecH,Ptr,peSz)res=AttachPE(CmdParam,peH,peSecH,Ptr,peSz,*Process
27、Id);VirtualFree(Ptr,peSz,MEM_DECOMMIT);returnres;/初始化classCInitpublic:CInit()MyVirtualAllocEx=(pfVirtualAllocEx)GetProcAddress(GetModuleHandle(Kernel32.dll),VirtualAllocEx);Init;intAPIENTRYWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow)HANDLEhFile=NULL;hFile=:CreateFile
28、(f:SourceFromCsdn2.exe,FILE_ALL_ACCESS,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(hFile=INVALID_HANDLE_VALUE)return -1;:SetFilePointer(hFile,0,NULL,FILE_BEGIN);DWORDdwFileSize=:GetFileSize(hFile,NULL);LPBYTEpBuf= newBYTEdwFileSize;memset(pBuf,0,dwFileSize);DWORDdwNumberOfBytesRead= 0;:ReadF
29、ile(hFile,pBuf,dwFileSize,&dwNumberOfBytesRead,NULL);:CloseHandle(hFile);unsignedlongulProcessId= 0;MemExecute(pBuf,dwFileSize,&ulProcessId);deletepBuf;return 0;=DELPHI版本=windows似乎只提供了一種啟動進程的方法:即必須從一個可執(zhí)行文件中加載并啟動。而下面這段代碼就是提供一種可以直接從內存中啟動一個exe的變通辦法。用途嘛, 也許可以用來保護你的exe,你可以對要保護的 exe 進行任意切分、加密、存儲,只要運行時能將ex
30、e的內容正確拼接到一塊內存中,就可以直接從內存中啟動,而不必不安全地去生成一個臨時文件再從臨時文件啟動進程。另外這段代碼也提供了一種自己寫exe外殼的簡單途徑,如果能配合其它各種外殼技術就更好地保護你的exe文件。原理很簡單:就是“借尸還魂”,啟動一個僵尸進程(NT下可以是自身程序啟動的另一個進程),然后在它運行前將其整個替換成內存中的exe內容,待正式運行后執(zhí)行的就是你的目標代碼了。不過代碼中還有一些不盡人意的地方,比如在98下運行會留一個僵尸程序的殼在硬盤上(其實那個僵尸程序本身就是一個完整的可執(zhí)行程序,直接運行的話只顯示一條錯誤信息然后就退出了)。另外由于客觀條件限制,代碼沒有經過充分測
31、試,只在XP下進行了一些初步測試:普通exe都能正常運行,upx壓縮過的exe絕大多數(shù)情況下都能運行,只有在不能卸載僵尸外殼時才有問題(upx壓縮過的exe沒有重定向表,無法加載到其它地址運行)。如果有bug望告之,如果有更好的方法特別是能解決98下的遺留尾巴的話希望不吝賜教。 Idle_ (阿呆) * * 從內存中加載并運行exe * * * 參數(shù): * Buffer: 內存中的exe地址 * Len: 內存中exe占用長度 * CmdParam: 命令行參數(shù)(不包含exe文件名的剩余命令行參數(shù)) * ProcessId: 返回的進程Id * 返回值: 如果成功則返回進程的Handle(Pr
32、ocessHandle), 如果失敗則返回INVALID_HANDLE_VALUE * unit PEUnit;interfaceuses windows;function MemExecute(const ABuffer; Len: Integer; CmdParam: string; varProcessId: Cardinal): Cardinal;implementation$R ExeShell.res / 外殼程序模板(98下使用)typeTImageSectionHeaders = array 0.0 of TImageSectionHeader;PImageSectionHea
33、ders = TImageSectionHeaders; 計算對齊后的大小 function GetAlignedSize(Origin, Alignment: Cardinal): Cardinal;beginresult := (Origin + Alignment - 1) div Alignment * Alignment;end; 計算加載pe并對齊需要占用多少內存,未直接使用OptionalHeader.SizeOfImage作為結果是因為據(jù)說有的編譯器生成的exe這個值會填0 function CalcTotalImageSize(MzH: PImageDosHeader; Fi
34、leLen: Cardinal; peH:PImageNtHeaders;peSecH: PImageSectionHeaders): Cardinal;vari: Integer;begin計算pe頭的大小result := GetAlignedSize(PeH.OptionalHeader.SizeOfHeaders,PeH.OptionalHeader.SectionAlignment);計算所有節(jié)的大小for i := 0 to peH.FileHeader.NumberOfSections - 1 doif peSecHi.PointerToRawData + peSecHi.Siz
35、eOfRawData FileLen then / 超出文件范圍beginresult := 0;exit;endelse if peSecHi.VirtualAddress 0 then /計算對齊后某節(jié)的大小if peSecHi.Misc.VirtualSize 0 thenresult := GetAlignedSize(peSecHi.VirtualAddress +peSecHi.Misc.VirtualSize, PeH.OptionalHeader.SectionAlignment)elseresult := GetAlignedSize(peSecHi.VirtualAddre
36、ss + peSecHi.SizeOfRawData,PeH.OptionalHeader.SectionAlignment)else if peSecHi.Misc.VirtualSize peSecHi.SizeOfRawData thenresult := result + GetAlignedSize(peSecHi.SizeOfRawData,peH.OptionalHeader.SectionAlignment)elseresult := result + GetAlignedSize(peSecHi.Misc.VirtualSize,PeH.OptionalHeader.Sect
37、ionAlignment);end; 加載pe到內存并對齊所有節(jié) function AlignPEToMem(const Buf; Len: Integer; var PeH: PImageNtHeaders;var PeSecH: PImageSectionHeaders; var Mem: Pointer; var ImageSize:Cardinal): Boolean;varSrcMz: PImageDosHeader; / DOS頭SrcPeH: PImageNtHeaders; / PE頭SrcPeSecH: PImageSectionHeaders; / 節(jié)表i: Integer
38、;l: Cardinal;Pt: Pointer;beginresult := false;SrcMz := Buf;if Len sizeof(TImageDosHeader) then exit;if SrcMz.e_magic IMAGE_DOS_SIGNATURE then exit;if Len SrcMz._lfanew+Sizeof(TImageNtHeaders) then exit;SrcPeH := pointer(Integer(SrcMz)+SrcMz._lfanew);if (SrcPeH.Signature IMAGE_NT_SIGNATURE) then exit
39、;if (SrcPeH.FileHeader.Characteristics and IMAGE_FILE_DLL 0) or(SrcPeH.FileHeader.Characteristics and IMAGE_FILE_EXECUTABLE_IMAGE = 0)or (SrcPeH.FileHeader.SizeOfOptionalHeader SizeOf(TImageOptionalHeader) then exit;SrcPeSecH := Pointer(Integer(SrcPeH)+SizeOf(TImageNtHeaders);ImageSize := CalcTotalI
40、mageSize(SrcMz, Len, SrcPeH, SrcPeSecH);if ImageSize = 0 thenexit;Mem := VirtualAlloc(nil, ImageSize, MEM_COMMIT,PAGE_EXECUTE_READWRITE); / 分配內存if Mem nil thenbegin/ 計算需要復制的PE頭字節(jié)數(shù)l := SrcPeH.OptionalHeader.SizeOfHeaders;for i := 0 to SrcPeH.FileHeader.NumberOfSections - 1 doif (SrcPeSecHi.PointerToR
41、awData 0) and (SrcPeSecHi.PointerToRawData l) thenl := SrcPeSecHi.PointerToRawData;Move(SrcMz, Mem, l);PeH := Pointer(Integer(Mem) + PImageDosHeader(Mem)._lfanew);PeSecH := Pointer(Integer(PeH) + sizeof(TImageNtHeaders);Pt := Pointer(Cardinal(Mem) +GetAlignedSize(PeH.OptionalHeader.SizeOfHeaders,PeH
42、.OptionalHeader.SectionAlignment);for i := 0 to PeH.FileHeader.NumberOfSections - 1 dobegin/ 定位該節(jié)在內存中的位置if PeSecHi.VirtualAddress 0 thenPt := Pointer(Cardinal(Mem) + PeSecHi.VirtualAddress);if PeSecHi.SizeOfRawData 0 thenbegin/ 復制數(shù)據(jù)到內存Move(Pointer(Cardinal(SrcMz) + PeSecHi.PointerToRawData), pt,PeSe
43、cHi.SizeOfRawData);if peSecHi.Misc.VirtualSize peSecHi.SizeOfRawData thenpt := pointer(Cardinal(pt) + GetAlignedSize(PeSecHi.SizeOfRawData,PeH.OptionalHeader.SectionAlignment)elsept := pointer(Cardinal(pt) + GetAlignedSize(peSecHi.Misc.VirtualSize,peH.OptionalHeader.SectionAlignment);/ pt 定位到下一節(jié)開始位置
44、endelsept := pointer(Cardinal(pt) + GetAlignedSize(PeSecHi.Misc.VirtualSize,PeH.OptionalHeader.SectionAlignment);end;result := True;end;end;typeTVirtualAllocEx = function (hProcess: THandle; lpAddress: Pointer;dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;varMyVirtualAllocEx:
45、TVirtualAllocEx = nil;function IsNT: Boolean;beginresult := Assigned(MyVirtualAllocEx);end; 生成外殼程序命令行 function PrepareShellExe(CmdParam: string; BaseAddr, ImageSize: Cardinal):string;varr, h, sz: Cardinal;p: Pointer;fid, l: Integer;buf: Pointer;peH: PImageNtHeaders;peSecH: PImageSectionHeaders;begin
46、if IsNT then NT 系統(tǒng)下直接使用自身程序作為外殼進程 result := ParamStr(0)+CmdParamelse begin/ 由于98系統(tǒng)下無法重新分配外殼進程占用內存,所以必須保證運行的外殼程序能容納目標進程并且加載地址一致/ 此處使用的方法是從資源中釋放出一個事先建立好的外殼程序,然后通過修改其PE頭使其運行時能加載到指定地址并至少能容納目標進程r := FindResource(HInstance, SHELL_EXE, RT_RCDATA);h := LoadResource(HInstance, r);p := LockResource(h);l := Si
47、zeOfResource(HInstance, r);GetMem(Buf, l);Move(p, Buf, l); / 讀到內存FreeResource(h);peH := Pointer(Integer(Buf) + PImageDosHeader(Buf)._lfanew);peSecH := Pointer(Integer(peH) + sizeof(TImageNtHeaders);peH.OptionalHeader.ImageBase := BaseAddr; / 修改PE頭重的加載基址if peH.OptionalHeader.SizeOfImage ImageSize the
48、n / 目標比外殼大,修改外殼程序運行時占用的內存beginsz := Imagesize - peH.OptionalHeader.SizeOfImage;Inc(peH.OptionalHeader.SizeOfImage, sz); / 調整總占用內存數(shù)Inc(peSecHpeH.FileHeader.NumberOfSections-1.Misc.VirtualSize, sz); / 調整最后一節(jié)占用內存數(shù)end;/ 生成外殼程序文件名, 為本程序改后綴名得到的/ 由于不想 uses SysUtils (一旦 use 了程序將增大80K左右), 而且偷懶,所以只支持最多運行11個進程
49、,后綴名為.dat, .da0.da9result := ParamStr(0);result := copy(result, 1, length(result) - 4) + .dat;r := 0;while r 10 dobeginfid := CreateFile(pchar(result), GENERIC_READ or GENERIC_WRITE, 0, nil,Create_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);if fid 0 thenbeginresult := copy(result, 1, length(result)-3)+da+Char
50、(r+Byte(0);inc(r);endelse begin/SetFilePointer(fid, Imagesize, nil, 0);/SetEndOfFile(fid);/SetFilePointer(fid, 0, nil, 0);WriteFile(fid, Buf, l, h, nil); / 寫入文件CloseHandle(fid);break;end;end;result := result + CmdParam; / 生成命令行FreeMem(Buf);end;end; 是否包含可重定向列表 function HasRelocationTable(peH: PImageN
51、tHeaders): Boolean;beginresult := (peH.OptionalHeader.DataDirectoryIMAGE_DIRECTORY_ENTRY_BASERELOC.VirtualAddress 0)and(peH.OptionalHeader.DataDirectoryIMAGE_DIRECTORY_ENTRY_BASERELOC.Size 0);end;typePImageBaseRelocation= TImageBaseRelocation;TImageBaseRelocation = packed recordVirtualAddress: cardi
52、nal;SizeOfBlock: cardinal;end; 重定向PE用到的地址 procedure DoRelocation(peH: PImageNtHeaders; OldBase, NewBase: Pointer);varDelta: Cardinal;p: PImageBaseRelocation;pw: PWord;i: Integer;beginDelta := Cardinal(NewBase) - peH.OptionalHeader.ImageBase;p := pointer(cardinal(OldBase) +peH.OptionalHeader.DataDire
53、ctoryIMAGE_DIRECTORY_ENTRY_BASERELOC.VirtualAddress);while (p.VirtualAddress + p.SizeOfBlock 0) dobeginpw := pointer(Integer(p) + Sizeof(p);for i := 1 to (p.SizeOfBlock - Sizeof(p) div 2 dobeginif pw and $F000 = $3000 thenInc(PCardinal(Cardinal(OldBase) + p.VirtualAddress + (pw and $0FFF), Delta);in
54、c(pw);end;p := Pointer(pw);end;end;typeTZwUnmapViewOfSection = function (Handle, BaseAdr: Cardinal): Cardinal;stdcall; 卸載原外殼占用內存 function UnloadShell(ProcHnd, BaseAddr: Cardinal): Boolean;varM: HModule;ZwUnmapViewOfSection: TZwUnmapViewOfSection;beginresult := False;m := LoadLibrary(ntdll.dll);if m
55、0 thenbeginZwUnmapViewOfSection := GetProcAddress(m, ZwUnmapViewOfSection);if assigned(ZwUnmapViewOfSection) thenresult := (ZwUnmapViewOfSection(ProcHnd, BaseAddr) = 0);FreeLibrary(m);end;end; 創(chuàng)建外殼進程并獲取其基址、大小和當前運行狀態(tài) function CreateChild(Cmd: string; var Ctx: TContext; var ProcHnd, ThrdHnd,ProcId, Ba
56、seAddr, ImageSize: Cardinal): Boolean;varsi: TStartUpInfo;pi: TProcessInformation;Old: Cardinal;MemInfo: TMemoryBasicInformation;p: Pointer;beginFillChar(si, Sizeof(si), 0);FillChar(pi, SizeOf(pi), 0);si.cb := sizeof(si);result := CreateProcess(nil, PChar(Cmd), nil, nil, False, Create_SUSPENDED, nil
57、,nil, si, pi); / 以掛起方式運行進程if result thenbeginProcHnd := pi.hProcess;ThrdHnd := pi.hThread;ProcId := pi.dwProcessId; 獲取外殼進程運行狀態(tài),ctx.Ebx+8內存處存的是外殼進程的加載基址,ctx.Eax存放有外殼進程的入口地址 ctx.ContextFlags := CONTEXT_FULL;GetThreadContext(ThrdHnd, ctx);ReadProcessMemory(ProcHnd, Pointer(ctx.Ebx+8), BaseAddr,SizeOf(C
58、ardinal), Old); / 讀取加載基址p := Pointer(BaseAddr); 計算外殼進程占有的內存 while VirtualQueryEx(ProcHnd, p, MemInfo, Sizeof(MemInfo) 0 dobeginif MemInfo.State = MEM_FREE thenbreak;p := Pointer(Cardinal(p) + MemInfo.RegionSize);end;ImageSize := Cardinal(p) - Cardinal(BaseAddr);end;end; 創(chuàng)建外殼進程并用目標進程替換它然后執(zhí)行 function
59、AttachPE(CmdParam: string; peH: PImageNtHeaders; peSecH:PImageSectionHeaders;Ptr: Pointer; ImageSize: Cardinal; var ProcId: Cardinal): Cardinal;vars: string;Addr, Size: Cardinal;ctx: TContext;Old: Cardinal;p: Pointer;Thrd: Cardinal;beginresult := INVALID_HANDLE_VALUE;s := PrepareShellExe(CmdParam, p
60、eH.OptionalHeader.ImageBase, ImageSize);if CreateChild(s, ctx, result, Thrd, ProcId, Addr, Size) thenbeginp := nil;if (peH.OptionalHeader.ImageBase = Addr) and (Size = ImageSize) then / 外殼進程可以容納目標進程并且加載地址一致beginp := Pointer(Addr);VirtualProtectEx(result, p, Size, PAGE_EXECUTE_READWRITE, Old);endelse
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 藥理學知識培訓課件
- 論文寫作指南
- 2025年度餐飲加盟連鎖經營合作協(xié)議書3篇
- 2025年度廣告?zhèn)髅讲鸹锖贤瑓f(xié)議4篇
- 專業(yè)藝術教師勞務合作合同(2024版)一
- 二零二四醫(yī)院護士勞動合同范本:護理危機管理與責任界定3篇
- 2025年茶山茶葉采摘與加工承包經營合同4篇
- 2025年度快遞快遞業(yè)務市場營銷承包合同3篇
- 2025年度餐飲行業(yè)節(jié)能減排合作協(xié)議范本3篇
- 2025年度情侶忠誠保障不分手協(xié)議書電子版下載3篇
- 直播帶貨助農現(xiàn)狀及發(fā)展對策研究-以抖音直播為例(開題)
- 腰椎間盤突出疑難病例討論
- 《光伏發(fā)電工程工程量清單計價規(guī)范》
- 2023-2024學年度人教版四年級語文上冊寒假作業(yè)
- (完整版)保證藥品信息來源合法、真實、安全的管理措施、情況說明及相關證明
- 營銷專員績效考核指標
- 陜西麟游風電吊裝方案專家論證版
- 供應商審核培訓教程
- 【盒馬鮮生生鮮類產品配送服務問題及優(yōu)化建議分析10000字(論文)】
- 肝硬化心衰患者的護理查房課件
- 2023年四川省樂山市中考數(shù)學試卷
評論
0/150
提交評論