3

このコードを使用して、64 ビット dll を Windows 7 64 ビットの 64 ビット プロセスに挿入しています。CreateRemoteThread は 200 を返しますが、それでも dll は挿入されません。別のソースで dll をテストしたところ、問題なく動作しました。Process Explorer は、私のコードが動作しません。このコードの何が問題なのですか。私は Delphi XE3 を使用しており、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;
4

1 に答える 1

4

を呼び出しLoadLibraryAていますが、UTF-16 でエンコードされたデータを渡しています。LoadLibraryWモジュール名を ANSI に切り替えるか、変換します。

私なら前者にします。に切り替えるだけでなく、バLoadLibraryW​​ッファ全体をコピーする必要があります。の 2 つのインスタンスを に置き換えることで、これを実現しLength(DLLPath) + 1ますSizeOf(Char)*(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
  • 使用するときは、size パラメータMEM_RELEASEを渡す必要があります。0

すべてをまとめると、コードは次のようになります。

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個人的には、おそらく aではなく aを渡したいと思いPWideCharますが、そうする動機が他にあるかもしれません。

于 2012-10-01T09:40:16.407 に答える