Delphi 7 WriteProcessMemory

时间:2012-03-29 16:59:41

标签: windows delphi delphi-7

这是我的工作代码

  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个程序,我根据我想写的字节数来调用。

procedure Wpm(Address: Cardinal; ChangeValues: Byte);
Begin
 WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 1, Write);
End;
procedure Wpm2(Address: Cardinal; ChangeValues: Word);
Begin
 WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 2, Write);
End;
procedure Wpm3(Address: Cardinal; ChangeValues: Word);
Begin
 WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 3, Write);
End;
procedure Wpm4(Address: Cardinal; ChangeValues: Cardinal);
Begin
 WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 4, Write);
End;

示例写入

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

Pchar是我发现没有程序编译的唯一方法,我不想使用assci。

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

3 个答案:

答案 0 :(得分:6)

您必须存储您正在某处写的单词的内容。 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

答案 1 :(得分:2)

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);

答案 2 :(得分:2)

在C ++中,这段代码:

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

在应用内存中声明一个const char[]缓冲区,其中包含两个字符'\x20''\x00'。通过在文字周围使用"双引号字符可以明显看出这一点。他们正在创建一个字符串文字,而不是字符文字(使用'单引号字符)。该文字的第一个字符的起始地址被传递给第三个参数,第四个参数被设置为1,以告诉WriteProcessMemory()仅从该2字节缓冲区中复制1个字节。

另一方面,Delphi在单字符和字符串文字周围使用'单引号字符,因此依赖代码上下文来决定需要创建哪种类型的文字。因此,Delphi没有直接的方法来声明单字符文字,它与C ++代码中的内联char[]等效。我现在可以想到的最接近的等值,而不是声明一个常数,将是这样的:

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);