串流是物件導向語言中資料輸入輸出的抽象化工具,徹底取代傳統函式式 I/O。Delphi 中所有串流類別繼承自 TStream,定義核心屬性 Size(資料大小)、Position(讀寫指標)與虛擬方法 Read、Write、Seek、SetSize。靜態方法 ReadBuffer、WriteBuffer、CopyFrom 提供更安全的封裝。常用派生類別:TFileStream(檔案)、TMemoryStream(記憶體)、TResourceStream(資源)。
加密流程:建立「頭檔案」(解密啟動器)→ 將目標 EXE 附加至頭檔案尾部 → 附加密碼與長度資訊。解密流程:執行頭檔案 → 讀取尾部密碼 → 驗證使用者輸入 → 正確則提取原 EXE 至暫存檔執行。三大核心函數:
Jmf_AddToFile(SourceFile, PassWord, TargetFile):附加檔案與密碼Jmf_LoadFromFile(SourceFile, TargetFile):提取原始檔案Jmf_PassFromFile(var Password, SourceFile):讀取尾部密碼頭檔案專案(Head.exe): 含密碼輸入框與解密按鈕,編譯保留 .res 資源檔。
加密工具專案(AddEncrypt.exe): 內嵌 Head.res 為資源,執行時提取 Head.exe、附加目標檔與密碼、替換原檔。
function Jmf_AddToFile(SourceFile, PassWord, TargetFile: String): Boolean;
var Target, Source: TFileStream; MyFileSize, PassWordSize: Integer;
begin
Result := False;
try
Source := TFileStream.Create(SourceFile, fmOpenRead or fmShareExclusive);
Target := TFileStream.Create(TargetFile, fmOpenWrite or fmShareExclusive);
try
Target.Seek(0, soFromEnd); // 移至檔案尾部
Target.CopyFrom(Source, 0); // 附加原始檔案
MyFileSize := Source.Size + SizeOf(MyFileSize);
Target.WriteBuffer(MyFileSize, SizeOf(MyFileSize)); // 寫入檔案大小
PassWordSize := SizeOf(PassWord) + SizeOf(PassWordSize);
Target.Seek(0, soFromEnd);
Target.WriteBuffer(PassWord, SizeOf(PassWord)); // 寫入密碼
Target.WriteBuffer(PassWordSize, SizeOf(PassWordSize)); // 寫入密碼長度
Result := True;
finally
Target.Free; Source.Free;
end;
except end;
end;
function Jmf_LoadFromFile(SourceFile, TargetFile: String): Boolean;
var Source: TFileStream; Target: TMemoryStream; MyFileSize, Position: Integer;
begin
Result := False;
try
Target := TMemoryStream.Create;
Source := TFileStream.Create(SourceFile, fmOpenRead or fmShareDenyNone);
try
Source.Seek(-SizeOf(Position), soFromEnd);
Source.ReadBuffer(Position, SizeOf(Position)); // 讀取位置標記
Source.Seek(-Position - SizeOf(MyFileSize), soFromEnd);
Source.ReadBuffer(MyFileSize, SizeOf(MyFileSize)); // 讀取檔案大小
Source.Seek(-Position - MyFileSize, soFromEnd); // 定位至檔案資料
Target.CopyFrom(Source, MyFileSize - SizeOf(MyFileSize));
Target.SaveToFile(TargetFile);
Result := True;
finally
Target.Free; Source.Free;
end;
except end;
end;
function Jmf_PassFromFile(var Password: String; SourceFile: String): Boolean;
var Source: TFileStream; PassWordSize: Integer;
begin
Result := False;
try
Source := TFileStream.Create(SourceFile, fmOpenRead or fmShareDenyNone);
try
Source.Seek(-SizeOf(PassWordSize), soFromEnd);
Source.ReadBuffer(PassWordSize, SizeOf(PassWordSize));
Source.Seek(-PassWordSize, soFromEnd);
Source.ReadBuffer(Pointer(Password)^, PassWordSize - SizeOf(PassWordSize));
Result := True;
finally Source.Free; end;
except end;
end;
procedure TForm1.UnbindClick(Sender: TObject);
var S, Pass, InPass: String;
begin
InPass := PasswordEdit.Text;
S := ChangeFileExt(Application.ExeName, '.jmf');
if Jmf_PassFromFile(Pass, Application.ExeName) then
if Pass = InPass then
begin
Jmf_LoadFromFile(Application.ExeName, S); // 提取原始 EXE
WinExec(PChar(S), SW_SHOW); // 執行原始程式
Application.Terminate; // 結束解密器
end
else Application.MessageBox('密碼錯誤!', '錯誤', MB_OK);
end;
此機制本質為「檔案捆綁」,同理可擴展為多檔案打包、自解壓安裝程式。實務應用建議:加入檢驗碼防篡改、採用更強加密演算法(AES)、防止記憶體傾印分析、數位簽章驗證完整性。串流抽象化讓檔案、記憶體、網路資料統一操作,是構建此類工具的關鍵基礎設施。