2012-10-01 52 views
3

我正在使用此代码注入我的64位DLL进入64位进程在Windows 7 64位,CreateRemoteThread返回200但仍然没有注入DLL,我测试我的DLL与另一个来源,它工作正常,进程资源管理器显示我的代码不起作用,这个代码有什么问题,我使用delphi XE3,我已经在64位目标平台上编译代码。德尔福XE3 DLL注入64位DLL到64位进程不起作用

function InjectDLL(dwPID: DWORD; DLLPath: pwidechar): integer; 
var 
dwThreadID: Cardinal; 
hProc, hThread, hKernel: NativeUInt; 
BytesWritten: NativeUInt; 
pRemoteBuffer, pLoadLibrary: Pointer; 
begin 
try 
hProc := OpenProcess(PROCESS_ALL_ACCESS, False, dwPID); 
if hProc = 0 then 
begin 
    Result := 0; 
    Exit; 
end; 
pRemoteBuffer := VirtualAllocEx(hProc, nil, Length(DLLPath) + 1, MEM_COMMIT, 
    PAGE_READWRITE); 
if pRemoteBuffer = nil then 
begin 
    Result := 0; 
    Exit; 
end; 
if WriteProcessMemory(hProc, Pointer(pRemoteBuffer), lpvoid(DLLPath), 
    Length(DLLPath) + 1, BytesWritten) = False then 
begin 
    Result := 0; 
    Exit; 
end; 
hKernel := GetModuleHandle(pwidechar('kernel32.dll')); 
pLoadLibrary := (GetProcAddress(hKernel, pansichar('LoadLibraryA'))); 
hThread := CreateRemoteThread(hProc, Pointer(nil), 0, Pointer(pLoadLibrary), 
    Pointer(pRemoteBuffer), 0, dwThreadID); 

WaitForSingleObject(hThread, INFINITE); 
VirtualFreeEx(hProc, Pointer(pRemoteBuffer), Length(DLLPath) + 1, 
    MEM_RELEASE); 
CloseHandle(hThread); 
CloseHandle(hProc); 
// ShowMessage(IntToStr(hThread)+' '+ inttostr(dwThreadID)); 
Result := 1; 
except 
on d: exception do 
begin 
end; 
end; 
end; 
+0

@ hvd我看不到任何代码可以引发异常。这些只是一堆WinAPI调用,不会引发。 –

+0

@DavidHeffernan你确定吗?我不会为'EAccessViolation'异常感到惊讶。 – hvd

+0

@ hvd您打算在哪里调用哪个API来提升AV? –

回答

4

你打电话给LoadLibraryA,但传递它UTF-16编码的数据。切换到LoadLibraryW或将模块名称转换为ANSI。

我会做前者。除了切换到LoadLibraryW之外,您还需要复制整个缓冲区。通过用SizeOf(Char)*(Length(DLLPath) + 1)替换Length(DLLPath) + 1的两个实例来实现此目的。

一些更多的评论:

  • 使用PROCESS_ALL_ACCESS过大。您只需要PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ
  • PAnsiChar投在GetProcAddress(hKernel, pansichar('LoadLibraryA'))看起来不对。因为'LoadLibraryA'是UTF-16编码的。只需使用GetProcAddress(hKernel, 'LoadLibraryA')即可。或者如果你沿着这条路线走下去的话'LoadLibraryW'
  • 使用NativeUInt作为句柄是错误的。它并不重要,但你应该使用THandle
  • 使用MEM_RELEASE时,您必须通过0获取size参数。

把那一起,代码应该是这样的:

function InjectDLL(dwPID: DWORD; DLLPath: PWideChar): integer; 
var 
    dwThreadID: Cardinal; 
    hProc, hThread, hKernel: THandle; 
    BytesToWrite, BytesWritten: SIZE_T; 
    pRemoteBuffer, pLoadLibrary: Pointer; 
begin 
    hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, dwPID); 
    if hProc = 0 then 
    exit(0); 
    try 
    BytesToWrite := SizeOf(WideChar)*(Length(DLLPath) + 1); 
    pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT, PAGE_READWRITE); 
    if pRemoteBuffer = nil then 
     exit(0); 
    try 
     if not WriteProcessMemory(hProc, pRemoteBuffer, DLLPath, BytesToWrite, BytesWritten) then 
     exit(0); 
     hKernel := GetModuleHandle('kernel32.dll'); 
     pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryW'); 
     hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer, 0, dwThreadID); 
     try 
     WaitForSingleObject(hThread, INFINITE); 
     finally 
     CloseHandle(hThread); 
     end; 
    finally 
     VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE); 
    end; 
    finally 
    CloseHandle(hProc); 
    end; 
    exit(1); 
end; 

就个人而言,我可能会传递一个string而非PWideChar,但也许你有一些其他的动机这样做。

+0

感谢您的时间David,但仍然是同样的结果,我知道我应该怎么做,我认为由Delphi XE编译器引起的问题,任何想法? – user1711256

+0

还是一样的结果?你甚至没有告诉我们结果是什么。 –

+0

无论如何,我测试了这个代码。注射工作正常。 –