tags:

views:

178

answers:

3

Hello,

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.

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

+2  A: 

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

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.

mghie
+1  A: 

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);
Kcats
+3  A: 

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.

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.

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.

Rob Kennedy