
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
![]() |
|
|
Итак, вопрос, я считаю, интересный, и, если он прояснится, думаю можно кинуть ссылку в ФАК.
Я работал с ReadProcessMemory в Дельфях, но когда я попробовал перенести код на VB, ничего не получилось. Для примера я проделывал следущее: пишу маленькую прогу, которая просто присваивает некоторой переменной некоторое значение, а затем пишу прогу, которая как раз пытается прочитать в памяти это значение с помощью ReadProcessMemory. Код второй проги: ![]() ![]() '... объявление других функций Private Declare Function ReadProcessMemory Lib "kernel32" (_ ByVal hProcess As Long, _ ByVal lpBaseAddress As Long, _ ByVal lpBuffer As Long, _ ByVal nSize As Long, _ lpNumberOfBytesWritten As Long) As Long Private Const PROCESS_ALL_ACCESS = &H20 Or &H8 Private Sub Command1_Click() Dim hW As Long, PId As Long, hP As Long, bn As Long, buf As Long hW = FindWindow("ThunderRT6FormDC", "Form1") GetWindowThreadProcessId hW, PId hP = OpenProcess(PROCESS_ALL_ACCESS, False, PId) ReadProcessMemory hP, &H51041C, buf, 4, bn MsgBox buf CloseHandle hP End Sub Я чего только не делал. Не работает. ![]() ![]() Тут есть несколько вариантов: неправильное объявление ReadProcessMemory (не знаю, всё перепробовал), неправильное объявление PROCESS_ALL_ACCESS (напишите плиз полностью на всяк), что-то ещё или, чего я боюсь, VB просто не дружит с этой функцией, может быть из-за несовместимости типов... При этом общеизвестный пример с чтением даты биос работает нормально, но там читается строка а не число... Подскажите плиз, а то для меня это принципиально, я пытаюсь доказать некоторым глупым любителям холиваров что VB такой же полноценный язык как и остальные ![]() |
Сообщ.
#2
,
|
|
|
Вот так работает:
![]() ![]() Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, _ lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Private Const PROCESS_ALL_ACCESS = 2035711 Dim l As Long, out As Long l = 100 Call ReadProcessMemory(procHandle, l, ByVal VarPtr(out), 4, 0&) ' out = 100 привет любителям любителям холиваров ![]() |
![]() |
Сообщ.
#3
,
|
|
![]() ![]() Private Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Private Const PROCESS_ALL_ACCESS = &H000F0000 or &H00100000 or &HFFF Private Sub Command1_Click() Dim hW As Long, PId As Long, hP As Long, bn As Long, buf As Long hW = FindWindow("ThunderRT6FormDC", "Form1") GetWindowThreadProcessId hW, PId hP = OpenProcess(PROCESS_ALL_ACCESS, False, PId) ReadProcessMemory hP, &H51041C, ByVal VarPtr(buf), 4, bn MsgBox buf CloseHandle hP End Sub попробуй так |
Сообщ.
#4
,
|
|
|
2Andrey_Kun
у меня почему то просто buf не работал, только ByVal VarPtr(out). хотя вроде тоже самое должно получаться. |
![]() |
Сообщ.
#5
,
|
|
nash, Ага, правильно говоришь там Pointer надо передавать B)
|
Сообщ.
#6
,
|
|
|
Цитата nash @ 22.11.04, 10:27 2Andrey_Kun у меня почему то просто buf не работал, только ByVal VarPtr(out). хотя вроде тоже самое должно получаться. А это всё потому, что виртуальная машина ВБ вносит свои коррекиты в размещении данных. На самом деле все истинные значения переменных хранятся в адресном пространстве msvbvm. В пространстве самого процесса находятся лишь ссылки на данные (ну или вроде этого, всё от типа зависит). Поэтому "ByRef buf" и "VаrPtr(buf)" это по сути не одного и тоже. VаrPtr возвращает реальный адрес. Странно другое, при вызове АПИ ВБ должен сам автоматически подставлять вместо buf нужный указатель. Это он и делает при работе с многими другими функциями. Непонятно, конечно... ![]() |
Сообщ.
#7
,
|
|
|
Цитата Странно другое, при вызове АПИ ВБ должен сам автоматически подставлять вместо buf нужный указатель. Это он и делает при работе с многими другими функциями. Непонятно, конечно... ![]() ![]() Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, _ [B]ByVal lpBuffer As Long[/B], ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Call ReadProcessMemory(procHandle, l, [B]VarPtr(out)[/B], 4, 0&) |
Сообщ.
#8
,
|
|
|
Ребят, не работает ваш код
![]() |
Сообщ.
#9
,
|
|
|
И, кстати, вот пример для сравнения (дата биоса):
![]() ![]() '... Private Declare Function ReadProcessMemory Lib "kernel32" (_ ByVal hProcess As Long, _ ByVal lpBaseAddress As Long, _ ByVal lpBuffer As String, _ ByVal nSize As Long, _ lpNumberOfBytesWritten As Long) As Long Private Sub Form_Load() Dim hInst As Long, num As Long, strText As String strText = String$(8, Chr$(0)) hInst = GetCurrentProcess ReadProcessMemory hInst, &HFFFF5, strText, 8, num MsgBox strText End Sub Заметьте, что VarPtr тут не используется... Тут читается 8 байт в переменную типа String, может быть вот в этом загвоздка? Тип long не соответствует тому, что должно быть? В Дельфях работал Integer, но, как известно, типы в VB не соответствуют тому, название чего они носят =) |
Сообщ.
#10
,
|
|
|
Блин, забываю всё время ник прописывать... Зарегиться чтоль у Вас тут
![]() |
Сообщ.
#11
,
|
|
|
Цитата Ребят, не работает ваш код Проверьте плиз на практике... Все работает. Юзай лучше ![]() ![]() ![]() Option Explicit Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, _ lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Private Const PROCESS_ALL_ACCESS = 2035711 Private Sub Command1_Click() Dim l As Long Dim out As Long Dim procId As Long Dim procHandle As Long ' l = 100 GetWindowThreadProcessId hwnd, procId procHandle = OpenProcess(PROCESS_ALL_ACCESS, False, procId) Call ReadProcessMemory(procHandle, l, ByVal VarPtr(out), 4, 0&) Debug.Print out ' out = 100 CloseHandle procHandle End Sub Добавлено Цитата Заметьте, что VarPtr тут не используется... Но не видно что ли, что функция по другому задекларирована ??? Смотри посты сверху уже. |
Сообщ.
#12
,
|
|
|
Блин... этот код читает память в собственном процессе, а нужно в другом. Если переписать этот код на чтение в другом процессе, он не работает.
На счёт декларации: это не важно... тут проблема не в декларации. Хотя, кстати, спасибо за код, потому что я понял одну вещь: тут проблема в обращении к другому процессу, ведь в своём работает нормально... |
Сообщ.
#13
,
|
|
|
Цитата На счёт декларации: это не важно... Я не знаю важно это или не важно, но от этого зависит как вызывать продекларированную функцию. Поэтому все таки ОЧЕНЬ ВАЖНО. Это было про варптр написано. А про другой процесс: - Как ты узнаешь по какому адресу надо читать ??? - Как ты пишешь параметр функции этого адреса ??? - Что значит не работает код ??? Так говорят пользователи. Программист говорит, ЧТО именно не работает. А доработать код, чтобы смотреть коды возврата и сказать какая именно функция не отрабатывает ? |
Сообщ.
#14
,
|
|
|
Хех.... Вот на оскорбления типа "пользователь" не надо переходить )) Тем более если не знаешь человека.
Кстати как раз программист, имхо, в данном случае *понял* бы, что "не работает код" в данном случае означает "значение не записывается в буфер", но не будем... Адрес я в данном случае узнаю с помощью проги ArtMoney, которая предназначена для взамывания игр путём изменения значений в памяти, соответствующих деньгам и т.п. Но эта прога также хорошо подходит для других целей ![]() Насчёт декларации я имел ввиду этот конкретный случай. Ещё раз говорю, тут дело видимо не в декларации. Если брать твой код, я просто дописываю доступ к другому процессу, а в переменную l загоняю вместо 100 нужный адрес. "Коды возврата" говорят, что работает всё кроме ReadProcessMemory. |
Сообщ.
#15
,
|
|
|
Цитата Вот на оскорбления типа "пользователь" не надо переходить Я и не думал оскорблять, но говорить надо конкретнее. Другое приложение ![]() ![]() Option Explicit Private l As Long Private Sub Form_Load() l = 100 Text1.Text = CStr(hWnd) Text2.Text = CStr(VarPtr(l)) End Sub Наше приложение ![]() ![]() Dim out As Long Dim procId As Long Dim procHandle As Long ' Dim lHwnd As Long Dim lVar As Long ' lHwnd = 1770340 ' Text1.Text lVar = 2005596 ' Text2.Text ' GetWindowThreadProcessId lHwnd, procId procHandle = OpenProcess(PROCESS_ALL_ACCESS, False, procId) Call ReadProcessMemory(procHandle, ByVal lVar, ByVal VarPtr(out), 4, 0&) Debug.Print out ' out = 100 CloseHandle procHandle Тоже не работает ? |
Сообщ.
#16
,
|
|
|
Опа!.. Ё-моё, оказывается дело было в том, что адрес, т.е. как у тебя lVar, надо передавать byval... Ура, товарищи! Visual Basic кривоват, но всесилен (почти=)), что и требовалось доказать... Пасибо тебе большое nash, был бы я зареген, я б тебе два плюса бы поставил!
З.Ы. Блин, насчёт оскорбления я пошутил конечно (разве не видно) Щас пойду поем, а потом выложу здесь полный работающий текст проги... |
Сообщ.
#17
,
|
|
|
Цитата Visual Basic кривоват Ничего личного, но кривоват обычно не бейсик ![]() Это опять не оскорбление ![]() |
Сообщ.
#18
,
|
|
|
Под кривоватостью VB я подразумеваю его фактическую кривоватость как языка, требующую порой хитрых манипуляций от кодера, а в данном случае я конечно же признаю, что тут я стормозил, хотя странно, что мне не пришло это всё в голову... И не такое ещё порой вытворяли
![]() Так, ща выложу код..... |
![]() |
Сообщ.
#19
,
|
|
M Код перемещен в фак - Как использовать ReadProcessMemory |