
(DLL поднята LoadLibrary из папки TEMP).
Имеется ввиду ассемблерный jmp?Если прыгнуть
0xy писал(а):Правильным--это через Declare? Но тогда dll в папке TEMP вряд ли найдется (собственно, в этом то и соль).
А разве "поиск" библиотеки происходит при вызове функции, не при старте?Хакер писал(а):Найдётся прекрасно, если папка temp будет CurDir-нута, а название файла не будет конфликтовать с библиотекой из более приоритетных местоположений.
Читал толковую статью про CallWindowProc, где автор клятвенно уверял, что без использования ассемблера это единственный способ.Хакер писал(а):Кстати, CallWindowProc не единственный способ.
Antonariy писал(а):А разве "поиск" библиотеки происходит при вызове функции, не при старте?
Antonariy писал(а):Читал толковую статью про CallWindowProc, где автор клятвенно уверял, что без использования ассемблера это единственный способ.
Declare Function MyFuncPointer Lib "::CallByPtr::" (ByVal Foo As Long, ByRef Bar As Single) As Object
Pointers("MyFuncPointer") = 123123123
Set x = MyFuncPointer(1, 2)
0xy писал(а):Кроме CallWindowProc
(DLL поднята LoadLibrary из папки TEMP).
Хакер писал(а):Ему надо вызвать функцию, не прибегая к CallWindowProc, а не получить её адрес, не прибегая к GetProcAddress
Хакер писал(а):Поиск библиотеки и поиск функции в ней происходит при первой попытке вызова этой функции.
Я хочуХакер писал(а):Кто хочет, чтобы я написал кирпич для вызова функций по указателю через вышеописанный трюк?
Хакер писал(а):В заготовках 4 штуки лежат. Я хочу их разом закинуть.
По поводу кирпича: я вспомнил, какая там сложность есть с режимом отладки в VB6. Т.е. я не вижу преграды, но боюсь, что очень «брутальное» решение отпугнёт многих. Во всяком случае, без большого числа желающих такие вещи точно не хочу писать.
Option Explicit
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal pBinaryCode As Long, _
ByVal Variable As Long, _
Optional ByVal lMSG As Long, _
Optional ByVal lp3 As Long, _
Optional ByVal lp4 As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Any, ByVal Source As Any, ByVal Length&)
Private Declare Function VirtualAlloc& Lib "kernel32" (lpAddress As Any, ByVal dwSize&, ByVal flAllocationType&, ByVal flProtect&)
Private Declare Function VirtualFree& Lib "kernel32" (lpAddress As Any, ByVal dwSize&, ByVal dwFreeType&)
Const MEM_COMMIT& = &H1000, MEM_RESERVE = &H2000, MEM_RELEASE& = &H8000
Const PAGE_READWRITE& = 4, PAGE_EXECUTE_READWRITE = &H40
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress& Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String)
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Function CallEX&(DllName$, FnName$, FnParam())
'позволяет вызвать любую функцию из любой dll
'ЗАМЕЧАНИЯ:
' 1. Переменные длиной до 4-x байт, а также строки, передаются функции ByVal (если нужно ByRef, то вместо параметра следует указать его VarPtr).
' 1.1. Штатные переменные длиной более 4-х байт (Currency и т.п.) всегда передаются ByRef!
' 1.2. Для структур необходимо передавать их VarPtr.
' 1.3. Корректность передачи подтипов, отличных от Long и String, не тестировалась!
' 2. Пока х.з. :)
' ===================ASM-код=================
' 55 PUSH EBP
' 8BEC MOV EBP,ESP
' 60 PUSHAD
' 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]
' 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+10]
'2: 85C9 TEST ECX,ECX
' 74 06 JE SHORT 1
' 49 DEC ECX
' FF348B PUSH DWORD PTR DS:[EBX+ECX*4]
' ^ EB F6 JMP SHORT 2
'1: FF55 08 CALL DWORD PTR SS:[EBP+8]
' 61 POPAD
' 5D POP EBP
' C2 1000 RET 10
Const AsmCode$ = "55 8B EC 60 8B 5D 0C 8B 4D 10 85 C9 74 06 49 FF 34 8B EB F6 FF 55 08 61 5D C2 10 00 "
Dim BinCode() As Byte, hDll&, i&, n&, p&, pFnParam&()
ReDim BinCode(1 To Len(AsmCode) / 3)
For i = 1 To Len(AsmCode) / 3 ' заполняем массив
BinCode(i) = Val("&h" & (Mid(AsmCode, (i - 1) * 3 + 1, 2)))
Next
hDll = LoadLibrary(DllName)
If hDll Then Else MsgBox DllName & " не найдена!": Exit Function
p = GetProcAddress(hDll, FnName)
If p Then
Else
MsgBox "Функция " & FnName & " не найдена!"
FreeLibrary hDll
Exit Function
End If
n = UBound(FnParam)
ReDim pFnParam(0 To n)
For i = 1 To n
Select Case VarType(FnParam(i))
Case vbString 'ByVal
FnParam(i) = StrConv(FnParam(i), vbFromUnicode)
pFnParam(i) = VarPtr(FnParam(i)) + 8
CopyMemory VarPtr(pFnParam(i)), ByVal pFnParam(i), 4
Case vbLong, vbInteger, vbByte, vbBoolean, vbSingle 'ByVal
pFnParam(i) = FnParam(i)
Case vbCurrency, vbDouble, vbDate 'ByRef
pFnParam(i) = VarPtr(FnParam(i)) + 12
Case vbDecimal 'хотя это уже лишьнее
pFnParam(i) = VarPtr(FnParam(i)) 'тупо ByRef на Variant:)
Case Else ' NOP (vbEmpty, vbNull)
End Select
Next
i = VirtualAlloc(ByVal 0&, UBound(BinCode), MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
CopyMemory ByVal i, ByVal VarPtr(BinCode(1)), UBound(BinCode)
CallEX = CallWindowProc(i, p, VarPtr(pFnParam(1)), n)
VirtualFree ByVal i, 0, MEM_RELEASE
FreeLibrary hDll
For i = 1 To n
If VarType(FnParam(i)) = vbString Then FnParam(i) = StrConv(FnParam(i), vbUnicode)
Next
End Function
Dim p(), n&
ReDim p(0 To 2)
n = 16
p(1) = String(n, vbNullChar)
p(2) = VarPtr(n)
CallEX "kernel32", "GetComputerNameA", p
p(1) = Left(p(1), n)
Предлагаю заценить
0xy писал(а):Предлагаю заценить мой кирпич на тему
jangle писал(а):0xy писал(а):Предлагаю заценить мой кирпич на тему
Наверное я совсем тупой, но в чем смысл этого кода? В каких случаях его следует применять?
… Использовать это можно по-разному, например: представим, что у нас есть функция сортирующая массив любых объектов. Для того чтобы отсортировать объекты, нужно уметь их сравнивать. Т.е. необходимо в каждом объекте реализовывать интерфейс IComparable, либо просто передавать в нашу функцию сортировки еще одну функцию, которая будет сравнивать объекты. В принципе одно и то же, но в первом случае нам придется изменять класс, а это может быть достаточно неудобно, если вообще возможно, поэтому использование делегатов в данном случае является вполне оправданным решением.
Хакер, зацени
Antonariy писал(а):jangle писал(а):0xy писал(а):Предлагаю заценить мой кирпич на тему
Наверное я совсем тупой, но в чем смысл этого кода? В каких случаях его следует применять?
Спасено из кэша яндекса:… Использовать это можно по-разному, например: представим, что у нас есть функция сортирующая массив любых объектов. Для того чтобы отсортировать объекты, нужно уметь их сравнивать. Т.е. необходимо в каждом объекте реализовывать интерфейс IComparable, либо просто передавать в нашу функцию сортировки еще одну функцию, которая будет сравнивать объекты. В принципе одно и то же, но в первом случае нам придется изменять класс, а это может быть достаточно неудобно, если вообще возможно, поэтому использование делегатов в данном случае является вполне оправданным решением.
Хакер писал(а):способ действительно допустим. Но: он требует ассемблерных вставок. Мой не требует.
Я не вникал в тонкости рассуждений коментатора о внутренних механизмах VB (далёк я от этого), но вот этот "псевдо-код" вызвал у меня большие сомнения по поводу его компетентности в области знаний о x86:Что касается комментатора, то он во многих местах неправ
Для указания адреса исполняемой инструкции используется регистр eip. Причём, нет инструкций явных чтения/записи из этого регистра. А в качестве неявно изменяющих содержимое регистра eip используются jmp, jxx и пары call-ret, enter-leave. VB'эшные компилятор и интерпретатор обычно используют jmp, jxx и пару call-ret. Последняя, как раз, нас и интересует. Выполнение инструкции
call operand
сводится.
push eip
jmp operand
или ещё подробнее к
mov dword ptr ds:[esp-4],eip
sub esp,4
mov eip,operand
При том что вышеприведенный код это вызов ф-ии по указателю. Вызов ф-ии по указателю = делегирование (насколько я понял). Выше приведенный пример (он там для сишарпа) показывает, что в этом случае можно использовать код типа приведенного еще более выше. Просто нужна голова и руки, чтобы адаптировать его для собственных нужд. И да, это не кирпич, а технологический семпл.jangle писал(а):Причем тут делегаты и выше приведенный код?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4