Преди време използвах Windows 98 и си бях направил любимите "образователни" програми когато изникна гигантски проблем.
Под 9X ядрата има област от паметта между 2Gb и 3Gb която е видима от всички програми. Там се качват повечето от библиотеките като Kernel32, User32, GDI32 и т.н. Когато моята програма направи кръпка върху Kernel32 в рамките на програмата кръпката работи, но когато се друга програма направи същото извикване следва моментален забив защото моя код не се намира в тази специфична област от паметта и в адресното пространство на другата програма го няма.
Тук следваше кратко проучване и се видя само че VisualC++ може да прави т.нар. shared sections и настройка на $IMAGEBASE над 2Gb размера (0x7FFFFFFF) под Delphi не може да се направи.
Така задачите станаха 2 - да направя секциите (всичките) shared и да настроя ImageBase над 2Gb. За щастие имах програма която зареждаше модула където трябва така че всичките настройки ги направих там.
procedure PatchLibrary(Filename: string);
var f: file of byte;
i: byte;
a,b,c,d: cardinal;
begin
AssignFile(f, Filename);
Reset(f);
// Seek(f,$136); i:=$23; write(f,i); i:=$81; write(f,i); //imagebase $81230000
Seek(f,$1FE); i:=$72; write(f,i); i:=$83; write(f,i);
Seek(f,$21F); i:=$70; write(f,i);
Seek(f,$226); i:=$72; write(f,i); i:=$83; write(f,i);
Seek(f,$247); i:=$D0; write(f,i);
Seek(f,$24E); i:=$72; write(f,i); i:=$83; write(f,i);
Seek(f,$26F); i:=$D0; write(f,i); i:=$83; write(f,i);
Seek(f,$297); i:=$D0; write(f,i); i:=$83; write(f,i);
a:=0; b:=0; c:=0; //d:=$8123000;
d:=GetModuleHandle('kernel32.dll');
ReBaseImage(PAnsiChar(Filename),nil,true,true,false,0,a,b,c,d,0);
closefile(f);
end;
Кратко разяснение - първия коментар е ImageBase. За мое огромно съжаление НЕ РАБОТИ (затова е и закоментарен), защото всички отмествания трябва наново да се направят (т.нар. rebasing). Следва пипането на атрибутите на секциите, тук по-принцип трябва да има някакво зареждане на PE файл и пипане на секциите му, но понеже съм мързелив съм настроил отместванията както на стандартна Delphi DLL. По-интересно е последното с ReBaseImage. Ако пряко се подаде нов ImageBase пак не работи - затова се прибягва до трик - вземам адреса на Kernel32 и казвам на библиотеката да се настрои спрямо него, а DLL loader-а все някак ще се оправи.
За моя съжаление това беше само началото на проблемите ми. Следва продължение...