Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Импрот функций из exe. [D6]


Страницы:   1 2 3 4 5 6

Тимохов ©   (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)?


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо