私はこの 1 週間、単純な注入アプリケーションで dll を他のプロセスに正常に注入できるように取り組んできました。ただし、これまでのところ、dll をインジェクター自体に挿入した場合にのみ機能しています。別のアプリケーションに注入しようとすると、関数は成功を報告します (スレッドが正常に作成され、メモリが割り当てられ、ターゲットに書き込まれます) が、dllMain が呼び出されないようです。さらに、エラー コード 0 (ERROR_SUCCESS) が によって指定されGetLastError()
ます。
targetProcessId
asを指定するとGetCurrentProcess()
、ダイアログ ボックスが表示され、RemoteThread が正常に実行されます。
しかし、targetProcessId を calc.exe の実行中のインスタンスに設定しようとしても、何も起こりません。モジュールがまだロードされていない可能性があるため、DllMain から MessageBox を呼び出すことは悪い考えであることを他の場所で読んだので、DllMain で無限ループを作成し、calc.exe のスレッド数が 1 増加したかどうかを確認しました。相変わらずでした。
これは StackOverflow に関する私の最初の質問であり、投稿する前にこのトピックについてできるだけ多くの調査を試みましたが、何時間も経ってもうまくいきませんでした。私は明らかにdllインジェクションに慣れていません(最近Ritcherの本、Windows via C/C++を読み終えました)。どんな助けでも大歓迎です。
私のコードはすべて、x64 プラットフォーム用に Visual Studio 2010 からコンパイルされています。
以下は、私の Injector アプリケーションからの関連コードです。
BOOL WINAPI Inject(DWORD processID, PCWSTR sourceDLL)
{
BOOL success = false;
HANDLE targetProcess = NULL, createdThread = NULL;
PWSTR pszLibFileRemote = NULL;
__try
{
std::cout << "Process ID: "<< processID << std::endl;
targetProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
FALSE, processID);
if (targetProcess == NULL)
{
std::cout << "ERROR: " << GetLastError();
MessageBox(NULL, L"Unable to open process.", L"Error", MB_OK);
__leave;
}
int cch = 1 + lstrlenW(sourceDLL); //Calculate the number of bytes required for the DLL's path
int cb = cch * sizeof(wchar_t);
pszLibFileRemote = (PWSTR)VirtualAllocEx(targetProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL)
{
MessageBox(NULL, L"Could not allocate dll pathname in target process.", L"Error", MB_OK);
__leave;
}
if (!WriteProcessMemory(targetProcess, pszLibFileRemote, (PVOID) sourceDLL, cb, NULL))
{
MessageBox(NULL, L"Could not write dll pathname in target process.", L"Error", MB_OK);
__leave;
}
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL)
{
MessageBox(NULL, L"Error finding LoadLibraryW address.", L"Error", MB_OK);
__leave;
}
createdThread = CreateRemoteThread(targetProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (createdThread == NULL)
{
__leave;
}
WaitForSingleObject(createdThread, INFINITE);
success = true;
}
__finally { // Now, we can clean everything up
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
VirtualFreeEx(targetProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (createdThread != NULL)
CloseHandle(createdThread);
if (targetProcess != NULL)
CloseHandle(targetProcess);
}
return success;
}
int _tmain(int argc, _TCHAR* argv[])
{
PCWSTR srcDll = L"test.dll"; //dll in the same directory as the injector.exe, its code is specified below.
DWORD processID = "768"; //Hard coded process ID of a running calc.exe. When I change this line to GetCurrentProcessId() the messagebox from my dll shows.
if (Inject(processID, srcDll))
{
std::cout << "Injection successful" << std::endl;
Eject(processID, srcDll); //This detaches the dll by calling freelibrary from a remote thread. This function was omitted from this response to keep things relavent.
}
system("PAUSE");
return 0;
}
そして、これが私の単純な helloworld test.dll のコードです。
#include "stdafx.h"
#include <Windows.h>
#include <tchar.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
case DLL_THREAD_ATTACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
case DLL_THREAD_DETACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
case DLL_PROCESS_DETACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
}
return TRUE;
}
解決済み: 挿入された dll のディレクトリは、ターゲット プロセスが見つけられるように、ターゲット プロセスに対して相対的に指定するか、フル パスとして指定する必要があります。(私はインジェクターのディレクトリにそれを持っていましたが、それが負荷の問題を引き起こしていました -- calc はそれがどこにあるかを知りませんでした。)