Page MenuHomedesp's stash

No OneTemporary

diff --git a/Plugins/ImpRec_Plugins/Imprec_Wrapper_DLL.dll b/Plugins/ImpRec_Plugins/Imprec_Wrapper_DLL.dll
new file mode 100644
index 0000000..6cd85b2
Binary files /dev/null and b/Plugins/ImpRec_Plugins/Imprec_Wrapper_DLL.dll differ
diff --git a/Plugins/ImpRec_Plugins/PECompact 2.7.x.dll b/Plugins/ImpRec_Plugins/PECompact 2.7.x.dll
new file mode 100644
index 0000000..13f044a
Binary files /dev/null and b/Plugins/ImpRec_Plugins/PECompact 2.7.x.dll differ
diff --git a/Plugins/Include_Headers/ScyllaPlugin.h b/Plugins/Include_Headers/ScyllaPlugin.h
new file mode 100644
index 0000000..3aad3f4
--- /dev/null
+++ b/Plugins/Include_Headers/ScyllaPlugin.h
@@ -0,0 +1,46 @@
+
+#include <windows.h>
+
+const char FILE_MAPPING_NAME[] = "ScyllaPluginExchange";
+
+#define SCYLLA_STATUS_SUCCESS 0
+#define SCYLLA_STATUS_UNKNOWN_ERROR 1
+#define SCYLLA_STATUS_UNSUPPORTED_PROTECTION 2
+#define SCYLLA_STATUS_IMPORT_RESOLVING_FAILED 3
+#define SCYLLA_STATUS_MAPPING_FAILED 0xFF
+
+/* Important note:
+ *
+ * If you write a plugin for the x86 (32-Bit) edition: DWORD_PTR address has 32 bit (4 byte)
+ * If you write a plugin for the x64 (64-Bit) edition: DWORD_PTR address has 64 bit (8 byte)
+ */
+typedef struct _UNRESOLVED_IMPORT { // Scylla Plugin exchange format
+ DWORD_PTR ImportTableAddressPointer; //in VA, address in IAT which points to an invalid api address
+ DWORD_PTR InvalidApiAddress; //in VA, invalid api address that needs to be resolved
+} UNRESOLVED_IMPORT, *PUNRESOLVED_IMPORT;
+
+typedef struct _SCYLLA_EXCHANGE {
+ BYTE status; //return a status, default 0xFF == SCYLLA_STATUS_MAPPING_FAILED
+ DWORD_PTR imageBase; //image base
+ DWORD_PTR imageSize; //size of the image
+ DWORD_PTR numberOfUnresolvedImports; //number of unresolved imports in this structure
+ BYTE offsetUnresolvedImportsArray;
+} SCYLLA_EXCHANGE, *PSCYLLA_EXCHANGE;
+
+
+
+#define DllExport __declspec(dllexport)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef UNICODE
+ DllExport wchar_t * __cdecl ScyllaPluginNameW();
+#else
+ DllExport char * __cdecl ScyllaPluginNameA();
+#endif
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/Plugins/PECompact.dll b/Plugins/PECompact.dll
new file mode 100644
index 0000000..667e26d
Binary files /dev/null and b/Plugins/PECompact.dll differ
diff --git a/Plugins/PESpin_x64_v1.dll b/Plugins/PESpin_x64_v1.dll
new file mode 100644
index 0000000..092e2c3
Binary files /dev/null and b/Plugins/PESpin_x64_v1.dll differ
diff --git a/Plugins/Sources/Imprec_Wrapper_DLL.cpp b/Plugins/Sources/Imprec_Wrapper_DLL.cpp
new file mode 100644
index 0000000..cf8a5fb
--- /dev/null
+++ b/Plugins/Sources/Imprec_Wrapper_DLL.cpp
@@ -0,0 +1,373 @@
+#include "ScyllaPlugin.h"
+
+//remove c runtime library
+//#pragma comment(linker, "/ENTRY:DllMain")
+
+//typedef DWORD (__stdcall * def_ImpREC_TraceSTD)(DWORD hFileMap, DWORD dwSizeMap, DWORD dwTimeOut, DWORD dwToTrace, DWORD dwExactCall);
+//typedef DWORD (__cdecl * def_ImpREC_TraceCDE)(DWORD hFileMap, DWORD dwSizeMap, DWORD dwTimeOut, DWORD dwToTrace, DWORD dwExactCall);
+typedef DWORD (* def_voidFunction)();
+
+#define PLUGIN_IMPREC_EXCHANGE_DLL_PATH "ScyllaImprecPluginExchangePath"
+#define PLUGIN_MAPPING_NAME "Imprec_plugin_exchanging"
+
+const char logFileName[] = "logfile_scylla_plugin.txt";
+BOOL writeToLogFile(const char * text);
+BOOL getLogFilePath();
+
+HMODULE hImprecPlugin = 0;
+HANDLE hMapFile = 0;
+LPVOID lpViewOfFile = 0;
+WCHAR imprecPluginPath[260];
+char textBuffer[200];
+char logFilePath[260];
+
+def_voidFunction voidFunction = 0;
+
+BOOL stdcallPlugin = 0;
+
+BOOL getMappedView();
+void cleanUp();
+
+void resolveImports();
+BOOL getImprecPlugin();
+
+DWORD callImprecTraceFunction(DWORD hFileMap, DWORD dwSizeMap, DWORD dwTimeOut, DWORD dwToTrace, DWORD dwExactCall);
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,LPVOID lpvReserved)
+{
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ // Initialize once for each new process.
+ // Return FALSE to fail DLL load.
+
+ getLogFilePath();
+
+ writeToLogFile("DLL attached - Injection successful\r\n");
+
+ if (getImprecPlugin())
+ {
+ writeToLogFile("Loading ImpREC Plugin successful\r\n");
+
+ if (getMappedView()) //open file mapping
+ {
+ writeToLogFile("Open mapping successful\r\n");
+ resolveImports(); //resolve imports
+ writeToLogFile("Resolving Imports successful\r\n");
+ cleanUp(); //clean up handles
+ writeToLogFile("Cleanup successful\r\n");
+ }
+ }
+ else
+ {
+ writeToLogFile("Failed to get ImpREC Plugin\r\n");
+ }
+
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Do thread-specific initialization.
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Do thread-specific cleanup.
+ break;
+
+ case DLL_PROCESS_DETACH:
+ // Perform any necessary cleanup.
+ writeToLogFile("DLL successfully detached\r\n");
+ break;
+ }
+ return TRUE; // Successful DLL_PROCESS_ATTACH.
+}
+
+/*void checkCallingConvention()
+{
+ __asm {
+ push eax
+ push 0
+ push 0
+ push 0
+ push 0
+ push 0x1337
+ }
+
+ voidFunction();
+
+ __asm {
+ cmp dword ptr ss:[esp],0x1337
+ je cdecl_call
+ mov stdcallPlugin, 1
+ jmp finished
+cdecl_call:
+ add esp, 0x14
+ mov stdcallPlugin, 0
+finished:
+ pop eax
+ }
+}*/
+
+BOOL getImprecPlugin()
+{
+ HANDLE hImprecExchange = OpenFileMappingA(FILE_MAP_ALL_ACCESS, 0, PLUGIN_IMPREC_EXCHANGE_DLL_PATH); //open named file mapping object
+ if (hImprecExchange == 0)
+ {
+ writeToLogFile("getImprecPlugin() -> OpenFileMappingA failed\r\n");
+ return FALSE;
+ }
+
+ LPVOID lpImprecViewOfFile = MapViewOfFile(hImprecExchange, FILE_MAP_READ, 0, 0, 0); //map the view with full access
+
+ if (lpImprecViewOfFile == 0)
+ {
+ CloseHandle(hImprecExchange); //close mapping handle
+ writeToLogFile("getImprecPlugin() -> MapViewOfFile failed\r\n");
+ return FALSE;
+ }
+
+ lstrcpyW(imprecPluginPath, (LPWSTR)lpImprecViewOfFile);
+
+ UnmapViewOfFile(lpImprecViewOfFile);
+ CloseHandle(hImprecExchange);
+
+ wsprintfA(textBuffer, "- ImpREC Plugin -> %S\r\n", imprecPluginPath);
+ writeToLogFile(textBuffer);
+
+ hImprecPlugin = LoadLibraryW(imprecPluginPath);
+
+ if (hImprecPlugin)
+ {
+ voidFunction = (def_voidFunction)GetProcAddress(hImprecPlugin, "Trace");
+ if (voidFunction)
+ {
+ return TRUE;
+ }
+ else
+ {
+ writeToLogFile("getImprecPlugin() -> Cannot find Trace method\r\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ wsprintfA(textBuffer, "getImprecPlugin() -> LoadLibraryW failed 0x%X\r\n", GetLastError());
+ writeToLogFile(textBuffer);
+ return FALSE;
+ }
+}
+
+BOOL getMappedView()
+{
+ hMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, 0, FILE_MAPPING_NAME); //open named file mapping object
+
+ if (hMapFile == 0)
+ {
+ writeToLogFile("OpenFileMappingA failed\r\n");
+ return FALSE;
+ }
+
+ lpViewOfFile = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0); //map the view with full access
+
+ if (lpViewOfFile == 0)
+ {
+ CloseHandle(hMapFile); //close mapping handle
+ hMapFile = 0;
+ writeToLogFile("MapViewOfFile failed\r\n");
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+void cleanUp()
+{
+ if (lpViewOfFile != 0)
+ {
+ UnmapViewOfFile(lpViewOfFile); //close map view
+ lpViewOfFile = 0;
+ }
+ if (hMapFile != 0)
+ {
+ CloseHandle(hMapFile); //close mapping handle
+ hMapFile = 0;
+ }
+ if (hImprecPlugin != 0)
+ {
+ FreeLibrary(hImprecPlugin);
+ hImprecPlugin = 0;
+ }
+}
+
+DWORD callImprecTraceFunction(DWORD hFileMap, DWORD dwSizeMap, DWORD dwTimeOut, DWORD dwToTrace, DWORD dwExactCall)
+{
+ DWORD retValue = 0;
+
+ //some ImpREC Plugins use __cdecl and some other use __stdcall
+
+ __asm {
+ push eax
+ xor eax, eax
+ push eax
+ push dwExactCall
+ push dwToTrace
+ push dwTimeOut
+ push dwSizeMap
+ push hFileMap
+ }
+
+ retValue = voidFunction();
+
+ __asm {
+ cmp dword ptr ss:[esp],0
+ jne cdecl_call
+ jmp finished
+cdecl_call:
+ add esp, 0x14
+finished:
+ pop eax
+ pop eax
+ }
+
+ return retValue;
+}
+
+void resolveImports()
+{
+ PSCYLLA_EXCHANGE scyllaExchange = 0;
+ PUNRESOLVED_IMPORT unresolvedImport = 0;
+ DWORD pluginRet = 0;
+ DWORD * pluginOutput = 0;
+ LPVOID lpMapped = 0;
+ HANDLE hPluginMap = 0, hPluginMapDup = 0;
+
+ scyllaExchange = (PSCYLLA_EXCHANGE)lpViewOfFile;
+ unresolvedImport = (PUNRESOLVED_IMPORT)((DWORD_PTR)scyllaExchange + scyllaExchange->offsetUnresolvedImportsArray);
+
+ scyllaExchange->status = SCYLLA_STATUS_SUCCESS;
+
+ hPluginMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE|SEC_COMMIT, 0, sizeof(DWORD), PLUGIN_MAPPING_NAME);
+
+ if (hPluginMap == 0)
+ {
+ scyllaExchange->status = SCYLLA_STATUS_MAPPING_FAILED;
+ writeToLogFile("resolveImports :: CreateFileMappingA hPluginMap failed\r\n");
+ return;
+ }
+
+ while (unresolvedImport->ImportTableAddressPointer != 0) //last element is a nulled struct
+ {
+
+ if (!DuplicateHandle(GetCurrentProcess(), hPluginMap, GetCurrentProcess(), &hPluginMapDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ wsprintfA(textBuffer,"resolveImports :: DuplicateHandle failed error code %d\r\n", GetLastError());
+ writeToLogFile(textBuffer);
+ }
+
+ /*
+ - hFileMap : HANDLE of the file mapped by ImportREC
+ - dwSizeMap : Size of the mapped file
+ - dwTimeOut : TimeOut in ImportREC Options
+ - dwToTrace : The pointer to trace (in VA)
+ - dwExactCall : The EIP of the 'Exact Call' (in VA)
+ (this value is 0 when it is not an 'Exact Call')
+ */
+
+ pluginRet = callImprecTraceFunction((DWORD)hPluginMapDup, sizeof(DWORD), 200, unresolvedImport->InvalidApiAddress, 0);
+
+ lpMapped = MapViewOfFile(hPluginMap, FILE_MAP_WRITE|FILE_MAP_READ, 0, 0, 0);
+
+ if (lpMapped != 0)
+ {
+ pluginOutput = (DWORD *)lpMapped;
+
+ wsprintfA(textBuffer, "- Plugin return value %d resolved import %X\r\n", pluginRet, *pluginOutput);
+ writeToLogFile(textBuffer);
+
+ if (*pluginOutput != 0)
+ {
+ unresolvedImport->InvalidApiAddress = *pluginOutput;
+ *pluginOutput = 0;
+ }
+ else
+ {
+ scyllaExchange->status = SCYLLA_STATUS_IMPORT_RESOLVING_FAILED;
+ }
+
+ if (!UnmapViewOfFile(lpMapped))
+ {
+ wsprintfA(textBuffer,"resolveImports :: UnmapViewOfFile failed error code %d\r\n", GetLastError());
+ writeToLogFile(textBuffer);
+ }
+
+
+ lpMapped = 0;
+ }
+ else
+ {
+ scyllaExchange->status = SCYLLA_STATUS_MAPPING_FAILED;
+ wsprintfA(textBuffer,"resolveImports :: MapViewOfFile failed error code %d\r\n", GetLastError());
+ writeToLogFile(textBuffer);
+ }
+
+ unresolvedImport++; //next pointer to struct
+ }
+
+ CloseHandle(hPluginMap);
+}
+
+BOOL getLogFilePath()
+{
+ size_t i = 0;
+
+ if (!GetModuleFileNameA(0, logFilePath, sizeof(logFilePath))) //get full path of exe
+ {
+ return FALSE;
+ }
+
+ for (i = (lstrlenA(logFilePath) - 1); i >= 0; i--) //remove the exe file name from full path
+ {
+ if (logFilePath[i] == '\\')
+ {
+ logFilePath[i+1] = 0x00;
+ break;
+ }
+ }
+
+ if (lstrcatA(logFilePath,logFileName) == 0) //append log file name to path
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL writeToLogFile(const char * text)
+{
+ DWORD lpNumberOfBytesWritten = 0;
+ BOOL wfRet = 0;
+ HANDLE hFile = 0;
+
+ hFile = CreateFileA(logFilePath, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); //open log file for writing
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
+
+ SetFilePointer(hFile, 0, 0, FILE_END); //set file pointer to the end of file
+
+ if (WriteFile(hFile, text, (DWORD)lstrlenA(text), &lpNumberOfBytesWritten, 0)) //write message to logfile
+ {
+ wfRet = TRUE;
+ }
+ else
+ {
+ wfRet = FALSE;
+ }
+
+ CloseHandle(hFile);
+ return wfRet;
+}
\ No newline at end of file
diff --git a/Plugins/Sources/PECompact.cpp b/Plugins/Sources/PECompact.cpp
new file mode 100644
index 0000000..03cc7b2
--- /dev/null
+++ b/Plugins/Sources/PECompact.cpp
@@ -0,0 +1,194 @@
+
+#include "ScyllaPlugin.h"
+
+//remove c runtime library
+//#pragma comment(linker, "/ENTRY:DllMain")
+
+
+const char logFileName[] = "logfile_scylla_plugin.txt";
+BOOL writeToLogFile(const char * text);
+
+
+HANDLE hMapFile = 0;
+LPVOID lpViewOfFile = 0;
+
+BOOL getMappedView();
+void cleanUp();
+
+void resolveImports();
+
+
+#define PLUGIN_NAME "PECompact v2.x"
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,LPVOID lpvReserved)
+{
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ // Initialize once for each new process.
+ // Return FALSE to fail DLL load.
+
+ writeToLogFile("DLL attached - Injection successful\r\n");
+ if (getMappedView()) //open file mapping
+ {
+ writeToLogFile("Open mapping successful\r\n");
+ resolveImports(); //resolve imports
+ cleanUp(); //clean up handles
+ }
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Do thread-specific initialization.
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Do thread-specific cleanup.
+ break;
+
+ case DLL_PROCESS_DETACH:
+ // Perform any necessary cleanup.
+ writeToLogFile("DLL successfully detached\r\n");
+ break;
+ }
+ return TRUE; // Successful DLL_PROCESS_ATTACH.
+}
+
+BOOL getMappedView()
+{
+ hMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, 0, FILE_MAPPING_NAME); //open named file mapping object
+
+ if (hMapFile == 0)
+ {
+ writeToLogFile("OpenFileMappingA failed\r\n");
+ return FALSE;
+ }
+
+ lpViewOfFile = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0); //map the view with full access
+
+ if (lpViewOfFile == 0)
+ {
+ CloseHandle(hMapFile); //close mapping handle
+ hMapFile = 0;
+ writeToLogFile("MapViewOfFile failed\r\n");
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+void cleanUp()
+{
+ if (lpViewOfFile != 0)
+ {
+ UnmapViewOfFile(lpViewOfFile); //close map view
+ }
+ if (hMapFile != 0)
+ {
+ CloseHandle(hMapFile); //close mapping handle
+ }
+}
+
+
+void resolveImports()
+{
+ DWORD_PTR invalidApiAddress = 0;
+ PSCYLLA_EXCHANGE scyllaExchange = 0;
+ PUNRESOLVED_IMPORT unresolvedImport = 0;
+
+ scyllaExchange = (PSCYLLA_EXCHANGE)lpViewOfFile;
+ unresolvedImport = (PUNRESOLVED_IMPORT)((DWORD_PTR)scyllaExchange + scyllaExchange->offsetUnresolvedImportsArray);
+
+ scyllaExchange->status = SCYLLA_STATUS_SUCCESS;
+
+ while (unresolvedImport->ImportTableAddressPointer != 0) //last element is a nulled struct
+ {
+ //get real WINAPI address
+
+ //overwrite the existing wrong value with the good api address
+ invalidApiAddress = unresolvedImport->InvalidApiAddress;
+
+ //PECompact example
+ //01BF01FF B8 45128275 MOV EAX,kernel32.GetModuleHandleA
+ //01BF0204 - FFE0 JMP EAX
+
+ if (*((BYTE *)invalidApiAddress) == 0xB8) //is it pe compact?
+ {
+ invalidApiAddress++; //increase 1 opcode
+
+ //write right value to struct
+ unresolvedImport->InvalidApiAddress = *((DWORD_PTR *)invalidApiAddress);
+ }
+ else
+ {
+ writeToLogFile("Unsupported opcode found\r\n");
+ scyllaExchange->status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION;
+ break;
+ }
+
+ unresolvedImport++; //next pointer to struct
+ }
+}
+
+BOOL writeToLogFile(const char * text)
+{
+ DWORD lpNumberOfBytesWritten = 0;
+ size_t i = 0;
+ BOOL wfRet = 0;
+ HANDLE hFile = 0;
+ char buffer[260];
+
+ if (!GetModuleFileNameA(0, buffer, sizeof(buffer))) //get full path of exe
+ {
+ return FALSE;
+ }
+
+ for (i = (lstrlenA(buffer) - 1); i >= 0; i--) //remove the exe file name from full path
+ {
+ if (buffer[i] == '\\')
+ {
+ buffer[i+1] = 0x00;
+ break;
+ }
+ }
+
+ if (lstrcatA(buffer,logFileName) == 0) //append log file name to path
+ {
+ return FALSE;
+ }
+
+ hFile = CreateFileA(buffer, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); //open log file for writing
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
+
+ SetFilePointer(hFile, 0, 0, FILE_END); //set file pointer to the end of file
+
+ if (WriteFile(hFile, text, (DWORD)lstrlenA(text), &lpNumberOfBytesWritten, 0)) //write message to logfile
+ {
+ wfRet = TRUE;
+ }
+ else
+ {
+ wfRet = FALSE;
+ }
+
+ CloseHandle(hFile);
+ return wfRet;
+}
+
+
+#ifdef UNICODE
+DllExport wchar_t * __cdecl ScyllaPluginNameW()
+{
+ return TEXT(PLUGIN_NAME);
+}
+#else
+DllExport char * __cdecl ScyllaPluginNameA()
+{
+ return PLUGIN_NAME;
+}
+#endif
\ No newline at end of file
diff --git a/Plugins/Sources/PESpin_x64_v1.cpp b/Plugins/Sources/PESpin_x64_v1.cpp
new file mode 100644
index 0000000..bdfde65
--- /dev/null
+++ b/Plugins/Sources/PESpin_x64_v1.cpp
@@ -0,0 +1,496 @@
+#include "ScyllaPlugin.h"
+
+const char logFileName[] = "logfile_scylla_plugin.txt";
+BOOL writeToLogFile(const char * text);
+
+
+HANDLE hMapFile = 0;
+LPVOID lpViewOfFile = 0;
+
+BOOL getMappedView();
+void cleanUp();
+
+void resolveImports();
+DWORD getApiHash(const char * apiName);
+DWORD_PTR findPattern(DWORD_PTR startOffset, DWORD size, const BYTE * pattern, const char * mask);
+DWORD_PTR getApiAddress(DWORD_PTR dllBaseArray, DWORD_PTR apiHash);
+BOOL searchMagicConstant(DWORD_PTR startAddress);
+DWORD_PTR findJumpDestination(DWORD_PTR startAddress);
+DWORD_PTR findApiDefinition(DWORD_PTR startAddress);
+DWORD_PTR findDllBaseArrayAddress(DWORD_PTR startAddress);
+
+#define PLUGIN_NAME "PESpin x64 v1.x"
+
+char textBuffer[200];
+DWORD magicConstant = 0;
+BOOL executeOnce = 0;
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,LPVOID lpvReserved)
+{
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ // Initialize once for each new process.
+ // Return FALSE to fail DLL load.
+
+ DisableThreadLibraryCalls(hinstDLL);
+
+ writeToLogFile("DLL attached - Injection successful\r\n");
+ if (getMappedView()) //open file mapping
+ {
+ writeToLogFile("Open mapping successful\r\n");
+
+ resolveImports(); //resolve imports
+ writeToLogFile("resolveImports done\r\n");
+
+ cleanUp(); //clean up handles
+ writeToLogFile("All Plugin stuff done\r\n");
+ }
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Do thread-specific initialization.
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Do thread-specific cleanup.
+ break;
+
+ case DLL_PROCESS_DETACH:
+ // Perform any necessary cleanup.
+ writeToLogFile("DLL successfully detached\r\n");
+ break;
+ }
+ return TRUE; // Successful DLL_PROCESS_ATTACH.
+}
+
+BOOL getMappedView()
+{
+ hMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, 0, FILE_MAPPING_NAME); //open named file mapping object
+
+ if (hMapFile == 0)
+ {
+ writeToLogFile("OpenFileMappingA failed\r\n");
+ return FALSE;
+ }
+
+ lpViewOfFile = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0); //map the view with full access
+
+ if (lpViewOfFile == 0)
+ {
+ CloseHandle(hMapFile); //close mapping handle
+ hMapFile = 0;
+ writeToLogFile("MapViewOfFile failed\r\n");
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+void cleanUp()
+{
+ if (lpViewOfFile != 0)
+ {
+ UnmapViewOfFile(lpViewOfFile); //close map view
+ }
+ if (hMapFile != 0)
+ {
+ CloseHandle(hMapFile); //close mapping handle
+ }
+}
+
+
+void resolveImports()
+{
+ DWORD_PTR invalidApiAddress = 0;
+ DWORD_PTR apiHash = 0;
+ DWORD_PTR destination = 0;
+ DWORD_PTR dllBaseArray = 0;
+ PSCYLLA_EXCHANGE scyllaExchange = 0;
+ PUNRESOLVED_IMPORT unresolvedImport = 0;
+
+ scyllaExchange = (PSCYLLA_EXCHANGE)lpViewOfFile;
+ unresolvedImport = (PUNRESOLVED_IMPORT)((DWORD_PTR)lpViewOfFile + scyllaExchange->offsetUnresolvedImportsArray);
+
+ scyllaExchange->status = SCYLLA_STATUS_SUCCESS;
+
+ while (unresolvedImport->ImportTableAddressPointer != 0) //last element is a nulled struct
+ {
+ //get real WINAPI address
+
+ //overwrite the existing wrong value with the good api address
+ invalidApiAddress = unresolvedImport->InvalidApiAddress;
+
+
+ //000000014000F676 50 push rax
+ //000000014000F677 48B800657410C2584800 mov rax,004858C210746500
+ //000000014000F681 E928030000 jmp 000000014000F9AE
+
+ if (*((BYTE *)invalidApiAddress) == 0x50) //is it pespin, push rax
+ {
+ apiHash = findApiDefinition(invalidApiAddress); //read 00657410C2584800
+
+ if (!apiHash)
+ {
+ writeToLogFile("API Definition not found\r\n");
+ scyllaExchange->status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION;
+ break;
+ }
+
+ destination = findJumpDestination(invalidApiAddress); //jmp 000000014000F9AE
+
+ if (!destination)
+ {
+ writeToLogFile("JMP Destination not found\r\n");
+ scyllaExchange->status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION;
+ break;
+ }
+
+ if (!executeOnce)
+ {
+ if (!searchMagicConstant(destination))
+ {
+ writeToLogFile("Magic Constant not found\r\n");
+ scyllaExchange->status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION;
+ break;
+ }
+ }
+
+ dllBaseArray = findDllBaseArrayAddress(destination);
+
+ if (!dllBaseArray)
+ {
+ writeToLogFile("DLL Base Array not found\r\n");
+ scyllaExchange->status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION;
+ break;
+ }
+
+ unresolvedImport->InvalidApiAddress = getApiAddress(dllBaseArray, apiHash);
+
+ if (!unresolvedImport->InvalidApiAddress)
+ {
+ writeToLogFile("API not found\r\n");
+ scyllaExchange->status = SCYLLA_STATUS_IMPORT_RESOLVING_FAILED;
+ break;
+ }
+
+ }
+ else
+ {
+ writeToLogFile("Unsupported opcode found\r\n");
+ scyllaExchange->status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION;
+ break;
+ }
+
+ unresolvedImport++; //next pointer to struct
+ }
+}
+
+
+ /*
+ 000000014000F9E1 4C 8D 1D AE FF FF FF lea r11, off_14000F996 ;dll base
+ 000000014000F9E8 4C 8B D0 mov r10, rax
+ 000000014000F9EB 49 81 E2 FF 00 00 00 and r10, 0FFh
+ 000000014000F9F2 49 C1 E2 03 shl r10, 3
+ 000000014000F9F6 4F 8B 14 1A mov r10, [r10+r11]
+ */
+DWORD_PTR findDllBaseArrayAddress(DWORD_PTR startAddress)
+{
+ __int32 relAddress = 0;
+
+ startAddress = findPattern(startAddress, 300, (BYTE *)"\x4C\x8D\xFF\xFF\xFF\xFF\xFF\x4C\x8B\xD0\x49\x81\xE2\xFF\x00\x00","xx?????xxxxxxxxx");
+
+ if (startAddress)
+ {
+ startAddress += 3;
+ relAddress = *((__int32 *)startAddress);
+
+ wsprintfA(textBuffer, "- Found DLL Base array -> %016I64X\r\n", (relAddress + startAddress + sizeof(DWORD)));
+ writeToLogFile(textBuffer);
+
+ return (relAddress + startAddress + sizeof(DWORD));
+ }
+ else
+ {
+ writeToLogFile("findDllBaseArrayAddress failed\r\n");
+ return 0;
+ }
+}
+
+DWORD_PTR findApiDefinition(DWORD_PTR startAddress)
+{
+ startAddress += 3; //increase 3 bytes
+
+ wsprintfA(textBuffer, "- Found API Definition -> %016I64X\r\n", *((DWORD_PTR *)startAddress));
+ writeToLogFile(textBuffer);
+
+ return *((DWORD_PTR *)startAddress); //read 00657410C2584800
+}
+
+DWORD_PTR findJumpDestination(DWORD_PTR startAddress)
+{
+ __int32 destination = 0;
+
+ startAddress += sizeof(DWORD_PTR) + 4; //increase 8 + 4 bytes
+
+ destination = *((__int32 *)startAddress); //get jmp relative 4 bytes
+
+ wsprintfA(textBuffer, "- Found JMP Destination -> %016I64X\r\n", destination + startAddress + sizeof(DWORD));
+ writeToLogFile(textBuffer);
+
+ return destination + startAddress + sizeof(DWORD); //increase 4 + 1 bytes
+}
+
+BOOL searchMagicConstant(DWORD_PTR startAddress)
+{
+
+ executeOnce = 1;
+ /*
+
+ 000000014000FBF9 32 D0 xor dl, al
+ 000000014000FBFB B0 08 mov al, 8
+ 000000014000FBFD
+ 000000014000FBFD loc_14000FBFD:
+ 000000014000FBFD D1 EA shr edx, 1
+ 000000014000FBFF 73 06 jnb short loc_14000FC07
+ 000000014000FC01 81 F2 1F AF 81 73 xor edx, 7381AF1F ; constant
+ 000000014000FC07
+ 000000014000FC07 loc_14000FC07:
+ 000000014000FC07 FE C8 dec al
+ 000000014000FC09 75 F2 jnz short loc_14000FBFD
+ 000000014000FC0B EB E3 jmp short loc_14000FBF0
+ 000000014000FC0D
+ 000000014000FC0D loc_14000FC0D:
+ 000000014000FC0D 48 92 xchg rax, rdx
+
+ */
+
+ DWORD_PTR address = findPattern(startAddress, 1000, (BYTE *)"\x32\xD0\xB0\x08\xD1\xEA\x73\x06\x81\xF2\xFF\xFF\xFF\xFF\xFE\xC8\x75","xxxxxxxxxx????xxx");
+ if (address)
+ {
+ address += 10;
+ magicConstant = *((DWORD *)address);
+
+ wsprintfA(textBuffer, "- Found magic constant -> %08X\r\n", magicConstant);
+ writeToLogFile(textBuffer);
+
+ return 1;
+ }
+ else
+ {
+ magicConstant = 0;
+ writeToLogFile("Magic Constant not found\r\n");
+ return 0;
+ }
+}
+
+/*
+ * Resolve PESpin Api String to VA
+ */
+DWORD_PTR getApiAddress(DWORD_PTR dllBaseArray, DWORD_PTR apiHash)
+{
+ PIMAGE_DOS_HEADER pDosHeader = 0;
+ PIMAGE_NT_HEADERS pNtHeader = 0;
+ PIMAGE_EXPORT_DIRECTORY pExportHeader = 0;
+ DWORD_PTR dllBase = 0;
+ int dllBaseIndex = 0;
+ DWORD *addressOfFunctionsArray = 0,*addressOfNamesArray = 0;
+ WORD *addressOfNameOrdinalsArray = 0;
+ char *functionName = 0;
+ DWORD_PTR RVA = 0, VA = 0, deltaAddress = 0;
+ DWORD apiNameHash = 0;
+ char apiNameCmp[3] = {0};
+
+ dllBaseIndex = apiHash & 0xFF;
+ dllBase = *((DWORD_PTR *)dllBaseArray + dllBaseIndex);
+
+ //e.g. 0x0021AF0957746500
+ apiNameHash = (DWORD)(apiHash >> 24); //21AF0957
+ apiNameCmp[0] = (char)(apiHash >> 8); //65
+ apiNameCmp[1] = (char)(apiHash >> 16); //74
+
+ pDosHeader = (PIMAGE_DOS_HEADER)dllBase;
+
+ if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ {
+ writeToLogFile("Wrong dll base, IMAGE_DOS_SIGNATURE doesn't match\r\n");
+ return 0;
+ }
+
+ pNtHeader = (PIMAGE_NT_HEADERS)(dllBase + pDosHeader->e_lfanew);
+
+ if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
+ {
+ writeToLogFile("Wrong dll base, IMAGE_NT_SIGNATURE doesn't match\r\n");
+ return 0;
+ }
+
+ if (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0)
+ {
+ writeToLogFile("No export table found\r\n");
+ return 0;
+ }
+
+ pExportHeader = (PIMAGE_EXPORT_DIRECTORY)(dllBase + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
+
+ deltaAddress = (DWORD_PTR)pExportHeader - pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ addressOfFunctionsArray = (DWORD *)((DWORD_PTR)pExportHeader->AddressOfFunctions + deltaAddress);
+ addressOfNamesArray = (DWORD *)((DWORD_PTR)pExportHeader->AddressOfNames + deltaAddress);
+ addressOfNameOrdinalsArray = (WORD *)((DWORD_PTR)pExportHeader->AddressOfNameOrdinals + deltaAddress);
+
+ for (DWORD i = 0; i < pExportHeader->NumberOfNames; i++)
+ {
+ functionName = (char*)(addressOfNamesArray[i] + deltaAddress);
+
+ if (functionName[1] == apiNameCmp[0] && functionName[2] == apiNameCmp[1])
+ {
+
+ if (getApiHash(functionName) == apiNameHash)
+ {
+ //VA = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]] + dllBase;
+
+ //avoid forward api handling:
+ VA = (DWORD_PTR)GetProcAddress((HMODULE)dllBase, functionName);
+
+ wsprintfA(textBuffer, "- Found %s %016I64X\r\n",functionName, VA);
+ writeToLogFile(textBuffer);
+
+ return VA;
+ }
+ }
+ }
+
+ wsprintfA(textBuffer, "- Cannot find apiHash %016I64X dllBaseArray address %016I64X\r\n",apiHash, dllBaseArray);
+ writeToLogFile(textBuffer);
+
+ return 0;
+}
+
+
+/*
+ * Api name hash function at VA 14000FBEC
+ *
+ * Start: 000000014000FBEC 52 push rdx
+ * End: 000000014000FC10 C3 retn
+ */
+DWORD getApiHash(const char * apiName)
+{
+ DWORD dwCheck = 0xFFFFFFFF;
+ char key = 0;
+
+ for (int i = 0; i < lstrlenA(apiName); i++)
+ {
+ key = apiName[i];
+
+ dwCheck = (dwCheck & 0xFFFFFF00) + ((dwCheck & 0xFF) ^ key);
+ key = 0x8;
+
+ do
+ {
+ if (dwCheck % 2)
+ {
+ dwCheck >>= 1;
+ dwCheck ^= magicConstant;
+ }
+ else
+ {
+ dwCheck >>= 1;
+ }
+
+ key--;
+ } while (key);
+ }
+
+ return dwCheck;
+}
+
+/*
+ * Search a memory region for a byte pattern and return the address
+ */
+DWORD_PTR findPattern(DWORD_PTR startOffset, DWORD size, const BYTE * pattern, const char * mask)
+{
+ DWORD pos = 0;
+ int searchLen = lstrlenA(mask) - 1;
+
+ for(DWORD_PTR retAddress = startOffset; retAddress < startOffset + size; retAddress++)
+ {
+ if( *(BYTE*)retAddress == pattern[pos] || mask[pos] == '?' )
+ {
+ if(mask[pos+1] == 0x00)
+ {
+ return (retAddress - searchLen);
+ }
+ pos++;
+ } else {
+ pos = 0;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Write text to a logfile, the logfile is in the same folder as the target exe
+ */
+BOOL writeToLogFile(const char * text)
+{
+ DWORD lpNumberOfBytesWritten = 0;
+ size_t i = 0;
+ BOOL wfRet = 0;
+ HANDLE hFile = 0;
+ char buffer[260];
+
+ if (!GetModuleFileNameA(0, buffer, sizeof(buffer))) //get full path of exe
+ {
+ return FALSE;
+ }
+
+ for (i = (lstrlenA(buffer) - 1); i >= 0; i--) //remove the exe file name from full path
+ {
+ if (buffer[i] == '\\')
+ {
+ buffer[i+1] = 0x00;
+ break;
+ }
+ }
+
+ if (lstrcatA(buffer,logFileName) == 0) //append log file name to path
+ {
+ return FALSE;
+ }
+
+ hFile = CreateFileA(buffer, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); //open log file for writing
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
+
+ SetFilePointer(hFile, 0, 0, FILE_END); //set file pointer to the end of file
+
+ if (WriteFile(hFile, text, (DWORD)lstrlenA(text), &lpNumberOfBytesWritten, 0)) //write message to logfile
+ {
+ wfRet = TRUE;
+ }
+ else
+ {
+ wfRet = FALSE;
+ }
+
+ CloseHandle(hFile);
+ return wfRet;
+}
+
+
+#ifdef UNICODE
+DllExport wchar_t * __cdecl ScyllaPluginNameW()
+{
+ return TEXT(PLUGIN_NAME);
+}
+#else
+DllExport char * __cdecl ScyllaPluginNameA()
+{
+ return PLUGIN_NAME;
+}
+#endif
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Sun, Sep 22, 2:48 AM (1 d, 17 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
11/91/2a133f58bc590aac9826c26a6972

Event Timeline