So I have this 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.
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.
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?
Thanks in advance.
when you create thread from DLL - of course DLL must not be unloaded while thread running. you need add reference to DLL before create thread. this can be done via call GetModuleHandleExW
function. when thread is exit - we must free reference to DLL - this is done via FreeLibraryAndExitThread
. and this need do for every dll thread.
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
.
with your concrete code you not need EjectThread
at all, but exit from MainThread
with FreeLibraryAndExitThread((HMODUE)&__ImageBase,0);
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)
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:
when thread is exit - we must free reference to DLL - this is done via FreeLibraryAndExitThread. and this need do for every dll thread.
I think what happnes, is that your EjectThread
actually susccsessfully unloads DLL and exits. 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. 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. Somehow (I'm not sure how) its not enough time for MainThread
to exit. Maybe because of console?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.