TMemoryStream 如何執行 exe |
答題得分者是:hagar
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
HikaruGo
中階會員 發表:22 回覆:69 積分:88 註冊:2007-12-09 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
這篇好像有提到這樣的作法,不知道是不是PD大所要的?
如何把一个EXE文件存入数据,并把它取出来执行它? ===================引 用 P.D. 文 章=================== 為了執行一些程式(如安裝, 註冊..但非駭客), 但不想user或公司執行人員可以取得該支exe檔 |
carstyc
資深會員 發表:16 回覆:254 積分:329 註冊:2003-07-18 發送簡訊給我 |
PD大大...
用TMemoryStream LoadFormFile(Exefile) ,那就表示執行時期必需要有那支 exe ,這樣不是也有機會被執行人員取得exe。 可以考慮把另一個exe 存在resource file 裡面,程式再去取出來執行,執行完就粑它刪掉。 http://delphi.ktop.com.tw/board.php?cid=30&fid=69&tid=98415 可以參考一下這篇,存入取出的作法都有了... ===================引 用 P.D. 文 章=================== 為了執行一些程式(如安裝, 註冊..但非駭客), 但不想user或公司執行人員可以取得該支exe檔 |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
感謝兩位回覆, 但我並不是想知道如何把 檔案 加到 exe, 再用 resource 取出, 這方面的技術資料討論的非常多, 而且實作上也沒有問題
我現在的需求, 其實我已經把 exe1 包在 install.exe 中, 也能夠取出 exe1, 但唯獨的是, 我必須執行 exe1 執行 不是用 winexec, 就是 ShellExecute, 這都是要在 硬碟中存在 exe1 的程式, 在本站的討論區中之前也有人發過 如何在 TMemoryStream 中執行 html 的方式, 其實是一樣的想法 因為我從 resorce 中取出 exe1 後, 並不想放在硬碟上再執行, 這會有漏洞, 例如, 萬一系統當機, 使用者中途強制中斷程式等等問題, 即使我的 intall.exe 中有設定 winexec(exe1), 最後下Deletefile(exe1), 但上述的情況都會導致 exe1 無法被正常執行刪除, 而被保留 所以最好的方式是由 resorce 取出 exe1 後, 直接載入 TMemoryStream, 然後直接啟動 exe1, 但如果不行的, 可以透過 MmeoryStream.LoadformFile(exe1)之後, 立即刪除 exe1, 再到Memory中執行exe1 這樣會比存到硬碟再以winexec()執行與刪除來的更安全 而我查遍了網路的資源(我花了四天, 看了至少上萬篇), 有一篇提到有這個技術, 但要刷卡付費才能看到 討論內容, 並非不願意付費, 而是這個網站在國外, 也不清楚狀況就直接刷卡, 我曾有切身之痛, 所以不敢做! 另外, 也找到幾篇有提供 Dll 載入到 TMemoryStream中, 然後執行的, 但實作不是出現 Access Error, 就是必須 在Delphi7以上版本運作, 可惜我的是Delphi5版本! ===================引 用 GrandRURU 文 章=================== 這篇好像有提到這樣的作法,不知道是不是PD大所要的? 如何把一个EXE文件存入数据,并把它取出来执行它? ===================引 用 P.D. 文 章=================== 為了執行一些程式(如安裝, 註冊..但非駭客), 但不想user或公司執行人員可以取得該支exe檔 |
gerojeng
一般會員 發表:23 回覆:25 積分:9 註冊:2004-06-19 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
參考這篇試試: http://www.delphipages.com/forum/showthread.php?t=202067
unit Unit1; interface {$IMAGEBASE $10000000} uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} type TSections = array [0..0] of TImageSectionHeader; function GetAlignedSize(Size: dword; Alignment: dword): dword; begin if ((Size mod Alignment) = 0) then Result := Size else Result := ((Size div Alignment) 1) * Alignment; end; function ImageSize(Image: pointer): dword; var Alignment: dword; ImageNtHeaders: PImageNtHeaders; PSections: ^TSections; SectionLoop: dword; begin ImageNtHeaders := pointer(dword(dword(Image)) dword(PImageDosHeader(Image)._lfanew)); Alignment := ImageNtHeaders.OptionalHeader.SectionAlignment; if ((ImageNtHeaders.OptionalHeader.SizeOfHeaders mod Alignment) = 0) then begin Result := ImageNtHeaders.OptionalHeader.SizeOfHeaders; end else begin Result := ((ImageNtHeaders.OptionalHeader.SizeOfHeaders div Alignment) 1) * Alignment; end; PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) ImageNtHeaders.FileHeader.SizeOfOptionalHeader); for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin if PSections[SectionLoop].Misc.VirtualSize <> 0 then begin if ((PSections[SectionLoop].Misc.VirtualSize mod Alignment) = 0) then begin Result := Result PSections[SectionLoop].Misc.VirtualSize; end else begin Result := Result (((PSections[SectionLoop].Misc.VirtualSize div Alignment) 1) * Alignment); end; end; end; end; procedure CreateProcessEx(FileMemory: pointer); var BaseAddress, Bytes, HeaderSize, InjectSize, SectionLoop, SectionSize: dword; Context: TContext; FileData: pointer; ImageNtHeaders: PImageNtHeaders; InjectMemory: pointer; ProcInfo: TProcessInformation; PSections: ^TSections; StartInfo: TStartupInfo; begin ImageNtHeaders := pointer(dword(dword(FileMemory)) dword(PImageDosHeader(FileMemory)._lfanew)); InjectSize := ImageSize(FileMemory); GetMem(InjectMemory, InjectSize); try FileData := InjectMemory; HeaderSize := ImageNtHeaders.OptionalHeader.SizeOfHeaders; PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) ImageNtHeaders.FileHeader.SizeOfOptionalHeader); for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin if PSections[SectionLoop].PointerToRawData < HeaderSize then HeaderSize := PSections[SectionLoop].PointerToRawData;<br /> end; CopyMemory(FileData, FileMemory, HeaderSize); FileData := pointer(dword(FileData) GetAlignedSize(ImageNtHeaders.OptionalHeader.SizeOfHeaders, ImageNtHeaders.OptionalHeader.SectionAlignment)); for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin if PSections[SectionLoop].SizeOfRawData > 0 then begin SectionSize := PSections[SectionLoop].SizeOfRawData; if SectionSize > PSections[SectionLoop].Misc.VirtualSize then SectionSize := PSections[SectionLoop].Misc.VirtualSize; CopyMemory(FileData, pointer(dword(FileMemory) PSections[SectionLoop].PointerToRawData), SectionSize); FileData := pointer(dword(FileData) GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment)); end else begin if PSections[SectionLoop].Misc.VirtualSize <> 0 then FileData := pointer(dword(FileData) GetAlignedSize(PSections[SectionLoop].Misc.VirtualSize, ImageNtHeaders.OptionalHeader.SectionAlignment)); end; end; ZeroMemory(@StartInfo, SizeOf(StartupInfo)); ZeroMemory(@Context, SizeOf(TContext)); CreateProcess(nil, pchar(ParamStr(0)), nil, nil, False, CREATE_SUSPENDED, nil, nil, StartInfo, ProcInfo); Context.ContextFlags := CONTEXT_FULL; GetThreadContext(ProcInfo.hThread, Context); ReadProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx 8), @BaseAddress, 4, Bytes); VirtualAllocEx(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectSize, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(ProcInfo.hProcess, pointer(ImageNtHeaders.OptionalHeader.ImageBase), InjectMemory, InjectSize, Bytes); WriteProcessMemory(ProcInfo.hProcess, pointer(Context.Ebx 8), @ImageNtHeaders.OptionalHeader.ImageBase, 4, Bytes); Context.Eax := ImageNtHeaders.OptionalHeader.ImageBase ImageNtHeaders.OptionalHeader.AddressOfEntryPoint; SetThreadContext(ProcInfo.hThread, Context); ResumeThread(ProcInfo.hThread); finally FreeMemory(InjectMemory); end; end; procedure TForm1.FormCreate(Sender: TObject); var MyStream: TMemoryStream; begin MyStream := TMemoryStream.Create; try MyStream.LoadFromFile('C:\windows\system32\wordpad.exe'); //MyStream.LoadFromStream(yourstream); CreateProcessEx(MyStream.Memory); finally MyStream.Free; end; end; end. |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
|
ddy
站務副站長 發表:262 回覆:2105 積分:1169 註冊:2002-07-13 發送簡訊給我 |
看到這篇覺得挺有意思的
ImageBase 指的是載入PE的位址 一般EXE載入位址是0x10000000,DLL為0x04000000... 此值在程式編譯後連結的時候可以透過連結參數更改 所以沒有一定要0x10000000, 與exe載入大小無關~ ===================引 用 P.D. 文 章=================== 再度感謝hager兄提供資訊, 接二連三都麻煩hager兄真是不好意思! 另外, 請教一下, 有關 {$IMAGEBASE $10000000} 是否固定都要為這個值, 這個設定主要的目的與 exe 程式的載入大小有關嗎? |
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
很好的一篇進階文章! 有趣 ! 頂一下。
稍微看了一下,註解一下: 它大致上是採用「以己身的exe檔來請windows創出另一個process的空間」,這很妙,就是先搞個分身。 然後再去寫該分身的記憶體,包含修正裡面的PE內容,最後有寫入寄生的exe檔的內容(比如例子中的wordpad)。 然後再把分身process的thread從suspend轉resume,正式開跑… ps 我的註解也許會有錯誤,因為我花了幾分大致看了一下。想說若有一天有需要,再仔細看,所以有錯也請指正 :-)
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2010-09-08 11:19:11, 註解 無‧
|
dd_zhouqian
一般會員 發表:0 回覆:1 積分:0 註冊:2010-11-26 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |