![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Импрот функций из exe. [D6]
Тимохов © (2004-06-29 11:44:00)Прочел тут как-то, что импортировать функции можно не только из 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;
В последнем случае все вывелось корректно.
SammIk (2004-06-29 18:44:00) [81]По идее, окно со стеком должно быть справа снизу, в окне
дизасмера.
SammIk (2004-06-29 18:43:00) [82]Это нормально))
А теперь скажи, что у тебя в стеке по этому адресу?
Тимохов (2004-06-29 18:40:00) [83]Находясь на указанной вами строке в esp имею 0012F5AC
SammIk (2004-06-29 18:31:00) [84]
00DFDBE1 8D442404 lea eax,[esp+$04]<---Сдесь
00DFDBE5 50 push eax
00DFDBE6 8D442408 lea eax,[esp+$08]
00DFDBEA 50 push eax
Тимохов (2004-06-29 18:20:00) [85]
> 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
Тимохов (2004-06-29 18:16:00) [86]
> SammIk © (29.06.04 18:13) [25]
Прошу прощения, я почити совсем не знаю асм (только учить начал :)). В какой момент нужно знать значение esp?
SammIk (2004-06-29 18:13:00) [87]Да и скажи что в есп при случае с mb(0,'ggg','ggg'.
Будет полезно
Тимохов (2004-06-29 18:12:00) [88]
> SammIk © (29.06.04 18:07) [22]
пойду смотреть ...
Тимохов (2004-06-29 18:10:00) [89]
> Игорь Шевченко © (29.06.04 17:58) [17]
Я понял Ваш тонкий намек - никакой релокации нет, т.к. этого нет в соответствующей секции модуля.
Тогда уже два вопроса:
1. Как посмотреть секцию pe модуля? Тем же dumpbin?
2. Как вы думаете, почему константные строки не склчюаются в секцию релокации? Или это не нужно exe, а в dll делается (последнее надо проверить :)))?
SammIk (2004-06-29 18:07:00) [90]Ну как раз из-за этого и баг.
А ты попробуи так
var
str:string;
begin
str:='ffff';
....
messagebox(0,@str[1],pchar(str),MB_OK);
....
end;
Тимохов (2004-06-29 18:05:00) [91]
> SammIk © (29.06.04 18:02) [20]
ну код, какой есть.
логичней было бы относительный адрес сделатать...
SammIk (2004-06-29 18:02:00) [92]Тоесть должно быть где-то здесь $00DFDBF4-$(4-10),а не $0044dc08
Тимохов (2004-06-29 18:01:00) [93]
> Игорь Шевченко © (29.06.04 17:58) [17]
Игорь, мне стыдно, но я не знаю как посмотреть (а-а-а-ааа)
SammIk (2004-06-29 17:59:00) [94]Мое мнение такое:
Когда делаешь через строки, то адрес получается статическим
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 17:58:00) [95]
> Почему не было релокации?
А что находится в Relocation Info в PE-модуле ? :)
Тимохов (2004-06-29 17:46:00) [96]Хочу добавить, что cpu функции ExportFunctionWithStringConst будучи просмотренным из ExeLibrary имеет точно такие же ссылки на адреса, т.е. на адрес $0044dc08.
При этом этот адрес находится сразу после функции ExportFunctionWithStringConst. Ну, т.е. как обычно дельфи располагает строковые константы.
Почему не было релокации?
Тимохов (2004-06-29 17:43:00) [97]Итак развернутый вопрос :)
Написано два exe: ExeLibrary (сама библиотека, эскспортирующая функции) и ExeLibraryClient (пример использования).
Код главной формы ExeLibrary
unit 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 функции выглядят так:
ExportFunctionWithCharArray
00DFDBD0 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
ExportFunctionWithStringConst
00DFDBF4 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 16:47:00) [98]
> Игорь Шевченко © (29.06.04 16:40) [13]
виноват, да я так - по ходу спросил.
больше не буду.
)
Игорь Шевченко (2004-06-29 16:40:00) [99]Тимохов © (29.06.04 16:33)
А зачем нам заниматься гаданием - выкладываешь то, что я попросил, мы смотрим.
Тимохов (2004-06-29 16:33:00) [100]
> значит, секция иниц.данных в случае LoadLibrary() была загружена
> по иному вирт.адресу
это утверждение следует из того, что оба exe имели одинаковый предпочитительный адрес (стандартный для exe)?