Delphi 7 WriteProcessMemory - PullRequest
       7

Delphi 7 WriteProcessMemory

2 голосов
/ 29 марта 2012

Это мой рабочий код

  DriftMul:=99;
  WriteProcessMemory(HandleWindow, ptr($4E709C), @DriftMul, 2, Write);

Я хочу преобразовать его без использования переменной, но он не будет работать. Ниже приведен только пример того, что я хочу сделать.

WriteProcessMemory(HandleWindow, ptr($4E709C),  ptr(99), 2, Write);

Кто-нибудь знает способ заставить это работать с использованием переменной ???Я могу программировать на нескольких языках, и каждый язык, которым я пользуюсь, это способ сделать это.Причина, по которой я хочу это сделать, заключается в том, что я собираюсь сделать большую программу, которая выполняет много разных значений, и это сэкономит мне более 300 строк.Ниже приведен пример использования c ++, который я использовал.

WriteProcessMemory(hProcess, (void*)0x4E709C, (void*)(PBYTE)"\x20", 1, NULL);

Обновление: решено. Я использую 4 процедуры, которые я вызываю в зависимости от того, сколько байтов я хочу записать.пишет

 Wpm($477343,$EB);
 Wpm2($40A889,$37EB);
 Wpm3($416E34,$0086E9);

Pchar - единственный метод, который я нашел для компиляции без процедур, хотя я не хочу использовать assci.

WriteProcessMemory(HandleWindow, Pointer($449A17), PChar('90'), 1, Write);

Ответы [ 3 ]

6 голосов
/ 29 марта 2012

Вы должны хранить содержимое слова, которое вы где-то пишете. WriteProcessMemory ожидает указатель на некоторую память в вашем рабочем пространстве. Если вы не хотите использовать переменную, используйте константу.

const
  DriftMul: word=99;
....
WriteProcessMemory(HandleWindow, ptr($4E709C),  @DriftMul, 2, Write);

Передача ptr(99) завершается неудачно, поскольку ptr(99) не является указателем на слово, содержащее значение 99. Это указатель на адрес 99. Я думаю, что вы пытались написать @Word(99), но вы не можете взять адрес истинной константы.

Вы можете сделать это более удобным, заключив вызов в WriteProcessMemory во вспомогательные методы. Хотя ваш вопрос предполагает, что вы хотите записать Word значений, в длинном чате стало очевидно, что вы действительно хотите писать байтовые последовательности. Запись целочисленных типов данных приведет к путанице с машинным порядком байтов. Поэтому вместо этого я бы использовал открытый массив Byte, чтобы обеспечить гибкость на сайте вызовов.

procedure WriteBytes(hProcess: THandle; Address: Pointer;
  const Buffer: array of Byte);
var
  NumberOfBytesWritten: DWORD;
begin
  if not WriteProcessMemory(hProcess, Address, @Buffer[0], Length(Buffer),
    NumberOfBytesWritten) then RaiseLastOSError;
end;

Затем можно позвонить по коду

WriteBytes(Handle, Pointer($523328), [$42]);//single byte
WriteBytes(Handle, Pointer($523328), [$CC, $90, $03]);//3 bytes
2 голосов
/ 29 марта 2012

В C ++ этот код:

WriteProcessMemory(hProcess, (void*)0x4E709C, (void*)(PBYTE)"\x20", 1, NULL); 

объявляет буфер const char[] в памяти приложения, который содержит два символа '\x20' и '\x00'.Это видно по использованию двойных кавычек " вокруг литерала.Они создают строковый литерал, а не символьный литерал (вместо него используется ' символ одинарной кавычки).Начальный адрес первого символа этого литерала передается третьему параметру, а четвертому параметру присваивается значение 1, чтобы WriteProcessMemory() должен копировать только 1 байт из этого 2-байтового буфера.

Delphi вс другой стороны, используется символ одинарной кавычки ' вокруг односимвольных и строковых литералов и, таким образом, для определения типа литерала необходимо использовать контекст кода.Таким образом, Delphi не имеет прямого способа объявить односимвольный литерал, эквивалентный встроенному char[], как в коде C ++.Ближайший эквивалент, который я могу себе представить, без объявления константы, будет выглядеть примерно так:

WriteProcessMemory(hProcess, Pointer($4E709C), PAnsiChar(AnsiString(' ')), 1, nil); 

В противном случае используйте вместо этого только явную константу.Прямым эквивалентом того, что делает код C ++, является следующее:

const
  buffer: array[0..1] of AnsiChar = (#$20, #0);

WriteProcessMemory(hProcess, Pointer($4E709C), Pointer(PByte(@buffer[0])), 1, nil); 

В качестве альтернативы вы можете упростить его до следующего:

const
  space: Byte = $20;

WriteProcessMemory(hProcess, Pointer($4E709C), @space, 1, nil); 
2 голосов
/ 29 марта 2012

Метод ptr () преобразует адрес в указатель.Таким образом, значение во втором методе не 99, а значение, которое записано по адресу 99.

Мой грязный метод, но с несколькими строками кода:

procedure WriteBytes(hProcess: THandle; address: Pointer; buffer: Variant; count: Integer);
begin
  WriteProcessMemory(hProcess, address, @buffer, count, nil);
end;

Тогда вы можетевызовите метод с помощью:

WriteBytes(HandleWindow, Pointer($449A17), 90, 1);
...