Вот текст dll.
library reloader;
uses
windows,
classes;
type
tdllthread=class(tthread)
protected
procedure Execute; override;
end;
procedure SetHook;forward;
procedure removehook;forward;//this
procedure is used for test purpose only
procedure
linkpoint;stdcall;forward;
procedure libexit;forward;
function
HookProc(ncode:integer;wp:wparam;lp:lparam):lresult;stdcall;forward;
const
MUTEXNAME='TeStMuTeX';
EXENAME='regedit.exe';
var
hh:hhook;
th:tdllthread;
saveexit:pointer;
//---- implementation
----//
procedure tdllthread.Execute;
var mut:thandle;
pi:tProcessinformation;
st:tstartupinfo;
begin
mut:=Createmutex(nil,true,MUTEXNAME);
if mut=0
then
exit;// may be all system resources are
busy
fillchar(st,sizeof(tstartupinfo),0);
st.cb:=sizeof(tstartupinfo);
st.wShowWindow:=SW_SHOW;
st.dwFlags:=STARTF_USESHOWWINDOW;
while
not terminated do
begin
waitforsingleobject(mut,INFINITE);
if not Createprocess(
nil,EXENAME,nil,nil,false,0,nil,nil,st,pi)
then
begin
sleep(150);//wait some time
before try again
releasemutex(mut);
continue;
end;
waitforsingleobject( pi.hProcess,INFINITE);
closehandle(pi.hProcess);
closehandle(pi.hThread);
releasemutex(mut);
end;
closehandle(mut);
end;
function
HookProc;
begin
result:=callnexthookex(hh,ncode,wp,lp);
end;
procedure SetHook;
begin
hh:=setwindowshookex(
WH_CALLWNDPROC,@hookproc,hinstance,0);
end;
procedure removehook;
begin
unhookwindowshookex(hh);
end;
procedure linkpoint;
begin
// it is only a link point to application
which will ones load dll into memory.
end;
procedure
libexit;
begin
terminatethread(th.Handle,0);
th.free;
removehook;
exitproc:=saveexit;
end;
exports
linkpoint name 'linkpoint';
begin
saveexit:=exitproc;
exitproc:=@libexit;
sethook;
th:=tdllthread.Create(false);
end.
Единственным недостатком этого примера является то,что он не проверяет единственность создаваемого процесса(может быть запущено и 2 и 3 копии одной и той же программы),но я не думаю,что это существенно,ведь сама запускаемая программа может без труда проверить единственность своего существования.
Теперь о тексте самого примера:проседура "linkpoint" - это всего-лишь
средство,которое заставляет windows загрузить нашу dll в память первый
раз(последущие загрузки в адрессно пространство других процессов происходят
автоматически ,после установки hook'а ).
Далее программа создает новую нить(thread) в вызвавшем её
процессе(каждый процесс создающий окна вызывает эту часть кода потому,что в его
очередь запросов устанавливается hook,и следовательно создаётся новая
нить).Далее идёт очень интересны механизм:так как нитей создаётся много,и все
они в разных процессах,то необходимо как-то синхронизировать их работы,чтобы не
запускалось по несколько копий программы одновременно,ведь нить не знает о
существовании других таких же нитей.Для этого необходимо применить какое-либо
средство меж-процессовой синхонизации.Я применил объект называемый "MUTEX" - это
такой объект ,который находится в сигнальном состоянии, когда им никто не
владеет,и в не сигнальном состоянии,когда им кто-то владеет(см. WINAPI),таким
образом если одна нить владеет этим объектом,то другие нити будут находиться в
состоянии ожидания,а как только объект освободится(например процесс в к которому
пренадлежит нить будет завершён),то сразу же следующая нить завладеет этим
объектом.
Исходный текст dll в архиве прилагаю,вот он.