Zitat:
Aber wie bringst du das dem Delphi-Linker bei?
@Assarbad: die neue Fensterprocedure in dem MMF nutzt keinerlei Delphi
RTL, ist so codiert das sie an jede Stelle des Speichers verschoben werden kann, hat also keine relativen Adressen auf Importe in unseren Prozess oder Sprünge an Adressen in unserem Prozess, und alle nötigen Importe auf die Kernel32.dll werden entweder in einer eigenen "Import" tabelle gemacht oder eben dynamisch.
Also, man würde in das MMF eine Datenstruktur ablegen wie
Delphi-Quellcode:
type
PHookData = ^THookData;
THookData = packed record
AssemblerHook: array[] of Byte;
LoadLibrary: function(FileName: PChar): hModule; stdcall;
GetProcAddress: function(Lib: hModule; Name: PChar): Pointer; stdcall;
Name: array[0..MAX_PATH -1] of Char;
OtherData: Integer;
.. usw. usw.
// Code: array[0..0] of Byte;
end;
Nun wird das MMF erzeugt und obige Datenstruktur an erster Position initialisiert. Dahinter steht der Code der nur auf diese PHookData zugreift.
Der Code könnte so aussehen:
Delphi-Quellcode:
function MyWndProc(..., HookData: PHookData): Integer; stdcall;
var
Module: hModule;
begin
Lib := HookData.LoadLibrary(HookData.Name);
...
HookData.FreeLibrary(Lib);
end;
In den ersten Bytes von HookData steht dynamischer Code
Delphi-Quellcode:
asm
POP ECX
// hole Return Address
CALL @@1
// ermittle HookData Address
@@1: POP EAX
// EAX = @@@1
SUB EAX,3
// EAX = @POP ECX = HookData
PUSH EAX
// erster Param unserer WindowProc
PUSH ECX
// return address
ADD EAX,SizeOf THookData
// Sprung zu WindowProc(HookData, ....)
JMP EAX
end;
D.h. im MMF steht als erstes eine HookData Struktur, danach unser PASCAL Code.
Wir initialisieren das MMF, setzten AssemblerHook auf obigen Assembler, initialisieren die Importe und kopieren unseren PASCAL Code an Code.
Danach ist die Adresse des MMFs die Adresse unserer neuen WindowProc().
Gruß Hagen