开发者

target process crash when using remoteThread to inject a function

I'm using this code to inject my function, but it causes the target process to crash. Does anyone know why?

program Sky;
  {$IMAGEBASE $13140000}
uses
  Unit2 in 'Unit2.pas',
  chstrDec in 'chstrDec.pas',Psapi,

  unitinject in 'unitinject.pas', ShellAPI,dialogs,registry,  Windows, Messages, tlhelp32, SysUtils, Variants, Classes, Graphics, Controls, Forms;


{$R *.res}

 function GetProcessID(ProcessName:string):Integer;
var
Handle:tHandle;
Process:tProcessEntry32;
GotProcess:Boolean;
begin
Handle:=CreateToolHelp32SnapShot(TH32CS_SNAPALL,0) ;
Process.dwSize:=SizeOf(Process);
GotProcess := Process32First(Handle,Process);
{$B-}
if GotProcess and (Process.szExeFile<>ProcessName) then
repeat
GotProcess := Process32Next(Handle,Process);
until (not GotProcess) or (Process.szExeFile=ProcessName);开发者_如何学Go
{$B+}
if GotProcess then Result := Process.th32ProcessID
else Result := 0;
CloseHandle(Handle);
end;

 {$IMAGEBASE $13140000}
function Main(dwEntryPoint: Pointer): longword; stdcall;
var
  s : String;
begin
    ShowMessage('hi');
  Result := 0;
  Sleep(2000);
  Main(dwEntryPoint);
end;
var
x:pointer;
  Handle:tHandle;
 PID:Cardinal;
begin



 Pid:=getProcessID('calc.exe');
  Handle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);

Inject(Handle,@Main);
CloseHandle(Handle);

     end.


//inject
procedure Inject(ProcessHandle: longword; EntryPoint: pointer);
var
  Module, NewModule: Pointer;
  Size, BytesWritten, TID: longword;
begin
  Module := Pointer(GetModuleHandle(nil));
  Size := PImageOptionalHeader(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
  VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
  NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten);
  CreateRemoteThread(ProcessHandle, nil, 0, EntryPoint, Module, 0, TID);
end;


Err, GetModuleHandle(nil) is going to be value for your process, not the target process. Even if the values happen to be the same (or even if they are not) VirtualFreeEx ing that memory out from under the process is a bad idea, it might be you know, in the middle of executing some code there. That's the first place I see that can cause a potential crash. But let's assume that works somehow. So you allocate some new memory to scribble your code in, which you do. But you haven't relocated if you've needed to, and you also directly use EntryPoint, again not relocated. Why don't you use one of the "easy" code injection methods like a window hook?

Here are some examples:

http://www.codeproject.com/KB/threads/winspy.aspx

They are in C++, but you seem capable of "Delphi-ifying" them.

A simplification of what you are doing currently can be achieved by writing a DLL containing the code you want to inject, and using LoadLibrary to load it (by way of CreateRemoteThread). You use VirtualAllocEx to allocate space for the DLL name, WriteProcessMemory to write it over, and GetModuleHandle("kernel32.dll") for the handle to use with CreateRemoteThread and GetProcAddress("LoadLibraryW") (or LoadLibraryA) to pass to CreateRemoteThread. You should definitely never release memory you haven't allocated like you're currently doing. Every process is guaranteed to have kernel32 loaded in the same place (even with ASLR), so by bootstrapping with LoadLibrary you avoid a lot of the issues you'd have to deal with to get something like your current code working reliably.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜