Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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 (пример использования).

Код главной формы 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 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
4-1091110061
kblc
2004-07-29 18:07
2004.09.19
Как для TRichEdit организовать прозрачность?


3-1093322607
snake1977
2004-08-24 08:43
2004.09.19
правильное индексирование


14-1093587725
peypivo
2004-08-27 10:22
2004.09.19
американцы и луна


6-1087821074
NLO
2004-06-21 16:31
2004.09.19
HTTP ЗАПрос


14-1093894000
GuAV
2004-08-30 23:26
2004.09.19
Авторам нижеперечисленых и всех подобных веток посвящается :)