Okie, sorry for explaining in English, as won't be able to speak much in Russian...
RZM imports its file functions as follows:
Код:
Address Ordinal Name Library
------- ------- ---- -------
044D80F4 fclose msvcrt
044D80F8 fopen msvcrt
044D80FC fread msvcrt
044D8100 fwrite msvcrt
In order to make it work with stdio, we hook those functions and make the exe run our own custom functions, like we hook fread to read from stdin and fwrite to write in stdout instead of file handlers. Example for hooking:
Код:
library stdio;
uses
WinAPI.Windows,
MagicApiHook in 'MagicApiHook.pas';
{$R *.res}
var
fopen: function(const lpPathName: PAnsiChar; const mode: PAnsiChar)
: HFILE; cdecl;
function pfopen(const lpPathName: PAnsiChar; const mode: PAnsiChar)
: HFILE; cdecl;
begin
result := fopen(lpPathName, mode); // replace this with something, this is just an example
end;
procedure DLLEntryPoint(dwReason: DWORD);
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
Write(ErrOutput, 'Executable patched by RamiroCruzo');
ApiHook('msvcrt.dll', 'fopen', nil, @pfopen, @fopen);///Some of API hooks need DWORD address which I have mentioned above
end;
DLL_PROCESS_DETACH:
begin
ApiUnHook('msvcrt.dll', 'fopen', nil, @pfopen, @fopen);
end;
end;
end;
begin
DllProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Once you've written the code part, compile the dll and then you can follow two paths:
1. Use dllmerge to merge rzm.exe and stdio.dd
2. Make another program which runs rzm in debug mode w/ zero memory, injects dll and then resumes the process
Now, if done everything bug free, you'll have a working stdio rzm, this removes temp file need. Now to remove 2 GB limit, you'll have two pathways:
1. RCE the entire exe and then recompile it, which will take ages
2. Create an exe which will act as wrapper for our rzm and feed the rzm data, it'll feed data until 2 GB then restart rzm in order to chunk it. Compression won't support stdio this way because we need input filesize in advanced, but we can bypass 2 GB limit.