force unload modules of a process - c++

I want to unload some module in a process .
I use this function :
bool UnInjectDll(const TCHAR* ptszDllFile, DWORD dwProcessId)
{
if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))
{
return false;
}
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (INVALID_HANDLE_VALUE == hModuleSnap)
{
return false;
}
MODULEENTRY32 me32;
memset(&me32, 0, sizeof(MODULEENTRY32));
me32.dwSize = sizeof(MODULEENTRY32);
if(FALSE == ::Module32First(hModuleSnap, &me32))
{
::CloseHandle(hModuleSnap);
return false;
}
bool isFound = false;
do
{
isFound = (0 == ::_tcsicmp(me32.szModule, ptszDllFile) || 0 == ::_tcsicmp(me32.szExePath, ptszDllFile));
if (isFound)
{
break;
}
} while (TRUE == ::Module32Next(hModuleSnap, &me32));
::CloseHandle(hModuleSnap);
if (false == isFound)
{
return false;
}
hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, FALSE, dwProcessId);
if (NULL == hProcess)
{
return false;
}
LPTHREAD_START_ROUTINE lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "FreeLibrary");
if (NULL == lpThreadFun)
{
::CloseHandle(hProcess);
return false;
}
hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, me32.modBaseAddr , 0, NULL);
if (NULL == hThread)
{
::CloseHandle(hProcess);
return false;
}
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
::CloseHandle(hProcess);
return true;
}
But when I use this code it can not special module that I want to unload from project.
I also use "process detective" tool for doing this but this tool can not do this also.
Now I want a function that I can be sure will unload a special module from a process I want. for example you create a simple program that only show a messagebox , now if you see the modules of it's process , it has a module ntdll.dll and some other modules , now you can not remove ntdll.dll module or some other module from it. i want a function to force a process to remove any module from process I want.

What your are trying to do is utterly dangerous (and as of my knowledge, luckily, not possible).
Your program or library is linked against certain other DLLs. These libraries in return are referencing others as well, and so on, and so on. When your program or DLL is loaded into memory space by the loader of Windows, these "dependencies" will be loaded also and your import address tables will be patched so that your calls know where to jump when they are to be executed. All of your code will be hard-wired together as an atomic entity.
Unloading a DLL that has been statically linked in that manner (.dlls files can be linked statically also, not to be confused with static .lib files) basically forces your application to crash the second any call is made that depends on that libarary - especially the ntdll.dll which will be the root of most of all the libs you linked against. The calls will be thrown into the void. These libraries cannot be unloaded because they are in a sense part of your program.
If you however loaded a library dynamically at runtime, you are free to unload it any time you want. Since you are probably working via dynamic addresses using GetProcAddress anyway, it is up to you to make sure that your function pointers have a valid target.
You can take a hat on and off any way you desire, but you can't (and shouldn't) rip out your heart ;)
It doesn't fully answer your question though I know, but although this is just a warning that you never should do this without a very very good reason (which I don't know you really have), I am quite positive that you can't do what you are asking - but I am happy to let other people correct me here.
If you want to do something to the loaded libraries, and you are already on this destructive course, just overwrite the library or IATs in memory directly. You can go in with a crowbar, sure, but I don't think you will achive what you are looking for...

Related

Access violation error with injected dll C++

So recently I made my own dll injector to be able to debug my other app by injecting a debug dll in it; Using c++/cli for the interface and c++ for the code.
I tested the same code I used on this project on a C++ console app project and it worked without any problems.
The injection occurs inside the Init.cpp file, which essentially gets the provided dll path under the form of C:\\user\\documents\\debug.dll and checks if it exists. After that it gets the process id by passing the name, in this case myotherapp.exe, as a parameter. If successful it then get's the Handle to the process and store's it in g.h_process, it continues by allocating readable/writable memory in the process and then writing to this memory the path of the dll and finally use's LoadLibraryA to load the dll inside the process.
Init.cpp:
void Injector::Init(void)
{
Inject::Checks((char*)g.dll_path, g.procName);//checking for dll validity
}
bool Injector::Inject::Checks(char* dll_path, PCSTR procName)
{
if (!Utils::file_exists(dll_path))
return Utils::error("File does not exist.");
Utils::successInput("Prepared DLL for injection");
Utils::getProcId(procName, g.proc_id);
if (!g.proc_id) {
return Utils::error("Could not find specified process.");
}
g.h_process = OpenProcess(PROCESS_ALL_ACCESS, NULL, g.proc_id);
if (!g.h_process) {
return Utils::error("Failed to open a handle to process");
}
g.allocatedMemory = VirtualAllocEx(g.h_process, nullptr, MAX_PATH, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);//mem_reserver reserve memory then commit memory to be able to write to that memory
Allocate(g.allocatedMemory, dll_path);
Llib();
Release(dll_path, g.allocatedMemory);
return 0;
}
bool Injector::Inject::Allocate(void* allocatedMemory, char* dll_path)
{
if (!allocatedMemory)
return Utils::error("Failed to allocate memory");
if (!WriteProcessMemory(g.h_process, g.allocatedMemory, g.dll_path, MAX_PATH, nullptr))
return Utils::error("Failed to write process");
return true;
}
bool Injector::Inject::Llib() {
HANDLE h_thread = CreateRemoteThread(g.h_process, nullptr, NULL, LPTHREAD_START_ROUTINE(LoadLibraryA), g.allocatedMemory, NULL, nullptr);
if (!h_thread)
return Utils::error("Failed to create remote thread");
return true;
}
bool Injector::Inject::Release(PCSTR dll_path, void* allocatedMemory)
{
CloseHandle(g.h_process);
VirtualFreeEx(g.h_process, allocatedMemory, NULL, MEM_RELEASE);
return true;
}
The g.debug is just a flag which tells us if the console is enabled or not. found in the globals.hpp which just contains global variables.
You can also check the Utils namespace here.
The error:
The problem I'm experiencing here is whenever I inject my DLL into the process, my injector works fine with no errors but when I attach vs to the process I want to inject to I get an Access Violation error with the process exiting with an error code.
I don't understand, I can't see where I am accessing invalid memory.
Thanks in advance.

Ejecting dll by calling CreateRemoteThread : crash

I am trying to make for myself a tool for extracting/releasing dlls from processes. I have already experienced with LoadLibrary and injecting but this time the logic doesn't seem to apply.
This is my code:
HMODULE findModuleOffset(HANDLE proc, char *mod_name) {
//Finds module address in specified process. 0 if not found
HMODULE hMods[2048];
DWORD modules_byte_size;
if (EnumProcessModules(proc, hMods, sizeof(hMods), &modules_byte_size))
{
for (unsigned long i = 0; i < (modules_byte_size / sizeof(HMODULE)); i++) {
CHAR module_name[MAX_PATH];
// Get the full path to the module's file.
if (GetModuleFileNameExA(proc, hMods[i], module_name, sizeof(module_name))) {
if (strcmp(strrchr(module_name,'.')+1,"exe")!=0 && compareExeName(module_name, mod_name)) {
return hMods[i];
}
}
}
}
return 0;
}
bool compareExeName(char *path, char *partial_name) {
//This will substract the filename from path and compare it with partial_name
char *lastSlash = strrchr(path, '\\') + 1;
if (lastSlash != NULL && strstr(lastSlash, partial_name) == lastSlash) return 1;
return 0;
}
void unload_all_dll(char *dll_name) {
DWORD process_ids[2048];
DWORD process_byte_size; //size of filled process_ids in BYTES (after the call)
DWORD process_count; //count of all elements in process_ids
HMODULE ext_dll_module;
HANDLE opened_process;
HANDLE Hthread;
DWORD thread_exit_code = 1;
CHAR exe_path[1024];
if (EnumProcesses(process_ids, sizeof(process_ids), &process_byte_size)) {
process_count = process_byte_size / sizeof(DWORD);
for (int i = 0; i < process_count; i++) {
thread_exit_code = 0;
if ((opened_process = OpenProcess(PROCESS_ALL_ACCESS, false, process_ids[i])) == NULL) continue;
GetModuleFileNameExA(opened_process, 0, exe_path, MAX_PATH);
if ((ext_dll_module = findModuleOffset(opened_process, dll_name)) != 0) {
while (thread_exit_code == 0) {
if ((Hthread = CreateRemoteThread(opened_process, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary"), (void*)ext_dll_module, 0, NULL)) == NULL) {
cout<<"Process closed meanwhile or dll unloaded";
break; //process has closed meanwhile
}
while (WaitForSingleObject(Hthread, 1000) == WAIT_TIMEOUT);
GetExitCodeThread(Hthread, &thread_exit_code);
}
cout << "Dll unloaded from " << exe_path << endl;
}
}
}
}
Warning:some variables names might be confusing(I am in hurry)
But every time I try to eject a dll everything crashes(of course,only the apps that contained the specfied dll). I tested everything I could and everything seems fine: the module address returned by findModuleOffset is good(checked against the value given by process explorer). I have no ideea what the return value of createremotethread or thread_exit_code is because the app crashes(it contasins the dll to be ejected..so...). Can you help me?
(moving from the comments)
Given that there are threads in the target process that are running code from the dll being unloaded, they are going to crash immediately after the dll gets freed - after all, the very pages of code that the CPU is executing are being unmapped!
To avoid the problem, the running threads have to be notified in some way, so they can terminate before unloading the dll; Windows provides many IPC methods, one rarely used is particularly well-fitted for this case, namely mailslots.
When the dll is injected, the "master" thread that gets created will create a mailslot with a well-known name, and periodically check if there's any message for him. When you want to unload the dlls, instead of brutally injecting a thread that forcefully frees the dll, just ask to your "inside man": post a message to the mailslot asking it to terminate1.
The thread will see that there's a message in the mailslot, take care to possibly terminate the other threads that were started inside the target process (a shared atomic variable + WaitForSingleObject can be used) and, when the cleanup is finished, call FreeLibraryAndExitThread to suicide both the last thread and the dll.
Notes
A particularly interesting peculiarity of mailslots is that, if they are created multiple times with the same name, messages sent to such a name will be delivered to all them, so if, as it seems, you want to shut down all the injected dlls at the same time, this greatly simplifies the controlling program - there's not even need to enumerate the running processes.

Can i block a program using ASM?

I am trying for a few days to block a cheat program for my game, i talked with several coders, and one said i can block it using ASM. The program hides very good, i cannot find it in memory, i cannot detect it scanning processes, so maybe this could be the solution? Can someone give me a example how can i detect and block a program with c++ and ASM?
This is my current method to detect and block cheats, using memory dumps:
void SystemProcessesScan()
{
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hProcessSnap, &pe32))
{
do
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(hProcess != NULL)
{
if(ScanProcessMemory(hProcess))
{
ExitProcess(0);
}
}
}
while(Process32Next(hProcessSnap, &pe32));
}
}
CloseHandle(hProcessSnap);
}
bool ScanProcessMemory(HANDLE hProcess)
{
for(int i = 0; i < MAX_PROCESS_DUMP; i++)
{
char aTmpBuffer[MAX_DUMP_SIZE];
SIZE_T aBytesRead = 0;
ReadProcessMemory(hProcess, (LPCVOID)g_ProcessesDumps[i].m_aOffset, (LPVOID)aTmpBuffer, sizeof(aTmpBuffer), &aBytesRead);
if(memcmp(aTmpBuffer, g_ProcessesDumps[i].m_aMemDump, MAX_DUMP_SIZE) == 0)
{
return true;
break;
}
}
return false;
}
The cheat injects a DLL into your game and it sounds like it uses manual mapping to hide the DLL in memory.
The best solution to detect it is to find a sequence of bytes that are unique to this DLL. Pattern scan your own game processes, if the signature is found, close the game or whatever you want to do at that point.
Search for C++ internal pattern scanning or signature scanning, there are dozens of sources floating around that are uses regularly for this purpose.
Due to it being manually mapped, you must scan all committed memory regions rather than looping through the list of modules. Use VirtualQuery() in a while loop starting with address 0 until it fails.

FreeLibrary() Access Violation

Follwing Code should scan a directory with .dll for Plugin containers. If it encounters a non-Container .dll, it crashes at the given location with an Access Violation Exception
(Execution at 0x00000000). I am pretty sure that this is not a overflow error or similar because it is freed right after being loaded. I can guarantee there is not a single call of the dll's function. Only the GetProcAddress trying to figure out my entry point to the Plugin discovery.
What else can go wrong here? Could it be that im freeing a module that one of my plugin-dll's is internally linking to? If so, how could I detect this is the case, and opt for not calling FreeLibrary in this case?
string filePathStr (path);
string fileSearchKey = filePathStr + "\\*.dll";
WIN32_FIND_DATAA fd;
HMODULE hmod;
bool bFirstRun = true;
bool bFinishedRun = false;
HANDLE h = INVALID_HANDLE_VALUE;
printf("\r\n");
while (!bFinishedRun)
{
if (bFirstRun)
{
h = FindFirstFileA(fileSearchKey.c_str(), &fd);
bFirstRun = false;
} else
{
if (FindNextFileA(h, &fd) == FALSE) bFinishedRun = true;
}
if (!SetDllDirectoryA(filePathStr.c_str())) break;
hmod = LoadLibraryA(fd.cFileName);
if (!hmod) continue;
rpiRegisterPluginsCall prpiRegisterPlugins = reinterpret_cast<rpiRegisterPluginsCall>(GetProcAddress(hmod, "_rpiRegisterPlugins#4"));
if (prpiRegisterPlugins == NULL)
{
FreeLibrary(hmod); // Access violation
continue;
}
if (prpiRegisterPlugins(this) != 0)
{
FreeLibrary(hmod);
continue;
}
m_loaded.push_back((unsigned long long)hmod);
}
Edit:
Apparently there is only one offending .dll in many non-containers (deleted that one and it works). So I am opting for the explanation that something goes wrong in dllmain.

How do I find out if a .exe is running in c++?

How can you find out if an executable is running on Windows given the process name, e.g. program.exe?
The C++ standard library has no such support. You need an operating system API to do this. If this is Windows then you'd use CreateToolhelp32Snapshot(), followed by Process32First and Process32Next to iterate the running processes. Beware of the inevitable race condition, the process could have exited by the time you found it.
I just created one using Hans suggestion. Works like a champ!
Oh and here is the basic code.
Please you will have to add CStrings sAppPath and sAppName.
StartProcess is a small function that uses CreateProcess and returns the PID(not used here). You will need to replace it.
This is not a complete program, just the code to find if the program is running using Hans suggestion. A fun test is to set the path to c:\windows\ and the app to notepad.exe and set it for 10 seconds.
#include <tlhelp32.h>
PROCESSENTRY32 pe32 = {0};
HANDLE hSnap;
int iDone;
int iTime = 60;
bool bProcessFound;
while(true) // go forever
{
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe32.dwSize = sizeof(PROCESSENTRY32);
Process32First(hSnap,&pe32); // Can throw away, never an actual app
bProcessFound = false; //init values
iDone = 1;
while(iDone) // go until out of Processes
{
iDone = Process32Next(hSnap,&pe32);
if (strcmp(pe32.szExeFile,sAppName) == 0) // Did we find our process?
{
bProcessFound = true;
iDone = 0;
}
}
if(!bProcessFound) // if we didn't find it running...
{
startProcess(sAppPath+sAppName,""); // start it
}
Sleep(iTime*1000); // delay x amount of seconds.
}
Assumptions: since you mention '.exe', you want this for some flavor of Windows. You want to write a program in C++ to determine whether a program with a particular executable name is running (regardless of the language used to implement the target program).
Enumerate the running processes using either the Toolhelp API or the process status API. Compare the name of the executable for each running process to the one you're looking for (and be aware that there may be more than one process with that executable name).
hProcessInfo = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );
do{
if(strcmp(pe32.szExeFile,"process.exe") == 0)
{
processfound = true;
break;
}
}while( Process32Next( hProcessSnap, &pe32 ) );
If you don't want to get process detail from code just press Ctrl+Alt+Del and check process list.