Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
20.06.2014, 02:25
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Ну т.е. обычно dll либо системная, либо кладется в папку с программой. Тогда достаточно указать ее имя: Код: vbnet 1.
Если dll лежит в другой, заранее известной папке C:\MyKnownPath\, то работает такой вариант: Код: vbnet 1.
Предположим, я заранее не знаю в какой папке лежит dll, но могу ее вычислить из кода т.е. нужно реализовать следующее: 1) Программа вычисляет SomePath (путь установки приложения, кот. может быть любым) 2) Программа знает что по пути SomePath лежит известная cpp_my_dll.dll 3) Программа знает что в этой dll есть известная ф-ция CPP_MyFunction и хочет ее вызвать. Задекларировать заранее я не могу. Я не знаю SomePath, знаю только алгоритм его вычисления. Как? ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 02:40
|
|||
---|---|---|---|
|
|||
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Дмитрий77, LoadLibrary ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 03:04
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
скукотища, именно по этому пути и иду. Ну допустим Код: vbnet 1. 2. 3. 4. 5. 6.
А как мне ее вызвать, зная ProcAdd? В C++ такая штука декларируется (как-то так): Код: plaintext 1. 2. 3. 4.
А а VB чего делать? ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 03:45
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
У меня (видимо к счастью) CPP_MyFunction не имеет аргументов. Просто возвращает указатель на Null-Terminated строку в памяти. Код: vbnet 1.
Т.е. вот такой простой вариант получился: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Ничего не упустил? PtrToString -это моя приблуда, которая вытаскивает строку по Ptr (адресу в памяти), я ее неоднократно приводил в своих топиках. Главное, код выше этот Ptr возвращает. ... с параметрами наверно тяжело, судя по рассуждениям на разных форумах. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 04:33
|
|||
---|---|---|---|
|
|||
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
> Дмитрий77, > ... с параметрами наверно тяжело, судя по рассуждениям на разных форумах. пример реализации для stdcall (в сообщении от 03-29-2005, 12:53 PM). ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 05:28
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
скукотища, я именно (видимо копию) этого топика и изучал. И вот то что в первом посте мне понравилось значительно больше, нежели заумности в проекте куда ведет ссылка внизу. И мне к счастью CallWindowProc достаточно. В принципе, я думаю можно сделать и с аргументами без тех заумностей что в указанном тобой примере. Но это надо копать документацию и врубаться, и если честно не охота. Итак уже на своего Визарда неделю потратил. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 06:31
|
|||
---|---|---|---|
|
|||
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Посмотрите в эту сторону http://www.script-coding.com/dynwrap.html и возможно по ссылке в шапке на langmf http://forum.script-coding.com/ ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 07:10
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
experience, ну не знаю. Чего я точно не люблю, так это всякие wrap-перы. Их и в самом VB, да и в любом нете кривых-косых хватает. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 07:44
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
http://books.google.ru/books?id=q9_Y_dRnslgC&pg=PA348&lpg=PA348&dq=LoadLibrary GetProcAddress vb6&source=bl&ots=X_ARPcdvD1&sig=ZdcIQ9ycAX5rXE96KOu5SAfUGq0&hl=ru&sa=X&ei=LqijU7vdE4Op4gShy4CYBA&ved=0CEgQ6AEwCDgK#v=onepage&q=LoadLibrary GetProcAddress vb6&f=false Листинг 8.3 и 8.4 Любое "грамотное решение" по ходу сводится к запихиванию Array() из параметров в первый параметр ф-ции CallWindowProc ассамблеровскими методами (либо побайтно, либо с использованием API работы с памятью). У меня, повторюсь, параметров у ф-ции нет. Единственное, чего чуть беспокоит (как человека съевшего не одну собаку), это вызов Код: vbnet 1.
Ну т.е. не мусорится ли чего. Автор упомянутой статьи настаивает на безобидности прямого вызова только для случая "ровно 4 параметра", у меня же их нуль. Хотя в принципе, код такой невинный, что работает да и ладно. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 08:37
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Обычно делал так: 1. Декларировал DLL без пути 2. Запоминал текущий диск и папку (не обязательно) 3. Устанавливал текущую папку с DLL при помощи ChDrive SomePath и ChDir SomePath 4. Вызвал какую нибудь (dummy) функцию из этой DLL 5. Восстанавливал то, что менялось в п.2 (не обязательно) После этого при любой текущей папке можно вызывать и другие функции этой DLL ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 10:39
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
ZVI, я понял твою идею. Короче, это все лишнее ZVI2. Запоминал текущий диск и папку (не обязательно) 3. Устанавливал текущую папку с DLL при помощи ChDrive SomePath и ChDir SomePath 4. Вызвал какую нибудь (dummy) функцию из этой DLL 5. Восстанавливал то, что менялось в п.2 (не обязательно) Вариант 1: Код: vbnet 1. 2. 3. 4. 5. 6. 7.
Но если блин промахнулись с папкой (проверять SetDllDirectory бесполезно, она и несуществующую забабахает и вернет True) или файла dll в ней нет (в моем случае не гарантировано) то будет ошибка Вариант 2: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Но опять же, если промахнулись с наличием ф-ции (в старой версии cpp_my_dll.dll одна из ф-ций отсутствует, а априори не знаю версию клиента), то будет ошибка. Посему грамотный вариант без использования вызова по ProcAdd такой: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Честно говоря, я не уверен в эффективности и необходимости FreeLibrary, да еще и с циклом (по MSDN извините). Очевидно, что при обычном задекларированном вызове VB всегда делает LoadLibrary, но ни фига и никогда не делает FreeLibrary (а иначе как он путь продолжает видеть после вызова твоего dummy и реверсной смены папки назад). Если неграмотно вызывать dll, которую VB не найдет то будет "Dll not found". А вот если вызвать dll сначала грамотно любым из 4-х методов включая твой и 3 моих, потом выполнить грамотный цикл из FreeLibrary, а потом вызвать dll "неграмотно", то будет не "Dll not found", а просто crash VB-приложения, почему ХЗ и я с Opal так однажды уже игрался и так и не докопался почему. Вот поэтому думаю, может и не стоит вообще FreeLibrary делать. Ну накрутит прога несколько рефренсов, хуже то от этого не будет. А вот не будет ли хуже от FreeLibrary, честно говоря не уверен. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 11:00
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Модуль класса FunctionPtr Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240.
Пример вызова Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Это не единственный способ вызова функции по адресу, но, как по мне, самый гибкий. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 11:25
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Бенедикт, спасибо. Давно тебя не слышал. Ну, смотри. Тот пример который ты привел (в подробности каюсь не вдавался, но по беглому уловил) по сути повторение уже сказанного: 1. 16192859 ссылка на Zip внизу 2. 16192954 Согласен? === Из совета ZVI и моего топика 16193687 следует что достаточно 1) задекларировать без пути 2) cделать LoadLibrary с путем (либо SetDllDirectory ) 3) вызвать задекларированную ф-цию (со всеми параметрами как положено) Нафига извращаться? Как считаешь? ================== В VB по сути хорошо что декларировать можно что угодно. Например пример C-шного кода А как установить/обновить драйвер для одного конкретного модема? Обрати внимание что с pInstallSelectedDriver пришлось извращаться именно по принципу о кот. сейчас говорим, хотя обычно в C достаточно include <.h>, но вот забыли нарисовать. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51.
А в VB оказалось проще: 16072864 Код: vbnet 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 11:47
|
|||
---|---|---|---|
|
|||
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Дмитрий77Бенедикт, спасибо. Давно тебя не слышал. Тоже рад тебя слышать. А то твое имя уже в качестве эталона приходится использовать )) 15961785 ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 12:05
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Промахнулись ли папкой с DLL определяется однократно Dir-ом перед обращением к dummy-функции DLL. Начинку DLL можно косвенно вычислить по размеру/контрольной сумме/версии файла ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 12:24
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
ZVIПромахнулись ли папкой с DLL определяется однократно Dir-ом перед обращением к dummy-функции DLL. Не надо Dir-ов, тем более однократных. Dir -плохо, PathFileExists-хорошо. Только писал об этом недавно. Как узнать, существует ли файл? ZVIНачинку DLL можно косвенно вычислить по размеру/контрольной сумме/версии файла md5 этой dll я обычно проверяю, но не в данном конкретном случае. md5 зависит от версии dll, а они у меня в разных версиях проги могут отличаться. Утилита кот. пишу, должна работать с любой версией, а также допускать отсутствие dll. Вариант который я привел Declare -> Load(FullPath) > GetProc -> Run (то что в Declare) -думаю оптимальный. При любом промахе ф-ция вернет пустую строку, и в этом случае я перейду к след. методу определения искомого. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 12:44
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Дмитрий77Вариант который я привел Declare -> Load(FullPath) > GetProc -> Run (то что в Declare) -думаю оптимальный. При любом промахе ф-ция вернет пустую строку, и в этом случае я перейду к след. методу определения искомого. Вроде да, оптимально. Как работает Declare после первого вызова любой функции DLL и почему очень быстро еще и потом, хорошо расписано у Владислава Петровского (Хакер) - Magic Pointers («красивые» указатели на функции, вызов) ... |
|||
:
Нравится:
Не нравится:
|
|||
|
20.06.2014, 23:00
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
ZVIхорошо расписано у Владислава Петровского (Хакер) - Magic Pointers («красивые» указатели на функции, вызов) Да уж, расписано. Все что расписано, не противоречит сказанному. Но я вот на что обратил внимание, авторVB(A) устроен так: Для всех существующих в проекте Declare-функций имеется одна таблица, в которой хранятся адреса вызываемых функций. Это VB-специфичная таблица, и для каждой Declare-функции имеется ячейка, которая хранит адрес соответствующей Declare-функции. Изначально эта таблица вся заполнена нулями. Как только какая-либо из Declare-функций вызывается в первый раз, в её ячейке содержится 0, что означает, что адрес функции ещё не известен. ( в первый раз )определяет адрес вызываемой сейчас функции и заносит его в таблицу. Последующие вызовы некоторой Declare-функции берут адрес прямо из таблицы и делают переход по нему. А теперь то что мне не нравится и что я не могу допонять: I. ДимаЕсли неграмотно вызывать dll, которую VB не найдет то будет "Dll not found". Имеется в виду следующий код: Код: vbnet 1. 2. 3. 4.
Run-time error '53' File not found: cpp_my_dll.dll II. ДимаА вот если вызвать dll сначала грамотно любым из 4-х методов включая твой и 3 моих, потом выполнить грамотный цикл из FreeLibrary, а потом вызвать dll "неграмотно", то будет не "Dll not found", а просто crash VB-приложения, почему ХЗ и я с Opal так однажды уже игрался и так и не докопался почему. Имеется в виду следующий код: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Причем если не делать первый вызов (который успешный - между LoadLibrary и FreeLibrary), то будет Run-time error '53' not found как и в верхнем примере. Т.е. как это увязать с рассуждениями о "VB-специфичной таблице"? Я подозреваю что если в таблице записан 0, то имеем Run-time error '53' not found. После первого (успешного) вызова там не 0 а валидный адрес ф-ции. А после FreeLibrary там НЕвалидный адрес ф-ции. Т.е. VB суко свою "таблицу" при FreeLibrary не чистит и делает вызов по НЕвалидному адресу, отсюда краш при повторном вызове. Так что ли? Как увязать? Потому что у меня были большие заморочки из-за этих непоняток. И вопрос был скорее забит/заретушеван, нежели решен. Как временно "отвязать" dll от VB-проги (чтобы файл "dll" можно было при этом удалить) ... |
|||
:
Нравится:
Не нравится:
|
|||
|
21.06.2014, 08:15
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Дмитрий77II. Имеется в виду следующий код: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Причем если не делать первый вызов (который успешный - между LoadLibrary и FreeLibrary), то будет Run-time error '53' not found как и в верхнем примере. Я подозреваю что если в таблице записан 0, то имеем Run-time error '53' not found. После первого (успешного) вызова там не 0 а валидный адрес ф-ции. А после FreeLibrary там НЕвалидный адрес ф-ции. Т.е. VB суко свою "таблицу" при FreeLibrary не чистит и делает вызов по НЕвалидному адресу, отсюда краш при повторном вызове. Так что ли? Походу так и есть. Этот краш можно вызвать в чистом виде, тупо FreeLibrary -> CallWindowProc(по уже невалидному ProcAdd) Вот таким кодом: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Ошибка точно такая же, то бишь в краш-окне то же самое написано. Вот и вопрос, как этот 0 обратно в "VB-специфичную таблицу" засунуть. И что это за таблица? И где к ней доступ? Потому как VB это сам делать не умеет. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
21.06.2014, 20:44
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Я тут покопался еще. Влезть в таблицу наверно можно. Ссылка приведенная ZVI, там есть ссылка на ZIP. Вызов функций по указателю В принципе автор как-то лезет в таблицу импорта через msvbvm60.dll, где он эти все ф-ции и структуры выкопал это видимо только ему известно. Я пытался, но мне не удалось получить адрес именно своей ф-ции в этой таблице. Короче, надоело, и времени жалко - пусть хакеры развлекаются. Но что касается темы топика и грамотного решения: Дмитрий77Посему грамотный вариант без использования вызова по ProcAdd такой: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Честно говоря, я не уверен в эффективности и необходимости FreeLibrary, да еще и с циклом (по MSDN извините). Очевидно, что при обычном задекларированном вызове VB всегда делает LoadLibrary, но ни фига и никогда не делает FreeLibrary Неграмотный он, с учетом сказанного. Я думаю так: 1) Не надо множить Referenc-ы, можно безобидно проверить ЗАГРУЖЕНА ЛИ: Код: vbnet 1.
И только если не загружена, то загрузить: Код: vbnet 1.
2) Не надо вообще делать цикл FreeLibrary(hMod) VB этого не понимает и не отслеживает. При следующем запуске ф-ции "обычным способом" - даже если путь к ней видим (без LoadLibrary) получим краш. Правильно короче так: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Т.е. мы не нарушаем идеологию VB, и при этом не плодим reference count при многократном обращениям к ф-циям dll. При любом к-ве вызовов любых ф-ций dll reference count будет максимум 2 (почему иногда 2, а не всегда 1 - видимо какие-то внутренние заморочки VB, скорее всего повторный вызов LoadLibrary если не видит адрес ф-ции в своей таблице) Если уж очень надо полностью выгрузить dll (полная выгрузка в частности означает что dll-файл можно удалить без закрытия VB-приложения), то тогда ДА, цикл с FreeLibrary. Но при этом обязательно помнить, что перед следующим вызовом ф-ции этой dll надо обязательно делать LoadLibrary, ибо сам VB с этой ситуацией не справится. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
23.06.2014, 11:40
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Дмитрий77 Код: vbnet 1.
Не надо ее вообще использовать по возможности. Видимо хакеры переусердствовали в стараниях по запихиванию в нее всякой дряни. Я exe-шники свои обычно авирой проверяю -охренели эти антивирусы, но казусов то не нужно. Смотрю ругается TR/Droper.VB.Gen Я обычно давлю: либо ресурсы тасую, либо код протектором мешаю,+ Code Signing подписываю. А тут вцепилась гадина анти(а)вирусная и ругается - и ничего не помогает. Короче пока не закомментировал, не слезла. Код: vbnet 1. 2.
И это при том, что ф-ция в коде нигде не использовалась!!! На CallWindowProcA в файле тупо смотрит скотина авировская. А блин, без этой ф-ции сабклассинг не получится. Но на больших exe-шниках обычно пропускает, а здесь 300-400кб - и прицепилась тварь. Часа 3 искал. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
23.06.2014, 11:46
|
|||
---|---|---|---|
Вызвать известную ф-цию из известной dll, но путь к dll -вычисляется в коде |
|||
#18+
Можно ли компилировать проект так, чтобы API, кот. задекларированы но проект реально не использует, никоим образом не влияли/ не "упомянались" в exe-шнике? Я последнее время подключаю свои "общие стандартные" модули к проекту. Поэтому там естественно куча всего. И я обратил внимание, что exe-шник несильно, но таки побольше, чем если декларировать только необходимое как я делал раньше. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
|
start [/forum/topic.php?fid=60&mobile=1&tid=2156299]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
160ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
2ms |
others: | 327ms |
total: | 595ms |
0 / 0 |