Сейчас на форуме: asfa (+6 невидимых)

 eXeL@B —› Вопросы новичков —› Явное связывание
Посл.ответ Сообщение

Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 13 декабря 2013 18:34
· Личное сообщение · #1

В VS C++ пытался явно вызвать функцию MyFunc из DLL, используя GetProcAddress(hDll,"MyFunc").
Не получается, т.к. компилятор дописывает к имени подчеркивание и хвост.
Возможно ли нейтрализовать это так называемое манглирование, не трогая DLL.
Через dllexp.exe хорошо видно в DLL неискаженное имя MyFunc, кроме того, если в GetProcAddress
заменить имя на вызов по её ординалу, то происходит нормальный вызов. Также при неявном
связывании в VS C++ работает и имя этой функции. Используется код СРР в программе.
На ассемблере, насколько помнится, этой закавыки не возникает.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 13 декабря 2013 18:49 · Поправил: reversecode
· Личное сообщение · #2

а зачем трогать длл? вы ее перекомпиливаете? или кого?
правильный http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx
укажите

и добавте еще extern "C"




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 13 декабря 2013 19:11
· Личное сообщение · #3

Он не может дописывать что то к текстовым константам.

Плюсы это рак си, ну а если и компиль глюченный, то удалите это вообще из системы.



Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 13 декабря 2013 19:24
· Личное сообщение · #4

ksol пишет:
Через dllexp.exe хорошо видно в DLL неискаженное имя MyFunc

Теперь сравни его с тем именем, которое ты указываешь в GetProcAddress. Регистр важен.



Ранг: 512.7 (!), 360thx
Активность: 0.270.03
Статус: Модератор

Создано: 13 декабря 2013 23:07
· Личное сообщение · #5

ksol пишет:
неискаженное имя MyFunc


что ето за предрассудки?

Декорация, манглинг (name decoration, name mangling)



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 14 декабря 2013 14:10
· Личное сообщение · #6

reversecode и др.
Посмотрел я ссылку - там перечисляются соглашения по вызову. У меня в программе
используется __stdcall, и как показывает dllexp, то же самое в DLL. Да, до стека дело ещё
не доходит. Я пишу в GetProcAddress "MyFunc", а как видно в OllyDbg, в параметрах
GetProcAdress появляется "_MyFunc@1". Вот эти приписки и мешают.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 14 декабря 2013 14:15 · Поправил: reversecode
· Личное сообщение · #7

"_MyFunc@1" значит она так експортируется и в самой длл, фар -> F3
как она там отображена?

конвершин колл влияют как раз на создание мангл имени

значит задавайте в GetProcAddress как "_MyFunc@1"

ну либо я опять чего то не понимаю




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 14 декабря 2013 14:35
· Личное сообщение · #8

Файлы в студию же. Не может быть, чтоб ты писал одну строку в GetProcAddress, а реально была другая. Строку на ходу компилятор не исправляет.



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 14 декабря 2013 18:45
· Личное сообщение · #9

Проверил ваши предложения. Когда в программе задал вызов в виде "_MyFunc@1", в
дизассемблированном коде - это же "_MyFunc@1" и вызова функции нет.
Посмотрел в Far'e эту DLL. Там в отличие от того, что показывает dllexp, искаженное
(манглированное ) имя "?MyFunc@@YZXXZ". Задав его в программе - функция вызвалась!
То есть при создании DLL с намерением явной загрузки функций надо изменять
экспортируемые имена, что, наверное, выполняет def-файл, Опять надо что-то делать!!
Спасибо за предложения!




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 14 декабря 2013 18:48 · Поправил: reversecode
· Личное сообщение · #10

ksol пишет:
То есть при создании DLL с намерением явной загрузки функций надо изменять
экспортируемые имена, что, наверное, выполняет def-файл, Опять надо что-то делать!!


reversecode пишет:
конвершин колл влияют как раз на создание мангл имени


reversecode пишет:
и добавте еще extern "C"


rmn
внимательнее читаем, то на что я отвечаю

а def файлом можно только перемапить
но для правильности для этого делают .h файл который подключают
а не тупо функции по именам вызывают где в конверш-кол можно пролететь



Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 14 декабря 2013 19:10
· Личное сообщение · #11

reversecode
куда добавить extern "C"? у него dll скомпиленная уже

просто его dllexp.exe показывает имя размангленным, а не как есть.



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 16 декабря 2013 18:48
· Личное сообщение · #12

При создании DLL указал для прототипа extern "C" :
Code:
  1. extern "C" __declspec(dllexport) void __stdcall MyFunc();
  2.  void __stdcall MyFunc()
  3. {
  4.  MessageBox(NULL, "in DLL", "DLL", MB_OK);
  5. }

Теперь в библиотеке функция имеет имя "_MyFunc@0".
Компилятор Visual C++ - тот ещё!



Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 16 декабря 2013 19:32
· Личное сообщение · #13

ну так убери stdcall оттуда и все будет нормально

| Сообщение посчитали полезным: ksol

Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 17 декабря 2013 18:56
· Личное сообщение · #14

rmn
Спасибо! Так я и сделал:
Code:
  1. #include <windows.h>
  2. extern "C" __declspec(dllexport) void  MyFunc();
  3.  void  MyFunc()
  4. {
  5.  MessageBox(NULL, "in DLL", "DLL", MB_OK);
  6. }

И получил, что мне и требовалось:
Code:
  1. ordinal hint RVA      name
  2.  
  3.           1    0 00011113 MyFunc = @ILT+270(_MyFunc)
  4.  

Но, созданная таким способом DLL на ура не заработает при неявном связывании!



Ранг: 19.7 (новичок), 14thx
Активность: 0.030
Статус: Участник

Создано: 17 декабря 2013 21:06
· Личное сообщение · #15

ksol
А прикрутить def-файл?
Пример:
b2p.cpp:
Code:
  1. bool WINAPI ImgGetVisibility(long Img)


b2p.def:
Code:
  1. EXPORTS
  2. ImgGetVisibility




Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 17 декабря 2013 21:30
· Личное сообщение · #16

ksol пишет:
Но, созданная таким способом DLL на ура не заработает при неявном связывании!

orly?

Code:
  1. extern "C" __declspec(import) void  MyFunc();
  2. #pragma comment(lib, "MyDll.lib")

и усе



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 18 декабря 2013 16:49
· Личное сообщение · #17

rmn
А я и не думал, что так можно! Поэтому запустил, изменив соглашение:
Code:
  1. #include <windows.h>
  2.  __declspec(dllexport) void __stdcall MyFunc();
  3.  void __stdcall MyFunc()
  4. {
  5.  MessageBox(NULL, "in DLL", "DLL", MB_OK);
  6. ==============================================
  7. #include <windows.h>
  8. #pragma comment(lib, "dll2.lib")
  9. void __stdcall  MyFunc();
  10. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  11.            LPSTR lpszCmdParam, int nCmdShow)
  12.          {
  13.           MyFunc();
  14.           return 0;
  15.     }





Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 18 декабря 2013 16:51
· Личное сообщение · #18

смысл всего этого? только что бы удобнее было вызывать GetProcAddress с обычным именем функции ?



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 18 декабря 2013 17:00
· Личное сообщение · #19

reversecode
Наверное, может быть...


 eXeL@B —› Вопросы новичков —› Явное связывание
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати