[英]Unloading dll throws an Access violation error
So I have this dll:所以我有这个 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;
}
Explanation :说明:
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 when the VK_DELETE
key is pressed. 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
键时。
Steps and error experienced :经历的步骤和错误:
So I'm injecting my dll inside a process with an injector, then if the Delete key is pressed it unloads the dll, however I get an access violation error telling me that I cannot access the process at a memory location.所以我将我的 dll 注入到一个带有注入器的进程中,然后如果按下 Delete 键,它会卸载 dll,但是我收到一个访问冲突错误,告诉我我无法在 ZCD69B4957F0918080229 位置访问该进程。
Error :错误:
Exception thrown at 0x1CD62194 in process.exe: 0xC0000005: Access violation executing location 0x1CD62194.
What did I do wrong here, why does it throw an access violation
error?我在这里做错了什么,为什么会引发access violation
错误?
Thanks in advance.提前致谢。
when you create thread from DLL - of course DLL must not be unloaded while thread running.当您从 DLL 创建线程时 - 当然,在线程运行时不得卸载 DLL。 you need add reference to DLL before create thread.您需要在创建线程之前添加对 DLL 的引用。 this can be done via call GetModuleHandleExW
function.这可以通过调用GetModuleHandleExW
function 来完成。 when thread is exit - we must free reference to DLL - this is done via FreeLibraryAndExitThread
.当线程退出时——我们必须自由引用 DLL——这是通过FreeLibraryAndExitThread
完成的。 and this need do for every dll thread.这需要为每个dll 线程做。
so code for create thread in general must be next所以创建线程的代码通常必须是下一个
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();
}
and in the end of thread must be call to并且在线程结束时必须调用
FreeLibraryAndExitThread((HMODULE)&__ImageBase,0);
if you want self unload DLL - create thread direct via CreateThread
without call GetModuleHandleExW
before it and in the end of thread call FreeLibraryAndExitThread
.如果您想自行卸载 DLL - 通过CreateThread
直接创建线程,而不在它之前调用GetModuleHandleExW
并在线程结束时调用FreeLibraryAndExitThread
。
with your concrete code you not need EjectThread
at all, but exit from MainThread
with FreeLibraryAndExitThread((HMODUE)&__ImageBase,0);
使用您的具体代码,您根本不需要EjectThread
,而是使用FreeLibraryAndExitThread((HMODUE)&__ImageBase,0);
从MainThread
退出and not call GetModuleHandleExW
( CreateThreadInDLL
need if you create several additional threads and can exit from main thread (with DLL unload) without wait on this thread termination)并且不调用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;
}
Quouting RbMm's answer:引用 RbMm 的回答:
when thread is exit - we must free reference to DLL - this is done via FreeLibraryAndExitThread.当线程退出时——我们必须自由引用 DLL——这是通过 FreeLibraryAndExitThread 完成的。 and this need do for every dll thread.这需要为每个 dll 线程做。
I think what happnes, is that your EjectThread
actually susccsessfully unloads DLL and exits.我认为发生的事情是,您的EjectThread
实际上成功卸载 DLL 并退出。 BUT, you MainThread
is still running at this time, So what happens next, it tries to do one of it's function calls and uses memory from DLL that no longer exists.但是,此时您的MainThread
仍在运行,所以接下来会发生什么,它尝试执行其中一个 function 调用并使用 DLL 中的 memory 不再存在。 which causes access violation.这会导致访问冲突。 I had same error in my own program.我在自己的程序中遇到了同样的错误。 What you need to do is WaitForSingleObject
instead of using timeout of 100 ms.您需要做的是WaitForSingleObject
而不是使用 100 毫秒的超时。 Somehow (I'm not sure how) its not enough time for MainThread
to exit.不知何故(我不确定如何)它没有足够的时间让MainThread
退出。 Maybe because of console?也许是因为控制台?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.