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.
Related
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.
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.
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...
Goodday all,
I'm getting the following error:
First-chance exception at 0x67887AB7 (SDL2_mixer.dll) in Racing.exe: 0xC0000005: Access violation reading location 0xCCCCCCD4.
I think the problem could be with the pointer, but I'm not experienced enough in c++ to find it.
I'm hoping someone can tell me what I did wrong, and hopefully I can learn from it :)
Trying to call it from my gamebus.
Music Mus;
Mus.SpeelGeluid("crash");
Music class
bool Music::LoadMusic(){
//Load music
Mix_Music *gMusic = NULL;
gMusic = Mix_LoadMUS("MusicTest.wav");
Mix_PlayMusic(gMusic, -1);
bool success = true;
if (gMusic == NULL)
{
printf("Failed to load Music background song! SDL_mixer Error: %s\n", Mix_GetError());
success = false;
}
// Load sound effects
Mix_Chunk *gCrash = NULL;
gCrash = Mix_LoadWAV("Crash.wav");
if (gCrash == NULL)
{
printf("Failed to load scratch sound effect! SDL_mixer Error: %s\n", Mix_GetError());
success = false;
}
return success;
}
void Music::SpeelGeluid(string soundname){
cout << soundname << endl;
if (soundname == "crash")
{
try
{
Mix_PlayChannel(-1, gCrash, 0);
}
catch (int e)
{
cout << "An exception occurred. Exception Nr. " << e << '\n';
}
}
else
{
} }
Thank you for your time
You have two major problems:
First, you're using gMusic before checking whether it's NULL.
This may crash Mix_PlayMusic, and actually means that compilers may optimise out the later NULL check.
Second, and most likely the cause of your problem, you're declaring gCrash and gMusic as local variables in LoadMusic.
From the names, and your use of gCrash in SpeelGeluid, my educated guess is that you also have two global variables, or possibly member variables, with the same names where you intend to store the results of loading the files.
Your local variables are hiding these globals, and you're only modifying the local variables.
Remove the lines
Mix_Music *gMusic = NULL;
and
Mix_Chunk *gCrash = NULL;
to get rid of these local variables.
And do initialise the globals to NULL when you define them.
Check your pointers as soon as you've allocated them and handle them appropriately. You nearly do:
gMusic = Mix_LoadMUS("MusicTest.wav");
Mix_PlayMusic(gMusic, -1); // <- You're using the pointer here before you check it
bool success = true;
if (gMusic == NULL) // <- this needs to be immediately after assignment
That's just from the code you've pointed. It's also possible you've missed a generic initialisation call from the SDL2_mixer.dll.
Do debug it and step through line by line so you know which bit is causing the error.
I have a version resource in my resources in a C++ project which contains version number, copyright and build details. Is there an easy way to access this at run-time to populate my help/about dialog as I am currently maintaining seperate const values of this information. Ideally, the solution should work for Windows/CE mobile and earlier versions of Visual C++ (6.0 upwards).
This is an edited version of my original answer.
bool GetProductAndVersion(CStringA & strProductName, CStringA & strProductVersion)
{
// get the filename of the executable containing the version resource
TCHAR szFilename[MAX_PATH + 1] = {0};
if (GetModuleFileName(NULL, szFilename, MAX_PATH) == 0)
{
TRACE("GetModuleFileName failed with error %d\n", GetLastError());
return false;
}
// allocate a block of memory for the version info
DWORD dummy;
DWORD dwSize = GetFileVersionInfoSize(szFilename, &dummy);
if (dwSize == 0)
{
TRACE("GetFileVersionInfoSize failed with error %d\n", GetLastError());
return false;
}
std::vector<BYTE> data(dwSize);
// load the version info
if (!GetFileVersionInfo(szFilename, NULL, dwSize, &data[0]))
{
TRACE("GetFileVersionInfo failed with error %d\n", GetLastError());
return false;
}
// get the name and version strings
LPVOID pvProductName = NULL;
unsigned int iProductNameLen = 0;
LPVOID pvProductVersion = NULL;
unsigned int iProductVersionLen = 0;
// replace "040904e4" with the language ID of your resources
if (!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductName"), &pvProductName, &iProductNameLen) ||
!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
{
TRACE("Can't obtain ProductName and ProductVersion from resources\n");
return false;
}
strProductName.SetString((LPCSTR)pvProductName, iProductNameLen);
strProductVersion.SetString((LPCSTR)pvProductVersion, iProductVersionLen);
return true;
}
To get a language independent result to Mark's answer change :
// replace "040904e4" with the language ID of your resources
!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
{
TRACE("Can't obtain ProductName and ProductVersion from resources\n");
return false;
}
To
UINT uiVerLen = 0;
VS_FIXEDFILEINFO* pFixedInfo = 0; // pointer to fixed file info structure
// get the fixed file info (language-independent)
if(VerQueryValue(&data[0], TEXT("\\"), (void**)&pFixedInfo, (UINT *)&uiVerLen) == 0)
{
return false;
}
strProductVersion.Format("%u.%u.%u.%u",
HIWORD (pFixedInfo->dwProductVersionMS),
LOWORD (pFixedInfo->dwProductVersionMS),
HIWORD (pFixedInfo->dwProductVersionLS),
LOWORD (pFixedInfo->dwProductVersionLS));
Something like might get you started, perhaps:
TCHAR moduleName[MAX_PATH+1];
(void)GetModuleFileName(AfxGetInstanceHandle(), moduleName, MAX_PATH);
DWORD dummyZero;
DWORD versionSize = GetFileVersionInfoSize(moduleName, &dummyZero);
if(versionSize == 0)
{
return NULL;
}
void* pVersion = malloc(versionSize);
if(pVersion == NULL)
{
return NULL;
}
if(!GetFileVersionInfo(moduleName, NULL, versionSize, pVersion))
{
free(pVersion);
return NULL;
}
UINT length;
VS_FIXEDFILEINFO* pFixInfo;
VERIFY(VerQueryValue(pVersionInfo, const_cast<LPTSTR>("\\"), (LPVOID*)&pFixInfo, &length));
Something like this will give you raw access to the resource data and get you started:
HRSRC res = ::FindResource(NULL, MAKEINTRESOURCE(MY_VERSION_ID), RT_VERSION);
DWORD size = ::SizeofResource(NULL, res);
HGLOBAL mem = ::LoadResource(NULL, res);
LPVOID raw_data = ::LockResource(mem);
...
::FreeResource(mem);
Beware!
Using FindResource..LockResource is not correct. It will sometimes work (as it did in my small demo program) and sometimes cause access violations (example: the production code I was making the demo for).
The VerQueryValue() documentation states that you should call GetFileVersionInfoSize and GetFileVersionInfo instead.
Raymond Chen explains, see http://blogs.msdn.com/oldnewthing/archive/2006/12/26/1365215.aspx
Ok, a bit more googleing found the following on CodeGuru. Basically this approach uses the CFileVersionInfo object to get on any given file. It should be interesting to see if it works on the currently running .EXE file and on Windows CE.
Sometimes I receive Access Violation when use VerQueryValueA. But I never got this error when use VerQueryValueW. I think something wrong with VerQueryValueA in version.dll. Therefore I use VerQueryValueW instead of VerQueryValueA even in projects Multi-byte Character Encoding. Here is my code of ReadVersion function