1

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#.

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.