如何为Open或Fixed-size数组分配多个值?

时间:2021-08-13 03:33:28

I want to do the following,but I get errors:

我想做以下,但我得到错误:

procedure JumpToCodeCave(CurrentLocation:DWORD;Destination:Pointer;out_JmpBack:Pointer);
var calc:DWORD;
jmppatch:Array[0..3] of byte absolute calc;
Buffer:Array[0..9] of byte;
begin
  calc := (Cardinal(Destination) - $5)-(CurrentLocation + $4);
  Buffer := [$90,$90,$90,$90,$E9,jmppatch,$90]; //<< Error here <<
  WriteProcessmemory(Handle,Pointer(CurrentLocation),Pointer(Buffer),10,nil);
  out_JmpBack^ := Currentlocation + $A;
end;

Buffer should look like this:

缓冲区应如下所示:

0x90,0x90,0x90,0xE9,jmppatch[0],jmppatch[1],jmppatch[2],jmppatch[3],0x90

The function calculates the value that should be written to jump from one address(current) to another address(CodeCave).The result is converted into bytes and written into the process,but I can't put the bytes in the Buffer like I did above.

该函数计算应写入的值,以便从一个地址(当前)跳转到另一个地址(CodeCave)。结果转换为字节并写入进程,但我不能像我那样将字节放入缓冲区以上。

I'm sorry for the stupid question,but I have forgotten Delphi after I began my education with C#.

我很抱歉这个愚蠢的问题,但是在我开始接受C#教育后,我忘记了Delphi。

3 个解决方案

#1


Delphi doesn't support array literals like that, especially not ones that would accept a four-byte value and turn it into four one-byte values.

Delphi不支持这样的数组文字,尤其不支持接受四字节值并将其转换为四个单字节值的数组文字。

You can have array constants, as Kcats's answer demonstrates. You can also have open-array literals, but then you can only pass it to a function expecting an open-array parameter.

你可以有数组常量,正如Kcats的回答所示。您也可以使用开放式数组文字,但是只能将其传递给期望开放数组参数的函数。

I'd do something different, in your case. Code is not just an array of bytes. It has structure, so I'd make a record and give it fields for each of the instructions in the code.

在你的情况下,我会做一些与众不同的事情。代码不仅仅是一个字节数组。它有结构,所以我会创建一个记录,并为代码中的每个指令提供字段。

type
  TPatch = packed record
    Nops: array [0..3] of Byte;
    JmpInst: packed record
      Opcode: Byte;
      Offset: LongWord;
    end;
    Nop: Byte;
  end;
const
  Nop = $90;
  Jmp = $e9;

var
  Buffer: TPatch;
begin
  // nop; nop; nop; nop;
  FillChar(Buffer.Nops, SizeOf(Buffer.Nops), Nop);
  // jmp xxxx
  Buffer.JmpInst.Opcode := Jmp;
  Buffer.JmpInst.Offset := LongWord(Destination) - SizeOf(Buffer.JmpInst)
                         - (CurrentLocation + SizeOf(Buffer.Nops));
  // nop
  Buffer.Nop := Nop;

  WriteProcessmemory(Handle, Ptr(CurrentLocation), @Buffer, SizeOf(Buffer), nil);
end;

Even if you don't do all that, note that I've changed the third parameter of WriteProcessMemory. Your Buffer variable is not a pointer, so you really can't type-cast it to be one. You need to pass the address.

即使你没有做到这一切,请注意我已经改变了WriteProcessMemory的第三个参数。您的Buffer变量不是指针,因此您实际上无法将其类型化为一个。你需要传递地址。

#2


There's no way to assign the way you want to. Instead, use the Move() and FillMemory() procedures:

没有办法指定你想要的方式。而是使用Move()和FillMemory()过程:

FillMemory(@Buffer[0], 4, $90);
Buffer[4] := $E9;
Move(Calc, Buffer[5], 4);
Buffer[9] := $90;

Note that I have removed the absolute variable, as it's no longer necessary.

请注意,我已经删除了绝对变量,因为它不再是必需的。

#3


You can't do that. Try something like:

你不能这样做。尝试类似的东西:

var
  Buffer:Array[0..9] of byte = ($90,$90,$90,$90,$E9,$CC,$CC,$CC,$CC,$90);
begin
  PCardinal(@buffer[5])^ := (Cardinal(Destination) - $5)-(CurrentLocation + $4);

#1


Delphi doesn't support array literals like that, especially not ones that would accept a four-byte value and turn it into four one-byte values.

Delphi不支持这样的数组文字,尤其不支持接受四字节值并将其转换为四个单字节值的数组文字。

You can have array constants, as Kcats's answer demonstrates. You can also have open-array literals, but then you can only pass it to a function expecting an open-array parameter.

你可以有数组常量,正如Kcats的回答所示。您也可以使用开放式数组文字,但是只能将其传递给期望开放数组参数的函数。

I'd do something different, in your case. Code is not just an array of bytes. It has structure, so I'd make a record and give it fields for each of the instructions in the code.

在你的情况下,我会做一些与众不同的事情。代码不仅仅是一个字节数组。它有结构,所以我会创建一个记录,并为代码中的每个指令提供字段。

type
  TPatch = packed record
    Nops: array [0..3] of Byte;
    JmpInst: packed record
      Opcode: Byte;
      Offset: LongWord;
    end;
    Nop: Byte;
  end;
const
  Nop = $90;
  Jmp = $e9;

var
  Buffer: TPatch;
begin
  // nop; nop; nop; nop;
  FillChar(Buffer.Nops, SizeOf(Buffer.Nops), Nop);
  // jmp xxxx
  Buffer.JmpInst.Opcode := Jmp;
  Buffer.JmpInst.Offset := LongWord(Destination) - SizeOf(Buffer.JmpInst)
                         - (CurrentLocation + SizeOf(Buffer.Nops));
  // nop
  Buffer.Nop := Nop;

  WriteProcessmemory(Handle, Ptr(CurrentLocation), @Buffer, SizeOf(Buffer), nil);
end;

Even if you don't do all that, note that I've changed the third parameter of WriteProcessMemory. Your Buffer variable is not a pointer, so you really can't type-cast it to be one. You need to pass the address.

即使你没有做到这一切,请注意我已经改变了WriteProcessMemory的第三个参数。您的Buffer变量不是指针,因此您实际上无法将其类型化为一个。你需要传递地址。

#2


There's no way to assign the way you want to. Instead, use the Move() and FillMemory() procedures:

没有办法指定你想要的方式。而是使用Move()和FillMemory()过程:

FillMemory(@Buffer[0], 4, $90);
Buffer[4] := $E9;
Move(Calc, Buffer[5], 4);
Buffer[9] := $90;

Note that I have removed the absolute variable, as it's no longer necessary.

请注意,我已经删除了绝对变量,因为它不再是必需的。

#3


You can't do that. Try something like:

你不能这样做。尝试类似的东西:

var
  Buffer:Array[0..9] of byte = ($90,$90,$90,$90,$E9,$CC,$CC,$CC,$CC,$90);
begin
  PCardinal(@buffer[5])^ := (Cardinal(Destination) - $5)-(CurrentLocation + $4);