Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Прочитать значение из оперативки


Автор: Kluyg 8.1.2005, 12:23
Помогите плиз, очень нужно реализовать функцию чтения значения из определенной ячейки памяти на языке Delphi. Например PID 248, адрес 00F3B333. Как оттуда прочитать значение??
Заранее спасибо

Автор: dm9 8.1.2005, 13:17
http://forum.vingrad.ru/index.php?showtopic=38150
smile

Автор: p0s0l 8.1.2005, 14:41
Перенесенно из раздела Delphi

Автор: Guest 8.1.2005, 17:25
Во-первых спасибо за оперативный ответ smile
Во-вторых возникло пару вопросов...
Код

hProcess := OpenProcess (PROCESS_VM_WRITE or PROCESS_VM_OPERATION, False, ProcessID);
WriteProcessMemory (hProcess, Pointer(Адрес в чужом процесса), Pointer(Адрес записываемых данных), <Число записываемых байт>, WrittenBytes);
CloseHandle (hProcess);


1) А нельзя поподробней о функции OpenProcess (ну о параметрах возможных).
2) Мне не писать а читать нужно... ReadProcessMemory я полагаю тоже существует? Какие там пораметры?
3) Только не смейтесь... hProcess - это что?smile Ну всмысле тип какой?

Автор: Kluyg 8.1.2005, 17:41
Reads data from the process.

Delphi syntax:

function ReadProcessMemory(Address: LongWord; Count: Integer; var Buffer): Integer;

Description

ReadProcessMemory reads data from an arbitrary address in the process’s memory.

The Address parameter specifies the starting address to read.

The Count parameter specifies the number of bytes to read.

The Buffer parameter specifies the starting location where the data are to be stored.

The return value is the number of bytes successfully read. Note that the return value is always the same as Count because if the read fails, the IDE throws an EDbkError exception.

Это я сам себе ответил smile

Автор: Kluyg 8.1.2005, 18:11
Итак я поразбирался и вопросы 2) и 3) снимаются smile
Так как мои знания Дельфи и строения ПК пока далеки от идеала то у меня появился вопрос по поводу Буфера. Это, я так понял, указатель на какую-то область памяти? Вообщем вопрос такой: как мне с помощью ReadProcessMemory получить массив со значениями собственно?
З.Ы. Сори за флуд. Поторопился я что-то.

Автор: dm9 8.1.2005, 20:05
Цитата(Kluyg @ 8.1.2005, 17:41)
var Buffer


При такой записи это просто набор байт.

Если памяти много не надо, можно просто объявить массив.

Код
var Buffer : packed array [0..9] of Byte;


Использование - ReadProcessMemory (..., Buffer);

Если памяти надо больше, выделять её лучше динамически.

Код
type
  TBuf = packed array [0..$7FFFFFFE] of Byte;
  PBuf = ^TBuf;
var
  Buffer : PBuf;
  Size : Integer;
begin
  GetMem (Buffer, Size);
  ...
  ReadProcessMemory (..., Buffer^); //Тут уже сама переменная Buffer - указатель, поэтому используем её по-другому.
  ...
  //Читать так:
  a := Buffer[0];
  //Или так:
  a := Buffer^[0];
  FreeMem (Buffer, Size);
end;


Я сам этим никогда не занимался, но у меня по Ctrl + клик по ф-ции выдаётся такое описание ReadProcessMemory:

Код
function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer;
  nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL; stdcall;


Тут lpBuffer - Pointer;
В этом случае также выделаешь память GetMem-ом, но передаёшь в ф-цию сам указатель, просто Buffer (не Buffer^).

Автор: Kluyg 8.1.2005, 22:02
Не работает smile(
вот код, который я использую:

Код

type

  TBuf = packed array [0..$7FFFFFFE] of Byte;
  PBuf = ^TBuf;

var
ProcessID, hProcess, WritenByte,BR: Cardinal;
Buffer : PBuf;
Size : Integer;
a:byte;
i:integer;

begin
GetMem (Buffer, Size);
...
 ProcessID:= GetIDProcess('MUDClient.exe'); {работает правильно - проверял}
 hProcess := OpenProcess(PROCESS_VM_WRITE or PROCESS_VM_OPERATION, False, ProcessID);
 readprocessmemory(hProcess,Pointer($00F3B333),Buffer,2,BR); {Почемуто BR - 0, я в раздумьях}
 for i:=1 to 5 do
 begin
 a := buffer[i]; {а - все время ноль}
  FreeMem (Buffer, Size);
end;



Что-то я ничего не понимаю...

Автор: dm9 8.1.2005, 22:16
Ты Size-то где задаёшь?
Добавлено @ 22:18
Вначале Size := 2
Добавлено @ 22:18
То есть Size - это размер памяти, которую надо выделить.

Автор: Kluyg 8.1.2005, 22:29
Упс у меня ПИД - cardinal. А там надо Dword. Может тут ошибка?
Добавлено @ 22:35
Нет не тут smile (проверил)

Автор: dm9 8.1.2005, 22:36
PROCESS_VM_WRITE -> PROCESS_VM_READ
Добавлено @ 22:36
smile

Автор: Kluyg 8.1.2005, 22:36
Цитата

Ты Size-то где задаёшь?
Добавлено @ 22:18
Вначале Size := 2
Добавлено @ 22:18
То есть Size - это размер памяти, которую надо выделить.

smile Щас попробую. Но помойму проблема не в этом - пробовал другими способами (без getmem) - то же самое.
Добавлено @ 22:37
Цитата
PROCESS_VM_WRITE -> PROCESS_VM_READ
Добавлено @ 22:36
smile

???

Автор: dm9 8.1.2005, 22:38
Или, наверное, сразу можно PROCESS_ALL_ACCESS
Добавлено @ 22:39
Цитата(Kluyg @ 8.1.2005, 22:36)
???


Ты на запись открываешь, а пытаешься читать!
Укажи вместо PROCESS_VM_WRITE PROCESS_VM_READ, или попробуй указать 1-м параметром OpenProcess PROCESS_ALL_ACCESS.

Автор: Kluyg 8.1.2005, 22:54
Тьфу блин!!! Получилось!!! ПАСИБО ОГРОМНОЕ!! smile)) Пойду спать smile

Автор: dm9 8.1.2005, 22:57
Это хорошо, что получилось smile

Автор: MSergey 11.3.2005, 13:07
Я тут попробывал эту функцию, работает, но медленно
Допустим мне надо просканировать память и найти определенные значения

for i := $0046DEB1 to $01FFFFFF do begin
ReadProcessMemory(hProcess, Pointer(i), buffer, 4, BR);
a := buffer[0];

На это уходит порядка 10 минут, есть программы, например ArtMoney
которые туже операцию выполняют в считанные секунды.

Может кто нибудь знает как ускорить выполнение такой процедуры?

Автор: dm9 11.3.2005, 15:56
Попробуй сначала всё прочитать в буфер, а потом выполнять поиск по этому буферу.

Автор: MSergey 14.3.2005, 11:28
Я с оперативкой еще не работал, поэтому до меня так и не дошло как скопировать ее в буфер.

Автор: dm9 16.3.2005, 00:01
Копируй информацию не по байтику (ну, не по 4 байта), а сразу большими блоками, затем по этим блокам ищи нужную информацию. Думаю, так будет быстрее. Лучше один раз запросить данные и получить их, а затем ползать по этим данным, чем тысячу раз вызывать функцию.

Автор: Girder 16.3.2005, 11:16
Цитата(MSergey @ 11.3.2005, 13:07)
На это уходит порядка 10 минут, есть программы, например ArtMoney
которые туже операцию выполняют в считанные секунды.

1. Буфер для чтения... надо больше использовать
2. наХ весь диапозон сканить? http://forum.vingrad.ru/index.php?showtopic=36807&view=findpost&p=274736

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)