From 745737abdffef2b93e980e71ada2be5a28bc9efe Mon Sep 17 00:00:00 2001 From: Berserker Date: Tue, 14 May 2019 16:28:27 +0300 Subject: [PATCH] VfsPatching now uses global static memory block. NtQueryDirectoryFile patch is rollbacked during finalization --- VfsHooks.pas | 3 ++- VfsPatching.pas | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/VfsHooks.pas b/VfsHooks.pas index f6219cc..0faa0e7 100644 --- a/VfsHooks.pas +++ b/VfsHooks.pas @@ -607,7 +607,8 @@ begin NativeNtQueryDirectoryFile := VfsPatching.SpliceWinApi ( VfsApiDigger.GetRealProcAddress(NtdllHandle, 'NtQueryDirectoryFile'), - @Hook_NtQueryDirectoryFile + @Hook_NtQueryDirectoryFile, + @NtQueryDirectoryFilePatch ); end; // .if diff --git a/VfsPatching.pas b/VfsPatching.pas index 1a1479f..6cf124b 100644 --- a/VfsPatching.pas +++ b/VfsPatching.pas @@ -7,7 +7,7 @@ unit VfsPatching; (***) interface (***) uses - Windows, SysUtils, Utils, PatchForge; + Windows, SysUtils, Utils, PatchForge, Concur; type PAppliedPatch = ^TAppliedPatch; @@ -18,6 +18,7 @@ type procedure Rollback; end; + (* Replaces original STDCALL function with the new one with the same prototype and one extra argument. The argument is callable pointer, used to execute original function. The pointer is passed as THE FIRST argument before other arguments. *) @@ -32,6 +33,36 @@ type TPatchMaker = PatchForge.TPatchMaker; TPatchHelper = PatchForge.TPatchHelper; +const + PERSISTENT_MEM_CAPACITY = 100 * 1024; + +var + PersistentMemCritSection: Concur.TCritSection; + PersistentMem: array [0..PERSISTENT_MEM_CAPACITY - 1] of byte; + PersistentMemPos: integer; + + +procedure AllocPersistentMem (var Addr; Size: integer); +begin + {!} Assert(@Addr <> nil); + {!} Assert(Size >= 0); + + with PersistentMemCritSection do begin + Enter; + pointer(Addr) := nil; + + try + if PersistentMemPos + Size > High(PersistentMem) then begin + raise EOutOfMemory.Create('Failed to allocate another persistent memory block of size ' + SysUtils.IntToStr(Size)); + end; + + pointer(Addr) := @PersistentMem[PersistentMemPos]; + Inc(PersistentMemPos, Size); + finally + Leave; + end; + end; // .with +end; // .procedure AllocPersistentMem (* Writes arbitrary data to any write-protected section *) function WriteAtCode (NumBytes: integer; {n} Src, {n} Dst: pointer): boolean; @@ -119,7 +150,7 @@ begin // === END generating SpliceBridge === // Persist splice bridge - GetMem(SpliceBridge, p.Size); + AllocPersistentMem(SpliceBridge, p.Size); WritePatchAtCode(p.PatchMaker, SpliceBridge); // Turn result from offset to absolute address @@ -147,4 +178,6 @@ begin end; end; +begin + PersistentMemCritSection.Init; end. \ No newline at end of file