Текущий архив: 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]В хелпе
Страницы: 1 2 3 вся ветка
Текущий архив: 2004.09.19;
Скачать: CL | DM;
Память: 0.58 MB
Время: 0.04 c