Ну почему фарс? Просто хотелось услышать что-то новое о сей технологии. И почему противники? Просто интересующиеся... Странно, но в сети довольно редко встречаются палемики на тему "а нафига нам ассемблер?". А вот о .NET'е спорят намного чаще. С чего бы?А то право же, чуть ли не каждый топик противники дотнета разводят фарс и флейм.
Twister писал(а):Странно, но в сети довольно редко встречаются палемики на тему "а нафига нам ассемблер?". А вот о .NET'е спорят намного чаще. С чего бы?
По второй ссылке ниже в теме лежат и исходникиХакер писал(а):это что-то закрытое
Хакер писал(а):По первой ссылке - не только статья, но и очень интересное обсуждение между GSerg-ом, tyomitch-ем и Approximator-ом (как раз с тем самым комментарием, который на сайте лежит вместе со статьёй, кстати). Там есть и про вызов по указателю через отдельную маленькую длл и сама эта длл выложена(я, кстати, ей даже пользуюсь)
MagicPointer("Example") = ...
Example 1, 2, 3
MagicPointers!Example = ...
Example 1, 2, 3
Вопроса не понял, кода, скорее всего, всё равно испугаюсь...Хакер писал(а):как мне сделать словарь ИмяУказателя→{Адрес+Флаг}? Т.е. каким мне его сделать, чтобы вы не испугались кода.
А в первом варианте - один модуль? Тогда так легче не испугаться кода...Хакер писал(а):Но будем два модуля (класса и обычный). Ага или не ага?
Хакер писал(а):MagicPointers!Example = ...
arthur2 писал(а):С такой конструкцией я не знакомТо есть, я знаю, что в языке что-то такое есть, но не понимаю, ни как использовать, ни что это вообще... Так что голосую за этот вариант - чтобы за одно и с этим разобраться
Второй вариант в плане "испугаться кода" кажется страшней, но, наверное, удобней? И - раз такой вопрос у тебя возник, наверное, интересней?Хакер писал(а):Так и не понял, какой из вариантов ты выбрал.
arthur2 писал(а):Так что голосую за этот вариант
Хакер писал(а):Кстати, ещё родился третий вопрос:
С исходником? Тоже интересноХакер писал(а):Патчер, который делает из любой dll (vba5, vba6) пропатченную.
Второй вариант в плане "испугаться кода" кажется страшней, но, наверное, удобней? И - раз такой вопрос у тебя возник, наверное, интересней?
Я - за без ассемблерных вставок
С исходником? Тоже интересноА его можно будет приладить только к твоему кирпичу, или и к тому же субклассингу, чтобы стало возможно стопом пользоваться?
Вот я за этот вариант.Хакер писал(а):Без ассемблерных вставок только один вариант: с самостоятельным отключением.
А я и пользуюсь другимХакер писал(а):Для сабклассинга разумнее и проще пользоваться другим методом
Вариант кирпича без вставок - это "бери и разбирайся сам"
Вариант со вставками - это "бери и пользуйся", так что мне интересней первое
Public Sub MagicPointersOnOff(ByVal bEngage As Boolean)
Static bEngaged As Boolean
Static lpIATEntry As Long
Static lIATOrigValue As Long
If bEngage Then
If bEngaged Then Exit Sub
If lpIATEntry = 0 Then
Dim hMyModule As Long
Dim vaPEHeader As Long
Dim vaImportTable As Long
Dim i As Long
Dim ImportTable() As IMAGE_IMPORT_DESCRIPTOR
Dim saImportTable As SA_DESCRIPTOR_FOR_VECTOR
Dim nRelRtlDescriptor As Long
Dim nDbgRtlDescriptor As Long
hMyModule = App.hInstance
GetMem4 hMyModule + Offs_e_lfanew, vaPEHeader: vaPEHeader = vaPEHeader + hMyModule
With saImportTable
.cDimensions = 1
.cbItemSize = Sz_ImportDescriptor
GetMem4 vaPEHeader + Offs_ImportTableRVA, .pData: .pData = .pData + hMyModule
GetMem4 vaPEHeader + Offs_ImportTableSize, .cL1Elements
End With
PutMem4 AryPtr(ImportTable), VarPtr(saImportTable)
nRelRtlDescriptor = -1
nDbgRtlDescriptor = -1
For i = 0 To saImportTable.cL1Elements - 1
If ImportTable(i).rvaLookupTable = 0 Then Exit For
Dim vaModuleName As Long
vaModuleName = ImportTable(i).rvaModuleName + hMyModule
Select Case 0
Case lstrcmpiA(vaModuleName, Nm_DbgRtlModuleName & Nm_DllExtension), _
lstrcmpiA(vaModuleName, Nm_DbgRtlModuleName)
nDbgRtlDescriptor = i
Case lstrcmpiA(vaModuleName, Nm_RelRtlModuleName & Nm_DllExtension), _
lstrcmpiA(vaModuleName, Nm_RelRtlModuleName)
nRelRtlDescriptor = i
Exit For
End Select
Next i
If nRelRtlDescriptor = nDbgRtlDescriptor Then
PutMem4 AryPtr(ImportTable), 0&
Err.Raise 5, , "Runtime library have not been found in module imports!"
Exit Sub
End If
If nRelRtlDescriptor <> -1 Then
Dim lpLookupCursor As Long
Dim lpszProcName As Long
With ImportTable(nRelRtlDescriptor)
lpLookupCursor = .rvaLookupTable + hMyModule
Do
GetMem4 lpLookupCursor, lpszProcName
If lpszProcName = 0& Then Exit Do
If lpszProcName > 0& Then
lpszProcName = lpszProcName + hMyModule + 2&
If lstrcmpiA(lpszProcName, "DllFunctionCall") = 0& Then Exit Do
End If
lpLookupCursor = lpLookupCursor + 4&
Loop
If lpszProcName = 0 Then
PutMem4 AryPtr(ImportTable), 0&
Err.Raise 5, , "This module does not import DllFunctionCall."
Exit Sub
End If
lpIATEntry = .rvaFirstThunk + (lpLookupCursor - .rvaLookupTable)
End With
Dim DFCDiscoveryBuffer(0 To 3) As Long
Dim DFCDiscoveryLookup As EB_DELAYED_IMPORT_LOOKUP_ENTRY
DFCDiscoveryLookup.lpszModuleName = StrPtr(StrConv(Nm_RelRtlModuleName, vbFromUnicode))
DFCDiscoveryLookup.lpszFunctionName = StrPtr(StrConv("DllFunctionCall", vbFromUnicode))
DFCDiscoveryLookup.sImportFlags = EB_DELAYED_IMPORT_FLAG_BY_NAME
DFCDiscoveryLookup.lpImportEntryAddresses = VarPtr(DFCDiscoveryBuffer(0))
lIATOrigValue = DllFunctionCall(DFCDiscoveryLookup)
Else
' код, включающий фичу под IDE. Зависит от выбранного способа
End If
PutMem4 AryPtr(ImportTable), 0&
End If
VirtualProtect lpIATEntry, 4, PAGE_EXECUTE_READWRITE, i
PutMem4 lpIATEntry, AddressOf LocalResolver
VirtualProtect lpIATEntry, 4, i, i
bEngaged = True
Else
Надо бы понять, какие особенности работы DllFunctionCallХакер писал(а):а полагание на особенности работы работы msvbvm минимально
arthur2 писал(а):Хорошо бы посмотреть, что за структуры и как они объявлены:
Private Type IMAGE_IMPORT_DESCRIPTOR
rvaLookupTable As Long
TimeDateStampt As Long
ForwarderChain As Long
rvaModuleName As Long
rvaFirstThunk As Long
End Type
Private Type SA_DESCRIPTOR_FOR_VECTOR
cDimensions As Integer
fFeatures As Integer
cbItemSize As Long
cLocks As Long
pData As Long
cL1Elements As Long
iL1LBound As Long
End Type
Private Type EB_DELAYED_IMPORT_LOOKUP_ENTRY
lpszModuleName As Long
lpszFunctionName As Long
sImportFlags As Integer
sFunctionOrdinal As Integer
lpImportEntryAddresses As Long
End Type
Хорошо бы минимальные комментарии.
Из того, что я понял (если понял): ты ищешь в таблице импорта DllFunctionCall и подменяешь указатель на неё на собственную функцию LocalResolver.
Хакер писал(а):Что она возвращает?
Ты её вызываешь, скормив ей в качестве параметра структуру, где в качестве имени функции указана она жеЭто чтобы потом вернуть всё как было?
arthur2 писал(а):На сколько я понимаю, DllFunctionCall в бейсике ответственна за вызов продекларированных Апи...
У меня тут появилась мысль: раз мы перехватываем DllFunctionCall, значит по большому счёту перехватываем все продекларированные функции. Так?
Если мы поместим эту фичу в аддин, то можем делать не падающие в ИДЕ хуки, субклассинги и таймеры, просто подменяя в нужный момент в вызовах соответствующий функций адреса callback-функции на безопасные внутри аддина. При этом код самих проектов можно будет вообще не трогать
Хакер писал(а):Не за вызов, а за поиск и занесение адреса в таблицу (или вывод ошибки). И для каждой функции DllFunctionCall вызывает единожды, я же сказал.
Хакер писал(а):Есть гораздо более правильные пути. «Перехватывать AddressOf» например.
Хакер писал(а):Собираешься в Add-in-е предусматривать обработку всех возможных WinAPI?
Хакер писал(а):Понимаешь, что это не сработает для TLB?
Субклассинг ведь ставится только SetWindowLong
Сейчас этот форум просматривают: SemrushBot, Yandex-бот и гости: 5