我正在尝试更改具有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
谢谢,
答案 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;