Delphi更改正在运行的进程的汇编代码

时间:2014-10-13 06:16:29

标签: delphi

我正在尝试更改具有00741FA5的地址PUSH Test.009E721C。我想将其更改为PUSH Test.009E71C8

procedure Callback;
asm
  PUSH $9E71C8
end;

procedure TForm2.btn1Click(Sender: TObject);
var
  PPid :DWORD;
  PProcess : Cardinal;
begin
  GetWindowThreadProcessId(FindWindow(nil,PChar('Test')), @PPid);
  PProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PPid);

  InjectASM(PProcess, $741FA5, 10, Integer(@Callback), 0);
end;

这是InjectASM功能(带错误检查)

function InjectASM(Process: LongWord; InjectAddress, InjectSize, CodeAddress, CodeSize : Integer): Pointer;
var
  CSize, RSize : Integer;
  Replaced : array of byte;
  Jmp : array [0..4] of byte;
  JmpAddress : Integer;
  NopV : Byte;

  I : Integer;
  NBR: ULONG_PTR;
begin
  //InjectSize must be equal or greater than 5, because we need space for our
  //(far) JMP WWXXYYZZ instruction
  //If there's no space, then just inject it in place of few instructions
  if InjectSize < 5 then raise Exception.Create('InjectSize must be equal or greater than 5.');

  //Let's copy replaced code
  SetLength(Replaced, InjectSize);
  for I := 0 to InjectSize - 1 do Replaced[i] := byte(pointer(dword(InjectAddress) + I)^);

  //Now get procedure's size
  if CodeSize < 1 then begin
    CSize := 0;
    while byte(pointer(CodeAddress + CSize)^) <> $C3 do CSize := CSize + 1;
  end else begin
    CSize := CodeSize;
  end;

  //Size of injected code
  RSize := InjectSize + CSize + 5; //5 stand for far jmp back


  //Allocate memory for code
  Result := VirtualAllocEx(Process, nil, CSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);

  //Write code to allocated memory
  Win32Check(WriteProcessMemory(Process, Result, Ptr(CodeAddress), CSize, NBR));

  //Write replaced code
  Win32Check(WriteProcessMemory(Process, Ptr(Integer(Result) + CSize), @Replaced[0], InjectSize, NBR));

  //Write back jmp
  JmpAddress := (InjectAddress + InjectSize) - (Integer(Result) + CSize + InjectSize) - 5;
  Jmp[0] := $E9;
  Jmp[1] := byte(JmpAddress);
  Jmp[2] := byte(JmpAddress shr 8);
  Jmp[3] := byte(JmpAddress shr 16);
  Jmp[4] := byte(JmpAddress shr 24);
  Win32Check(WriteProcessMemory(Process, Ptr(Integer(Result) + CSize + InjectSize), @Jmp[0], 5, NBR));


  if Win32Check(VirtualProtectEx(Process,pointer(dword(InjectAddress)),5, PAGE_EXECUTE_READWRITE, @NBR)) then
  begin
    //Fill the code which we're going to replace with nops
    if InjectSize > 5 then begin
      NopV := $90;
      for I := 5 to InjectSize - 1 do begin
      Win32Check(WriteProcessMemory(Process, Ptr(InjectAddress+I), @NopV, 1, NBR));
      end;
    end;

    //Write jmp to injected code
    JmpAddress := Integer(Result) - InjectAddress - 5;
    Jmp[0] := $E9;
    Jmp[1] := byte(JmpAddress);
    Jmp[2] := byte(JmpAddress shr 8);
    Jmp[3] := byte(JmpAddress shr 16);
    Jmp[4] := byte(JmpAddress shr 24);
    Win32Check(WriteProcessMemory(Process, Ptr(InjectAddress), @Jmp[0], 5, NBR));
  end;

  Win32Check(VirtualProtectEx(Process,pointer(dword(InjectAddress)),5, NBR, nil));
end;

但它不会改变。 请帮助。

原始功能可以在这里找到 http://tpforums.org/forum/threads/1428-Delphi-Asm-code-hooking

谢谢,

1 个答案:

答案 0 :(得分:0)

Procedure FuncNewEntry;
begin
  asm
  PUSH $9E71C8 //the new asm code you want to add.
  end;
end;

Function ChangeEntry(PID:Cardinal;TargetOffest:DWORD;FuncProcedure:Pointer):Pointer;
var
  lpNumberOfBytesWritten:ULONG_PTR;
begin
  PID := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
  Win32Check(WriteProcessMemory(PID, Pointer(TargetOffest), FuncProcedure, sizeof(@FuncProcedure), lpNumberOfBytesWritten));
  CloseHandle(pid);
end;

用法

procedure TForm3.btn1Click(Sender: TObject);
var
  PPID:Cardinal;
begin
  GetWindowThreadProcessId(FindWindow(nil,PChar('Test')), @PPid);
  ChangeEntry(PPid,$00741FA5,@FuncNewEntry);
end;