"Битовое вращение" или сдвиг

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Samrat
Новичок
Новичок
 
Сообщения: 31
Зарегистрирован: 11.08.2004 (Ср) 10:32

"Битовое вращение" или сдвиг

Сообщение Samrat » 11.08.2004 (Ср) 10:39

Люди, подскажите на VB Есть возможность делать битовое вращение целочисленной переменной или её битовый сдвиг, как в других языках программирования (С или Ассемблер) или нужно преобразовать её в бинарный массив , затем в строку, после чего оперировать , как со строкой? Просто делаю контрольную сумму для протокола передачи, могу и обойтись, но хочется сделать покрасивше.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.08.2004 (Ср) 11:05

x << y - то же самое, что x * 2 ^ y
x >> y - то же самое, что x \ 2 ^ y
С вращением придётся повозиться, но тоже всё можно сделать.
"Бинарные массивы" и тем более строки здесь уж точно не нужны.

Samrat
Новичок
Новичок
 
Сообщения: 31
Зарегистрирован: 11.08.2004 (Ср) 10:32

Сообщение Samrat » 11.08.2004 (Ср) 14:36

Не , ну это мне понятно, просто хочется сделать покрасивше, умножение и деления я применяю просто хочется узнать есть ли возможность писать на VBкоманды типа: ROL, ROR (rotate on left, right) или придётся изголиться и надругаться. (Как изголиться я знаю просто надругаться не хочется)

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.08.2004 (Ср) 16:25

Нету. И из беззнаковых типов только Byte. Абыдно, да? ;-(

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.08.2004 (Ср) 16:52

Тёмич, ты чё :)

Код: Выделить всё
Option Explicit

Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private AsmFunctions(1 To 4, 1 To 4) As Long

Private Enum AsmFuncs
  asmShiftLeft = 1
  asmShiftRight
  asmRotateLeft
  asmRotateRight
End Enum

Private Function CallAsmFunction(ByVal func As AsmFuncs, ByVal Value As Long, ByVal BitCount As Long) As Long
  CallAsmFunction = CallWindowProc(VarPtr(AsmFunctions(LBound(AsmFunctions, 1), func)), Value, BitCount, 0, 0)
End Function

Private Sub Command1_Click()
  MsgBox Hex$(CallAsmFunction(asmRotateRight, &H10203040, 16))
End Sub

Private Sub Form_Load()
  AsmFunctions(1, asmShiftLeft) = &H8BEC8B55
  AsmFunctions(2, asmShiftLeft) = &H458B0C4D
  AsmFunctions(3, asmShiftLeft) = &H5DE0D308
  AsmFunctions(4, asmShiftLeft) = &H10C2&
 
  AsmFunctions(1, asmShiftRight) = &H8BEC8B55
  AsmFunctions(2, asmShiftRight) = &H458B0C4D
  AsmFunctions(3, asmShiftRight) = &H5DE8D308
  AsmFunctions(4, asmShiftRight) = &H10C2&
 
  AsmFunctions(1, asmRotateLeft) = &H8BEC8B55
  AsmFunctions(2, asmRotateLeft) = &H458B0C4D
  AsmFunctions(3, asmRotateLeft) = &HC0A50F08
  AsmFunctions(4, asmRotateLeft) = &H10C25D
 
  AsmFunctions(1, asmRotateRight) = &H8BEC8B55
  AsmFunctions(2, asmRotateRight) = &H458B0C4D
  AsmFunctions(3, asmRotateRight) = &HC0AD0F08
  AsmFunctions(4, asmRotateRight) = &H10C25D
End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.08.2004 (Ср) 17:03

GSerg писал(а):Тёмич, ты чё :)

Samrat писал(а):просто хочется сделать покрасивше, ... или придётся изголиться и надругаться. (Как изголиться я знаю просто надругаться не хочется)

Так-то каждый сможет... :-P Но неужели это меньшее извращение, чем с умножением и делением?
Код: Выделить всё
Option Explicit

Sub Main()
Debug.Print Hex(SHL(&H55AA, 5))
Debug.Print Hex(SHR(&H55AA, 5))
Debug.Print Hex(ROL(&H55AA, 5))
Debug.Print Hex(ROR(&H55AA, 5))
End Sub

Public Function Cast(ByVal Arg As Long) As Integer
    Arg = Arg And &HFFFF&
    If Arg > 32767 Then Arg = Arg - 65536
    Cast = Arg
End Function

Public Function SHL(ByVal Arg As Integer, ByVal Sh As Byte) As Integer
SHL = Cast(CLng(Arg) * 2& ^ Sh)
End Function

Public Function SHR(ByVal Arg As Integer, ByVal Sh As Byte) As Integer
SHR = Cast(CLng(Arg) \ 2& ^ Sh)
End Function

Public Function ROL(ByVal Arg As Integer, ByVal Sh As Byte) As Integer
ROL = (SHL(Arg, Sh)) Or (SHR(Arg, 16 - Sh))
End Function

Public Function ROR(ByVal Arg As Integer, ByVal Sh As Byte) As Integer
ROR = (SHR(Arg, Sh)) Or (SHL(Arg, 16 - Sh))
End Function


[edit]Чёрт, как ты успел до меня отправить?[/edit]
Последний раз редактировалось tyomitch 11.08.2004 (Ср) 17:15, всего редактировалось 2 раз(а).

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.08.2004 (Ср) 17:04

Так ты всё-таки не получаешь от них удовольствие? :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Samrat
Новичок
Новичок
 
Сообщения: 31
Зарегистрирован: 11.08.2004 (Ср) 10:32

Сообщение Samrat » 11.08.2004 (Ср) 19:33

Ну товарищи Гуру Вы круты, я то уже хотел на дельфях длл накидать. а пока скучал успел надругаться следующим образом:
Public Function ROL(Dannie As Integer) As Integer
Dim Fixa As String
Dim J, Dumb As Integer

For J = 1 To 16
Fixa = CStr(Dannie Mod 2) + Fixa
Dannie = Fix(Dannie / 2)
Next J
Fixa = Mid(Fixa, 2, 15) + Mid(Fixa, 1, 1)

Dumb = 0
For J = 0 To 15 Step 1
Dumb = Dumb + CInt(Mid(Fixa, J + 1, 1)) * 2 ^ (15 - J)
Next J
ROL = Dumb
End Function
А за примеры спасибо

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.08.2004 (Ср) 20:00

А теперь сравни три варианта по скорости... ;-)

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 11.08.2004 (Ср) 20:03

Неохота :)
Твой типа быстрее?
Зато мой извращённее :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 12.08.2004 (Чт) 2:57

tyomitch писал(а):А теперь сравни три варианта по скорости... ;-)

GSerg писал(а):Неохота :)
Твой типа быстрее?
Зато мой извращённее :)

И только потому, что GSerg использует CallWindowProc. :)
С уважением, Approximator.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.08.2004 (Чт) 10:45

Approximator писал(а):И только потому, что GSerg использует CallWindowProc. :)

Кстати, никто не экспериментировал с такой фишкой: начало какой-нибудь процедуры перезаписывается ассемблерной вставкой, и потом для её вызова просто вызывается нужная процедура.
Говорят, работает 1) существенно быстрее, чем CallWindowProc 2) только в скомпилированном файле.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.08.2004 (Чт) 13:12

Во, есть ещё куда копать :) Хе-хе. Гы-гы. Где моя лопата?..
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.08.2004 (Чт) 16:18

Нее, тут земснаряд нужен... :)

В общем, из IDE попытка записи в тело функции игнорируется, а из экзешника приводит к access violation.
Ну и как обойти запрет на запись? Давай, думай, раз начал эту мысль :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.08.2004 (Чт) 16:52

:shock:
Всё, пора писать статью :)
Тёмич, а ты катализатор тот ещё :razz:

В общем, после создания экзешника его нужно пропатчить - заменить байт по адресу 0x01df на 0xe0. Это даст возможность писать в секцию кода :)

После этого можно спокойно расставлять jmp XXXXXXXX в любую функцию модуля, что даёт возможность вызывать что угодно по указателю так, как будто это VB код...
Мдя :) Рулез.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.08.2004 (Чт) 17:25

GSerg писал(а):Нее, тут земснаряд нужен... :)

В общем, из IDE попытка записи в тело функции игнорируется, а из экзешника приводит к access violation.
Ну и как обойти запрет на запись? Давай, думай, раз начал эту мысль :)

Мысль не моя, я готовый пример видел.
Всё просто - свой процесс открываешь с нужными правами, и пишешь через WriteProcessMemory.
А снимать защиту от записи с секции кода очень нехорошо. После этого она не сможет быть разделяемой, т.е. все запущенные экземпляры программы будут иметь свои секции кода, а не одну общую. Соответственно, память теряется зазря.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.08.2004 (Чт) 17:26

Ага... И сюда пойдём.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.08.2004 (Чт) 18:29

Пошли и успешно вернулись :)
Да, это круто... Хотя только в экзешнике, но всё равно круто :)
Но всё-таки почему WPM может написать в память, помеченную как RO в PE? :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.08.2004 (Чт) 19:13

GSerg писал(а):Пошли и успешно вернулись :)
Да, это круто... Хотя только в экзешнике, но всё равно круто :)

Под IDE скомпилированной процедуры к моменту входа в неё может и не существовать, поэтому у неё нет адреса, чтобы туда что-то записать.
AddressOf под IDE возвращает адрес переходничка, который, естественно, бесполезно перезаписывать: он не вызывается при вызове самой процедуры.
Т.е. этот замечательный трюк под IDE никак не реализовать.

GSerg писал(а):Но всё-таки почему WPM может написать в память, помеченную как RO в PE? :)

Потому что у тебя много прав. В процесс другого пользователя, скорее всего, писать не дадут.
Ну и потому что флаги секций анализирует только загрузчик; после загрузки весь образ (снаружи) выглядит как единое целое, и права на доступ к нему задаются тоже как к единому целому.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.08.2004 (Чт) 20:14

Ясненько :)

Как бы то ни было, я тут такую ерунду написал, сам её боюсь :) Сейчас пойду напишу статью... :)
В общем, работает и в IDE, и в экзешнике...
Ждём релиза :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 13.08.2004 (Пт) 4:51

tyomitch писал(а):
Approximator писал(а):И только потому, что GSerg использует CallWindowProc. :)

Кстати, никто не экспериментировал с такой фишкой: начало какой-нибудь процедуры перезаписывается ассемблерной вставкой, и потом для её вызова просто вызывается нужная процедура.
Говорят, работает 1) существенно быстрее, чем CallWindowProc 2) только в скомпилированном файле.

:) Я делал. Действительно ("с чего бы это вдруг?" :) :) :)) работает несравненно быстрее. :)
С уважением, Approximator.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 13.08.2004 (Пт) 4:53

GSerg писал(а)::shock:
Всё, пора писать статью :)
Тёмич, а ты катализатор тот ещё :razz:

В общем, после создания экзешника его нужно пропатчить - заменить байт по адресу 0x01df на 0xe0. Это даст возможность писать в секцию кода :)

После этого можно спокойно расставлять jmp XXXXXXXX в любую функцию модуля, что даёт возможность вызывать что угодно по указателю так, как будто это VB код...
Мдя :) Рулез.

Дык, я об этом уже писал. Где-то здесь: http://bbs.vbstreets.ru/viewtopic.php?t=8818&start=0
С уважением, Approximator.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 13.08.2004 (Пт) 5:15

GSerg писал(а):Нее, тут земснаряд нужен... :)

В общем, из IDE попытка записи в тело функции игнорируется, а из экзешника приводит к access violation.
Ну и как обойти запрет на запись? Давай, думай, раз начал эту мысль :)

Ошибочное направление. Ты, дорогой, конечно шаман. Но сейчас не в ту сторону пляшешь. И Тёмыч, как мне кажется тоже. Что сделал я:
Код: Выделить всё
'в класс модуле (GlobalMutiUse)
Public Sub CallWProc(ByRef PAddress as Long)
MdMain.CallProc PAddress
End Sub

Private Sub Class_Initialize()
Dim lPA as Long, lGS as String
'это (то, что делается ниже) можно организовать и по другому, но мне тогда было некогда. Там я ещё проверял наличие окрываемого файла, но исходник не сохранился. Сейчас пишу по памяти основную идею...
Open "C:\123.txt" For Append as #1
Open "C:\234.txt" For Binary as #2
lPA=GetPA(AddressOf CallProc)
Print #1, lPA
lGS=String(32, " ")
lGS=StrConv(lGS, vbFromUnicode)
CopyMem StrPtr(lGS), lPA, 32
lGS=StrConv(lGS, vbUnicode)
Print #2, lGS
Close
End Sub


Код: Выделить всё
'в модуле MdMain
Public Sub CallProc(ByVal PAddress as Long)
PAddress=Paddress-1
End Sub

Public Function GetPA(ByRef vPA as Long) as Long
GetPA=vPA
End Sub


Затем откомпилял ActiveX DLL нашёл в нём код, скопированный в 234.txt и заменил на свой ("лишние" байты можно заменять на Nop, а можно просто её урезать). В итоге имеем нормальный ActiveX DLL c компактной и быстрой функцией. И кто теперь скажет, что Васик - медлительный хлам. :)
Чичас пытаюсь проработать ещё более извращённую фичу в этом направлении...
С уважением, Approximator.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.08.2004 (Пт) 7:47

Честно говоря, основную идею кода я не уловил :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.08.2004 (Пт) 8:40

GSerg писал(а):Честно говоря, основную идею кода я не уловил :)
По сути то же, что и влинковка OBJ-ей в ехешник, только руками.
Наш метод - без модификации ехешника - существенно круче \m/

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.08.2004 (Пт) 11:23

Это точно (без обид) :)
Только что-то отзывов нет в Трёпе, диалог у нас какой-то получается, а общественность опять безмолвствует :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 13.08.2004 (Пт) 12:03

Общественность потрясенно молчит :)
Lasciate ogni speranza, voi ch'entrate.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.08.2004 (Пт) 12:46

Вот ради этих слов стóит... :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 14.08.2004 (Сб) 4:37

tyomitch писал(а):
GSerg писал(а):Честно говоря, основную идею кода я не уловил :)
По сути то же, что и влинковка OBJ-ей в ехешник, только руками.

Так уж и руками? Или подразумевались "VB-руки"? Только не влинковка, а локальная перелинковка. Раз и навсегда, чтобы не городить огород.
Наш метод - без модификации ехешника - существенно круче \m/

Дык, "ваш метод" я давеча ужо обсуждал. А так я предложил функцию, аналогичную CallWindowProc, но быстрее. :) Не оценили.
С уважением, Approximator.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 14.08.2004 (Сб) 4:47

GSerg писал(а):Это точно (без обид) :)

Да, помилуй, какие обиды. Вы и обсуждали-то только, как получить права на запись в процесс. Ты предложил обнулять (причём все) флаги разрешающие чтение/запись в сегменты. Тёмыч предложил (разумеется, более разумное решение в некоторых случаях) делать это (получать доступ) RunTime. Что здесь такого, что не обсуждалось здесь же ранее? В т.ч. мной. Я же не пытался здесь повторяться, а решал ЛОКАЛЬНУЮ задачу - быстро и надолго сделать CallWProc. :) Imo, вы с локальной задачей так и не справились. Каке могут быть обиды. :)
С уважением, Approximator.

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот, Yandex-бот и гости: 21

    TopList