Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.22;
Скачать: CL | DM;

Вниз

Минимальная DLL   Найти похожие ветки 

 
XProger ©   (2005-11-08 15:44) [0]

Как будут выглядеть System.pas и SysInit.pas, с минмальным размером кода, для успешной компиляции DLL библиотеки?

Заранее благодарен!

P.S.
С ехе всё достаточно просто...


 
XProger ©   (2005-11-08 15:52) [1]

Извините, неверно причину ошибки при компиляции понял, ну и полез в дебри...
Вот решение:

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 _InitExe;
procedure _halt0;
procedure _InitLib(Context: PInitContext);

var
ModuleIsLib : Boolean;
TlsIndex    : integer = -1;
TlsLast     : Byte;

const
PtrToNil: pointer = nil;

implementation

procedure _InitLib(Context: PInitContext);
asm
end;

procedure _InitExe;
asm
end;

procedure _halt0;
asm
end;

end.


 
XProger ©   (2005-11-08 16:06) [2]

Всё просто супер! Только вот процедуры не экспортируются... по крайней мере ошибка вылетает страшная :(

Что я забыл?


 
XProger ©   (2005-11-08 16:36) [3]

Поправка: В таблице импорта они есть, но вызов их приводит к ошибке :)


 
SPeller ©   (2005-11-08 17:55) [4]

Было бы очень хорошо, если бы компилтор после вычищения системных модулей не сувал в модули вызовы функций. Всё-равно две, по-моему, суются. Если бы их небыло - можно было бы драйвера на Дельфях писать :)


 
XProger ©   (2005-11-13 03:50) [5]

SPeller, драйвера на дельфях уже пишут (статейку читал), пущай через одно место, но пишут :)
Что за функции, просто реально хочу посмотреть на минимальную DLL :)
Минимальный EXE -> com  у меня 524 байта выходит :)


 
SPeller ©   (2005-11-13 09:14) [6]

XProger ©   (13.11.05 3:50) [5]
драйвера на дельфях уже пишут

Дрова, которые работают в режиме ядра, не могут вызывать функции режима пользователя (вроде так). Дельфя же суёт-таки два вызова функций режима пользователя. По крайней мере, моя 6.0.2.


 
XProger ©   (2005-11-13 18:44) [7]

SPeller, подробнее пожалуйста...


 
SPeller ©   (2005-11-14 06:00) [8]

А что подробнее?


 
XProger ©   (2005-11-14 14:22) [9]

SPeller, что за функции без которых DLL компилируется, но не работает?


 
Vladimir Kladov   (2005-11-14 14:35) [10]

я провел эксперимент выше. Ничего не пихается кроме того, что руками импортировать или экспортировать. Секции пустые. Но работать такая dll не может, ее нельзя даже загрузить. Второй вызов (_InitLib... ? не помню) должен перед возвратом (видимо) вытолкнуть из стека на 1 dword больше, иначе дальше код пытается выполнить нули. В итоге сама попытка сделать loadlibrary возвращает 0, а при связывании с dll на этапе компиляции два раза вылетает от системы сообщение про доступ к памяти, после чего прга запускается, но dll все равно вызвать не получается.


 
referrer   (2005-11-14 14:41) [11]

Ой, ну чего вы обсуждаете. Опубликовано же давно.
http://ms-rem.dot-link.net/articles/delphi/delphi.htm


 
Vladimir Kladov   (2005-11-14 16:39) [12]

абсолютно аналогичная картина (взял includes.rar, перекомпилировал в Delphi5 - там были dcu для D7). При попытке сделать LoadLibrary возвращается 0, GetLastError дает Invalid access to memory location. Для DLL эти system и sysinit не подходят.


 
Vladimir Kladov   (2005-11-14 17:42) [13]

Вот так работает:

procedure _InitLib;
asm
 LEAVE
 RET 12
end;



 
SPeller ©   (2005-11-14 17:59) [14]

Vladimir Kladov   (14.11.05 14:35) [10]
я провел эксперимент выше. Ничего не пихается кроме того, что руками импортировать или экспортировать

На какой версии компилировали? На 5? Я на 6.0.2. У меня 2 функции остались. Не помню уже какие.


 
SPeller ©   (2005-11-14 17:59) [15]

Значит, на пятой можно дрова писать? :)


 
referrer   (2005-11-14 18:16) [16]

Прочтите ссылку в [11].
На третьей.


 
SPeller ©   (2005-11-14 18:20) [17]

Дык, если компилятор не вставляет лишние импорты, и длл нормально грузится - то что мешает дрова писать? Драйвер .sys - это та же ДЛЛ, только в таблице импорта вызовы только функций режима ядра.


 
referrer   (2005-11-14 18:54) [18]

linker


 
referrer   (2005-11-14 18:58) [19]

http://www.rsdn.ru/article/delphi/kmdelphi.xml


 
XProger ©   (2005-11-14 19:07) [20]

Всем огромное спасибо, особенно Вам, Владимир :)
Всё благополучно компилируется и работает, минимальный размер 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

?


 
SPeller ©   (2005-11-14 19:17) [21]

А что мешает поменять флаги в РЕ заголовках? Или там сам исполняемый код какой-то особый.


 
Vladimir Kladov   (2005-11-14 19:30) [22]

LEAVE
RET12

Делает возврат в систему, когда она в момент загрузки библиотеки передает ей управление. Никакие секции initialization/finalization работать не будут, если так сделать. Но для DLL это не актуально. Актуально другое: менеджер памяти - хотя бы простенький, возможность использования API. А если используются функции из KOL.pas, то все равно придется использовать нашу замену system.


 
XProger ©   (2005-11-15 01:50) [23]

Менеджера памяти как такового - нет!

function LocalAlloc(uFlags, uBytes: DWORD): DWORD; stdcall; external kernel32;
function LocalFree(hMem: DWORD): DWORD; stdcall; external kernel32;

Вместо него :)
Просто пытаюсь написать библиотеку функций без "лишнего" кода :)


 
Игорь Шевченко ©   (2005-12-27 10:49) [24]

Еще момент, насчет драйверов на Delphi - все равно, придется чем-то менять готовый образ, хотя бы для того, чтобы указать тип подсистемы Native в заголовке. В этом случае, не проще ли будет оставить вызовы функций пользовательских библиотек, которые вставляет среда, но при смене подсистемы заодно поменять и ссылки на библиотеки, например, имя kernel32 сменить на kernel33, положив рядом суррогатную kernel33.dll, вызывающую аналогичные функции из ntoskrnl.exe ?


 
SPeller ©   (2005-12-28 02:08) [25]

Игорь Шевченко ©   (27.12.05 10:49) [24]
все равно, придется чем-то менять готовый образ

Скорее всего, добавить пару флагов в РЕ заголовок, не больше. РЕ формат не нарушается.

Игорь Шевченко ©   (27.12.05 10:49) [24]
вызывающую аналогичные функции из ntoskrnl.exe

Придётся данный суррогат писать на MSVC ) Проще, наверное, сразу поменять kernel32 на ntoskrnl, если вызовы аналогичных функций совподают.


 
Игорь Шевченко ©   (2005-12-28 12:57) [26]

SPeller ©   (28.12.05 02:08) [25]


> Скорее всего, добавить пару флагов в РЕ заголовок, не больше.
>  РЕ формат не нарушается.


Так никто и не говорит, что формат нарушается. Драйвер он изначально тоже PE-формат имеет.


> Придётся данный суррогат писать на MSVC )


Один раз. Что немаловажно.


> Проще, наверное, сразу поменять kernel32 на ntoskrnl, если
> вызовы аналогичных функций совподают.


Не совпадают. Более того, аналогичных функций нет.


 
SPeller ©   (2005-12-28 19:15) [27]

Игорь Шевченко ©   (28.12.05 12:57) [26]
Не совпадают. Более того, аналогичных функций нет.

Тогда да, нужен суррогат. Кто-нибудь такой подход использовал? Есть опыт? Или это пока только на уровне теории? На первый взгляд никаких проблем написать любой драйвер при наличии суррогата нет.


 
SPeller ©   (2005-12-28 19:19) [28]

Кстати, компилятор может вставлять импорты из пользовательских длл вне зависимости от наличия явного описания, для обеспечения каких-то своих рутин? Если нет, то ничто, вроде бы, не мешает переписать системные модули на использование аналогов из другой подсистемы. При таком подходе и суррогаты не понадобятся.


 
Игорь Шевченко ©   (2005-12-29 10:57) [29]

SPeller ©   (28.12.05 19:19) [28]


> Кстати, компилятор может вставлять импорты из пользовательских
> длл вне зависимости от наличия явного описания, для обеспечения
> каких-то своих рутин


Нет, он вставляет вызовы к процедурам RTL. Об этом, собственно, и речь. В SysInit и в System как раз такие вызовы активно используются. Для чего и нужны суррогатные DLL.


 
SPeller ©   (2005-12-30 11:36) [30]

Игорь Шевченко ©   (29.12.05 10:57) [29]
В SysInit и в System как раз такие вызовы активно используются

А не проще ли переписать рутины на использование аналогов другого уровня?


 
Игорь Шевченко ©   (2005-12-30 11:58) [31]

SPeller ©   (30.12.05 11:36) [30]

И каждый раз вспоминать, какой у тебя System.pas


 
SPeller ©   (2005-12-31 12:34) [32]

Не понял вашей мысли. Я лишь предложил переписать рутины так, чтобы они с точки зрения использования в программе идентичны оригинальным, но использовали API другого уровня. Зачем что-то помнить? Или имеется ввиду переносимость с одной версии Дельфи на другую?


 
Игорь Шевченко ©   (2005-12-31 22:10) [33]


> Не понял вашей мысли. Я лишь предложил переписать рутины
> так, чтобы они с точки зрения использования в программе
> идентичны оригинальным, но использовали API другого уровня


Я поясню: Мне бы хотелось, чтобы один и тот же system.pas (sysinit.pas) использовался как при написании стандартных Win32-программ, так и не очень стандартных. В случае не очень стандартных программ мне бы хотелось, чтобы импортируемые функции системных DLL пользовательского режима были реализованы в фиктивных DLL.


 
SPeller ©   (2006-01-01 00:20) [34]

Аа, понял. Решение может быть достаточно простым, которое и используется в KOL - прописать в свойствах проекта путь поиска модулей, по которому будут искаться и системные модули system.dcu и sysinit.dcu. Надо обычное пользовательское приложение - ничего не меняем. Надо драйвер - прописываем нужный путь, и компилятор включит нужные нам системные модули, которые мы предварительно переписали и скомпиляли. Думаю, такой подход лучше создания всяких конвертеров готового ЕХЕ-шника, меняющих имя библиотек.



Страницы: 1 вся ветка

Текущий архив: 2006.10.22;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.033 c
1-1157794682
yahaha
2006-09-09 13:38
2006.10.22
Webbrowser


2-1159875748
term1t
2006-10-03 15:42
2006.10.22
Выборка(Oracle 9)


15-1159682379
cyborg
2006-10-01 09:59
2006.10.22
Кто нибудь имел дело с видеокартами конторы Palit?


2-1160140411
Xtreme
2006-10-06 17:13
2006.10.22
Delphi.Begin3


15-1158567296
Alien1769
2006-09-18 12:14
2006.10.22
Город богов