Skip to content
Snippets Groups Projects
Commit 591c1863 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Made SharedLibraryInjector compile with MinGW.

parent e0de0119
No related branches found
No related tags found
No related merge requests found
...@@ -56,6 +56,12 @@ ...@@ -56,6 +56,12 @@
#include <QtCore/QDebug> #include <QtCore/QDebug>
#ifdef __GNUC__ // MinGW does not have a complete windows.h
typedef DWORD (__stdcall *PTHREAD_START_ROUTINE) (LPVOID lpThreadParameter);
#endif
enum { debug = 0 }; enum { debug = 0 };
static QString msgFuncFailed(const char *f, unsigned long error) static QString msgFuncFailed(const char *f, unsigned long error)
...@@ -68,7 +74,7 @@ template <class SymbolType> ...@@ -68,7 +74,7 @@ template <class SymbolType>
inline bool resolveSymbol(const char *libraryName, HMODULE libraryHandle, const char *symbolName, SymbolType *s, QString *errorMessage) inline bool resolveSymbol(const char *libraryName, HMODULE libraryHandle, const char *symbolName, SymbolType *s, QString *errorMessage)
{ {
*s = 0; *s = 0;
void *vs = ::GetProcAddress(libraryHandle, symbolName); FARPROC WINAPI vs = ::GetProcAddress(libraryHandle, symbolName);
if (vs == 0) { if (vs == 0) {
*errorMessage = QString::fromLatin1("Unable to resolve '%2' in '%1'.").arg(QString::fromAscii(symbolName), QString::fromAscii(libraryName)); *errorMessage = QString::fromLatin1("Unable to resolve '%2' in '%1'.").arg(QString::fromAscii(symbolName), QString::fromAscii(libraryName));
return false; return false;
...@@ -158,29 +164,29 @@ bool SharedLibraryInjector::hasLoaded(const QString &modulePath) ...@@ -158,29 +164,29 @@ bool SharedLibraryInjector::hasLoaded(const QString &modulePath)
QString SharedLibraryInjector::findModule(const QString &moduleName) QString SharedLibraryInjector::findModule(const QString &moduleName)
{ {
const TCHAR *moduleNameC = moduleName.utf16(); const TCHAR *moduleNameC = reinterpret_cast<const TCHAR*>(moduleName.utf16());
if (GetFileAttributesW(moduleNameC) != INVALID_FILE_ATTRIBUTES) if (GetFileAttributesW(moduleNameC) != INVALID_FILE_ATTRIBUTES)
return moduleName; return moduleName;
TCHAR testpathC[MAX_PATH]; TCHAR testpathC[MAX_PATH];
// Check application path first // Check application path first
GetModuleFileNameW(NULL, testpathC, MAX_PATH); GetModuleFileNameW(NULL, testpathC, MAX_PATH);
QString testPath = QString::fromUtf16(testpathC); QString testPath = QString::fromUtf16(reinterpret_cast<unsigned short*>(testpathC));
const int lastSlash = testPath.lastIndexOf(QLatin1Char('\\')); const int lastSlash = testPath.lastIndexOf(QLatin1Char('\\'));
if (lastSlash != -1) if (lastSlash != -1)
testPath.truncate(lastSlash + 1); testPath.truncate(lastSlash + 1);
testPath += moduleName; testPath += moduleName;
if (GetFileAttributesW(testPath.utf16()) != INVALID_FILE_ATTRIBUTES) if (GetFileAttributesW(reinterpret_cast<const TCHAR*>(testPath.utf16())) != INVALID_FILE_ATTRIBUTES)
return testPath; return testPath;
// Path Search // Path Search
if (SearchPathW(NULL, moduleName.utf16(), NULL, sizeof(testpathC)/2, testpathC, NULL)) if (SearchPathW(NULL, reinterpret_cast<const TCHAR*>(moduleName.utf16()), NULL, sizeof(testpathC)/2, testpathC, NULL))
return QString::fromUtf16(testpathC); return QString::fromUtf16(reinterpret_cast<unsigned short*>(testpathC));
// Last chance, if the module has already been loaded in this process, then use that path // Last chance, if the module has already been loaded in this process, then use that path
const HMODULE loadedModule = GetModuleHandleW(moduleName.utf16()); const HMODULE loadedModule = GetModuleHandleW(reinterpret_cast<const TCHAR*>(moduleName.utf16()));
if (loadedModule) { if (loadedModule) {
GetModuleFileNameW(loadedModule, testpathC, sizeof(testpathC)); GetModuleFileNameW(loadedModule, testpathC, sizeof(testpathC));
if (GetFileAttributes(testpathC) != INVALID_FILE_ATTRIBUTES) if (GetFileAttributes(testpathC) != INVALID_FILE_ATTRIBUTES)
return QString::fromUtf16(testpathC); return QString::fromUtf16(reinterpret_cast<unsigned short*>(testpathC));
} }
return QString(); return QString();
} }
...@@ -188,13 +194,13 @@ QString SharedLibraryInjector::findModule(const QString &moduleName) ...@@ -188,13 +194,13 @@ QString SharedLibraryInjector::findModule(const QString &moduleName)
unsigned long SharedLibraryInjector::getModuleEntryPoint(const QString &moduleName) unsigned long SharedLibraryInjector::getModuleEntryPoint(const QString &moduleName)
{ {
// If file doesn't exist, just treat it like we cannot figure out the entry point // If file doesn't exist, just treat it like we cannot figure out the entry point
if (moduleName.isEmpty() || GetFileAttributesW(moduleName.utf16()) == INVALID_FILE_ATTRIBUTES) if (moduleName.isEmpty() || GetFileAttributesW(reinterpret_cast<const TCHAR*>(moduleName.utf16())) == INVALID_FILE_ATTRIBUTES)
return 0; return 0;
// Read the first 1K of data from the file // Read the first 1K of data from the file
unsigned char peData[1024]; unsigned char peData[1024];
unsigned long peDataSize = 0; unsigned long peDataSize = 0;
const HANDLE hFile = CreateFileW(moduleName.utf16(), FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); const HANDLE hFile = CreateFileW(reinterpret_cast<const WCHAR*>(moduleName.utf16()), FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE if (hFile == INVALID_HANDLE_VALUE
|| !ReadFile(hFile, peData, sizeof(peData), &peDataSize, NULL)) || !ReadFile(hFile, peData, sizeof(peData), &peDataSize, NULL))
return 0; return 0;
...@@ -236,7 +242,7 @@ bool SharedLibraryInjector::escalatePrivileges(QString *errorMessage) ...@@ -236,7 +242,7 @@ bool SharedLibraryInjector::escalatePrivileges(QString *errorMessage)
Debug_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // set to enable privilege Debug_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // set to enable privilege
Debug_Privileges.PrivilegeCount = 1; // working with only 1 Debug_Privileges.PrivilegeCount = 1; // working with only 1
if (!OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
*errorMessage = msgFuncFailed("OpenProcessToken", GetLastError()); *errorMessage = msgFuncFailed("OpenProcessToken", GetLastError());
break; break;
} }
...@@ -289,8 +295,8 @@ bool SharedLibraryInjector::doStubInjection(unsigned long pid, ...@@ -289,8 +295,8 @@ bool SharedLibraryInjector::doStubInjection(unsigned long pid,
if (!escalatePrivileges(errorMessage)) if (!escalatePrivileges(errorMessage))
return false; return false;
// MinGW lacks OpenThread() and the advapi.lib as of 6.5.2009
#if (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) #if (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) || defined(__GNUC__)
*errorMessage = QLatin1String("Not implemented for this architecture."); *errorMessage = QLatin1String("Not implemented for this architecture.");
return false; return false;
#else #else
...@@ -462,7 +468,7 @@ HMODULE SharedLibraryInjector::findModuleHandle(const QString &modulePath, QStri ...@@ -462,7 +468,7 @@ HMODULE SharedLibraryInjector::findModuleHandle(const QString &modulePath, QStri
for (unsigned i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
TCHAR szModName[MAX_PATH]; TCHAR szModName[MAX_PATH];
if (m_pfnGetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName))) { if (m_pfnGetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName))) {
if (QString::fromUtf16(szModName) == modulePath) { if (QString::fromUtf16(reinterpret_cast<const unsigned short *>(szModName)) == modulePath) {
::FreeLibrary(m_hModPSAPI); ::FreeLibrary(m_hModPSAPI);
::CloseHandle(hProcess); ::CloseHandle(hProcess);
return hMods[i]; return hMods[i];
......
...@@ -7,5 +7,8 @@ HEADERS += $$PWD/peutils.h \ ...@@ -7,5 +7,8 @@ HEADERS += $$PWD/peutils.h \
$$PWD/dbgwinutils.h \ $$PWD/dbgwinutils.h \
$$PWD/sharedlibraryinjector.h $$PWD/sharedlibraryinjector.h
# For the Privilege manipulation functions in sharedlibraryinjector.cpp contains(QMAKE_CXX, cl) {
LIBS += advapi32.lib # For the Privilege manipulation functions in sharedlibraryinjector.cpp.
# Not required for MinGW.
LIBS += advapi32.lib
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment