我想做以下事情,但我收到错误:
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。
答案 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);