Текущий архив: 2004.09.19;
Скачать: CL | DM;
Вниз
Импрот функций из exe. Найти похожие ветки
← →
Тимохов © (2004-06-29 11:44) [0]Прочел тут как-то, что импортировать функции можно не только из dll, но и из других exe. Попробовал сделать динамической загрузкой, получилось :)) Я сделал один dpr, даже без begin и end, т.е. одна функция и секция exports.
Вопросы:
1. Что происходит при загрузке exe череp LoadLibrary? Для dll, если не ошибаюсь вызывается стартовая функция библиотеки с соответствующим флагом, что-то типа dllproc process_attach (на память не помню). Что вызывается для exe? У него вроде нет такой функции.
2. Почему у меня не сработал такой код в библиотекеprocedure f();
begin
MessageBox(0, "text", "caption", MB_OK);
end;
При вызове f из другого приложения впесто текстов получается ерунда (т.е. случайная область памяти).
И совершенно нормально сработал такойprocedure f();
var
kText: packed array[0..4] of char;
kCaption: packed array[0..7] of char;
begin
kText[0] := "t";
kText[1] := "t";
kText[2] := "t";
kText[3] := "t";
kText[4] := #0;
kCaption[0] := "c";
kCaption[1] := "a";
kCaption[2] := "p";
kCaption[3] := "t";
kCaption[4] := "i";
kCaption[5] := "o";
kCaption[6] := "t";
kCaption[7] := #0;
MessageBox(0, @kText, @kCaption, MB_OK);
end;
В последнем случае все вывелось корректно.
← →
Игорь Шевченко © (2004-06-29 13:34) [1]
> 2. Почему у меня не сработал такой код в библиотеке
>
> procedure f();
> begin
> MessageBox(0, "text", "caption", MB_OK);
> end;
Как ты загружал приложение ?
← →
Тимохов © (2004-06-29 13:53) [2]
> Как ты загружал приложение ?
Приложение, из которого, я ипортировал процедуру f я загрузал через loadlibrary.
← →
Игорь Шевченко © (2004-06-29 14:14) [3]Тимохов © (29.06.04 13:53)
По какому базовому адресу загрузилось приложение ? :))
← →
Тимохов © (2004-06-29 14:17) [4]
> По какому базовому адресу загрузилось приложение ? :))
конечно не по желаемому, т.к. оба exe имели $00400000 в качестве оного :)
Но вроде это не мое дело - система должна сделать релокацию? Имхо так в рихтере написано :)
← →
Digitman © (2004-06-29 15:32) [5]а посмотреть в ходе трассировки 1-го случая CPU-окно - не судьба ?
← →
Тимохов © (2004-06-29 15:56) [6]
> Digitman © (29.06.04 15:32) [5]
смотрел :)))
адрес откуда загружается текст указывает на область, в которой хранится явно не то, что нужно
← →
Игорь Шевченко © (2004-06-29 16:04) [7]
> адрес откуда загружается текст указывает на область, в которой
> хранится явно не то, что нужно
Вот и ответ на "
> 2. Почему у меня не сработал такой код в библиотеке
"
← →
Тимохов © (2004-06-29 16:10) [8]
> Игорь Шевченко © (29.06.04 16:04) [7]
Ну Игорь, ну что вы издеваетесь :))
Какой же это ответ.
Это вполне корректный кодprocedure f();
begin
MessageBox(0, "text", "caption", MB_OK);
end;
Он же без проблем выполняется. Почему же не выполняется в случае загрузки exe как библиотеки.
Данный вопрос, конечно не является для меня в текущую секунду жизненно важным. Для меня важно понять, что я понимаю не так: про релокацию я вроде читал, опять же не вижу причин почему это не работает.
Есть у меня предположение, что в случае задания строковых констант загрузчик не может им сделать корректную релокацию. Вот и интересуюсь мнением бывалых почему.
← →
Игорь Шевченко © (2004-06-29 16:20) [9]Тимохов © (29.06.04 16:10)
Я не издеваюсь. Но с другой стороны, я не собираюсь делать тестовый пример, и смотреть, что и как там проиходит. Я полагаю, что лучше бы было, если бы ты привел здесь содержимое окна CPU с кодом функции, заодно и показал бы, на что указывают адреса и т.д.
Я эта...тонко намекаю, что чужое время можно бы и уважать...
← →
Тимохов © (2004-06-29 16:24) [10]
> Игорь Шевченко © (29.06.04 16:20) [9]
да ладно, раньше бы сказали, что времени нет :)))
я сделаю развернутый пример.
Честно говоря у меня была идея его сделать, но мне мочему-то показалось, что причины моего непонимания на поверхности.
Оказалось нет...
← →
Digitman © (2004-06-29 16:28) [11]
> адрес откуда загружается текст указывает на область, в которой
> хранится явно не то, что нужно
значит, секция иниц.данных в случае LoadLibrary() была загружена по иному вирт.адресу
← →
Тимохов © (2004-06-29 16:33) [12]
> значит, секция иниц.данных в случае LoadLibrary() была загружена
> по иному вирт.адресу
это утверждение следует из того, что оба exe имели одинаковый предпочитительный адрес (стандартный для exe)?
← →
Игорь Шевченко © (2004-06-29 16:40) [13]Тимохов © (29.06.04 16:33)
А зачем нам заниматься гаданием - выкладываешь то, что я попросил, мы смотрим.
← →
Тимохов © (2004-06-29 16:47) [14]
> Игорь Шевченко © (29.06.04 16:40) [13]
виноват, да я так - по ходу спросил.
больше не буду.
)
← →
Тимохов © (2004-06-29 17:43) [15]Итак развернутый вопрос :)
Написано два exe: ExeLibrary (сама библиотека, эскспортирующая функции) и ExeLibraryClient (пример использования).
Код главной формы ExeLibraryunit FExeLibrary;
... // здесь стандартный заголовок модуля с формой, ничего больше
implementation
{$R *.dfm}
// Пример с массивом char
procedure ExportFunctionWithCharArray();
var
kText: packed array[0..2] of char;
begin
kText[0] := "h";
kText[1] := "i";
kText[2] := #0;
MessageBox(0, @kText, @kText, MB_OK);
end;
// Пример со строковой константой
procedure ExportFunctionWithStringConst();
begin
MessageBox(0, "hi", "hi", MB_OK);
end;
exports
ExportFunctionWithCharArray,
ExportFunctionWithStringConst;
// Это две кнопки, призванные показать, что
// если ExeLibrary запускать как таковой, то обе
// экспортируемые функции работают корректно.
procedure TForm1.Button1Click(Sender: TObject);
begin
ExportFunctionWithCharArray();
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ExportFunctionWithStringConst();
end;
end.
Код главной формц ExeLibraryClient...// вырезано лишнее.
implementation
{$R *.dfm}
// здесь будет все ок,т.е. "hi"
procedure TForm1.Button1Click(Sender: TObject);
var
kLib: HMODULE;
kP: Pointer;
begin
kLib := LoadLibrary("ExeLibrary.exe");
kP := GetProcAddress(kLib, "ExportFunctionWithCharArray");
TProcedure(kP);
FreeLibrary(kLib);
end;
// здесь будет случайная ерунда
procedure TForm1.Button2Click(Sender: TObject);
var
kLib: HMODULE;
kP: Pointer;
begin
kLib := LoadLibrary("ExeLibrary.exe");
kP := GetProcAddress(kLib, "ExportFunctionWithStringConst");
TProcedure(kP);
FreeLibrary(kLib);
end;
end.
Будучи просмотренными из ExeLibraryClient функции выглядят так:
ExportFunctionWithCharArray00DFDBD0 51 push ecx
00DFDBD1 C6042468 mov byte ptr [esp],$68
00DFDBD5 C644240169 mov byte ptr [esp+$01],$69
00DFDBDA C644240200 mov byte ptr [esp+$02],$00
00DFDBDF 6A00 push $00
00DFDBE1 8D442404 lea eax,[esp+$04]
00DFDBE5 50 push eax
00DFDBE6 8D442408 lea eax,[esp+$08]
00DFDBEA 50 push eax
00DFDBEB 6A00 push $00
00DFDBED E83691FBFF call -$00046eca
00DFDBF2 5A pop edx
00DFDBF3 C3 ret
ExportFunctionWithStringConst00DFDBF4 6A00 push $00
00DFDBF6 6808DC4400 push $0044dc08
00DFDBFB 6808DC4400 push $0044dc08
00DFDC00 6A00 push $00
00DFDC02 E82191FBFF call -$00046edf
00DFDC07 C3 ret
Меня вначале удивило, что MessageBox имеет разный адрес, но потом я понял, что скорее всего это из-за того, что я загружаею библиотеку каждый раз повтороно. Или нет?
Заметьте00DFDBF6 6808DC4400 push $0044dc08
По идее это пихается в стек адрес слова "hi".Но по этому адресу лежит полная ерунда :(((
ЗЫ
Если кто-нибудь проявит инетерес к моему вопросу, готов дать любую дополнительную инфу
← →
Тимохов © (2004-06-29 17:46) [16]Хочу добавить, что cpu функции ExportFunctionWithStringConst будучи просмотренным из ExeLibrary имеет точно такие же ссылки на адреса, т.е. на адрес $0044dc08.
При этом этот адрес находится сразу после функции ExportFunctionWithStringConst. Ну, т.е. как обычно дельфи располагает строковые константы.
Почему не было релокации?
← →
Игорь Шевченко © (2004-06-29 17:58) [17]
> Почему не было релокации?
А что находится в Relocation Info в PE-модуле ? :)
← →
SammIk © (2004-06-29 17:59) [18]Мое мнение такое:
Когда делаешь через строки, то адрес получается статическим00DFDBF6 6808DC4400 push $0044dc08
00DFDBFB 6808DC4400 push $0044dc08
Определенно чувствуется разница))) Как думаешь
А сдесь(массив)00DFDBE1 8D442404 lea eax,[esp+$04]
00DFDBE5 50 push eax
00DFDBE6 8D442408 lea eax,[esp+$08]
00DFDBEA 50 push eax
Динамически, но еслибы ты сказал значение esp,
можно было точнее сказать.
---------
И по моему, никто тебе не будет релокать если у тебя нет соответствующеи секции(вот не знаю, встовляет ли компилер
в exe релоки, посмотри. Интересно)):)
← →
Тимохов © (2004-06-29 18:01) [19]
> Игорь Шевченко © (29.06.04 17:58) [17]
Игорь, мне стыдно, но я не знаю как посмотреть (а-а-а-ааа)
← →
SammIk © (2004-06-29 18:02) [20]Тоесть должно быть где-то здесь $00DFDBF4-$(4-10),а не $0044dc08
← →
Тимохов © (2004-06-29 18:05) [21]
> SammIk © (29.06.04 18:02) [20]
ну код, какой есть.
логичней было бы относительный адрес сделатать...
← →
SammIk © (2004-06-29 18:07) [22]Ну как раз из-за этого и баг.
А ты попробуи такvar
str:string;
begin
str:="ffff";
....
messagebox(0,@str[1],pchar(str),MB_OK);
....
end;
← →
Тимохов © (2004-06-29 18:10) [23]
> Игорь Шевченко © (29.06.04 17:58) [17]
Я понял Ваш тонкий намек - никакой релокации нет, т.к. этого нет в соответствующей секции модуля.
Тогда уже два вопроса:
1. Как посмотреть секцию pe модуля? Тем же dumpbin?
2. Как вы думаете, почему константные строки не склчюаются в секцию релокации? Или это не нужно exe, а в dll делается (последнее надо проверить :)))?
← →
Тимохов © (2004-06-29 18:12) [24]
> SammIk © (29.06.04 18:07) [22]
пойду смотреть ...
← →
SammIk © (2004-06-29 18:13) [25]Да и скажи что в есп при случае с mb(0,"ggg","ggg".
Будет полезно
← →
Тимохов © (2004-06-29 18:16) [26]
> SammIk © (29.06.04 18:13) [25]
Прошу прощения, я почити совсем не знаю асм (только учить начал :)). В какой момент нужно знать значение esp?
← →
Тимохов © (2004-06-29 18:20) [27]
> SammIk © (29.06.04 18:07) [22]
> messagebox(0,@str[1],pchar(str),MB_OK);
в этом случае при присвоении значения str есть абс адрес
kS := "ggg";0044DC07 8D45FC lea eax,[ebp-$04]
0044DC0A BA58DC4400 mov edx,$0044dc58
0044DC0F E87C66FBFF call @LStrLAsg
← →
SammIk © (2004-06-29 18:31) [28]
00DFDBE1 8D442404 lea eax,[esp+$04]<---Сдесь
00DFDBE5 50 push eax
00DFDBE6 8D442408 lea eax,[esp+$08]
00DFDBEA 50 push eax
← →
Тимохов © (2004-06-29 18:40) [29]Находясь на указанной вами строке в esp имею 0012F5AC
← →
SammIk © (2004-06-29 18:43) [30]Это нормально))
А теперь скажи, что у тебя в стеке по этому адресу?
← →
SammIk © (2004-06-29 18:44) [31]По идее, окно со стеком должно быть справа снизу, в окне
дизасмера.
← →
Тимохов © (2004-06-29 18:45) [32]
> Игорь Шевченко © (29.06.04 17:58) [17]
Выполнил команду
TDUMP.EXE ExeLibrary.exe > result
Что в полученном файле является relocation секцией?
По строке "Relocation" найдено всего два места
Relocation Table entry count 0000h ( 0. )
Relocation Table address 0040h ( 64. )
← →
SammIk © (2004-06-29 18:47) [33]Хотя в принципе это не важно))
И так ясно, куда надо указывает)))
Извени, загонял тебя)
← →
Тимохов © (2004-06-29 18:48) [34]
> SammIk © (29.06.04 18:43) [30]
Я понять не могу, зачем мы разбираем случай вызова ExportFunctionWithCharArray - там вроде все ок работает.
> SammIk © (29.06.04 18:44) [31]
Находится 00000000
← →
Тимохов © (2004-06-29 18:50) [35]
> SammIk © (29.06.04 18:47) [33]
да ничего.
ведь интересно же - в чем фишка.
ведь ничего такого ужасного я вроде не делаю.
ламо вроде тоже не светит. вот и нужно знать, где облажался, чтобы не облажаться в след раз.
← →
SammIk © (2004-06-29 18:57) [36]Вообщем мои ответ тако:
В случае №1(когда не получается) у тебя адрес(те push $xxxxxx)
статическии(на этапи компиляции биндится), а когда ты грузишь свои exe как либу, то база у тебя далеко не $40000(или какая там). А поскольку базы у фаилов одни и теже, то фортень
загружает твою "длл" в другое место и все адреса меняются, НО
этот статическии адрес НЕ меняется. Получается, что строка
берется из адресного пространства вызывающеи проги.
Короче видешь ерундень вместо текста.
Что делать?
Поищи в делфовом справочнике директивы на эту тему.
У меня справочника нет, подсказать не могу.
← →
Тимохов © (2004-06-29 19:00) [37]
> Поищи в делфовом справочнике директивы на эту тему.
Пойду искать...
Дома еще попробую ту же фишку с dll.
Не может быть там такого, чтобы был тот же баг.
← →
SammIk © (2004-06-29 19:02) [38]И не будет)))
← →
Тимохов © (2004-06-29 19:02) [39]я тоже в этом уверен.
интересно было бы знать, где это написано...
← →
SammIk © (2004-06-29 19:03) [40]В хелпе
← →
Тимохов © (2004-06-29 19:09) [41]
> SammIk © (29.06.04 19:03) [40]
уверены?
Что-нибудь типа "Program control"?
← →
SammIk © (2004-06-29 19:09) [42]ХЗ
← →
Тимохов © (2004-06-29 19:32) [43]X3 так ХЗ.
Разберусь - сообщу. Может кому будет интересно :))
← →
Игорь Шевченко © (2004-06-29 20:46) [44]Number interesting RVAs 00000010
Name RVA Size
------------------ -------- --------
Exports 00000000 00000000
Imports 00048000 00001F6E
Resources 00051000 00003600
Exceptions 00000000 00000000
Security 00000000 00000000
Fixups 0004C000 00004A7C
Debug 00000000 00000000
Description 00000000 00000000
Global Ptr 00000000 00000000
TLS 0004B000 00000018
Callbacks 00000000 00000000
Bound Imports 00000000 00000000
Import Addr Table 00000000 00000000
Delayed Imports 00000000 00000000
COM Runtime 00000000 00000000
reserved 00000000 00000000
То, что жирным и есть Relocations
Секция обычно называется
07 .reloc 00004A7C 0004C000 00004C00 00048400 50000040 [IRS]
tdump -R обычно показывает таблицу Fixup"ов (она же Relocations)
← →
Digitman © (2004-06-30 08:57) [45]
> SammIk © (29.06.04 18:07) [22]
> Ну как раз из-за этого и баг.
> А ты попробуи так
> var
> str:string;
> begin
> str:="ffff";
> ....
> messagebox(0,@str[1],pchar(str),MB_OK);
> ....
> end;
а уж вот это ты очевидную ерунду сморозил
задействуя дин.тип, ты задействуешь как минимум модули system и sysutils, которые не инициализированы
← →
Тимохов © (2004-06-30 11:04) [46]
> а уж вот это ты очевидную ерунду сморозил
>
> задействуя дин.тип, ты задействуешь как минимум модули system
> и sysutils, которые не инициализированы
Тогда почему это все работает в dll? Там происходит инициализация system и sysutils?
← →
Тимохов © (2004-06-30 11:11) [47]
> Игорь Шевченко © (29.06.04 20:46) [44]
Научиться бы еще это все понимать.
До ключа -R я вчера дома дошел. Структура информации где-то описана? Т.е. вчера я попробовал все тоже самое но из dll с базовым адресом, равным exe. Все корректно перенеслось.
Вот я и подумал: почему в exe ничего не переносится. Попытался понять структуру отчета tdump -R для dll и exe. Но думаю, что тут просто так не разберешься - нужно описание структуры.
Всем.
ВОПРОСЫ.
1. Почему в dll создается таблица релокации, а в exe нет?
2. Этим можно как-то управлять, например, директивами компилятора?
← →
SammIk © (2004-06-30 11:16) [48]2[45]
А если такvar
?
p:DWORD
И почему вы сделали такои вывод?
Может инициализированы.
← →
Digitman © (2004-06-30 11:16) [49]
> Тогда почему это все работает в dll? Там происходит инициализация
> system и sysutils?
ну а как же ?! при иниц-ции библ-ки система вызывает DllEntryPoint(), в ходе этого как раз и иниц-ся модули
а поскольку в exe нет DllEntryPoint(), то и иниц-ция не выполняется
← →
Игорь Шевченко © (2004-06-30 11:17) [50]
> а поскольку в exe нет DllEntryPoint(), то и иниц-ция не
> выполняется
Ой.
← →
SammIk © (2004-06-30 11:22) [51]2[49]
Насколько я понимаю, приходит всетоки сообщение
PROCESS_ATTACH.
Вернее даже не сообщение, просто по энтрипоинт передается управление, с 3 параметрами.
← →
Digitman © (2004-06-30 11:22) [52]
> SammIk © (30.06.04 11:16) [48]
> 2[45]
> А если так
> var
> p:DWORD?
а так - пожалуйста
если переменная р локальная, то память под нее аллокируется в стеке, и никаких проблем нет
> И почему вы сделали такои вывод?
> Может инициализированы.
см. [49]
← →
SammIk © (2004-06-30 11:28) [53]Насколько я понял из сдк, то это принятое название.
И кличат им точку входа(entrypoint), или я чегото не допонимаю?
Если так, то поясните пожалуисто.
← →
Игорь Шевченко © (2004-06-30 11:39) [54]Тимохов © (30.06.04 11:11)
> 1. Почему в dll создается таблица релокации, а в exe нет?
Почему не пользоваться TDUMP прежде чем задавать подобные вопросы? Практика - критерий истины.
← →
Digitman © (2004-06-30 11:40) [55]
> SammIk © (30.06.04 11:28) [53]
все верно понимаешь.. но что тебе из всего этого остается неясным ?
← →
SammIk © (2004-06-30 11:43) [56]Тогда все понятно, просто выш светло голубои
(c)
с понтолыку иногда сбивает.
Малоли что, вдруг что-то не допонимаю.
← →
SammIk © (2004-06-30 11:43) [57]Кстати, да простят знающие, можно ручками создать
таблицу релоков.
← →
SammIk © (2004-06-30 11:45) [58]Удалено модератором
Примечание: Offtopic
← →
Тимохов © (2004-06-30 11:46) [59]
> Игорь Шевченко © (30.06.04 11:39) [54]
> Почему не пользоваться TDUMP прежде чем задавать подобные
> вопросы? Практика - критерий истины.
Силился понять, как этот ответ (выше) отностися к этому вопросу (ниже) :))
> > 1. Почему в dll создается таблица релокации, а в exe нет?
tdump я полльзовался. О чем я выше и сказал. А также спросил про формат данных, которые tdump выдает. Он описан где нибудь?
Все же - один и тот же код в dll делает перемещаемым, в exe - нет. Можно ли в дельфи управлять перемещаемостью кода? НАсколько я понимаю в dll это делается само, в exe - нет.
← →
Тимохов © (2004-06-30 11:58) [60]
> SammIk © (30.06.04 11:43) [57]
Наверное, можно и ручками (не знаю).
Но ведь и компилятор должен предоставлять такой сервис?
Для dll он же это радостно делает. Почему не хочет для exe?
Посмотрел вчера директивы компилятора: знаний не хватает, чтобы понять есть ли такая директива. Есть там, что-то по управлению PE флагами.
← →
Игорь Шевченко © (2004-06-30 12:17) [61]Тимохов © (30.06.04 11:46)
> Силился понять, как этот ответ (выше) отностися к этому
> вопросу (ниже) :))
Ответ относится так, что у EXE есть таблица Fixup(Relocations), как и у DLL
← →
Тимохов © (2004-06-30 12:21) [62]
> Игорь Шевченко © (30.06.04 12:17) [61]
Спасибо, что принмаете участие в этом обсуждении.
Про fixup у exe я понял - посмотрю внимательнее.
Но как относиться к тому, что у dll в нее внесены константные строки, а в exe - нет. Я же не делал никаких действий ни в том ни в другом случае. Это на компилятор дельфи директивы labrary и program так действуют?
Т.е. никто не говорит о том, где свзять описание формата данных, выдаваемых tdump, то я прихожу к выводу, что такого формата нет, а для того, чтобы понимать, что там написано, нужно просто хорошо знать структуру исполняемых модулей, например, изучив msdn и другие источники. Так?
← →
Тимохов © (2004-06-30 12:24) [63]Попытаюсь объяснить, зачем это нужно.
Вопрос возник просто как теоретический. Но сейчас в том, чтобы делать export функции в своей программе я вижу практические выгоды. Не буду говорить какие, т.к. ногами затоптать могут (скажут пользуйся com и не умничай :))).
Поэтому вопрос из чистого любопытсва для меня перешел в разряд важных с практической точки зрения.
← →
Игорь Шевченко © (2004-06-30 12:28) [64]Тимохов © (30.06.04 12:24)
Есть встречное предложение: Ты собираешь ма-аленький неработающий пример, со всеми EXE, PAS"ами, DPR"ами и прочими нужными файлами, посылаешь мне на почту. Я не гарантирую, что посмотрю быстро, но специально для этого мне разрабатывать проект некогда. Результаты своих наблюдений я сообщу в форум.
← →
Тимохов © (2004-06-30 12:31) [65]
> Игорь Шевченко © (30.06.04 12:28) [64]
Отличное предложение.
Завтра составлю и пришлю пример с документацией, о том, что не не понятно и что понятно. А также вопросы.
Спасибо.
:)
← →
Piter © (2004-06-30 15:05) [66]Я тоже очень заинтересовался фактом, "открытым" Тимоховым. Очень хотел бы знать его объяснение
← →
Тимохов © (2004-06-30 15:12) [67]Удалено модератором
Примечание: Offtopic
← →
Тимохов © (2004-06-30 15:13) [68]Удалено модератором
Примечание: Offtopic
← →
Тимохов © (2004-06-30 18:00) [69]
> Игорь Шевченко © (30.06.04 12:28) [64]
Вопрос-уточнение про формат примера, который я хочу Вам предоставить.
Скажите нужно или мне в комментирии к каждой выписывать асм код, который у меня получается или нет?
← →
Игорь Шевченко © (2004-07-01 00:50) [70]Тимохов © (30.06.04 18:00)
> Скажите нужно или мне в комментирии к каждой выписывать
> асм код, который у меня получается или нет?
Я думаю, не стоит. Мне главное, чтобы его можно было быстро и ничего не настраивая, собрать и запустить.
← →
Piter © (2004-07-02 21:37) [71]ну и как там что?
← →
GrayFace © (2004-07-03 07:41) [72]Похоже, все это связано именно с System и SysUtils. В Delphi есть менеджер памяти, находящийся в одном из этих модулей. Глобальное выделение памяти идет чераз него, а, значит, не идет в данном случае.
Попробуй так:
procedure ...;
const Text="text"; Caption="Caption";
begin
MessageBox(0, Text, Caption, MB_OK);
end;
Digitman [45]
>задействуя дин.тип, ты задействуешь как минимум модули system и sysutils, которые не инициализированы
Я так не думаю. ИМХО, это обычный PChar с выделением памяти. Если бы каждый раз, когда нужна строка, компилятор ставил обращение к System и/или SysUtils, то оптимизация летела бы к чертям... тоже ИМХО.
← →
GrayFace © (2004-07-03 07:49) [73]Ой. Я ступил в ответе на [45].
А так точно должно работать:procedure ...;
const Text:ShortString="text"; Caption:ShortString="Caption";
begin
MessageBox(0, Text, Caption, MB_OK);
end;
← →
Piter © (2004-07-05 23:46) [74]Игорь Шевченко (01.07.04 00:50) [70]
ну так как ваше мнение?
← →
Тимохов © (2004-07-06 10:37) [75]
> Piter © (05.07.04 23:46) [74]
Игорь сказал, что нам придется подождать, т.к. у него отпуск.
Но после он обязательно посмотрит.
← →
Piter © (2004-07-08 12:16) [76]Удалено модератором
Примечание: Offtopic
← →
Piter © (2004-07-11 12:43) [77]И когда мы увидим ответ? Ветка умерт к тому времени?
← →
SammIk © (2004-07-11 20:17) [78]Слухаи, и мне пошли свои ваилик, тож интересно скомпилить да поразбирать.
sammik(DOG)mail(DOT)ru
Скорее всего в понедельник скажу, вот экзамен сдам))
← →
Тимохов © (2004-07-12 12:05) [79]
> Piter © (11.07.04 12:43) [77]
потерпите - я же объяснил в чем дело.
вопрос не помрет - уверяю вас. :)))
← →
SammIk © (2004-07-12 17:55) [80]
Из дизасма:
CODE:0044DBF4 public ExportFunctionWithStringConst
CODE:0044DBF4 ExportFunctionWithStringConst proc near
CODE:0044DBF4 push 0
CODE:0044DBF6 push 44DC08h<<<Конкретно компилер подвел нас, записал пуш статически((CODE:0044DBFB push 44DC08h<<<Тут тоже
CODE:0044DC00 push 0
CODE:0044DC02 call pMessageBoxA
CODE:0044DC07 retn
CODE:0044DC07 ; ---------------------------------------------------------------------------
CODE:0044DC08 db 68h ; h<<Наша HI
CODE:0044DC09 db 69h ; iС дугои функциеи дела проще
:
CODE:0044DBD0 public ExportFunctionWithCharArray
CODE:0044DBD0 ExportFunctionWithCharArray proc near
CODE:0044DBD0
CODE:0044DBD0 var_2 = byte ptr -2
CODE:0044DBD0 var_1 = byte ptr -1
CODE:0044DBD0
CODE:0044DBD0 push ecx
CODE:0044DBD1 mov byte ptr [esp+0], 68h
CODE:0044DBD5 mov [esp+3+var_2], 69h
CODE:0044DBDA mov [esp+3+var_1], 0
CODE:0044DBDF push 0
CODE:0044DBE1 lea eax, [esp+4]<<Тут переменные грузит из стека, динамически
CODE:0044DBE5 push eax
CODE:0044DBE6 lea eax, [esp+8]
CODE:0044DBEA push eax
CODE:0044DBEB push 0
CODE:0044DBED call pMessageBoxA
CODE:0044DBF2 pop edx
CODE:0044DBF3 retn
CODE:0044DBF3 ExportFunctionWithCharArray endp ; sp = -10h
___________________________________________А это вообще одельно
CODE:0044DBED call pMessageBoxAОн сначала кидает нас сюда:
CODE:00406D28 pMessageBoxA proc near ;
CODE:00406D28 ;
CODE:00406D28 jmp ds:MessageBoxA_0
CODE:00406D28 pMessageBoxA endpА потом джампаем сюда:
.idata:00450490 extrn MessageBoxA_0:dword ;
Таким образом, когда первую грузит вторая прога, то мы при вызове
CODE:0044DBED call pMessageBoxA
поподаем в адресное пространство вызывающеи проги, а не нашеи
псевдодлл.
А по этому адресу малоли чего может быть.
Лично у меня не работал ни первыи, ни второи вариант.
>>>Тоесть правильно что у тебя ацессвиол, это следствие того, что мы колимся в кудато-туда, а не туда куда надо))
Релоки есть, но мне надо про них скил поднять.
Потом скажу что релокают, а что нет))
← →
Тимохов © (2004-07-12 17:58) [81]
> Лично у меня не работал ни первыи, ни второи вариант.
у меня дома один работает, второй - нет.
А вот на работе также - оба не работают.
Перефразирую вопрос, чтобы не свести данный к топик к личной переписке
Как использоваться exe в качестве dll, загружая с помощью LoadLibrary?
← →
SammIk © (2004-07-12 18:26) [82]Дело в том, что загружается exe превосходно.
И адрес процедуры берет верно, и релоки добовляет(но странно как-то).
Разобрался с релоками, в таблице релоков есть ссылка на изменение
адресов:CODE:0044DBF6 push 44DC08h<<<Конкретно
CODE:0044DBFB push 44DC08h<<<Тут тоже
И больше, в интересующеи нас области данных, ничего не релокируется!?!? Ни вызовы, ни что!!
По идее еще надо это релокать:CODE:0044DBED call pMessageBoxA
Но не релокается.
--------------------------------
Так же, глядя в дебагере, ось не исправляет адреса(!?!?!?) хотя они(релоки, фиксапы[как ни называи]) есть!
--------------------------------
Вообщем эта история требует детального изучения)))
Я бы пока не советовал юзать exe как длл, но никто не запрещает.
НО при условии, что не будет вызова других ф-ии
← →
Тимохов © (2004-07-12 18:57) [83]
> Я бы пока не советовал юзать exe как длл, но никто не запрещает.
я и не собираюсь.
этот вопрос возник как теоретический с возможным будущим применением.
← →
SammIk © (2004-07-12 19:02) [84]Сеичас лежу в NTDLL посмотрим как он грузит.
На сеи момент известно, что LoadLibrary обращается к ф-ии
LdrLoadDLL из NTDLL.DLL
← →
SammIk © (2004-07-12 20:37) [85]Интересно выслушать и другие мнения
← →
SammIk © (2004-07-12 20:37) [86]Интересно выслушать и другие мнения
← →
Тимохов © (2004-07-13 12:57) [87]
> SammIk © (12.07.04 20:37) [86]
во-во
← →
-SeM- (2004-07-13 15:25) [88]Странно, у меня оба примера работают без ошибок (D7, Me). Как и работало два месяца назад
Даже если переделать так [82]:
procedure test;
begin
MessageBox(0, "hi", "hi", MB_OK);
end;
// Пример со строковой константой
procedure ExportFunctionWithStringConst();
begin
Test;
end;
Может связано с директивами компилятора? Даю для сравнения мои:
-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
← →
Тимохов © (2004-07-13 15:27) [89]фиг его знает, с чем это связано. У меня тоже, то работает, то нет. Даже понять сложно логику зависимости. :(((
Я решил ждать выхода из отпуска Игоря Шевченко. Он говорил, что посмотрит.
← →
-SeM- (2004-07-13 15:31) [90]А вообще одним MessageBox сыт не будешь. После него все равно будут вопросы
На чем тормознулся я:
1. Как отловить момент загрузки/выгрузки (DLLEntryPoint)
2. Инициализация EXE (VCL)
Будут мысли, предположения - высказывайте, будем думать.
← →
Тимохов © (2004-07-13 15:35) [91]
> 2. Инициализация EXE (VCL)
я тоже не знаю как exe инициализируется. Как dll вроде в msdn описано, а как exe - не знаю.
так что мыслей нет.
← →
Ertong © (2004-07-16 09:26) [92]Попробуйте в EXE(тот что типа DLL) написать:
{$IMAGEBASE $40000000}
----------cut----------------------
When Windows succeeds in loading a DLL (or package) at its image base address, the load time is decreased because relocation fix-ups do not have to be applied.
----------cut----------------------
PS Вышлите, пожалуйста, еще мне ваш тестовый исходник :)
← →
jack128 © (2004-07-16 11:29) [93]
> Попробуйте в EXE(тот что типа DLL) написать:
> {$IMAGEBASE $40000000}
это заглушка. А если я буду использовать еще одну dll"ку с таким же базовым адресом?
← →
Ertong © (2004-07-16 11:43) [94]
> А если я буду использовать еще одну dll"ку с таким же базовым
> адресом?
Главное, чтобы все EXE имели разные базовые адреса, а DLL, если че, пересчитает релоки :)
P.S. А вообше вы правы - это не универсальный метод.
← →
имя (2004-07-16 11:45) [95]Удалено модератором
← →
Piter © (2004-07-18 20:49) [96]Тимохов, если не против - я отправлю твой вопрос в FIDO - ответы могу кидать сюда. да ты и сам можешь их читать через talk.mail.ru. Как считаешь?
← →
jack128 © (2004-07-18 21:16) [97]
> Главное, чтобы все EXE имели разные базовые адреса, а DLL,
> если че, пересчитает релоки :)
:-) Ага, как только ты придумаешь способ обеспечить это требование, так сразу и наступит рай на земле ;-)
← →
имя (2004-07-19 11:06) [98]Удалено модератором
← →
Piter © (2004-07-22 20:07) [99]ФИДО молчит...
← →
имя (2004-07-22 20:10) [100]Удалено модератором
← →
Serge_ (2004-07-25 02:48) [101]procedure XXX;
begin
asm
@Start:
push ebx
Call @Begin
@Begin:
pop ebx
sub ebx,6
jmp @GOGO
@Hi:
db "Hi there mother fuckers!",0
@GOGO:
mov eax,offset @Hi
mov ecx,offset @Start
sub eax,ecx
add eax,ebx
push $40
push eax
push eax
push 0
call messagebox
pop ebx
end;
end;
exports XXX;
.......
Только так... потомучто там действительно адресс меняется,
значит надо его вычеслять ...
← →
Serge_ (2004-07-25 02:52) [102]Но при этом надо учитывать что переменные лежат в объекте кода,
который имеет флаг только чтение, что соответсвенно легко
сменить с помощью PEEditor...
← →
имя (2004-07-25 09:56) [103]Удалено модератором
← →
Serge_ (2004-07-25 14:59) [104]Я про переменные, а не про константы.
← →
Piter © (2004-07-27 14:50) [105]Вроде Игорь вернулся из отпуска... Может что скажет?
← →
pasha_golub © (2004-07-27 15:37) [106]Классный вопрос, как я его сразу не заметил...
← →
Игорь Шевченко © (2004-07-27 16:05) [107]Piter © (27.07.04 14:50) [105]
Вредный ты. Вернулся.
Кстати, с иходным проектом получается полная ерунда - если сменить ImageBase у EXE"шника, загружаемого, как DLL, то вместо одной работающей функции и одной неработающей получаются две вылетающие по AV функции :) Причина AV в некорректной таблице вызова импортируемых функций из загружаемого EXEшника.
Такое у меня ощущение возникает (могу ошибаться, конечно), что загрузчик производит настройку адресов только у DLL. При попытке обмануть загрузчик и сказать, что файл EXE является DLL"ю, он его честно загружает, начинает исполнять код точки входа (для EXEшника) и сталкивается с невозможностью инициализации кода двух EXEшников в адресном пространстве одного процесса (начинают выдаваться сообщения EOSError (System error. Code: 1410. Class already exists), то есть, была попытка вызова RegisterClass с одним и тем же именем несколько раз. При загрузке EXEшника без признака DLL это сообщение, разумеется, не появлялось, так как его стартовый код не выполнялся.
Мораль: нефиг импортировать функции из Exeшников, написанных на Delphi :)
← →
Piter © (2004-07-27 18:15) [108]Игорь Шевченко © (27.07.04 16:05) [107]
Вредный ты. Вернулся.
ну если есть работа для настоящего профессионала - то надо его привлечь :)
← →
-SeM- (2004-07-27 18:24) [109]Игорь Шевченко © (27.07.04 16:05) [107]
> При загрузке EXEшника без признака DLL
Какого-такого признака, подробнее можно? plz...
← →
Игорь Шевченко © (2004-07-27 21:52) [110]-SeM- (27.07.04 18:24) [109]
tdump exe_file
tdump dll_file
сравниваем поле Flags (вторая строчка сверху в разделе Portable Executable header)
Флажок с значением 0x2000 и есть признак DLL или не DLL
← →
имя (2004-08-09 11:16) [111]Удалено модератором
Страницы: 1 2 3 вся ветка
Текущий архив: 2004.09.19;
Скачать: CL | DM;
Память: 0.78 MB
Время: 0.027 c