![](/img/trans.png)
[英]Access violation when unloading injected DLL via CreateRemoteThread
[英]Unloading dll throws an Access violation error
所以我有这个 dll:
#include <Windows.h>
#include <iostream>
HMODULE myhModule;
DWORD __stdcall EjectThread(LPVOID lpParameter) {
Sleep(100);
FreeLibraryAndExitThread(myhModule,0);
}
DWORD WINAPI MainThread(LPVOID param) // our main thread
{
AllocConsole(); // enables the console
freopen("CONIN$", "r", stdin); // makes it possible to output to output to console with cout.
freopen("CONOUT$", "w", stdout);
while (true) {
Sleep(100);
if (GetAsyncKeyState(VK_DELETE) & 1) {
cout << "[+] Attempting dll unload" << endl;
Sleep(800);
break;
}
}
FreeConsole();
CreateThread(NULL, 0, EjectThread, NULL, 0, 0);
return false;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH) {// gets runned when injected
myhModule = hModule;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MainThread, NULL, 0, 0); // creates our main thread
return TRUE;
}
return FALSE;
}
说明:
When the dll is loaded we are creating an myhModule
variable to be able to assign to it the base address of our dll, then we Create a mainthread which will create a thread calling the ejectThread function which should unload the dll using myhModule
and the FreeLibraryAndExitThread
method当按下VK_DELETE
键时。
经历的步骤和错误:
所以我将我的 dll 注入到一个带有注入器的进程中,然后如果按下 Delete 键,它会卸载 dll,但是我收到一个访问冲突错误,告诉我我无法在 ZCD69B4957F0918080229 位置访问该进程。
错误:
Exception thrown at 0x1CD62194 in process.exe: 0xC0000005: Access violation executing location 0x1CD62194.
我在这里做错了什么,为什么会引发access violation
错误?
提前致谢。
当您从 DLL 创建线程时 - 当然,在线程运行时不得卸载 DLL。 您需要在创建线程之前添加对 DLL 的引用。 这可以通过调用GetModuleHandleExW
function 来完成。 当线程退出时——我们必须自由引用 DLL——这是通过FreeLibraryAndExitThread
完成的。 这需要为每个dll 线程做。
所以创建线程的代码通常必须是下一个
ULONG CreateThreadInDLL(PTHREAD_START_ROUTINE StartAddress, PVOID Parameter, PHANDLE phThread = 0, PDWORD pThreadId = 0)
{
HMODULE hModule;
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PCWSTR)StartAddress, &hModule))
{
if (HANDLE hThread = CreateThread(0, 0, StartAddress, Parameter, 0, pThreadId))
{
if (phThread) *phThread = hThread; else CloseHandle(hThread);
return NOERROR;
}
ULONG dwError = GetLastError();
FreeLibrary(hModule);
return dwError;
}
return GetLastError();
}
并且在线程结束时必须调用
FreeLibraryAndExitThread((HMODULE)&__ImageBase,0);
如果您想自行卸载 DLL - 通过CreateThread
直接创建线程,而不在它之前调用GetModuleHandleExW
并在线程结束时调用FreeLibraryAndExitThread
。
使用您的具体代码,您根本不需要EjectThread
,而是使用FreeLibraryAndExitThread((HMODUE)&__ImageBase,0);
从MainThread
退出并且不调用GetModuleHandleExW
(如果您创建几个额外的线程并且可以从主线程退出(使用 DLL 卸载)而无需等待此线程终止,则需要CreateThreadInDLL
)
DWORD WINAPI MainThread(LPVOID param) // our main thread
{
// do something...
FreeLibraryAndExitThread((HMODULE)&__ImageBase,0);
return 0; //never executed really
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH) {// gets runned when injected
myhModule = hModule;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MainThread, NULL, 0, 0); // creates our main thread
return TRUE;
}
return FALSE;
}
引用 RbMm 的回答:
当线程退出时——我们必须自由引用 DLL——这是通过 FreeLibraryAndExitThread 完成的。 这需要为每个 dll 线程做。
我认为发生的事情是,您的EjectThread
实际上成功卸载 DLL 并退出。 但是,此时您的MainThread
仍在运行,所以接下来会发生什么,它尝试执行其中一个 function 调用并使用 DLL 中的 memory 不再存在。 这会导致访问冲突。 我在自己的程序中遇到了同样的错误。 您需要做的是WaitForSingleObject
而不是使用 100 毫秒的超时。 不知何故(我不确定如何)它没有足够的时间让MainThread
退出。 也许是因为控制台?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.