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

时间:2009-07-10 12:50:31

标签: delphi

我想做以下事情,但我收到错误:

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;

缓冲区应如下所示:

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

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

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

3 个答案:

答案 0 :(得分:3)

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

您可以拥有数组常量as Kcats's answer demonstrates。您也可以使用开放式数组文字,但是只能将它传递给期望开放数组参数的函数。

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

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;

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

答案 1 :(得分:2)

没有办法指定你想要的方式。相反,使用 Move() FillMemory()程序:

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

请注意,我已删除absolute变量,因为它已不再需要。

答案 2 :(得分:1)

你做不到。尝试类似:

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