![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Минимальная DLL [Delphi, Windows]
XProger © (2005-11-08 15:44:00)Как будут выглядеть System.pas и SysInit.pas, с минмальным размером кода, для успешной компиляции DLL библиотеки?
Заранее благодарен!
P.S.
С ехе всё достаточно просто...
SPeller (2006-01-01 00:20:00) [1]Аа, понял. Решение может быть достаточно простым, которое и используется в KOL - прописать в свойствах проекта путь поиска модулей, по которому будут искаться и системные модули system.dcu и sysinit.dcu. Надо обычное пользовательское приложение - ничего не меняем. Надо драйвер - прописываем нужный путь, и компилятор включит нужные нам системные модули, которые мы предварительно переписали и скомпиляли. Думаю, такой подход лучше создания всяких конвертеров готового ЕХЕ-шника, меняющих имя библиотек.
Игорь Шевченко (2005-12-31 22:10:00) [2]
> Не понял вашей мысли. Я лишь предложил переписать рутины
> так, чтобы они с точки зрения использования в программе
> идентичны оригинальным, но использовали API другого уровня
Я поясню: Мне бы хотелось, чтобы один и тот же system.pas (sysinit.pas) использовался как при написании стандартных Win32-программ, так и не очень стандартных. В случае не очень стандартных программ мне бы хотелось, чтобы импортируемые функции системных DLL пользовательского режима были реализованы в фиктивных DLL.
SPeller (2005-12-31 12:34:00) [3]Не понял вашей мысли. Я лишь предложил переписать рутины так, чтобы они с точки зрения использования в программе идентичны оригинальным, но использовали API другого уровня. Зачем что-то помнить? Или имеется ввиду переносимость с одной версии Дельфи на другую?
Игорь Шевченко (2005-12-30 11:58:00) [4]SPeller © (30.12.05 11:36) [30]
И каждый раз вспоминать, какой у тебя System.pas
SPeller (2005-12-30 11:36:00) [5]Игорь Шевченко © (29.12.05 10:57) [29]
В SysInit и в System как раз такие вызовы активно используются
А не проще ли переписать рутины на использование аналогов другого уровня?
Игорь Шевченко (2005-12-29 10:57:00) [6]SPeller © (28.12.05 19:19) [28]
> Кстати, компилятор может вставлять импорты из пользовательских
> длл вне зависимости от наличия явного описания, для обеспечения
> каких-то своих рутин
Нет, он вставляет вызовы к процедурам RTL. Об этом, собственно, и речь. В SysInit и в System как раз такие вызовы активно используются. Для чего и нужны суррогатные DLL.
SPeller (2005-12-28 19:19:00) [7]Кстати, компилятор может вставлять импорты из пользовательских длл вне зависимости от наличия явного описания, для обеспечения каких-то своих рутин? Если нет, то ничто, вроде бы, не мешает переписать системные модули на использование аналогов из другой подсистемы. При таком подходе и суррогаты не понадобятся.
SPeller (2005-12-28 19:15:00) [8]Игорь Шевченко © (28.12.05 12:57) [26]
Не совпадают. Более того, аналогичных функций нет.
Тогда да, нужен суррогат. Кто-нибудь такой подход использовал? Есть опыт? Или это пока только на уровне теории? На первый взгляд никаких проблем написать любой драйвер при наличии суррогата нет.
Игорь Шевченко (2005-12-28 12:57:00) [9]SPeller © (28.12.05 02:08) [25]
> Скорее всего, добавить пару флагов в РЕ заголовок, не больше.
> РЕ формат не нарушается.
Так никто и не говорит, что формат нарушается. Драйвер он изначально тоже PE-формат имеет.
> Придётся данный суррогат писать на MSVC )
Один раз. Что немаловажно.
> Проще, наверное, сразу поменять kernel32 на ntoskrnl, если
> вызовы аналогичных функций совподают.
Не совпадают. Более того, аналогичных функций нет.
SPeller (2005-12-28 02:08:00) [10]Игорь Шевченко © (27.12.05 10:49) [24]
все равно, придется чем-то менять готовый образ
Скорее всего, добавить пару флагов в РЕ заголовок, не больше. РЕ формат не нарушается.
Игорь Шевченко © (27.12.05 10:49) [24]
вызывающую аналогичные функции из ntoskrnl.exe
Придётся данный суррогат писать на MSVC ) Проще, наверное, сразу поменять kernel32 на ntoskrnl, если вызовы аналогичных функций совподают.
Игорь Шевченко (2005-12-27 10:49:00) [11]Еще момент, насчет драйверов на Delphi - все равно, придется чем-то менять готовый образ, хотя бы для того, чтобы указать тип подсистемы Native в заголовке. В этом случае, не проще ли будет оставить вызовы функций пользовательских библиотек, которые вставляет среда, но при смене подсистемы заодно поменять и ссылки на библиотеки, например, имя kernel32 сменить на kernel33, положив рядом суррогатную kernel33.dll, вызывающую аналогичные функции из ntoskrnl.exe ?
XProger (2005-11-15 01:50:00) [12]Менеджера памяти как такового - нет!
function LocalAlloc(uFlags, uBytes: DWORD): DWORD; stdcall; external kernel32;
function LocalFree(hMem: DWORD): DWORD; stdcall; external kernel32;
Вместо него :)
Просто пытаюсь написать библиотеку функций без "лишнего" кода :)
Vladimir Kladov (2005-11-14 19:30:00) [13]LEAVE
RET12
Делает возврат в систему, когда она в момент загрузки библиотеки передает ей управление. Никакие секции initialization/finalization работать не будут, если так сделать. Но для DLL это не актуально. Актуально другое: менеджер памяти - хотя бы простенький, возможность использования API. А если используются функции из KOL.pas, то все равно придется использовать нашу замену system.
SPeller (2005-11-14 19:17:00) [14]А что мешает поменять флаги в РЕ заголовках? Или там сам исполняемый код какой-то особый.
XProger (2005-11-14 19:07:00) [15]Всем огромное спасибо, особенно Вам, Владимир :)
Всё благополучно компилируется и работает, минимальный размер DLL после компиляции в Delphi 7, без .RCData секции составляет 3,00 КБ (3 072 байт)
Вот код системных модулей :)
unit System;
interface
procedure _HandleFinally;
type
TGUID = record
D1: LongWord;
D2: Word;
D3: Word;
D4: array [0..7] of Byte;
end;
PInitContext = ^TInitContext;
TInitContext = record
OuterContext : PInitContext;
ExcFrame : pointer;
InitTable : pointer;
InitCount : integer;
Module : pointer;
DLLSaveEBP : pointer;
DLLSaveEBX : pointer;
DLLSaveESI : pointer;
DLLSaveEDI : pointer;
ExitProcessTLS : procedure;
DLLInitState : Byte;
end;
implementation
procedure _HandleFinally;
asm
end;
end.
unit SysInit;
interface
procedure _halt0;
procedure _InitLib(Context: PInitContext);
var
ModuleIsLib : Boolean;
TlsIndex : integer = -1;
TlsLast : Byte;
const
PtrToNil: pointer = nil;
implementation
procedure _InitLib(Context: PInitContext);
asm
LEAVE
RET 12
end;
procedure _halt0;
asm
end;
end.
P.S.
Маленький вопросик:
что делает
LEAVE
RET 12
?
referrer (2005-11-14 18:58:00) [16]http://www.rsdn.ru/article/delphi/kmdelphi.xml
referrer (2005-11-14 18:54:00) [17]linker
SPeller (2005-11-14 18:20:00) [18]Дык, если компилятор не вставляет лишние импорты, и длл нормально грузится - то что мешает дрова писать? Драйвер .sys - это та же ДЛЛ, только в таблице импорта вызовы только функций режима ядра.
referrer (2005-11-14 18:16:00) [19]Прочтите ссылку в [11].
На третьей.
SPeller (2005-11-14 17:59:00) [20]Значит, на пятой можно дрова писать? :)