Delphi 7 WriteProcessMemory

时光总嘲笑我的痴心妄想 提交于 2019-12-11 03:23:01

问题


This is my Working Code

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

I want to Convert it without using a variable but it wont work Below is just an Example of what i want to do.

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

Does anyone know a way to make this work with using a variable??? I am able to program in a few languages and every language i use their is a way to to do this. The reason i want to do this is because i am gonna be making a big program that does alot of writing of different values and it will save me around 300+ lines. Below is an Example in c++ i was using.

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

Update: Solved it Im using 4 Procedures that i call depending on how many bytes i want to write.

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;

Example writes

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

Pchar is the only method i found to compile without procedures, i dont want to use assci though.

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

回答1:


You have to store the contents of the word that you are writing somewhere. WriteProcessMemory expects a pointer to some memory in your process space. If you don't want to use a variable, use a constant.

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

Passing ptr(99) fails because ptr(99) is not a pointer to a word containing the value 99. It is a pointer to address 99. I think you were trying to write @Word(99) but you cannot take the address of a true constant.

You can make this more convenient by wrapping up the call to WriteProcessMemory in a helper methods. Although your question suggests that you want to write Word values, it became apparent in out lengthy chat that you actually want to write byte sequences. Writing integer data types will lead to machine endianness confusion. So instead I would do it using an open array of Byte to give the flexibility at the call site.

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;

You can then call the code

WriteBytes(Handle, Pointer($523328), [$42]);//single byte
WriteBytes(Handle, Pointer($523328), [$CC, $90, $03]);//3 bytes



回答2:


In C++, this code:

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

Is declaring a const char[] buffer in the app's memory that contains the two characters '\x20' and '\x00' in it. This is evident by the use of the " double-quote characters around the literal. They are creating a string literal, not a character literal (which uses ' single-quote character instead). The starting address of that literal's first character is being passed to the third parameter and the fourth parameter is set to 1 to tell WriteProcessMemory() to copy only 1 byte from that 2-byte buffer.

Delphi, on the other hand, uses the ' single-quote character around both single-character and string literals, and thus relies on code context to decide which type of literal needs to be created. As such, Delphi does not have a direct means of declaring a single-character literal that is the equivilent of an inlined char[] like in the C++ code. The closest equivilent I can think of right now, without declaring a constant, would be something like this:

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

Otherwise, use just an explicit constant instead. The direct equivilent of what the C++ code is doing is the following:

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

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

Alternatively, you can simplify it to the following:

const
  space: Byte = $20;

WriteProcessMemory(hProcess, Pointer($4E709C), @space, 1, nil); 



回答3:


The ptr() Method converts an address to an pointer. So the value in the second method is not 99 but the value that is written at the address 99.

My dirty method, but with few lines of code:

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

Then you can call the method with:

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


来源:https://stackoverflow.com/questions/9929981/delphi-7-writeprocessmemory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!