Возможно, средствами VisualBasic, записать число в память?

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

Возможно, средствами VisualBasic, записать число в память?

Сообщение MisterSer » 10.03.2008 (Пн) 13:37

Необходимо записать некое число, скажем 123456789 в ячейку памяти по адресу 00А53а98(пример). Или увеличить число, которое находиться в памяти компа по адресу 00А53а98(пример) на 12345. Можно ответить коротко, в каком направлении искать.
Спасибо.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.03.2008 (Пн) 14:31

—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 10.03.2008 (Пн) 16:51

... хм. Я ожидал, что есть проще решение. Ну, если оно единственное, помогите разобраться, пожалуйста. Мне необходимо поместить число(размер 8байт) в ячейку памяти по адресу 00А53а98.
Как я понял используем эту функцию:
Public Declare Function PutMem2 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long
и здесь pDst - это адрес, в моем случае 00А53а98,
а NewValue - значение(123456789).
Выходит так:
Public Declare Function PutMem2 Lib "msvbvm60" (ByVal 00А53а98 As Long, ByVal 123456789 As Long) As Long
Верно?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.03.2008 (Пн) 17:08

Боже, какой бред.

123456789 - это Long и его размер 4 (а не 8 байт). Возможно конечно, хотя и мало вероятно, что тебе нужно записать в память это число в форме числа с плавающей точкой. Ладно, пофиг.

Почему было выбрано PutMem2 - остаётся загадкой. Числа в конце названия функции означает кол-во байт, которые этой функцией можно записать.


Выходит так:
Public Declare Function PutMem2 Lib "msvbvm60" (ByVal 00А53а98 As Long, ByVal 123456789 As Long) _ As Long
Верно?

Неверно в корне.

1) Числа в шестнадцатиричном представлении в VB записывают начиная с префикса &H (а в си-подобных языках, - с префикса 0x, а в ассемблерах - заканчивая постфиксом h). Посему - 00А53а98 - бред. &h00А53а98 должно быть.
2) Функции объявляются, а потом используются. Объявление, которое приведено в статье, тебе необходимо поместить в шапку модуля, туда, где у тебя объявленны глобальные константы и глобальные перменные.
3) А потом уже вызывать.


Итого:



Код: Выделить всё
Public Declare Function PutMem4 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) _
As Long

' ... /// .... ///

' ... /// .... ///

' ... /// .... ///


' Записй дворда в память:
PutMem4 &h00А53а98, 123456789




И ещё.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 10.03.2008 (Пн) 18:10

Исчерпывающй ответ. Спасибо.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 10.03.2008 (Пн) 18:37

Вероятно, сперва стоило узнать о другом. Возможно написать на VisualBasic программу, которая будет менять память(числа хранимые в памяти) других программ. Например, запущена программа МИР и она хранит по адресу 123 значение переменнай "а", которое равно 1. А другая, работающая программа ДЫМ, при определенном условии, меняет число, находящееся по адресу 123 на значение 2. В следствии чего, в программе МИР, переменная "а", становиться равной 2. Возможно на VisualBasic написать программу ДЫМ? Еще раз спасибо.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.03.2008 (Пн) 18:41

Возможно. Это возможно сделать на любом языке. VB в этом плане ничем не хуже других.

Но возможно это будет только под админом.

Внимание вопрос: нафига это? Не жалкая ли это попытка изобрести заново пайпы?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 10.03.2008 (Пн) 19:04

Пайпы? Не слыхал об этом. Что это? Моя изначальная цель - менять память другой программы. В Art Money я нахожу адрес нужного числа нужного процесса, а средствами другой программы, я планирую управлять этим числом. Менять его в зависимости от некоторых условий(время). На моем компе только одна учетная запись, админ.

ВТОРОЙ РАЗ ПРЕДУПРЕЖДАЮ!.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.03.2008 (Пн) 19:07

WriteProcessMemory.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 10.03.2008 (Пн) 20:31

Прям в точку! Спасибо.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 10.03.2008 (Пн) 22:45

По мотивам этого топика написал статью.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 11.03.2008 (Вт) 22:42

Нашел то что поможет решить мне мой вопрос http://visualprogs.medyal.ru/states/43.html. Проблемма в том, что не работает эта строка кода:
pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
после этого pHandle = 0. Не знаю в чем грабли. pid - определяеться верно.
Хакер, что скажете. Вот уже приблизился к двери, открыв которую я увижу конец пути. Только ключи мои не подходят... Спасибо, за потраченое на меня время.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 11.03.2008 (Вт) 22:50

Тот мусор, на который приведена ссылка читать категорически не рекомендуется. Концентрация ошибок на первой половине страницы настолько велика, что чтение подобного рода "статей" принесёт только вред.

Что в Err.LastDllError?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Lumen
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 841
Зарегистрирован: 03.12.2005 (Сб) 16:09
Откуда: Брянск

Сообщение Lumen » 11.03.2008 (Вт) 22:55

Срочно курим MSDN пока не торкнет:
MSDN писал(а):To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege

Делается это так:
Код: Выделить всё

Public Const TOKEN_QUERY As Long = &H8&
Public Const TOKEN_ADJUST_PRIVILEGES As Long = &H20&
Public Const SE_PRIVILEGE_ENABLED As Long = &H2
Public Const SE_DEBUG_NAME As String = "SeDebugPrivilege"

Public Type LUID
   lowpart As Long
   highpart As Long
End Type

Public Type LUID_AND_ATTRIBUTES
   pLuid As LUID
   Attributes As Long
End Type

Public Type TOKEN_PRIVILEGES
   PrivilegeCount As Long
   Privileges As LUID_AND_ATTRIBUTES
End Type

Public Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPriv As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long                'Used to adjust your program's security privileges, can't restore without it!
Public Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As Any, ByVal lpName As String, lpLuid As LUID) As Long          'Returns a valid LUID which is important when making security changes in NT.
Public Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Public Declare Function GetCurrentProcess Lib "kernel32" () As Long

Public Function EnablePrivilege(seName As String, fEnable As Boolean) As Boolean
Dim p_lngRtn As Long
Dim p_lngToken As Long
Dim p_lngBufferLen As Long
Dim p_typLUID As LUID
Dim p_typTokenPriv As TOKEN_PRIVILEGES
Dim p_typPrevTokenPriv As TOKEN_PRIVILEGES
p_lngRtn = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, p_lngToken)
If p_lngRtn = 0 Then
    Exit Function
ElseIf Err.LastDllError <> 0 Then
    Exit Function
End If
p_lngRtn = LookupPrivilegeValue(0&, seName, p_typLUID)
If p_lngRtn = 0 Then
    Exit Function
End If

p_typTokenPriv.PrivilegeCount = 1
p_typTokenPriv.Privileges.Attributes = IIf(fEnable, SE_PRIVILEGE_ENABLED, 0)
p_typTokenPriv.Privileges.pLuid = p_typLUID
EnablePrivilege = (AdjustTokenPrivileges(p_lngToken, False, p_typTokenPriv, Len(p_typPrevTokenPriv), p_typPrevTokenPriv, p_lngBufferLen) <> 0)
End Function
Подпись проходит рефакторинг

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 12.03.2008 (Ср) 0:00

... а, простите, как этот грандиозный код связать с кодом который на этой странице http://visualprogs.medyal.ru/states/43.html я все же использую его как основу для моей программы.

Lumen
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 841
Зарегистрирован: 03.12.2005 (Сб) 16:09
Откуда: Брянск

Сообщение Lumen » 12.03.2008 (Ср) 0:14

Просто добавь этот код в отдельный модуль, а в событии Form_Load пропиши че-нить типа:
Код: Выделить всё
bPrivilege = EnablePrivilege(SE_DEBUG_NAME, True)
Подпись проходит рефакторинг

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 12.03.2008 (Ср) 1:02

хм, не помогло. Все равно после
pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
pHandle равен нулю...

http://bel-com.nm.ru/VisualBasic.rar - здесь архив с проэктом на VB 6.0, вес 3Кб. Кода очень мало. В качестве программы, в памяти которой нужно заменить число, я взял - "Документ - WordPad".
Помогите разобраться с "pHandle" и я пойду дальше. Спасибо.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Сообщение Atoman » 12.03.2008 (Ср) 4:00

Добавь в начало каждого модуля Option Explicit и все твои ошибки сразу всплывут.

Вот здесь ты пытаешся открыть процесс.
Код: Выделить всё
pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)

А в каком модуле у тебя объявлена константа PROCESS_ALL_ACCESS?

А здесь что ты хочеш закрыть?
Код: Выделить всё
CloseHandle hProcess

Твой код вполне рабочий только надо с ошибками разобраться.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 12.03.2008 (Ср) 18:59

Почти все получилось. Только одно НО. Как только программа записывает число в нужную ячейку памяти, а она записывает, я проверил, винда высвечивает окно - ошибка приложения - мол инструкция по адресу... обратилась к памяти по адресу... Память не может быть "read".
Надо искать здесь - ...если программа не обрабатывает это исключение - или я не туда пошел? Спасибо.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 12.03.2008 (Ср) 21:09

Посмотрите пожалуйста, что не так, почему Винда ругает - Память не может быть "read".
это код модуля:
Код: Выделить всё
Option Explicit
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAcess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAdress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long()
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddess As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWriten As Long) As Long

Public Declare Function GetLastError Lib "kernel32" () As Integer
Public Const PROCESS_ALL_ACCESS = &H1F0FFF


это остальной код:
Код: Выделить всё
Private Sub Command1_Click()

Dim hwnd        As Long
Dim pid           As Long
Dim hProcess   As Long
Dim str            As String * 2
Dim str2          As String * 2

str = "Ww"

hwnd = FindWindow(vbNullString, "Калькулятор Плюс")
If (hwnd = 0) Then
    MsgBox "Window not found!"
    Exit Sub
    End If

GetWindowThreadProcessId hwnd, pid

hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, pid)
    If (hProcess = 0) Then
    MsgBox "Couldn 't get a process handle!"
    Exit Sub
    End If

Call ReadProcessMemory(hProcess, &H5D081236, str2, 2, 0&) 'читаються верные данные, проверено.
txtD1 = str2 'в текстовое поле txtD1 выводиться str2

Call WriteProcessMemory(hProcess, &H5D081236, str, 2, 0&) 'эта строка записывает в память(проверял) и вызывает ошибку Винды и Винда закрывает программу. Без этой строки программа работает нормально.

CloseHandle hProcess
    End Sub

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 13.03.2008 (Чт) 4:10

ByVal StrPtr(str) ?

А вообще, вооружись отладчиком.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 13.03.2008 (Чт) 19:46

Точно! Отладчик кое что прояснил. Я немного изменил код в конце:
Код: Выделить всё
str = "1q"
Call WriteProcessMemory(hProcess, &H5D081236, str, 3, 0&)

Call ReadProcessMemory(hProcess, &H5D081236, str2, 2, 0&)
txtD1 = str2

str = "2Q"
Call WriteProcessMemory(hProcess, &H5D081236, str, 3, 0&)

Call ReadProcessMemory(hProcess, &H5D081236, str2, 2, 0&)
txtD1 = str2

CloseHandle hProcess
    End Sub

Так вот. Запустил дебагер и программа исправно работает! Сперва она записала в память "1q", потом прочитала это с памяти и вывела еэто в текстовое поле. Дальше она исправно записала в память значение "2Q" и естественно верно его прочитала от туда и вывела его в текстовое поле txtD1. А вот все рушиться, когда программа выполняет последнбб строку кода: End Sub или если выполнение программы завершить принудительно(кнопкой стоп). Так вот, когда выполниться строка кода: End Sub, винда выдает - память не может быть и закрывает среду разработки(это если запустить программу в ВБ), а если запустить екзешником, то только екзешник естественоо. Может надо еще какая то строка кода перед End Sub ?

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 14.03.2008 (Пт) 1:04

Огромное вам всем спасибо !!! Ошибка найдена! Что в конце этой строки кода:
Код: Выделить всё
Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAdress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long()


заметили две скобки - As Long() ? В них то и причина! Скобки лишние!
Еще раз СПАСИБО!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 14.03.2008 (Пт) 1:28

MisterSer
О другом отладчике речь шла.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 21.03.2008 (Пт) 14:11

Немного не понятно с числами. К примеру у меня число А - Лонг, 4байта, максимальное значение этого числа составляет 2 147 483 647. А вот максимальное значение числа в памяти размером 4байта составляет 4 294 967 295. Есть в других языках програмирования тип числа ulong и максимальное значение его равно 4 294 967 295. Как правельно записать число 4 000 000 000 в память на ВБ? Я вижу, пока, один вариант. Это структура из двух лонгов, а вот записать в память 4 000 000 000 так: к примеру адрес 4байтного числа в памяти &H5B2917A0 и необходимо записать туда число 4 000 000 000. Решение такое: по адресу &H5B2917A0 я пишу число 7022592 ТРИ БАЙТА и по адресу &H5B2917A3 пишу число 238 ОДИН БАЙТ. В итоге 4байтное число по адресу &H5B2917A0 будет равно 4 000 000 000. Есть другие, более простые, варианты решения этой задачи? Спасибо.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 21.03.2008 (Пт) 14:28

В памяти нет чисел, в памяти есть биты. И от того, как будут интерпретированы эти биты, будет зависит, строка это или же число ( икакое число).

32 подряд идущих единицы можно интерпретировать как 4294967295, а можно как -1.

Чтобы записать в память число 4294967290, надо записать в память нужные биты. Числу -6 соответсвуют те же биты, что и 4294967295.

Я вижу, пока, один вариант. Это структура из двух лонгов

Жуткая идея.

Есть другие, более простые, варианты решения этой задачи?

Есть. Записать в память сразу же нужное число, а не записывать поочерёдно куски нужного числа.

Всем unsigned-числам больше &H7FFFFFF соотвуетсвуют signed-числа соотвественно начиная с -2147483648.

Т.е.

Код: Выделить всё
&h7ffffffd = 2147483645 = +2147483645
&h7ffffffe = 2147483646 = +2147483646
&h7fffffff = 2147483647 = +2147483647
&h80000000 = 2147483648 = -2147483648
&h80000001 = 2147483649 = -2147483647
&h80000002 = 2147483650 = -2147483646
...
&h90000123 = 2415919000 = -1879047901
...
&hffffffff = 4294967295 = -1
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 21.03.2008 (Пт) 15:24

Возможно, это еще один дурацкий вопрос. Как записать в память число из текстового поля С которое больше 2147483647 но меньше 4294967296 я понимаю так:
Код: Выделить всё
If (С > 2147483647) Then
   А = С - 4294967296#
   Else
   А = С
End If
WriteProcessMemory(hProcess, procAdres, VarPtr(А), 4, 0&)



А вот как правельно зделать это:
Код: Выделить всё
А = 2147483647
В = 100
С = А + В
здесь А В С тип Лонг. Спасибо.

MisterSer
Начинающий
Начинающий
 
Сообщения: 18
Зарегистрирован: 10.03.2008 (Пн) 13:20

Сообщение MisterSer » 21.03.2008 (Пт) 18:29

Код: Выделить всё
If (2147483647 - А < В) Then
        С = -4294967296# + А + В
End If
WriteProcessMemory(hProcess, procAdres, VarPtr(С), 4, 0&)


Число С - интропритируеться другой программой всегда как unsigned. И получим 2147483747. Или этот метод тоже не идеален?[/code]


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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7

    TopList