2010-07-05 3 views
1

이 코드를 사용하여 함수를 삽입하지만 대상 프로세스가 충돌합니다. 아무도 이유를 아나요?remoteThread를 사용하여 함수를 삽입 할 때 대상 프로세스가 충돌합니다.

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); 
{$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; 
+0

안녕하세요, Sam. 사람들이 쉽게 볼 수 있도록 여기에 코드를 복사했습니다. 우리는이 주변의 링크를 통해 선호하는 경향이 있습니다. :) –

+0

thx alot Mason Wheeler – sam

+2

* 완벽한 부울 평가 *를 사용하면 아이디어가 좋은 곳이 어디 있습니까? –

답변

2

Err, GetModuleHandle (nil)은 대상 프로세스가 아닌 프로세스의 값입니다. 값이 동일하거나 (심지어 같지 않더라도) VirtualFreeEx를 사용하여 프로세스에서 메모리를 꺼내는 것은 좋지 않은 생각입니다. 거기에 일부 코드를 실행하는 중간에 알 수 있습니다. 잠재적 인 충돌을 일으킬 수있는 첫 번째 장소입니다. 하지만 어떻게 든 그 일을 가정 해 봅시다. 그래서 새로운 메모리를 할당하여 코드를 쓸어 넘깁니다. 그러나 필요한 경우 이전하지 않았으며 다시 EntryPoint를 사용합니다. 다시 재배치되지 않았습니다. 왜 윈도우 훅과 같은 "쉬운"코드 삽입 방식을 사용하지 않습니까?

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

그들은 C++에 있지만, 당신은 "델파이 ifying"그들이 할 수있는 것 :

다음은 몇 가지 예입니다.

삽입하려는 코드가 포함 된 DLL을 작성하고 LoadLibrary를 사용하여 CreateRemoteThread를 통해로드하는 방법으로 현재 수행중인 작업을 단순화 할 수 있습니다. CreateRemoteThread 및 GetProcAddress ("LoadLibraryW") 또는 LoadLibraryA와 함께 사용할 핸들이 CreateRemoteThread에 전달할 수 있도록 VirtualAllocEx를 사용하여 DLL 이름, WriteProcessMemory 및이를 처리하기위한 GetModuleHandle ("kernel32.dll")에 대한 공간을 할당합니다. 현재하고있는 것처럼 할당하지 않은 메모리는 절대로 배포하지 않아야합니다. 모든 프로세스에서 kernel32가 같은 위치 (ASLR 포함)에로드되도록 보장되므로 LoadLibrary로 부트 스트랩하면 현재 코드가 안정적으로 작동하도록 처리해야하는 많은 문제를 피할 수 있습니다.

+0

당신이 링크를 남겨두면 – sam

+0

내 대상 프로세스 dosen't, 즉, – sam

+0

오, 그 이유는 "ShowMessage ('hi')"원격 스레드 수 있습니다. 종속 코드를 실행하면 다음과 같이됩니다. LoadLibrary ('kernel32.dll'); LoadLibrary ('user32.dll'); MessageBox (0, 'Hello World', 'Process Injection', 0); ExitThread (0); – sam

관련 문제