├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── Getx86Proc.exe ├── README.md └── src ├── LIB_INVADER ├── AnsiString.cpp ├── AnsiString.h ├── ArgUtils.cpp ├── ArgUtils.h ├── CurdirContent.h ├── DebugPrivileges.cpp ├── DebugPrivileges.h ├── EnumLoadReason.h ├── ErrorUtils.cpp ├── ErrorUtils.h ├── GDI_HANDLE_BUFFER.h ├── GetModules.cpp ├── GetOpenedHandles.h ├── GetPEBContent.cpp ├── GetPEBContent.h ├── GetProcessInformation.h ├── GetProcessModuleList.cpp ├── GetProcessModuleList.h ├── HandleProcessInformation.cpp ├── IMAGE_NT_HEADERS.h ├── Injector.cpp ├── Injector.h ├── KeyNameInformation.h ├── NTStatus.h ├── NtCreateThread.cpp ├── NtCreateThread.h ├── ObjectNameInformation.h ├── ObjectTypeInformation.h ├── PEBContent.cpp ├── PEBContent.h ├── PPVOID.h ├── PROCESSINFOCLASS.h ├── PoolType.h ├── ProcessBasicInformation.h ├── ProcessInformation.h ├── ProcessModule.cpp ├── ProcessModule.h ├── ProcessUtils.cpp ├── ProcessUtils.h ├── QueryOpenedFiles.cpp ├── QueryProcessInformation.cpp ├── RegUtils.cpp ├── RegUtils.h ├── RtlDriveLetterCurdirContent.h ├── SystemInformationClass.h ├── SystemProcessInformation.h ├── UnicodeString.cpp ├── UnicodeString.h ├── _LDR_DLL_LOAD_REASON.h ├── _PEB_LDR_DATA.h └── _RTL_BALANCED_NODE.h ├── LoadLibraryInMem.asm └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | /Debug/ 2 | /Release/ 3 | /.vs/ 4 | *.exe 5 | *.tmp 6 | *.pdb 7 | *.ilk 8 | *.tlog 9 | *.obj 10 | *.o 11 | *.log 12 | *.idb 13 | *.layout 14 | *.iobj 15 | *.ipdb 16 | /*/obj 17 | /CMakeFiles 18 | **/CMakeFiles 19 | Makefile 20 | **/Makefile 21 | /*/.vs 22 | /*/*.cbp 23 | /*/*.depend 24 | /*/*.sln* 25 | /*/*.vcxproj* 26 | *.un~ 27 | *.h~ 28 | *.cpp~ 29 | *.cscope_file_list 30 | .vcxproj* 31 | **/*.vcxproj* 32 | .sln 33 | **/*.sln 34 | /lib/ 35 | /bin/ 36 | **/Log.txt 37 | **/LogError.txt 38 | Log.txt 39 | LogError.txt 40 | CMakeCache.txt 41 | **/CMakeCache.txt 42 | *.dir 43 | .vscode 44 | *.log.txt 45 | *.cmake 46 | **/.vs 47 | /external/chipmunk/src/Debug 48 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/asm_utils"] 2 | path = external/asm_utils 3 | url = https://github.com/Scorbutics/ASMUtils.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | project(injectit) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 6 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 7 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 8 | 9 | add_subdirectory(external/asm_utils) 10 | 11 | include_directories(external/asm_utils/src) 12 | link_directories(lib) 13 | 14 | file(GLOB_RECURSE SOURCES 15 | src/*.h 16 | src/*.asm 17 | src/*.cpp 18 | ) 19 | 20 | string(REGEX REPLACE "[^;]*CMakeFiles/[^;]+;?" "" SOURCES "${SOURCES}") 21 | 22 | add_executable(injectitx64 ${SOURCES}) 23 | target_link_libraries(injectitx64 asm_utils) 24 | -------------------------------------------------------------------------------- /Getx86Proc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Scorbutics/InjectItx64/e9de011f8886f706b2cf1c3fa37cd23d112af873/Getx86Proc.exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Basic Injector running on x64 machines that is able to load into x64 AND x86 processes. 2 | You'll of course need a DLL compiled in the correct architecture (x86 if the target process is in x86, x64 if the target process is in x64). 3 | 4 | To use it : 5 | 6 | InjectItx64.exe cmd.exe -iCS mydll.dll 7 | 8 | It will inject the dll "mydll.dll" in a "cmd.exe" instance newly created. 9 | The "-iCS" attribute stands for "Create Suspended", which means that the process "cmd.exe" has to be created, then suspended, then the "mydll.dll" loaded into it, then resumed. 10 | -------------------------------------------------------------------------------- /src/LIB_INVADER/AnsiString.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "AnsiString.h" 3 | #include "UnicodeString.h" 4 | 5 | /* 6 | * malloc sur ANSI_STRING.Buffer 7 | */ 8 | 9 | ANSI_STRING CreateAnsiStringData(unsigned int size) 10 | { 11 | ANSI_STRING result; 12 | result.Buffer = (char*) calloc(size, sizeof(char)); 13 | result.Length = size; 14 | 15 | return result; 16 | } 17 | 18 | void ZeroAnsiString(ANSI_STRING *str) 19 | { 20 | memset(str, 0, sizeof(ANSI_STRING)); 21 | } 22 | 23 | ANSI_STRING CreateAnsiStringDataFromUnicodeString(UNICODE_STRING uni) 24 | { 25 | return CreateAnsiStringDataFromUnicode(uni.Buffer, uni.MaximumLength); 26 | } 27 | 28 | ANSI_STRING CreateAnsiStringDataFromUnicode(WCHAR* str, unsigned int size) 29 | { 30 | ANSI_STRING result = CreateAnsiStringData(size); 31 | utf8_encode(reinterpret_cast(str), size, result.Buffer, size); 32 | 33 | return result; 34 | } 35 | -------------------------------------------------------------------------------- /src/LIB_INVADER/AnsiString.h: -------------------------------------------------------------------------------- 1 | #ifndef ANSISTRING_H 2 | #define ANSISTRING_H 3 | #include "UnicodeString.h" 4 | 5 | struct ANSI_STRING { 6 | unsigned int Length; 7 | char* Buffer; 8 | }; 9 | typedef struct ANSI_STRING ANSI_STRING; 10 | 11 | ANSI_STRING CreateAnsiStringDataFromUnicode(WCHAR* str, unsigned int size); 12 | ANSI_STRING CreateAnsiStringDataFromUnicodeString(UNICODE_STRING uni); 13 | 14 | #endif // ANSISTRING_H 15 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ArgUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int FileExists(const char* pathFileName) 5 | { 6 | FILE * file = fopen(pathFileName, "r"); 7 | int result = file != NULL; 8 | fclose(file); 9 | 10 | return result; 11 | } 12 | 13 | const char* FindArg(const char* argStr[], unsigned int argc, const char* arg) 14 | { 15 | unsigned int i; 16 | for(i = 1; i < argc; i++) 17 | { 18 | if(strstr(argStr[i], arg) == argStr[i]) 19 | { 20 | return argStr[i]; 21 | } 22 | } 23 | 24 | return NULL; 25 | } 26 | 27 | const char* FindExtensionPathName(const char* argStr[], unsigned int argc, const char* ext) 28 | { 29 | unsigned int i; 30 | for(i = 1; i < argc; i++) 31 | { 32 | if(strstr(argStr[i], ext) == (argStr[i] + strlen(argStr[i]) - strlen(ext))) 33 | { 34 | return argStr[i]; 35 | } 36 | } 37 | return NULL; 38 | } 39 | 40 | const char* FindNextArg(const char* argStr[], unsigned int argc, const char* arg) { 41 | unsigned int i; 42 | for (i = 1; i < argc; i++) 43 | { 44 | if (!strcmp(argStr[i], arg)) 45 | { 46 | return (i + 1 < argc) ? argStr[i + 1] : NULL; 47 | } 48 | } 49 | return NULL; 50 | } 51 | 52 | const char* FindPidPathName(const char* argStr[], unsigned int argc) 53 | { 54 | return FindNextArg(argStr, argc, "-pid"); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ArgUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef ARGUTILS_H 2 | #define ARGUTILS_H 3 | 4 | int FileExists(const char* pathFileName); 5 | const char* FindArg(const char* argStr[], unsigned int argc, const char* arg); 6 | const char* FindNextArg(const char* argStr[], unsigned int argc, const char* arg); 7 | const char* FindExtensionPathName(const char* argStr[], unsigned int argc, const char* ext); 8 | const char* FindPidPathName(const char* argStr[], unsigned int argc); 9 | 10 | #endif // ARGUTILS_H 11 | -------------------------------------------------------------------------------- /src/LIB_INVADER/CurdirContent.h: -------------------------------------------------------------------------------- 1 | #ifndef CURDIRCONTENT_H 2 | #define CURDIRCONTENT_H 3 | 4 | 5 | 6 | #endif // CURDIRCONTENT_H 7 | -------------------------------------------------------------------------------- /src/LIB_INVADER/DebugPrivileges.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "DebugPrivileges.h" 4 | #include "ErrorUtils.h" 5 | 6 | BOOL SetPrivilege( 7 | HANDLE hToken, // access token handle 8 | LPCTSTR lpszPrivilege, // name of privilege to enable/disable 9 | BOOL bEnablePrivilege // to enable or disable privilege 10 | ) 11 | { 12 | TOKEN_PRIVILEGES tp; 13 | LUID luid; 14 | 15 | if ( !LookupPrivilegeValue( 16 | NULL, // lookup privilege on local system 17 | lpszPrivilege, // privilege to lookup 18 | &luid ) ) // receives LUID of privilege 19 | { 20 | printf("LookupPrivilegeValue error: %u\n", (unsigned int) GetLastError() ); 21 | return FALSE; 22 | } 23 | 24 | tp.PrivilegeCount = 1; 25 | tp.Privileges[0].Luid = luid; 26 | if (bEnablePrivilege) 27 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 28 | else 29 | tp.Privileges[0].Attributes = 0; 30 | 31 | // Enable the privilege or disable all privileges. 32 | 33 | if ( !AdjustTokenPrivileges( 34 | hToken, 35 | FALSE, 36 | &tp, 37 | sizeof(TOKEN_PRIVILEGES), 38 | (PTOKEN_PRIVILEGES) NULL, 39 | (PDWORD) NULL) ) 40 | { 41 | printf("AdjustTokenPrivileges error: %u\n", (unsigned int) GetLastError() ); 42 | return FALSE; 43 | } 44 | 45 | if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 46 | 47 | { 48 | printf("The token does not have the specified privilege. \n"); 49 | return FALSE; 50 | } 51 | 52 | return TRUE; 53 | } 54 | 55 | void MyPrivilegeCheck() 56 | { 57 | LPCTSTR lpszPrivilege = SE_DEBUG_NAME; 58 | BOOL bEnablePrivilege = TRUE; 59 | HANDLE token; 60 | PRIVILEGE_SET privset; 61 | BOOL bResult; 62 | 63 | printf("Setting SeDebugPrivilege\r\n"); 64 | 65 | privset.PrivilegeCount = 1; 66 | //privset.Control = PRIVILEGE_SET_ALL_NECESSARY; 67 | privset.Privilege[0].Attributes = 0; 68 | 69 | if (!LookupPrivilegeValue(NULL, lpszPrivilege, &privset.Privilege[0].Luid)) 70 | ErrorExit("LookupPrivilegeValue"); 71 | 72 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) 73 | ErrorExit("OpenProcessToken"); 74 | 75 | if (!PrivilegeCheck(token, &privset, &bResult)) 76 | ErrorExit("PrivilegeCheck"); 77 | 78 | if (bResult) 79 | printf(" We have debug privileges for the system\r\n"); 80 | else 81 | printf(" Nope, Try again. Attempting to get it...\r\n"); 82 | 83 | if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) 84 | { 85 | DisplayLastError(); 86 | return; 87 | } 88 | printf("SetPrivilege() return value: %d\n\n", SetPrivilege(token, lpszPrivilege, bEnablePrivilege)); 89 | 90 | } 91 | 92 | BOOL EnableDebugPrivilege(BOOL bEnable) 93 | { 94 | HANDLE hToken = NULL; 95 | LUID luid; 96 | 97 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE; 98 | if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { CloseHandle(hToken); return FALSE; } 99 | 100 | TOKEN_PRIVILEGES tokenPriv; 101 | tokenPriv.PrivilegeCount = 1; 102 | tokenPriv.Privileges[0].Luid = luid; 103 | tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; 104 | 105 | if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { CloseHandle(hToken); return FALSE; } 106 | 107 | return TRUE; 108 | } 109 | -------------------------------------------------------------------------------- /src/LIB_INVADER/DebugPrivileges.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUGPRIVILEGES_H 2 | #define DEBUGPRIVILEGES_H 3 | 4 | 5 | void MyPrivilegeCheck(); 6 | BOOL EnableDebugPrivilege(BOOL bEnable); 7 | 8 | #endif // DEBUGPRIVILEGES_H 9 | -------------------------------------------------------------------------------- /src/LIB_INVADER/EnumLoadReason.h: -------------------------------------------------------------------------------- 1 | #ifndef ENUMLOADREASON_H 2 | #define ENUMLOADREASON_H 3 | 4 | 5 | 6 | #endif // ENUMLOADREASON_H 7 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ErrorUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "UnicodeString.h" 4 | #include "ErrorUtils.h" 5 | 6 | void str_replace_char(char * str, char character, char charToReplace) 7 | { 8 | char* strSearched = NULL; 9 | while((strSearched = strchr(str, character))) 10 | { 11 | strSearched[0] = charToReplace; 12 | } 13 | } 14 | 15 | void str_delete_char(char * str, char character) 16 | { 17 | char result[1024] = {0}; 18 | unsigned int absIndex = 0, outputIndex = 0; 19 | unsigned int itNum = 1; 20 | 21 | char* strSearched = str; 22 | 23 | while((strSearched = strchr(str + absIndex, character))) 24 | { 25 | unsigned int index = strSearched - str; 26 | //Copie du contenu intermédiaire 27 | memcpy(result + outputIndex, str + absIndex, index - absIndex ); 28 | absIndex = index + 1; 29 | outputIndex = strlen(result); 30 | itNum++; 31 | } 32 | 33 | //Copie de fin de chaîne 34 | memcpy(result + outputIndex, str + absIndex, strlen(str) - absIndex); 35 | 36 | strcpy(str, result); 37 | } 38 | 39 | void ErrorExit(const char* msg) 40 | { 41 | puts(msg); 42 | DisplayLastError(); 43 | exit(EXIT_FAILURE); 44 | } 45 | 46 | void DisplayErrorWithCode(LPWSTR pMessage, long code) 47 | { 48 | LPVOID pBuffer = NULL; 49 | WCHAR finalMessage[2048] = { 0 }; 50 | 51 | FormatMessageW( 52 | FORMAT_MESSAGE_ALLOCATE_BUFFER | 53 | FORMAT_MESSAGE_FROM_SYSTEM | 54 | FORMAT_MESSAGE_IGNORE_INSERTS, 55 | pMessage, 56 | code, 57 | 0, // Default language 58 | (LPWSTR) &pBuffer, 59 | 0, 60 | NULL 61 | ) ; 62 | 63 | 64 | #ifdef UNICODE 65 | wsprintf(finalMessage, L"Erreur [0x%08x] : %s\n", (unsigned int)code, (LPCWSTR)pBuffer); 66 | WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), finalMessage, lstrlenW(finalMessage), NULL, NULL); 67 | #else 68 | printf("Erreur [0x%08x] : %s\n", (unsigned int)code, (LPCTSTR)pBuffer); 69 | #endif 70 | 71 | LocalFree(pBuffer); 72 | } 73 | 74 | void DisplayLastError() 75 | { 76 | DisplayErrorWithCode(NULL, (DWORD_PTR)GetLastError()); 77 | } 78 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ErrorUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_ERRORUTILS 2 | #define DEF_ERRORUTILS 3 | 4 | void ErrorExit(char const* msg); 5 | void DisplayLastError(); 6 | void DisplayErrorWithCode(LPWSTR pMessage, long code); 7 | 8 | #endif // DEF_ERRORUTILS 9 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GDI_HANDLE_BUFFER.h: -------------------------------------------------------------------------------- 1 | #ifndef GDI_HANDLE_BUFFER_H 2 | #define GDI_HANDLE_BUFFER_H 3 | 4 | #define GDI_HANDLE_BUFFER_SIZE32 34 5 | #define GDI_HANDLE_BUFFER_SIZE64 60 6 | #ifndef WIN64 7 | #define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE32 8 | #else 9 | #define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE64 10 | #endif 11 | 12 | typedef ULONG GDI_HANDLE_BUFFER[GDI_HANDLE_BUFFER_SIZE]; 13 | 14 | typedef ULONG GDI_HANDLE_BUFFER32[GDI_HANDLE_BUFFER_SIZE32]; 15 | typedef ULONG GDI_HANDLE_BUFFER64[GDI_HANDLE_BUFFER_SIZE64]; 16 | 17 | #endif // GDI_HANDLE_BUFFER_H 18 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GetModules.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int PrintModules( unsigned long processID ) 7 | { 8 | // HMODULE hMods[1024]; 9 | // HANDLE hProcess; 10 | // DWORD cbNeeded; 11 | // unsigned int i; 12 | 13 | // // Print the process identifier. 14 | 15 | // printf( "\nProcess ID: %u\n", processID ); 16 | 17 | // // Get a handle to the process. 18 | 19 | // hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | 20 | // PROCESS_VM_READ, 21 | // FALSE, processID ); 22 | // if (NULL == hProcess) 23 | // return 1; 24 | 25 | // // Get a list of all the modules in this process. 26 | 27 | // if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded, LIST_MODULES_ALL)) 28 | // { 29 | // for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ ) 30 | // { 31 | // TCHAR szModName[MAX_PATH]; 32 | 33 | // // Get the full path to the module's file. 34 | 35 | // if ( GetModuleFileName( hProcess, hMods[i], szModName, 36 | // sizeof(szModName) / sizeof(TCHAR))) 37 | // { 38 | // // Print the module name and handle value. 39 | 40 | // printf("\t%s (0x%08X)\n", szModName, hMods[i] ); 41 | // } 42 | // } 43 | // } 44 | 45 | // // Release the handle to the process. 46 | 47 | // CloseHandle( hProcess ); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GetOpenedHandles.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_QUERYOPENEDFILES 2 | #define DEF_QUERYOPENEDFILES 3 | 4 | #define SystemHandleInformation 16 5 | 6 | /* The following structure is actually called SYSTEM_HANDLE_TABLE_ENTRY_INFO, but SYSTEM_HANDLE is shorter. */ 7 | typedef struct _SYSTEM_HANDLE 8 | { 9 | ULONG ProcessId; 10 | BYTE ObjectTypeNumber; 11 | BYTE Flags; 12 | USHORT Handle; 13 | PVOID Object; 14 | ACCESS_MASK GrantedAccess; 15 | } SYSTEM_HANDLE, *PSYSTEM_HANDLE; 16 | 17 | typedef struct _SYSTEM_HANDLE_INFORMATION 18 | { 19 | ULONG HandleCount; /* Or NumberOfHandles if you prefer. */ 20 | SYSTEM_HANDLE Handles[1]; 21 | } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; 22 | 23 | 24 | HANDLE GetDuplicatedProcessHandle(unsigned int pid, char* processName, int silent); 25 | HandleProcessInformation* SystemHandleInformationHandler(HMODULE dllLoaded, PSYSTEM_HANDLE_INFORMATION handleInfo, unsigned int pid, char* processName, char* filterOnType, HandleProcessInformation* existantList, int silent); 26 | HandleProcessInformation* GetOpenedHandles(HMODULE dll, unsigned int pid, char* filterOnType, int silent); 27 | ProcessWithHandlesList* GetProcessWithAttachedHandle(char* attachedHandleName); 28 | void DisplayAllOpenedHandles(HMODULE ntdll, char* filterOnType); 29 | #endif 30 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GetPEBContent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ProcessBasicInformation.h" 4 | #include "PEBContent.h" 5 | #include "GetPEBContent.h" 6 | 7 | #include "ErrorUtils.h" 8 | 9 | #include "ProcessInformation.h" 10 | #include "GetProcessInformation.h" 11 | 12 | void FillLdrPEB(PPEB_LDR_DATA pLdr, PEBContent* output) 13 | { 14 | PEBLdrDataContent* ldr = output->Ldr; 15 | 16 | ldr->Initialized = pLdr->Initialized; 17 | ldr->Length = pLdr->Length; 18 | ldr->ShutdownInProgress = pLdr->ShutdownInProgress; 19 | 20 | ldr->InInitializationOrderModuleList = pLdr->InInitializationOrderModuleList; 21 | ldr->InLoadOrderModuleList = pLdr->InLoadOrderModuleList; 22 | ldr->InMemoryOrderModuleList = pLdr->InMemoryOrderModuleList; 23 | 24 | } 25 | 26 | void FillProcessParametersPEB(PRTL_USER_PROCESS_PARAMETERS pProcParam, PEBContent* output) 27 | { 28 | RtlUserProcessParametersContent* procParam = output->ProcessParameters; 29 | 30 | procParam->ConsoleFlags = pProcParam->ConsoleFlags; 31 | procParam->CountCharsX = pProcParam->CountCharsX; 32 | procParam->CountCharsY = pProcParam->CountCharsY; 33 | procParam->CountX = pProcParam->CountX; 34 | procParam->CountY = pProcParam->CountY; 35 | procParam->DebugFlags = pProcParam->DebugFlags; 36 | procParam->EnvironmentSize = pProcParam->EnvironmentSize; 37 | procParam->EnvironmentVersion = pProcParam->EnvironmentVersion; 38 | procParam->FillAttribute = pProcParam->FillAttribute; 39 | procParam->Flags = pProcParam->Flags; 40 | procParam->Length = pProcParam->Length; 41 | procParam->MaximumLength = pProcParam->MaximumLength; 42 | procParam->ProcessGroupId = pProcParam->ProcessGroupId; 43 | procParam->ShowWindowFlags = pProcParam->ShowWindowFlags; 44 | procParam->StartingX = pProcParam->StartingX; 45 | procParam->StartingY = pProcParam->StartingY; 46 | procParam->WindowFlags = pProcParam->WindowFlags; 47 | 48 | //Pointers 49 | procParam->ConsoleHandle = pProcParam->ConsoleHandle; 50 | procParam->PackageDependencyData = pProcParam->PackageDependencyData; 51 | procParam->StandardError = pProcParam->StandardError; 52 | procParam->StandardInput = pProcParam->StandardInput; 53 | procParam->StandardOutput = pProcParam->StandardOutput; 54 | 55 | } 56 | 57 | void FillMainPEB(PEB* peb, PEBContent* output) 58 | { 59 | unsigned int i; 60 | 61 | output->ActiveProcessAffinityMask = peb->ActiveProcessAffinityMask; 62 | output->AppCompatFlags = peb->AppCompatFlags.QuadPart; 63 | output->AppCompatFlagsUser = peb->AppCompatFlagsUser.QuadPart; 64 | output->AtlThunkSListPtr32 = peb->AtlThunkSListPtr32; 65 | output->BeingDebugged = peb->BeingDebugged; 66 | output->CriticalSectionTimeout = peb->CriticalSectionTimeout.QuadPart; 67 | output->CsrServerReadOnlySharedMemoryBase = peb->CsrServerReadOnlySharedMemoryBase; 68 | 69 | for(i = 0; i < 4; i++) 70 | output->FlsBitmapBits[i] = peb->FlsBitmapBits[i]; 71 | 72 | output->FlsHighIndex = peb->FlsHighIndex; 73 | output->GdiDCAttributeList = peb->GdiDCAttributeList; 74 | 75 | for(i = 0; i < 60; i++) 76 | output->GdiHandleBuffer[i] = peb->GdiHandleBuffer[i]; 77 | 78 | output->HeapDeCommitFreeBlockThreshold = peb->HeapDeCommitFreeBlockThreshold; 79 | output->HeapDeCommitTotalFreeThreshold = peb->HeapDeCommitTotalFreeThreshold; 80 | output->HeapSegmentCommit = peb->HeapSegmentCommit; 81 | output->HeapSegmentReserve = peb->HeapSegmentReserve; 82 | output->ImageSubsystem = peb->ImageSubsystem; 83 | output->ImageSubsystemMajorVersion = peb->ImageSubsystemMajorVersion; 84 | output->ImageSubsystemMinorVersion = peb->ImageSubsystemMinorVersion; 85 | output->InheritedAddressSpace = peb->InheritedAddressSpace; 86 | output->MaximumNumberOfHeaps = peb->MaximumNumberOfHeaps; 87 | output->MinimumStackCommit = peb->MinimumStackCommit; 88 | output->NtGlobalFlag = peb->NtGlobalFlag; 89 | output->NumberOfHeaps = peb->NumberOfHeaps; 90 | output->NumberOfProcessors = peb->NumberOfProcessors; 91 | output->OSBuildNumber = peb->OSBuildNumber; 92 | output->OSCSDVersion = peb->OSCSDVersion; 93 | output->OSMajorVersion = peb->OSMajorVersion; 94 | output->OSMinorVersion = peb->OSMinorVersion; 95 | output->OSPlatformId = peb->OSPlatformId; 96 | output->ReadImageFileExecOptions = peb->ReadImageFileExecOptions; 97 | output->SessionId = peb->SessionId; 98 | 99 | for(i = 0; i < 1; i++) 100 | output->SystemReserved[i] = peb->SystemReserved[i]; 101 | 102 | for(i = 0; i < 2; i++) 103 | output->TlsBitmapBits[i] = peb->TlsBitmapBits[i]; 104 | 105 | for(i = 0; i < 32; i++) 106 | output->TlsExpansionBitmapBits[i] = peb->TlsExpansionBitmapBits[i]; 107 | 108 | output->TlsExpansionCounter = peb->TlsExpansionCounter; 109 | 110 | 111 | //Pointers 112 | output->ActivationContextData = peb->ActivationContextData; 113 | output->AnsiCodePageData = peb->AnsiCodePageData; 114 | output->ApiSetMap = peb->ApiSetMap; 115 | output->AppCompatInfo = peb->AppCompatInfo; 116 | output->AtlThunkSListPtr = peb->AtlThunkSListPtr; 117 | output->FastPebLock = peb->FastPebLock; 118 | output->FlsBitmap = peb->FlsBitmap; 119 | output->FlsCallback = peb->FlsCallback; 120 | output->GdiSharedHandleTable = peb->GdiSharedHandleTable; 121 | output->IFEOKey = peb->IFEOKey; 122 | output->ImageBaseAddress = peb->ImageBaseAddress; 123 | output->LoaderLock = peb->LoaderLock; 124 | output->Mutant = peb->Mutant; 125 | output->OemCodePageData = peb->OemCodePageData; 126 | output->pImageHeaderHash = peb->pImageHeaderHash; 127 | output->PostProcessInitRoutine = peb->PostProcessInitRoutine; 128 | output->ProcessAssemblyStorageMap = peb->ProcessAssemblyStorageMap; 129 | output->ProcessHeap = peb->ProcessHeap; 130 | output->ProcessHeaps = peb->ProcessHeaps; 131 | output->ProcessStarterHelper = peb->ProcessStarterHelper; 132 | output->pShimData = peb->pShimData; 133 | output->pUnused = peb->pUnused; 134 | output->ReadOnlySharedMemoryBase = peb->ReadOnlySharedMemoryBase; 135 | output->ReadOnlyStaticServerData = peb->ReadOnlyStaticServerData; 136 | output->SparePvoid0 = peb->SparePvoid0; 137 | output->SubSystemData = peb->SubSystemData; 138 | output->SystemAssemblyStorageMap = peb->SystemAssemblyStorageMap; 139 | output->SystemDefaultActivationContextData = peb->SystemDefaultActivationContextData; 140 | output->TlsBitmap = peb->TlsBitmap; 141 | output->TlsExpansionBitmap = peb->TlsExpansionBitmap; 142 | output->UnicodeCaseTableData = peb->UnicodeCaseTableData; 143 | output->WerRegistrationData = peb->WerRegistrationData; 144 | output->WerShipAssertPtr = peb->WerShipAssertPtr; 145 | } 146 | 147 | 148 | 149 | ProcessModule* GetModuleListListEntryMethod(PEBContent* peb, unsigned int pid) 150 | { 151 | LDR_DATA_TABLE_ENTRY dataTable; 152 | LIST_ENTRY* moduleStart = peb->Ldr->InLoadOrderModuleList.Flink; 153 | LIST_ENTRY* currentModule = moduleStart; 154 | LIST_ENTRY nextModule = {0}; 155 | HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); 156 | WCHAR tmpData[2048] = {'\0'}; 157 | SIZE_T read = 0; 158 | 159 | ProcessModule* head = NULL; 160 | 161 | if(processHandle) 162 | { 163 | do 164 | { 165 | 166 | if(!ReadProcessMemory(processHandle, 167 | currentModule, 168 | &nextModule, 169 | sizeof(currentModule), 170 | &read)) 171 | { 172 | printf("Byte read : %lu\n", (unsigned long) read); 173 | DisplayLastError(); 174 | break; 175 | } 176 | 177 | if(!ReadProcessMemory(processHandle, 178 | currentModule, 179 | &dataTable, 180 | sizeof(dataTable), 181 | &read)) 182 | { 183 | printf("Byte read : %lu\n", (unsigned long) read); 184 | DisplayLastError(); 185 | break; 186 | } 187 | 188 | if(!ReadProcessMemory(processHandle, 189 | dataTable.FullDllName.Buffer, 190 | tmpData, 191 | dataTable.FullDllName.Length, 192 | &read)) 193 | { 194 | printf("Byte read : %lu\n", (unsigned long) read); 195 | DisplayLastError(); 196 | break; 197 | } 198 | 199 | ANSI_STRING tmpStrFullName = CreateAnsiStringDataFromUnicode(tmpData, read); 200 | dataTable.FullDllName.Buffer = (PWSTR) tmpStrFullName.Buffer; 201 | 202 | memset(tmpData, 0, dataTable.FullDllName.Length * sizeof(WCHAR)); 203 | 204 | if(!ReadProcessMemory(processHandle, 205 | dataTable.BaseDllName.Buffer, 206 | tmpData, 207 | dataTable.BaseDllName.Length, 208 | &read)) 209 | { 210 | printf("Byte read : %lu\n", (unsigned long) read); 211 | DisplayLastError(); 212 | break; 213 | } 214 | 215 | ANSI_STRING tmpStrDllName = CreateAnsiStringDataFromUnicode(tmpData, read); 216 | dataTable.BaseDllName.Buffer = (PWSTR) tmpStrDllName.Buffer; 217 | 218 | AddHeadProcessModule(&head, CreateSingleProcessModuleFromDataTable(&dataTable)); 219 | 220 | memset(tmpData, 0, dataTable.BaseDllName.Length * sizeof(WCHAR)); 221 | 222 | currentModule = nextModule.Flink; 223 | }while(currentModule != moduleStart); 224 | } 225 | 226 | CloseHandle(processHandle); 227 | 228 | return head; 229 | } 230 | 231 | 232 | 233 | 234 | PEBContent* GetPEBContentFromPid(unsigned long pid) 235 | { 236 | 237 | PEBContent* result = CreatePEBContent(); 238 | 239 | SIZE_T read; 240 | BOOL isWow64 = TRUE; 241 | HANDLE processHandle; 242 | PEB peb; 243 | RTL_USER_PROCESS_PARAMETERS procParam; 244 | PEB_LDR_DATA pLdrData; 245 | WCHAR tmpData[8192] = {'\0'}; 246 | 247 | PROCESS_BASIC_INFORMATION* pInfo; 248 | 249 | processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); 250 | 251 | if(!processHandle) 252 | { 253 | printf("INFO : Impossible d'obtenir un handle sur ce processus.\n"); 254 | DisplayLastError(); 255 | return result; 256 | } 257 | 258 | IsWow64Process(processHandle, &isWow64); 259 | 260 | pInfo = QueryProcessBasicInformation(NULL, pid); 261 | if(pInfo != NULL) 262 | { 263 | 264 | 265 | //PEB MAIN// 266 | if(!ReadProcessMemory(processHandle, 267 | pInfo->PebBaseAddress, 268 | &peb, 269 | sizeof(peb), 270 | &read)) 271 | { 272 | printf("Byte read : %lu\n", (unsigned long) read); 273 | DisplayLastError(); 274 | return result; 275 | } 276 | 277 | FillMainPEB(&peb, result); 278 | 279 | //PEB LDR// 280 | if(!ReadProcessMemory(processHandle, 281 | peb.Ldr, 282 | &pLdrData, 283 | sizeof(pLdrData), 284 | &read)) 285 | { 286 | printf("Byte read : %lu\n", (unsigned long) read); 287 | DisplayLastError(); 288 | return result; 289 | } 290 | 291 | FillLdrPEB(&pLdrData, result); 292 | 293 | 294 | //PEB PROCESS PARAMETERS// 295 | if(!ReadProcessMemory(processHandle, 296 | peb.ProcessParameters, 297 | &procParam, 298 | sizeof(RTL_USER_PROCESS_PARAMETERS), 299 | &read)) 300 | { 301 | printf("Byte read : %lu\n", (unsigned long) read); 302 | DisplayLastError(); 303 | return result; 304 | } 305 | 306 | FillProcessParametersPEB(&procParam, result); 307 | 308 | char* environmentStringsBuf = (char*) calloc(procParam.EnvironmentSize, sizeof(char)); 309 | char* formattedEnvironmentStrings = (char*) calloc(procParam.EnvironmentSize, sizeof(char)); 310 | 311 | //PEB PROCESS PARAMETERS ENVIRONMENT STRINGS// 312 | if(!ReadProcessMemory(processHandle, 313 | procParam.Environment, 314 | environmentStringsBuf, 315 | procParam.EnvironmentSize, 316 | &read)) 317 | { 318 | printf("Byte read : %lu\n", (unsigned long) read); 319 | DisplayLastError(); 320 | return result; 321 | } 322 | 323 | char currentChar; 324 | unsigned int index = 0; 325 | puts(""); 326 | do 327 | { 328 | 329 | currentChar = environmentStringsBuf[index]; 330 | 331 | if(currentChar != '\0') 332 | sprintf(formattedEnvironmentStrings+index/2, "%c", currentChar); 333 | else 334 | sprintf(formattedEnvironmentStrings+index/2, "\n"); 335 | 336 | index += 2; 337 | }while(index < procParam.EnvironmentSize); 338 | 339 | free(environmentStringsBuf); 340 | result->ProcessParameters->Environment = formattedEnvironmentStrings; 341 | 342 | 343 | //PEB PROCESS PARAMETERS CURRENT DIRECTORIES// 344 | unsigned int i = 0; 345 | do 346 | { 347 | if(!ReadProcessMemory(processHandle, 348 | procParam.CurrentDirectories[i].DosPath.Buffer, 349 | tmpData, 350 | procParam.CurrentDirectories[i].DosPath.Length, 351 | &read)) 352 | { 353 | printf("Byte read : %lu\n", (unsigned long) read); 354 | DisplayLastError(); 355 | return result; 356 | } 357 | 358 | result->ProcessParameters->CurrentDirectories[i].DosPath = CreateAnsiStringDataFromUnicode(tmpData, read); 359 | memset(tmpData, 0, procParam.CurrentDirectories[i].DosPath.Length * sizeof(WCHAR)); 360 | 361 | i++; 362 | }while(i < 32); 363 | 364 | 365 | //PEB PROCESS PARAMETERS CURRENT DIRECTORIES// 366 | if(!ReadProcessMemory(processHandle, 367 | procParam.CurrentDirectory.DosPath.Buffer, 368 | tmpData, 369 | procParam.CurrentDirectory.DosPath.Length, 370 | &read)) 371 | { 372 | printf("Byte read : %lu\n", (unsigned long) read); 373 | DisplayLastError(); 374 | return result; 375 | } 376 | result->ProcessParameters->CurrentDirectory.DosPath = CreateAnsiStringDataFromUnicode(tmpData, read); 377 | memset(tmpData, 0, procParam.CurrentDirectory.DosPath.Length * sizeof(WCHAR)); 378 | 379 | //PEB PROCESS PARAMETERS COMMAND LINE// 380 | if(!ReadProcessMemory(processHandle, 381 | procParam.CommandLine.Buffer, 382 | tmpData, 383 | procParam.CommandLine.Length, 384 | &read)) 385 | { 386 | printf("Byte read : %lu\n", (unsigned long) read); 387 | DisplayLastError(); 388 | return result; 389 | } 390 | result->ProcessParameters->CommandLine = CreateAnsiStringDataFromUnicode(tmpData, read); 391 | // printf("process handle (%p) : %s (%u octets)\n", processHandle, result->ProcessParameters->CommandLine.Buffer, result->ProcessParameters->CommandLine.Length); 392 | 393 | if(procParam.CommandLine.Length != 0) 394 | memset(tmpData, 0, procParam.CommandLine.Length * sizeof(WCHAR)); 395 | 396 | //PEB PROCESS PARAMETERS WINDOW TITLE// 397 | if(!ReadProcessMemory(processHandle, 398 | procParam.WindowTitle.Buffer, 399 | tmpData, 400 | procParam.WindowTitle.Length, 401 | &read)) 402 | { 403 | printf("Byte read : %lu\n", (unsigned long) read); 404 | DisplayLastError(); 405 | return result; 406 | } 407 | result->ProcessParameters->WindowTitle = CreateAnsiStringDataFromUnicode(tmpData, read); 408 | 409 | if(procParam.WindowTitle.Length != 0) 410 | memset(tmpData, 0, procParam.WindowTitle.Length * sizeof(WCHAR)); 411 | 412 | //PEB PROCESS PARAMETERS DLL PATH// 413 | if(!ReadProcessMemory(processHandle, 414 | procParam.DllPath.Buffer, 415 | tmpData, 416 | procParam.DllPath.Length, 417 | &read)) 418 | { 419 | printf("Byte read : %lu\n", (unsigned long) read); 420 | DisplayLastError(); 421 | return result; 422 | } 423 | result->ProcessParameters->DllPath = CreateAnsiStringDataFromUnicode(tmpData, read); 424 | 425 | if(procParam.DllPath.Length != 0) 426 | memset(tmpData, 0, procParam.DllPath.Length * sizeof(WCHAR)); 427 | 428 | //PEB PROCESS PARAMETERS IMAGE PATH// 429 | if(!ReadProcessMemory(processHandle, 430 | procParam.ImagePathName.Buffer, 431 | tmpData, 432 | procParam.ImagePathName.Length, 433 | &read)) 434 | { 435 | printf("Byte read : %lu\n", (unsigned long) read); 436 | DisplayLastError(); 437 | return result; 438 | } 439 | result->ProcessParameters->ImagePathName = CreateAnsiStringDataFromUnicode(tmpData, read); 440 | 441 | if(procParam.ImagePathName.Length != 0) 442 | memset(tmpData, 0, procParam.ImagePathName.Length * sizeof(WCHAR)); 443 | 444 | //PEB PROCESS PARAMETERS DESKTOP INFO// 445 | if(!ReadProcessMemory(processHandle, 446 | procParam.DesktopInfo.Buffer, 447 | tmpData, 448 | procParam.DesktopInfo.Length, 449 | &read)) 450 | { 451 | printf("Byte read : %lu\n", (unsigned long) read); 452 | DisplayLastError(); 453 | return result; 454 | } 455 | result->ProcessParameters->DesktopInfo = CreateAnsiStringDataFromUnicode(tmpData, read); 456 | 457 | if(procParam.DesktopInfo.Length != 0) 458 | memset(tmpData, 0, procParam.DesktopInfo.Length * sizeof(WCHAR)); 459 | 460 | //PEB PROCESS PARAMETERS SHELL INFO// 461 | if(!ReadProcessMemory(processHandle, 462 | procParam.ShellInfo.Buffer, 463 | tmpData, 464 | procParam.ShellInfo.Length, 465 | &read)) 466 | { 467 | printf("Byte read : %lu\n", (unsigned long) read); 468 | DisplayLastError(); 469 | return result; 470 | } 471 | result->ProcessParameters->ShellInfo = CreateAnsiStringDataFromUnicode(tmpData, read); 472 | 473 | if(procParam.ShellInfo.Length != 0) 474 | memset(tmpData, 0, procParam.ShellInfo.Length * sizeof(WCHAR)); 475 | 476 | //PEB LDR MODULE LIST// 477 | result->Ldr->moduleList = GetModuleListListEntryMethod(result, pid); 478 | 479 | } 480 | 481 | free(pInfo); 482 | CloseHandle(processHandle); 483 | 484 | return result; 485 | } 486 | 487 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GetPEBContent.h: -------------------------------------------------------------------------------- 1 | #ifndef GETPEBCONTENT_H 2 | #define GETPEBCONTENT_H 3 | 4 | 5 | PEBContent* GetPEBContentFromPid(unsigned long pid); 6 | 7 | #endif // GETPEBCONTENT_H 8 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GetProcessInformation.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_QUERYPROCESSINFORMATION 2 | #define DEF_QUERYPROCESSINFORMATION 3 | 4 | #include "ProcessBasicInformation.h" 5 | 6 | #define PTR_ADD_OFFSET(Pointer, Offset) ((PVOID)((ULONG_PTR)(Pointer) + (ULONG_PTR)(Offset))) 7 | 8 | void DisplayProcessList(HMODULE ntdllLibrary); 9 | ProcessInformationList* GetProcessList(HMODULE ntdllLibrary); 10 | ProcessInformation GetProcessInformationsFromPID(HMODULE ntdllLibrary, unsigned long pid); 11 | PROCESS_BASIC_INFORMATION* QueryProcessBasicInformation(HMODULE ntdll, unsigned long pid); 12 | ProcessInformationList* GetProcessInformationsFromName(HMODULE ntdllLibrary, char* processPathName); 13 | 14 | #endif // DEF_QUERYPROCESSINFORMATION 15 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GetProcessModuleList.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ProcessBasicInformation.h" 5 | #include "PEBContent.h" 6 | #include "GetProcessModuleList.h" 7 | 8 | #include "ErrorUtils.h" 9 | -------------------------------------------------------------------------------- /src/LIB_INVADER/GetProcessModuleList.h: -------------------------------------------------------------------------------- 1 | #ifndef GETPROCESSMODULELIST_H 2 | #define GETPROCESSMODULELIST_H 3 | 4 | ProcessModule* GetModuleListListEntryMethod(PEBContent* peb, unsigned int pid); 5 | 6 | #endif // GETPROCESSMODULELIST_H 7 | -------------------------------------------------------------------------------- /src/LIB_INVADER/HandleProcessInformation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ProcessInformation.h" 5 | 6 | 7 | HandleProcessInformation* CreateHandleProcessInformation() 8 | { 9 | HandleProcessInformation* result = (HandleProcessInformation*) malloc(sizeof(HandleProcessInformation)); 10 | if(result != NULL) 11 | { 12 | result->next = NULL; 13 | result->processName[0] = '\0'; 14 | result->name[0] = '\0'; 15 | result->type[0] = '\0'; 16 | result->processPid = -1; 17 | 18 | } 19 | return result; 20 | } 21 | 22 | 23 | void FreeHandleProcessInformation(HandleProcessInformation* handle) 24 | { 25 | HandleProcessInformation** next = &handle->next; 26 | while(handle != NULL) 27 | { 28 | free(handle); 29 | handle = *next; 30 | *next = NULL; 31 | } 32 | } 33 | 34 | void DisplayHandleProcessInformation(HandleProcessInformation* handle) 35 | { 36 | HandleProcessInformation* it; 37 | for(it = handle; it != NULL; it = it->next) 38 | { 39 | if(it != NULL && !(it->processName[0] == '\0' && it->name[0] == '\0' && it->type[0] == '\0')) 40 | { 41 | puts(""); 42 | printf("%s\n", it->name); 43 | printf("\tType : \t\t%s\n", it->type); 44 | printf("\tPossesseur : \t\t%s\n", it->processName); 45 | printf("\tPID possesseur : \t\t%ld\n", it->processPid); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/LIB_INVADER/IMAGE_NT_HEADERS.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGE_NT_HEADERS_H 2 | #define IMAGE_NT_HEADERS_H 3 | 4 | typedef struct _IMAGE_NT_HEADERS { 5 | DWORD Signature; 6 | IMAGE_FILE_HEADER FileHeader; 7 | IMAGE_OPTIONAL_HEADER OptionalHeader; 8 | } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; 9 | 10 | #endif // IMAGE_NT_HEADERS_H 11 | -------------------------------------------------------------------------------- /src/LIB_INVADER/Injector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "NtCreateThread.h" 5 | #include "ASMUtils.h" 6 | #include "ProcessUtils.h" 7 | #include "ErrorUtils.h" 8 | #include "Injector.h" 9 | 10 | 11 | #define DLL_METASPLOIT_ATTACH 4 12 | #define DLL_METASPLOIT_DETACH 5 13 | #define DLL_QUERY_HMODULE 6 14 | 15 | #define DEREF( name )*(UINT_PTR *)(name) 16 | #define DEREF_64( name )*(DWORD64 *)(name) 17 | #define DEREF_32( name )*(DWORD *)(name) 18 | #define DEREF_16( name )*(WORD *)(name) 19 | #define DEREF_8( name )*(BYTE *)(name) 20 | 21 | #define ERROR_CODE_NOT_VALID_WIN32_APP 193 22 | #define ERROR_CODE_FILE_NOT_FOUND 2 23 | 24 | /* 25 | typedef struct _IMAGE_DOS_HEADER 26 | { 27 | 28 | WORD e_magic; // Magic number 29 | WORD e_cblp; // Bytes on last page of file 30 | WORD e_cp; // Pages in file 31 | WORD e_crlc; // Relocations 32 | WORD e_cparhdr; // Size of header in paragraphs 33 | WORD e_minalloc; // Minimum extra paragraphs needed 34 | WORD e_maxalloc; // Maximum extra paragraphs needed 35 | WORD e_ss; // Initial (relative) SS value 36 | WORD e_sp; // Initial SP value 37 | WORD e_csum; // Checksum 38 | WORD e_ip; // Initial IP value 39 | WORD e_cs; // Initial (relative) CS value 40 | WORD e_lfarlc; // File address of relocation table 41 | WORD e_ovno; // Overlay number 42 | WORD e_res[4]; // Reserved words 43 | WORD e_oemid; // OEM identifier (for e_oeminfo) 44 | WORD e_oeminfo; // OEM information; e_oemid specific 45 | WORD e_res2[10]; // Reserved words 46 | LONG e_lfanew; // File address of new exe header 47 | 48 | } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 49 | */ 50 | 51 | PVOID AllocWriteStrInTarget(HANDLE hTarget, const char* str) { 52 | PVOID loc = VirtualAllocEx(hTarget, NULL, strlen(str) + 1, MEM_COMMIT, PAGE_READWRITE); 53 | WriteProcessMemory(hTarget, loc, str, strlen(str) + 1, NULL); 54 | return loc; 55 | } 56 | 57 | DWORD GetFileOffsetFromRVA(DWORD pRva, UINT_PTR pBaseAddress) 58 | { 59 | WORD index; 60 | 61 | //Pointe vers l'adresse réelle du header des nouveaux fichiers exécutables (et non les exécutables DOS) 62 | // = Récupération du pointeur vers le header du fichier 63 | PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(pBaseAddress + ((PIMAGE_DOS_HEADER)pBaseAddress)->e_lfanew); 64 | 65 | //Pointe vers la première section du header, se situant après le header optionnel (à ADDR_OPT_HEADER + SIZE_OPT_HEADER) 66 | // = Récupération du pointeur vers la 1ère section du header 67 | //Equivalent à IMAGE_FIRST_SECTION(pNtHeaders); 68 | PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader); 69 | 70 | //Si le pointeur fourni est hors des sections du header, on le retourne lui-même : il ne figure pas dans les sections. 71 | if(pRva < pSectionHeader[0].PointerToRawData) 72 | return pRva; 73 | 74 | for(index = 0; index < pNtHeaders->FileHeader.NumberOfSections; index++) 75 | { 76 | PIMAGE_SECTION_HEADER pCurSection = pSectionHeader + index; 77 | //Si le pointeur de RVA est dans la section pointée courante (entre "son adresse de base" et "son adresse de base + taille de la section") 78 | if(pRva >= pCurSection->VirtualAddress && pRva < pCurSection->VirtualAddress + pCurSection->SizeOfRawData) 79 | { 80 | 81 | //Maintenant que nous sommes sûrs que la RVA appartient bien à la section courante, 82 | //la "formule magique" pour obtenir le file offset pointant vers cette adresse est : 83 | // pRva - pVa + pSection 84 | DWORD fileOffset = pRva - pCurSection->VirtualAddress; 85 | fileOffset += pCurSection->PointerToRawData; 86 | return fileOffset; 87 | } 88 | } 89 | return 0; 90 | } 91 | 92 | //Les PE files peuvent être à la fois de 64 bits ou de 32 bits. 93 | //Cette fonction renvoie "true" lorsqu'un PE de 32 bits tourne sur une machine de 32 bits, 94 | //ou un PE de 64 bits sur une machine de 64 bits 95 | int IsValidCurrentPEBArchitecture(PVOID baseAddress) 96 | { 97 | DWORD currentArch; 98 | 99 | #ifdef WIN_X64 100 | currentArch = 2; 101 | #else 102 | currentArch = 1; 103 | //Toute archi sauf x64 (WIN RT et WIN32) 104 | #endif 105 | 106 | DWORD osVersion = ((PIMAGE_NT_HEADERS)baseAddress)->OptionalHeader.Magic; 107 | 108 | if( 109 | (osVersion == IMAGE_NT_OPTIONAL_HDR32_MAGIC && currentArch != 1) // PE32, x64 running 110 | || 111 | (osVersion == IMAGE_NT_OPTIONAL_HDR64_MAGIC && currentArch != 2) // PE64, x86 running 112 | ) 113 | { 114 | return 0; 115 | } 116 | return 1; 117 | } 118 | 119 | 120 | 121 | /* 122 | *typedef struct _IMAGE_EXPORT_DIRECTORY 123 | { 124 | DWORD Characteristics; 125 | DWORD TimeDateStamp; 126 | WORD MajorVersion; 127 | WORD MinorVersion; 128 | DWORD Name; 129 | DWORD Base; 130 | DWORD NumberOfFunctions; //Le nombre de fonctions exportées par le module 131 | DWORD NumberOfNames; //Le nombre de noms de fonctions 132 | DWORD AddressOfFunctions; //Un pointeur (PDWORD*) de pointeurs vers les adresses des fonctions 133 | DWORD AddressOfNames; //Pointeur (DWORD*) sur la première case d'un tableau de 134 | //pointeurs vers la chaîne de caractères du nom de la fonction 135 | //(en quelque sorte, un String**) 136 | DWORD AddressOfNameOrdinals; //Pointeur (WORD*) vers un tableau d'index pour convertir un ordinal 137 | //vers son index correspondant dans AddressOfFUnctions 138 | } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; 139 | */ 140 | 141 | 142 | DWORD GetExportDllOffset(UINT_PTR uiBaseAddress, char* dllPathName) 143 | { 144 | UINT_PTR uiExportDir = 0; 145 | UINT_PTR uiNameArray = 0; 146 | UINT_PTR uiAddressArray = 0; 147 | UINT_PTR uiNameOrdinals = 0; 148 | DWORD dwCounter = 0; 149 | 150 | DWORD pExportDllResult = 0; 151 | 152 | if(!IsValidCurrentPEBArchitecture((PVOID)uiBaseAddress)) 153 | { 154 | printf("Error : Invalid PEB version\n"); 155 | return 0; 156 | } 157 | 158 | printf("Base address : %p\n", (PVOID)uiBaseAddress); 159 | 160 | //Adresses RVA 161 | uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew; 162 | 163 | 164 | if(((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) 165 | { 166 | uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ]; 167 | printf("Export dir RVA : %p\n", (PVOID)uiExportDir); 168 | printf("Export Name Array RVA : %p\n", (PVOID)uiNameArray); 169 | 170 | //Adresses basées sur l'offset par rapport au fichier 171 | uiExportDir = uiBaseAddress + GetFileOffsetFromRVA( ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress ); 172 | uiNameArray = uiBaseAddress + GetFileOffsetFromRVA( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames, uiBaseAddress ); 173 | uiAddressArray = uiBaseAddress + GetFileOffsetFromRVA( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress ); 174 | uiNameOrdinals = uiBaseAddress + GetFileOffsetFromRVA( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals, uiBaseAddress ); 175 | 176 | printf("Export Dir FILE OFFSET : %p\n", (PVOID)uiExportDir); 177 | printf("Export Name Array FILE OFFSET : %p\n", (PVOID)uiNameArray); 178 | printf("Export Address Array FILE OFFSET : %p\n", (PVOID)uiAddressArray); 179 | printf("Export Name Ordinals FILE OFFSET : %p\n", (PVOID)uiNameOrdinals); 180 | 181 | //Nombre de fonctions exportées dans la dll 182 | dwCounter = ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->NumberOfNames; 183 | 184 | printf("Number of Names : %u\n", (unsigned int) dwCounter); 185 | 186 | LPSTR libname[256]; 187 | size_t i = 0; 188 | 189 | while(dwCounter--) 190 | { 191 | printf("Library Name :"); 192 | 193 | //Get the name of each DLL 194 | libname[i] = (PCHAR)((DWORD_PTR)uiBaseAddress + GetFileOffsetFromRVA(DEREF_32(uiNameArray), uiBaseAddress)); 195 | printf("%s\n", libname[i]); 196 | 197 | if(dllPathName != NULL && strstr(libname[i], dllPathName) != NULL ) 198 | { 199 | uiAddressArray = uiBaseAddress + GetFileOffsetFromRVA( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress ); 200 | 201 | // use the functions name ordinal as an index into the array of name pointers 202 | uiAddressArray += (DEREF_16( uiNameOrdinals ) * sizeof(DWORD) ); 203 | pExportDllResult = GetFileOffsetFromRVA(DEREF_32(uiAddressArray), uiBaseAddress); 204 | } 205 | 206 | // get the next exported function name 207 | uiNameArray += sizeof(DWORD); 208 | 209 | // get the next exported function name ordinal 210 | uiNameOrdinals += sizeof(WORD); 211 | i++; 212 | } 213 | 214 | } 215 | else 216 | { 217 | printf("No Export Table!\n"); 218 | } 219 | 220 | return pExportDllResult; 221 | } 222 | 223 | /* 224 | * ATTENTION, NE PAS OUBLIER L'APPEL à 225 | * 226 | VirtualFree(uiBaseAddress, fileSize, MEM_DECOMMIT); 227 | 228 | après avoir utilisé cette fonction. 229 | */ 230 | PVOID GetRVAFromFilename(char* pathFileName, DWORD* outputFileSize) 231 | { 232 | HANDLE handle = CreateFile((LPCTSTR)pathFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 233 | DWORD byteRead; 234 | 235 | if(handle) 236 | { 237 | *outputFileSize = GetFileSize(handle, NULL); 238 | PVOID vPFile = VirtualAlloc(NULL, *outputFileSize, MEM_COMMIT, PAGE_READWRITE); 239 | ReadFile(handle, vPFile, *outputFileSize, &byteRead, NULL); 240 | CloseHandle(handle); 241 | 242 | return vPFile; 243 | } 244 | return (PVOID)NULL; 245 | } 246 | 247 | DWORD WaitReturnValueFromThread(HANDLE pHandle, PDWORD exitCode) { 248 | DWORD result = WaitForSingleObject(pHandle, INFINITE); 249 | 250 | if (result == WAIT_OBJECT_0) { 251 | BOOL rc = GetExitCodeThread( pHandle, exitCode); 252 | if (rc != NULL) { 253 | return *exitCode; 254 | } 255 | DisplayLastError(); 256 | } 257 | 258 | return -1; 259 | } 260 | 261 | 262 | DWORD Queryx86ProcAddress(LPWSTR moduleName, LPWSTR procName) { 263 | STARTUPINFOW si; 264 | PROCESS_INFORMATION pi; 265 | 266 | ZeroMemory(&si, sizeof(si)); 267 | si.cb = sizeof(si); 268 | ZeroMemory(&pi, sizeof(pi)); 269 | 270 | WCHAR cmdLine[2048] = { 0 }; 271 | DWORD result; 272 | wsprintfW(cmdLine, L"Getx86Proc.exe %s %s", moduleName, procName); 273 | 274 | if (!CreateProcessW( 275 | NULL, 276 | cmdLine, 277 | NULL, // Process handle not inheritable 278 | NULL, // Thread handle not inheritable 279 | FALSE, // Set handle inheritance to FALSE 280 | 0, // No creation flags 281 | NULL, // Use parent's environment block 282 | NULL, // Use parent's starting directory 283 | &si, // Pointer to STARTUPINFO structure 284 | &pi)) 285 | { 286 | printf("CreateProcess (on Getx86Proc.exe) failed : "); 287 | DWORD lastErrorCode = GetLastError(); 288 | if (lastErrorCode != ERROR_CODE_FILE_NOT_FOUND) { 289 | DisplayErrorWithCode(NULL, lastErrorCode); 290 | } 291 | else { 292 | printf(" unable to find Getx86Proc.exe. Please put it next to Injectx64 and rewrite your command.\n"); 293 | } 294 | 295 | return NULL; 296 | } 297 | 298 | // Wait until child process exits. 299 | WaitForSingleObject(pi.hProcess, INFINITE); 300 | 301 | GetExitCodeProcess(pi.hProcess, &result); 302 | 303 | // Close process and thread handles. 304 | CloseHandle(pi.hProcess); 305 | CloseHandle(pi.hThread); 306 | 307 | return result; 308 | } 309 | 310 | PVOID InjectLoadLibraryInMem(HANDLE pHandle, const char* fullDllPath, PVOID dllFullPathNameLoc, bool injectx64, unsigned int *outputCodeSize) { 311 | BYTE* gCode; 312 | unsigned int codeSize; 313 | 314 | /* 315 | * "Strictly speaking, this is not guaranteed to work because the address of LoadLibraryA in your process is not necessarily the same as LoadLibraryA in the other process. 316 | * However, in practice it does work because system DLLs like kernel32 (where LoadLibraryA resides) are mapped to the same address in all processes, 317 | * so LoadLibraryA also has the same address in both processes." 318 | (Igor Skochinsky) 319 | Quoted from StackOverflow 320 | 321 | => In fact ASLR is only started once at startup and then, each Win32 Dll have the same address in any process 322 | */ 323 | 324 | 325 | if (injectx64) { 326 | #ifdef _WIN64 327 | PVOID outputCurrentDir = VirtualAllocEx(pHandle, NULL, 2048 + 1, MEM_COMMIT, PAGE_READWRITE); 328 | char * dllCurrentDirectory = (char*) malloc(strlen(fullDllPath) + 1); 329 | strcpy(dllCurrentDirectory, fullDllPath); 330 | 331 | bool firstSlash = false; 332 | 333 | for (int i = strlen(fullDllPath) + 1; i >= 0; i--) { 334 | if (fullDllPath[i] == '\\') { 335 | if (!firstSlash) { 336 | firstSlash = true; 337 | dllCurrentDirectory[i] = '\0'; 338 | continue; 339 | } 340 | } else if (!firstSlash) { 341 | continue; 342 | } 343 | 344 | dllCurrentDirectory[i] = fullDllPath[i]; 345 | } 346 | 347 | PVOID dllCurDirLoc = AllocWriteStrInTarget(pHandle, dllCurrentDirectory); 348 | free(dllCurrentDirectory); 349 | 350 | PVOID loadLibAProc = (PVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); 351 | PVOID setCurrentDirectoryA = (PVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetCurrentDirectoryA"); 352 | PVOID getCurrentDirectoryA = (PVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCurrentDirectoryA"); 353 | PVOID getLastErrorProc = (PVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetLastError"); 354 | 355 | if (loadLibAProc == NULL) { 356 | printf("Error occured while finding LoadLibraryA address : address = 0x%p\n", loadLibAProc); 357 | DisplayLastError(); 358 | return NULL; 359 | } 360 | 361 | if (getLastErrorProc == NULL) { 362 | printf("Error occured while finding GetLastError address : address = 0x%p\n", getLastErrorProc); 363 | DisplayLastError(); 364 | return NULL; 365 | } 366 | 367 | BYTE code[] = { 368 | 0x51, 0x52, 0x57, //PUSH RCX, PUSH RDX, PUSH RDI 369 | 0x48, 0x81, 0xEC, 0x80, 0x00, 0x00, 0x00, //SUB RSP, 0x80 370 | 371 | //GetCurrentDirectoryA 372 | 0x48, 0xB8, //MOV RAX, 373 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //getCurrentDirectoryA 374 | 0x48, 0xC7, 0xC1, //MOV RCX, 2048 375 | 0x00, 0x08, 0x00, 0x00, 376 | 0x48, 0xBA, //MOV RDX, 377 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //outputCurDir 378 | 0xFF, 0xD0, //CALL RAX 379 | 380 | //SetCurrentDirectoryA 381 | 0x48, 0xB8, //MOV RAX, 382 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //setCurrentDirectoryA 383 | 0x48, 0xB9, //MOV RCX, 384 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //dllDirectory 385 | 0xFF, 0xD0, //CALL RAX 386 | 387 | //LoadLibraryA 388 | 0x48, 0xB8, //MOV RAX, 389 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //loadLibAProc 390 | 0x48, 0xB9, //MOV RCX, 391 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //dllFullPathNameLoc 392 | 0xFF, 0xD0, //CALL RAX 393 | 0x48, 0x85, 0xC0, //TEST RAX, RAX 394 | 0x74, 0x05, //JE 395 | 0x48, 0x31, 0xC0, //XOR RAX, RAX 396 | 0xEB, 0x0C, //JMP 397 | //: 398 | 0x48, 0xb8, //MOV RAX, 399 | 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, //getLastErrorProc 400 | 0xff, 0xd0, //CALL RAX 401 | //: 402 | 403 | //SetCurrentDirectoryA 404 | 0x48, 0x89, 0xC7, //MOV RDI, RAX 405 | 0x48, 0xB8, //MOV RAX, 406 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //setCurrentDirectoryA 407 | 0x48, 0xB9, //MOV RCX, 408 | 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, //outputCurDir 409 | 0xFF, 0xD0, //CALL RAX 410 | 0x48, 0x89, 0xF8, //MOV RAX, RDI 411 | 412 | 0x48, 0x81, 0xc4, 0x80, 0x00, 0x00, 0x00, //ADD RSP, 0x80 413 | 0x5F, 0x5A, 0x59, //POP RDI, POP RDX, POP RCX 414 | 0xC3 }; //RET 415 | 416 | 417 | ASMUtils::reverseAddressx64((DWORD64)getCurrentDirectoryA, code + 9 + 3); 418 | ASMUtils::reverseAddressx64((DWORD64)outputCurrentDir, code + 26 + 3); 419 | ASMUtils::reverseAddressx64((DWORD64)setCurrentDirectoryA, code + 38 + 3); 420 | ASMUtils::reverseAddressx64((DWORD64)dllCurDirLoc, code + 48 + 3); 421 | ASMUtils::reverseAddressx64((DWORD64)loadLibAProc, code + 60 + 3); 422 | ASMUtils::reverseAddressx64((DWORD64)dllFullPathNameLoc, code + 70 + 3); 423 | ASMUtils::reverseAddressx64((DWORD64)getLastErrorProc, code + 92 + 3); 424 | ASMUtils::reverseAddressx64((DWORD64)setCurrentDirectoryA, code + 105 + 5); 425 | ASMUtils::reverseAddressx64((DWORD64)outputCurrentDir, code + 115 + 5); 426 | 427 | ASMUtils::printCode(code, sizeof(code)); 428 | 429 | gCode = code; 430 | codeSize = sizeof(code); 431 | #else 432 | printf("Erreur : l'injection a partir d'un injecteur 32 bits dans un processus 64 bits n'est pas supportee dans cette version\nMerci d'utiliser la version 64 bits\n"); 433 | return NULL; 434 | #endif 435 | } else { 436 | #ifdef _WIN64 437 | DWORD loadLibAProc = Queryx86ProcAddress(L"kernel32.dll", L"LoadLibraryA"); 438 | DWORD setCurrentDirectoryA = Queryx86ProcAddress(L"kernel32.dll", L"SetCurrentDirectoryA"); 439 | DWORD getCurrentDirectoryA = Queryx86ProcAddress(L"kernel32.dll", L"GetCurrentDirectoryA"); 440 | DWORD getLastErrorProc = Queryx86ProcAddress(L"kernel32.dll", L"GetLastError"); 441 | #else 442 | DWORD loadLibAProc = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); 443 | DWORD setCurrentDirectoryA = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetCurrentDirectoryA"); 444 | DWORD getCurrentDirectoryA = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCurrentDirectoryA"); 445 | DWORD getLastErrorProc = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetLastError"); 446 | #endif 447 | if (loadLibAProc == NULL) { 448 | printf("Error occured while finding LoadLibraryA address : address = 0x%08x\n", loadLibAProc); 449 | return NULL; 450 | } 451 | 452 | if (getLastErrorProc == NULL) { 453 | printf("Error occured while finding GetLastError address : address = 0x%08x\n", getLastErrorProc); 454 | return NULL; 455 | } 456 | 457 | BYTE code[] = { 458 | 0x57, //PUSH EDI 459 | 0x83, 0xEC, 0x40, //SUB ESP, 0x40 460 | 0xB8, //MOV EAX, 461 | 0xEF, 0xBE, 0xAD, 0xDE, //loadLibAProc 462 | 0x68, //PUSH 463 | 0xEF, 0xBE, 0xAD, 0xDE, //dllFullPathNameLoc 464 | 0xFF, 0xD0, //CALL EAX 465 | 0x85, 0xC0, //TEST EAX, EAX 466 | 0x74, 0x04, //JE 467 | 0x31, 0xC0, //XOR EAX, EAX 468 | 0xEB, 0x07, //JMP 469 | //: 470 | 0xB8, //MOV EAX, 471 | 0xEF, 0xBE, 0xAD, 0xDE, //getLastErrorProc 472 | 0xFF, 0xD0, //CALL EAX 473 | //: 474 | 0x83, 0xC4, 0x40, //ADD ESP, 0x40 475 | 0x5F, //POP EDI 476 | 0xC3 }; //RET 477 | 478 | 479 | 480 | DWORD dllLoc = (DWORD)dllFullPathNameLoc; 481 | 482 | ASMUtils::reverseAddressx86((DWORD)loadLibAProc, code + 5); 483 | ASMUtils::reverseAddressx86(dllLoc, code + 10); 484 | ASMUtils::reverseAddressx86((DWORD)getLastErrorProc, code + 25); 485 | 486 | gCode = code; 487 | codeSize = sizeof(code); 488 | } 489 | *outputCodeSize = codeSize; 490 | return ASMUtils::writeAssembly(pHandle, gCode, codeSize); 491 | } 492 | 493 | DWORD64 GetExecutionPointer(PCONTEXT ctx) { 494 | /* We cheat here : we convert every address to a 64 bits size variable in order 495 | to have enough place to stock both a 32 bits value or a 64 bits one */ 496 | #ifdef _WIN64 497 | DWORD64 executionPointer = ctx->Rip; 498 | #else 499 | DWORD64 executionPointer = (DWORD64)ctx->Eip; 500 | #endif 501 | return executionPointer; 502 | } 503 | 504 | void SetExecutionPointer(PCONTEXT ctx, DWORD64 ep) { 505 | #ifdef _WIN64 506 | ctx->Rip = ep; 507 | #else 508 | ctx->Eip = (DWORD) ep; 509 | #endif 510 | } 511 | 512 | PVOID InjectInfiniteLoop(HANDLE pHandle, SIZE_T* bytesWritten) { 513 | BYTE code[] = { 0xEB, 0xFE }; 514 | *bytesWritten = sizeof(code); 515 | return ASMUtils::writeAssembly(pHandle, code, sizeof(code)); 516 | } 517 | 518 | int InjectDllCreatingSuspendedProcess(const char* processPathName, const char* cmdLine, const char* dllPathName, int method) { 519 | char fullCmdLine[4096]; 520 | if (cmdLine != NULL) { 521 | sprintf(fullCmdLine, "%s %s", processPathName, cmdLine); 522 | } else { 523 | strcpy(fullCmdLine, processPathName); 524 | } 525 | 526 | CONTEXT ctx; 527 | PROCESS_INFORMATION pi; 528 | STARTUPINFOA startup; 529 | ZeroMemory(&startup, sizeof(startup)); 530 | ZeroMemory(&pi, sizeof(pi)); 531 | 532 | printf("Creating suspended process \"%s\"\n", fullCmdLine); 533 | if (!CreateProcessA(NULL, fullCmdLine, NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, &startup, &pi)) { 534 | DisplayLastError(); 535 | return 0; 536 | } 537 | 538 | ctx.ContextFlags = CONTEXT_CONTROL; 539 | GetThreadContext(pi.hThread, &ctx); 540 | 541 | /* We save current thread execution pointer in order to move it, execute some code (infinite loop) and restore it */ 542 | DWORD64 lastEPointer = GetExecutionPointer(&ctx); 543 | 544 | //printf("Thread Execution Pointer : 0x%p\n", lastEPointer); 545 | 546 | /* We write the infinite loop */ 547 | SIZE_T bytesWritten; 548 | PVOID infiniteLoopCode = InjectInfiniteLoop(pi.hProcess, &bytesWritten); 549 | SetExecutionPointer(&ctx, (DWORD64)infiniteLoopCode); 550 | ctx.ContextFlags = CONTEXT_CONTROL; 551 | SetThreadContext(pi.hThread, &ctx); 552 | 553 | ResumeThread(pi.hThread); 554 | printf("Process resumed in infinite loop, now injecting Dll\n"); 555 | 556 | int result = InjectDllRemoteThread(GetProcessId(pi.hProcess), dllPathName, method); 557 | 558 | printf("Injection terminated. Restoring EIP/RIP\n"); 559 | 560 | /* Injection OK : process will start with dll loaded, we cleanup everything*/ 561 | if (result == 1) { 562 | system("cls"); 563 | } 564 | 565 | SuspendThread(pi.hThread); 566 | 567 | ctx.ContextFlags = CONTEXT_CONTROL; 568 | GetThreadContext(pi.hThread, &ctx); 569 | SetExecutionPointer(&ctx, lastEPointer); 570 | SetThreadContext(pi.hThread, &ctx); 571 | 572 | VirtualFreeEx(pi.hProcess, infiniteLoopCode, bytesWritten, MEM_RELEASE); 573 | 574 | ResumeThread(pi.hThread); 575 | 576 | return result; 577 | } 578 | 579 | int InjectDllRemoteThread(DWORD pid, const char * dllPathName, int method) { 580 | HANDLE pHandle; 581 | HANDLE threadHandle; 582 | LPVOID dllFullPathNameLoc; 583 | int result = 1; 584 | 585 | char fullDllPath[1024] = { 0 }; 586 | 587 | pHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); 588 | if (pHandle == NULL) { 589 | DisplayLastError(); 590 | return 0; 591 | } 592 | 593 | if (GetFullPathNameA(dllPathName, sizeof(fullDllPath), fullDllPath, NULL) == 0) { 594 | DisplayLastError(); 595 | CloseHandle(pHandle); 596 | return 0; 597 | } 598 | 599 | printf("Full Dll path name : %s\n", fullDllPath); 600 | 601 | dllFullPathNameLoc = AllocWriteStrInTarget(pHandle, fullDllPath); 602 | 603 | /* x64 mode : LoadLibrary returns a QWORD (8 bits address to the module loaded) while an exit code only accepts 4 bits (DWORD) 604 | That's why I created a small assembly code that call GetLastError and returns the error code when LoadLibrary fails in x64 mode*/ 605 | PVOID remoteProcedure; 606 | bool isTargetx64; 607 | 608 | if (isTargetx64 = Is64Process(GetProcessId(pHandle))) { 609 | printf("Target process is in x64 mode\n"); 610 | } 611 | else { 612 | printf("Target process is in x86 mode\n"); 613 | } 614 | 615 | unsigned int procedureSize; 616 | remoteProcedure = InjectLoadLibraryInMem(pHandle, fullDllPath, dllFullPathNameLoc, isTargetx64, &procedureSize); 617 | 618 | if (remoteProcedure == NULL) { 619 | return 0; 620 | } 621 | 622 | switch (method) { 623 | case INJECTION_METHOD_NT: 624 | threadHandle = NtCreateRemoteThread(pHandle, (LPTHREAD_START_ROUTINE)remoteProcedure, (LPVOID)NULL); 625 | break; 626 | 627 | case INJECTION_METHOD_RTL: 628 | threadHandle = RtlCreateUserThread(pHandle, remoteProcedure, NULL); 629 | break; 630 | 631 | default: 632 | threadHandle = CreateRemoteThread(pHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteProcedure, (LPVOID)NULL, 0, NULL); 633 | break; 634 | } 635 | 636 | DWORD exitCode = 0; 637 | if (threadHandle == NULL) { 638 | DWORD lastErrorCode = GetLastError(); 639 | DisplayErrorWithCode(NULL, lastErrorCode); 640 | SetLastError(lastErrorCode); 641 | } 642 | else { 643 | WaitReturnValueFromThread(threadHandle, &exitCode); 644 | 645 | if (exitCode == 0) { 646 | printf("LoadLibraryA OK : returned 0\n"); 647 | } 648 | else { 649 | printf("LoadLibraryA FAILED (%ld) : ", exitCode); 650 | DisplayErrorWithCode(NULL, exitCode); 651 | if (exitCode == ERROR_CODE_NOT_VALID_WIN32_APP) { 652 | if (!isTargetx64) { 653 | printf("REM : it might failed cause you want to load a x64 dll into a x86 process\n"); 654 | } 655 | else { 656 | printf("REM : it might failed cause you want to load a x86 dll into a x64 process\n"); 657 | } 658 | 659 | } 660 | result = 0; 661 | } 662 | SetLastError(exitCode); 663 | } 664 | 665 | CloseHandle(pHandle); 666 | VirtualFreeEx(pHandle, (LPVOID)dllFullPathNameLoc, 0, MEM_DECOMMIT); 667 | VirtualFreeEx(pHandle, remoteProcedure, procedureSize, MEM_RELEASE); 668 | return result; 669 | } 670 | 671 | 672 | int ReleaseDllRemoteThread (DWORD pid, const char* dllPathName, int ntMethodBool) 673 | { 674 | HMODULE hKernel32 = LoadLibraryW(L"kernel32.dll"); 675 | HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid); 676 | LPVOID lpHandle = 0; 677 | 678 | SIZE_T dwWritten; 679 | 680 | if (hProcess == NULL) 681 | { 682 | DisplayLastError(); 683 | return 1; 684 | } 685 | 686 | //Récupération de la taille du nom du chemin vers la dll en bytes 687 | SIZE_T sizeDllPathName = (SIZE_T) strlen(dllPathName); 688 | 689 | //On réserve de la mémoire dans le processus cible, puis on y stocke le nom du chemin vers la dll 690 | LPVOID lpBuf = VirtualAllocEx (hProcess, NULL, sizeDllPathName, MEM_COMMIT, PAGE_READWRITE); 691 | 692 | printf("Dll path name written at \t0x%p ...\n", lpBuf); 693 | 694 | if (! WriteProcessMemory (hProcess, lpBuf, (LPVOID) dllPathName, sizeDllPathName, &dwWritten)) 695 | { 696 | DisplayLastError(); 697 | VirtualFreeEx (hProcess, lpBuf, sizeDllPathName, MEM_DECOMMIT); 698 | CloseHandle (hProcess); 699 | return 1; 700 | } 701 | 702 | //On effectue ensuite un appel vers GetModuleHandleA pour obtenir un handle vers le module de la dll par le biais d'un thread 703 | HANDLE hThread; 704 | if(ntMethodBool) 705 | { 706 | hThread = NtCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)GetProcAddress (hKernel32, "GetModuleHandleA"), lpBuf); 707 | } 708 | else 709 | { 710 | hThread = CreateRemoteThread (hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress (hKernel32, "GetModuleHandleA"), lpBuf, 0, NULL); 711 | } 712 | 713 | if (hThread == NULL) 714 | { 715 | DisplayLastError(); 716 | CloseHandle (hProcess); 717 | return 1; 718 | } 719 | 720 | WaitForSingleObject (hThread, INFINITE); 721 | 722 | //On récupère le module handle dans dwHandle 723 | GetExitCodeThread (hThread, (LPDWORD)&lpHandle); 724 | 725 | printf("Module handle %s (image base) : \t0x%p\n", dllPathName, (void*)lpHandle); 726 | 727 | //On fini par effacer la mémoire écrite pour le nom du chemin de la dll 728 | printf("Free-ing memory on module handle...\n"); 729 | VirtualFreeEx (hProcess, lpBuf, sizeDllPathName, MEM_DECOMMIT); 730 | printf("Closing GetModuleHandleA thread...\n"); 731 | CloseHandle (hThread); 732 | 733 | HANDLE ht; 734 | if(ntMethodBool) 735 | { 736 | ht = NtCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE) GetProcAddress (hKernel32, "FreeLibrary"), (LPVOID) lpHandle); 737 | } 738 | else 739 | { 740 | ht = CreateRemoteThread (hProcess, 0, 0, (LPTHREAD_START_ROUTINE) GetProcAddress (hKernel32, "FreeLibrary"), (LPVOID) lpHandle, 0, NULL); 741 | } 742 | 743 | // printf("Thread \"FreeLibrary\" handle \t0x%p ...\n", hThread); 744 | 745 | if (ht == NULL) 746 | { 747 | DisplayLastError(); 748 | FreeLibrary (hKernel32); 749 | CloseHandle (hProcess); 750 | return 1; 751 | } 752 | 753 | switch (WaitForSingleObject (ht, 2000)) 754 | { 755 | case WAIT_OBJECT_0: 756 | printf("Releasing OK\n"); 757 | break; 758 | 759 | default: 760 | DisplayLastError(); 761 | break; 762 | } 763 | 764 | printf("Closing FreeLibrary thread...\n"); 765 | // Closes the remote thread handle 766 | CloseHandle(ht); 767 | 768 | // Free up the kernel32.dll 769 | if (hKernel32 != NULL) 770 | { 771 | FreeLibrary (hKernel32); 772 | } 773 | 774 | // Close the process handle 775 | CloseHandle (hProcess); 776 | 777 | return 0; 778 | 779 | } 780 | 781 | 782 | -------------------------------------------------------------------------------- /src/LIB_INVADER/Injector.h: -------------------------------------------------------------------------------- 1 | #ifndef INJECTOR_H 2 | #define INJECTOR_H 3 | 4 | #define INJECTION_METHOD_NT 2 5 | #define INJECTION_METHOD_RTL 1 6 | #define INJECTION_METHOD_CreateRemoteThread 0 7 | 8 | DWORD GetExportDllOffset(UINT_PTR uiBaseAddress, char* dllPathName); 9 | PVOID GetRVAFromFilename(char* pathFileName, DWORD* outputFileSize); 10 | int InjectDllCreatingSuspendedProcess(const char* processPathName, const char* cmdLine, const char* dllPathName, int method); 11 | int InjectDllRemoteThread(DWORD pid, const char* dllPathName, int ntMethodBool); 12 | int ReleaseDllRemoteThread(DWORD pid, const char* dllPathName, int ntMethodBool); 13 | 14 | 15 | #endif // INJECTOR_H 16 | -------------------------------------------------------------------------------- /src/LIB_INVADER/KeyNameInformation.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_KEYNAMEINFORMATION 2 | #define DEF_KEYNAMEINFORMATION 3 | 4 | //The KEY_NAME_INFORMATION structure holds the name and name length of the key. 5 | typedef struct _KEY_NAME_INFORMATION { 6 | ULONG NameLength; 7 | WCHAR Name[1]; 8 | } KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION; 9 | /* 10 | NameLength 11 | 12 | The size, in bytes, of the key name string in the Name array. 13 | Name 14 | 15 | An array of wide characters that contains the name of the key. This character string is not null-terminated. 16 | Only the first element in this array is included in the KEY_NAME_INFORMATION structure definition. 17 | The storage for the remaining elements in the array immediately follows this element. 18 | 19 | */ 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/LIB_INVADER/NTStatus.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_NTSTATUS 2 | #define DEF_NTSTATUS 3 | 4 | typedef LONG NTSTATUS; 5 | 6 | #ifndef STATUS_SUCCESS 7 | #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) 8 | #endif 9 | 10 | #ifndef STATUS_BUFFER_TOO_SMALL 11 | #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) 12 | #endif 13 | 14 | #ifndef STATUS_INFO_LENGTH_MISMATCH 15 | #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L) 16 | #endif 17 | 18 | #endif // DEF_NTSTATUS 19 | -------------------------------------------------------------------------------- /src/LIB_INVADER/NtCreateThread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "NtCreateThread.h" 5 | #include "ErrorUtils.h" 6 | 7 | struct NtCreateThreadExBuffer { 8 | ULONG Size; 9 | ULONG Unknown1; 10 | ULONG Unknown2; 11 | PULONG Unknown3; 12 | ULONG Unknown4; 13 | ULONG Unknown5; 14 | ULONG Unknown6; 15 | PULONG Unknown7; 16 | ULONG Unknown8; 17 | }; 18 | typedef struct NtCreateThreadExBuffer NtCreateThreadExBuffer; 19 | 20 | 21 | typedef NTSTATUS(WINAPI *LPFUN_NtCreateThreadEx) ( 22 | OUT PHANDLE hThread, 23 | IN ACCESS_MASK DesiredAccess, 24 | IN LPVOID ObjectAttributes, 25 | IN HANDLE ProcessHandle, 26 | IN LPTHREAD_START_ROUTINE lpStartAddress, 27 | IN LPVOID lpParameter, 28 | IN BOOL CreateSuspended, 29 | IN ULONG StackZeroBits, 30 | IN ULONG SizeOfStackCommit, 31 | IN ULONG SizeOfStackReserve, 32 | OUT LPVOID lpBytesBuffer 33 | ); 34 | 35 | HANDLE RtlCreateUserThread(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpArgs) { 36 | 37 | typedef DWORD(WINAPI * tRtlCreateUserThread)( 38 | HANDLE ProcessHandle, 39 | PSECURITY_DESCRIPTOR SecurityDescriptor, 40 | BOOL CreateSuspended, 41 | ULONG StackZeroBits, 42 | PULONG StackReserved, 43 | PULONG StackCommit, 44 | LPVOID StartAddress, 45 | LPVOID StartParameter, 46 | HANDLE ThreadHandle, 47 | LPVOID ClientID); 48 | 49 | 50 | HANDLE hRemoteThread = NULL; 51 | HMODULE hNtDllModule = GetModuleHandleA("ntdll.dll"); 52 | if (hNtDllModule == NULL) { 53 | DisplayLastError(); 54 | return NULL; 55 | } 56 | 57 | tRtlCreateUserThread RtlCreateUserThread = (tRtlCreateUserThread)GetProcAddress(hNtDllModule, "RtlCreateUserThread"); 58 | 59 | if (!RtlCreateUserThread) { 60 | DisplayLastError(); 61 | return NULL; 62 | } 63 | 64 | RtlCreateUserThread(hProcess, NULL, 0, 0, 0, 0, lpBaseAddress, lpArgs, &hRemoteThread, NULL); 65 | 66 | return hRemoteThread; 67 | 68 | } 69 | 70 | 71 | HANDLE NtCreateRemoteThread(HANDLE hHandle, LPVOID pRoutine, LPVOID parameters) { 72 | 73 | HANDLE hRemoteThread = NULL; 74 | 75 | LPVOID ntCreateThreadExAddr = NULL; 76 | NtCreateThreadExBuffer ntbuffer; 77 | DWORD temp1 = 0; 78 | DWORD temp2 = 0; 79 | HMODULE ntdllModule = GetModuleHandle(TEXT("ntdll.dll")); 80 | 81 | ntCreateThreadExAddr = GetProcAddress(ntdllModule, "NtCreateThreadEx"); 82 | 83 | if (ntCreateThreadExAddr) { 84 | memset(&ntbuffer, 0, sizeof(NtCreateThreadExBuffer)); 85 | ntbuffer.Size = sizeof(struct NtCreateThreadExBuffer); 86 | ntbuffer.Unknown1 = 0x10003; 87 | ntbuffer.Unknown2 = 0x8; 88 | ntbuffer.Unknown3 = &temp2; 89 | ntbuffer.Unknown4 = 0; 90 | ntbuffer.Unknown5 = 0x10004; 91 | ntbuffer.Unknown6 = 4; 92 | ntbuffer.Unknown7 = &temp1; 93 | ntbuffer.Unknown8 = 0; 94 | 95 | LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)ntCreateThreadExAddr; 96 | NTSTATUS status = funNtCreateThreadEx( 97 | &hRemoteThread, 98 | 0x1FFFFF, //All accesses 99 | NULL, 100 | hHandle, 101 | (LPTHREAD_START_ROUTINE)pRoutine, 102 | parameters, 103 | FALSE, 104 | 0, 105 | 0, 106 | 0, 107 | //NULL 108 | &ntbuffer 109 | ); 110 | 111 | if (hRemoteThread == NULL) { 112 | printf("Error : NtCreateThreadEx Failed (returned status %08x)\n", (unsigned int)status); 113 | DisplayLastError(); 114 | } 115 | else { 116 | return hRemoteThread; 117 | } 118 | 119 | } 120 | else { 121 | printf("Error : unable to find \"NtCreateThreadEx\" in ntdll.dll\n"); 122 | } 123 | 124 | return NULL; 125 | } 126 | -------------------------------------------------------------------------------- /src/LIB_INVADER/NtCreateThread.h: -------------------------------------------------------------------------------- 1 | #ifndef NTCREATETHREAD_H 2 | #define NTCREATETHREAD_H 3 | 4 | 5 | HANDLE NtCreateRemoteThread(HANDLE hHandle, LPVOID pRoutine, LPVOID parameters); 6 | HANDLE RtlCreateUserThread(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpSpace); 7 | 8 | #endif // NTCREATETHREAD_H 9 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ObjectNameInformation.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_OBJECTNAMEINFORMATION 2 | #define DEF_OBJECTNAMEINFORMATION 3 | 4 | typedef struct _OBJECT_NAME_INFORMATION { 5 | UNICODE_STRING Name; 6 | } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; 7 | 8 | #endif // DEF_OBJECTNAMEINFORMATION 9 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ObjectTypeInformation.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_OBJECTTYPEINFORMATION 2 | #define DEF_OBJECTTYPEINFORMATION 3 | 4 | typedef struct _OBJECT_TYPE_INFORMATION 5 | { 6 | UNICODE_STRING Name; 7 | ULONG TotalNumberOfObjects; 8 | ULONG TotalNumberOfHandles; 9 | ULONG TotalPagedPoolUsage; 10 | ULONG TotalNonPagedPoolUsage; 11 | ULONG TotalNamePoolUsage; 12 | ULONG TotalHandleTableUsage; 13 | ULONG HighWaterNumberOfObjects; 14 | ULONG HighWaterNumberOfHandles; 15 | ULONG HighWaterPagedPoolUsage; 16 | ULONG HighWaterNonPagedPoolUsage; 17 | ULONG HighWaterNamePoolUsage; 18 | ULONG HighWaterHandleTableUsage; 19 | ULONG InvalidAttributes; 20 | GENERIC_MAPPING GenericMapping; 21 | ULONG ValidAccess; 22 | BOOLEAN SecurityRequired; 23 | BOOLEAN MaintainHandleCount; 24 | USHORT MaintainTypeList; 25 | POOL_TYPE PoolType; 26 | ULONG PagedPoolUsage; 27 | ULONG NonPagedPoolUsage; 28 | } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; 29 | 30 | #endif // DEF_OBJECTTYPEINFORMATION 31 | -------------------------------------------------------------------------------- /src/LIB_INVADER/PEBContent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "AnsiString.h" 6 | #include "ProcessBasicInformation.h" 7 | #include "PEBContent.h" 8 | #include "ProcessInformation.h" 9 | #include "GetProcessInformation.h" 10 | #include "ErrorUtils.h" 11 | #include "ProcessModule.h" 12 | 13 | #define LDRP_HASH_TABLE_SIZE 32 14 | #define LDRP_HASH_MASK (LDRP_HASH_TABLE_SIZE-1) 15 | #define LDRP_COMPUTE_HASH_INDEX(wch) ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK ) 16 | 17 | void ZeroRtlUserProcessParametersContent(RtlUserProcessParametersContent* rtl) 18 | { 19 | memset(rtl, 0, sizeof(RtlUserProcessParametersContent)); 20 | } 21 | 22 | RtlUserProcessParametersContent* CreateRtlUserProcessParametersContent() 23 | { 24 | RtlUserProcessParametersContent* result = (RtlUserProcessParametersContent*) malloc(sizeof(RtlUserProcessParametersContent)); 25 | ZeroRtlUserProcessParametersContent(result); 26 | return result; 27 | } 28 | 29 | 30 | void FreeRtlUserProcessParametersContent(RtlUserProcessParametersContent* rtl) 31 | { 32 | unsigned int i; 33 | 34 | //ANSI_STRINGs 35 | free(rtl->CommandLine.Buffer); 36 | free(rtl->WindowTitle.Buffer); 37 | free(rtl->DllPath.Buffer); 38 | free(rtl->DesktopInfo.Buffer); 39 | free(rtl->ImagePathName.Buffer); 40 | free(rtl->RuntimeData.Buffer); 41 | free(rtl->ShellInfo.Buffer); 42 | 43 | //Pointers 44 | // free(rtl->ConsoleHandle); 45 | free(rtl->Environment); 46 | 47 | for(i = 0; i < 32; i++) 48 | free(rtl->CurrentDirectories[i].DosPath.Buffer); 49 | 50 | free(rtl->CurrentDirectory.DosPath.Buffer); 51 | // free(rtl->PackageDependencyData); 52 | // free(rtl->StandardError); 53 | // free(rtl->StandardInput); 54 | free(rtl); 55 | } 56 | 57 | void ZeroPEBLdrDataContent(PEBLdrDataContent* ldr) 58 | { 59 | memset(ldr, 0, sizeof(PEBLdrDataContent)); 60 | } 61 | 62 | 63 | PEBLdrDataContent* CreatePEBLdrDataContent() 64 | { 65 | PEBLdrDataContent* result = (PEBLdrDataContent*) malloc(sizeof(PEBLdrDataContent)); 66 | ZeroPEBLdrDataContent(result); 67 | return result; 68 | } 69 | 70 | void FreePEBLdrDataContent(PEBLdrDataContent* ldr) 71 | { 72 | free(ldr->EntryInProgress); 73 | FreeProcessModuleList(ldr->moduleList); 74 | free(ldr); 75 | } 76 | 77 | void ZeroPEBContent(PEBContent* peb) 78 | { 79 | memset(peb, 0, sizeof(PEBContent)); 80 | } 81 | 82 | PEBContent* CreatePEBContent() 83 | { 84 | PEBContent* result = (PEBContent*) malloc(sizeof(PEBContent)); 85 | ZeroPEBContent(result); 86 | 87 | result->Ldr = CreatePEBLdrDataContent(); 88 | result->ProcessParameters = CreateRtlUserProcessParametersContent(); 89 | 90 | return result; 91 | } 92 | 93 | 94 | void DisplayPEBContent(PEBContent* peb) 95 | { 96 | RtlUserProcessParametersContent* procParam = peb->ProcessParameters; 97 | PEBLdrDataContent* ldr = peb->Ldr; 98 | unsigned int i; 99 | 100 | puts(""); 101 | printf("Activation Context Data : %p\n", peb->ActivationContextData); 102 | printf("ActiveProcessAffinityMask : %I64d\n", peb->ActiveProcessAffinityMask); 103 | printf("Ansi Code Page Data : %p\n", peb->AnsiCodePageData); 104 | printf("Api Set Map : %p\n", peb->ApiSetMap); 105 | printf("App Compat Flags : %I64d\n", peb->AppCompatFlags); 106 | printf("App Compat Flags User : %I64d\n", peb->AppCompatFlagsUser); 107 | printf("App Compat Info : %p\n", peb->AppCompatInfo); 108 | printf("AtlThunkSListPtr : %p\n", peb->AtlThunkSListPtr); 109 | printf("AtlThunkSListPtr32 : %lu\n", peb->AtlThunkSListPtr32); 110 | printf("Being Debugged : %s\n", peb->BeingDebugged ? "TRUE" : "FALSE"); 111 | printf("Critical Section Timeout : %I64d\n", peb->CriticalSectionTimeout); 112 | printf("CSD Version : %s\n", peb->CSDVersion.Buffer); 113 | printf("CsrServerReadOnlySharedMemoryBase : %I64d\n", peb->CsrServerReadOnlySharedMemoryBase); 114 | printf("Fast PEB Lock : %p\n", peb->FastPebLock); 115 | printf("Fls Bitmap : %p\n", peb->FlsBitmap); 116 | 117 | printf("Fls Bitmap Bits :\n"); 118 | for(i = 0; i < 4; i++) 119 | printf("\t[%u] = %lu\n", i, peb->FlsBitmapBits[i]); 120 | 121 | printf("Fls Callback : %p\n", peb->FlsCallback); 122 | printf("Fls High Index : %lu\n", peb->FlsHighIndex); 123 | printf("Fls List Head Flink : %p\n", peb->FlsListHead.Flink); 124 | printf("GdiDC Attribute List : %lu\n", peb->GdiDCAttributeList); 125 | 126 | printf("Gdi Handle Buffers : \n"); 127 | for(i = 0; i < 60; i++) 128 | printf("\t[%u] = %lu\n", i, peb->GdiHandleBuffer[i]); 129 | 130 | printf("GdiSharedHandleTable : %p\n", peb->GdiSharedHandleTable); 131 | printf("HeapDeCommitFreeBlockThreshold : %I64d\n", peb->HeapDeCommitFreeBlockThreshold); 132 | printf("HeapDeCommitTotalFreeThreshold : %I64d\n", peb->HeapDeCommitTotalFreeThreshold); 133 | printf("HeapSegmentCommit : %I64d\n", peb->HeapSegmentCommit); 134 | printf("HeapSegmentReserve : %I64d\n", peb->HeapSegmentReserve); 135 | printf("IFEOKey : %p\n", peb->IFEOKey); 136 | printf("Image Base Address : %p\n", peb->ImageBaseAddress); 137 | printf("Image Subsystem : %lu\n", peb->ImageSubsystem); 138 | printf("Image Subsystem Major Version : %lu\n", peb->ImageSubsystemMajorVersion); 139 | printf("Image Subsystem Minor Version : %lu\n", peb->ImageSubsystemMinorVersion); 140 | printf("Inherited Address Space : %d\n", peb->InheritedAddressSpace); 141 | 142 | if(ldr != NULL) 143 | { 144 | printf("\tEntry In Progress : %p\n", ldr->EntryInProgress); 145 | printf("\tIn Initialization Order Module List : \n"); 146 | printf("\tInitialized : %i\n", ldr->Initialized); 147 | printf("\tIn Load Order Module List Flink : %p\n", ldr->InLoadOrderModuleList.Flink); 148 | printf("\tLength : %lu\n", ldr->Length); 149 | printf("\tIn Memory Order Module List Flink : %p\n", ldr->InMemoryOrderModuleList.Flink); 150 | printf("\tShutdown In Progress : %i\n", ldr->ShutdownInProgress); 151 | printf("\tShutdown Thread Id : %p\n", ldr->ShutdownThreadId); 152 | printf("\tSsHandle : %p\n", ldr->SsHandle); 153 | } 154 | 155 | printf("Loader Lock : %p\n", peb->LoaderLock); 156 | printf("Maximum Number Of Heaps : %lu\n", peb->MaximumNumberOfHeaps); 157 | printf("Minimum Stack Commit : %I64d\n", peb->MinimumStackCommit); 158 | printf("Mutant : %p\n", peb->Mutant); 159 | printf("Nt Global Flag : %lu\n", peb->NtGlobalFlag); 160 | printf("Number Of Heaps : %lu\n", peb->NumberOfHeaps); 161 | printf("Oem Code Page Data : %p\n", peb->OemCodePageData); 162 | printf("OS Build Number : %u\n", (unsigned int)peb->OSBuildNumber); 163 | printf("OS CSDVersion : %u\n", (unsigned int)peb->OSCSDVersion); 164 | printf("OS Major Version OS : %lu\n", peb->OSMajorVersion); 165 | printf("OS Minor Version OS : %lu\n", peb->OSMinorVersion); 166 | printf("OS Platform Id : %lu\n", peb->OSPlatformId); 167 | printf("pImageHeaderHash : %p\n", peb->pImageHeaderHash); 168 | printf("Post Process Init Routine : %p\n", peb->PostProcessInitRoutine); 169 | printf("Process Assembly Storage Map : %p\n", peb->ProcessAssemblyStorageMap); 170 | printf("Process Heap : %p\n", peb->ProcessHeap); 171 | printf("Process Heaps : %p\n", peb->ProcessHeaps); 172 | 173 | printf("Process Parameters :\n"); 174 | if(procParam != NULL) 175 | { 176 | printf("\tCommand Line : %s\n", procParam->CommandLine.Buffer); 177 | printf("\tWindow Title : %s\n", procParam->WindowTitle.Buffer); 178 | printf("\tImage Path Name : %s\n", procParam->ImagePathName.Buffer); 179 | printf("\tDLL Path : %s\n", procParam->DllPath.Buffer); 180 | printf("\tShell Info : %s\n", procParam->ShellInfo.Buffer); 181 | printf("\tDesktop Info : %s\n", procParam->DesktopInfo.Buffer); 182 | printf("\tConsole Flags : %lu\n", procParam->ConsoleFlags); 183 | printf("\tConsole Handle : %p\n", procParam->ConsoleHandle); 184 | printf("\tCount Chars X : %lu\n", procParam->CountCharsX); 185 | printf("\tCount Chars Y : %lu\n", procParam->CountCharsY); 186 | printf("\tCount X : %lu\n", procParam->CountX); 187 | printf("\tCount Y : %lu\n", procParam->CountY); 188 | printf("\tEnvironment Strings :\n"); 189 | puts((const char*)procParam->Environment); 190 | 191 | printf("\tCurrent directories : \n"); 192 | for(i = 0; i < 32; i++) 193 | printf("\t\t[%u] = %s\n", i, procParam->CurrentDirectories[i].DosPath.Buffer); 194 | 195 | printf("\tCurrent Directory : %s\n", procParam->CurrentDirectory.DosPath.Buffer); 196 | printf("\tDebug Flags : %lu\n", procParam->DebugFlags); 197 | printf("\tEnvironment : %p\n", procParam->Environment); 198 | printf("\tEnvironment Size : %I64d\n", procParam->EnvironmentSize); 199 | printf("\tEnvironment Version : %I64d\n", procParam->EnvironmentVersion); 200 | printf("\tFill Attribute : %lu\n", procParam->FillAttribute); 201 | printf("\tFlags : %lu\n", procParam->Flags); 202 | printf("\tLength : %lu\n", procParam->Length); 203 | printf("\tMaximum Length : %lu\n", procParam->MaximumLength); 204 | printf("\tPackage Dependency Data : %p\n", procParam->PackageDependencyData); 205 | printf("\tProcess Group Id : %lu\n", procParam->ProcessGroupId); 206 | printf("\tRuntime Data : %s\n", procParam->RuntimeData.Buffer); 207 | printf("\tShow Window Flags : %lu\n", procParam->ShowWindowFlags); 208 | printf("\tStandard Error : %p\n", procParam->StandardError); 209 | printf("\tStandard Input : %p\n", procParam->StandardInput); 210 | printf("\tStandard Output : %p\n", procParam->StandardOutput); 211 | printf("\tStarting X : %lu\n", procParam->StartingX); 212 | printf("\tStarting Y : %lu\n", procParam->StartingY); 213 | printf("\tWindow Flags : %lu\n", procParam->WindowFlags); 214 | 215 | } 216 | 217 | printf("Process Starter Helper : %p\n", peb->ProcessStarterHelper); 218 | printf("pShimData : %p\n", peb->pShimData); 219 | printf("pUnused : %p\n", peb->pUnused); 220 | printf("Read Image File Exec Options : %i\n", peb->ReadImageFileExecOptions); 221 | printf("Read Only Shared Memory Base : %p\n", peb->ReadOnlySharedMemoryBase); 222 | printf("Read Only Static Server Data : %p\n", peb->ReadOnlyStaticServerData); 223 | printf("Session Id : %lu\n", peb->SessionId); 224 | printf("SparePvoid0 : %p\n", peb->SparePvoid0); 225 | printf("Sub System Data : %p\n", peb->SubSystemData); 226 | printf("System Assembly Storage Map : %p\n", peb->SystemAssemblyStorageMap); 227 | printf("System Default Activation Context Data : %p\n", peb->SystemDefaultActivationContextData); 228 | 229 | for(i = 0; i < 1; i++) 230 | printf("System Reserved : %lu\n", peb->SystemReserved[i]); 231 | 232 | printf("Tls Bitmap : %p\n", peb->TlsBitmap); 233 | 234 | printf("Tls Bitmap Bits : \n"); 235 | for(i = 0; i < 2; i++) 236 | printf("\t[%u] = %lu\n", i, peb->TlsBitmapBits[i]); 237 | 238 | printf("Tls Expansion Bitmap : %p\n", peb->TlsExpansionBitmap); 239 | 240 | printf("Tls Expansion Bitmap Bits : \n"); 241 | for(i = 0; i < 32; i++) 242 | printf("\t[%u] = %lu\n", i, peb->TlsExpansionBitmapBits[i]); 243 | 244 | printf("Tls Expansion Counter : %lu\n", peb->TlsExpansionCounter); 245 | printf("Unicode Case Table Data : %p\n", peb->UnicodeCaseTableData); 246 | printf("Wer Registration Data : %p\n", peb->WerRegistrationData); 247 | printf("Wer Ship Assert Ptr : %p\n", peb->WerShipAssertPtr); 248 | 249 | puts(""); 250 | } 251 | 252 | void FreePEBContent(PEBContent* peb) 253 | { 254 | // free(peb->ActivationContextData); 255 | // free(peb->AnsiCodePageData); 256 | // free(peb->ApiSetMap); 257 | // free(peb->AppCompatInfo); 258 | // free(peb->AtlThunkSListPtr); 259 | // free(peb->FastPebLock); 260 | // free(peb->FlsBitmap); 261 | // free(peb->FlsCallback); 262 | // free(peb->GdiSharedHandleTable); 263 | // free(peb->IFEOKey); 264 | // free(peb->ImageBaseAddress); 265 | 266 | FreePEBLdrDataContent(peb->Ldr); 267 | 268 | // free(peb->LoaderLock); 269 | // free(peb->Mutant); 270 | // free(peb->OemCodePageData); 271 | // free(peb->pImageHeaderHash); 272 | // free(peb->PostProcessInitRoutine); 273 | // free(peb->ProcessAssemblyStorageMap); 274 | // free(peb->ProcessHeap); 275 | // free(peb->ProcessHeaps); 276 | 277 | FreeRtlUserProcessParametersContent(peb->ProcessParameters); 278 | 279 | // free(peb->ProcessStarterHelper); 280 | // free(peb->pShimData); 281 | // free(peb->pUnused); 282 | // free(peb->ReadOnlySharedMemoryBase); 283 | // free(peb->ReadOnlyStaticServerData); 284 | // free(peb->SparePvoid0); 285 | // free(peb->SubSystemData); 286 | // free(peb->SystemAssemblyStorageMap); 287 | // free(peb->SystemDefaultActivationContextData); 288 | // free(peb->TlsBitmap); 289 | // free(peb->TlsExpansionBitmap); 290 | // free(peb->UnicodeCaseTableData); 291 | // free(peb->WerRegistrationData); 292 | // free(peb->WerShipAssertPtr); 293 | 294 | free(peb); 295 | } 296 | 297 | 298 | 299 | 300 | 301 | 302 | /* 303 | void DisplayModuleListHashTableListMethod(unsigned long pid) 304 | { 305 | WCHAR tmpData[2048] = {'\0'}; 306 | LIST_ENTRY nextModule = {0}; 307 | LDR_DATA_TABLE_ENTRY dataTable; 308 | SIZE_T read = 0; 309 | PEBContent* peb = CreatePEBContentFromPid(pid); 310 | LIST_ENTRY* pLoadOrderModuleList = peb->Ldr->InLoadOrderModuleList.Flink; 311 | HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); 312 | 313 | 314 | if(!ReadProcessMemory(processHandle, 315 | pLoadOrderModuleList, 316 | &dataTable, 317 | sizeof(dataTable), 318 | &read)) 319 | { 320 | printf("Byte read : %lu\n", (unsigned long) read); 321 | DisplayLastError(); 322 | return; 323 | } 324 | 325 | 326 | LIST_ENTRY* moduleStart = dataTable.HashLinks.Flink; 327 | LIST_ENTRY* currentModule = moduleStart; 328 | 329 | 330 | 331 | 332 | if(processHandle) 333 | { 334 | do 335 | { 336 | printf("Reading %p\n", currentModule); 337 | 338 | if(!ReadProcessMemory(processHandle, 339 | currentModule, 340 | &nextModule, 341 | sizeof(currentModule), 342 | &read)) 343 | { 344 | printf("Byte read : %lu\n", (unsigned long) read); 345 | DisplayLastError(); 346 | break; 347 | } 348 | 349 | printf("OK1\n"); 350 | if(!ReadProcessMemory(processHandle, 351 | currentModule, 352 | &dataTable, 353 | sizeof(dataTable), 354 | &read)) 355 | { 356 | printf("Byte read : %lu\n", (unsigned long) read); 357 | DisplayLastError(); 358 | break; 359 | } 360 | 361 | printf("OK2 : %p\n", dataTable.FullDllName.Buffer); 362 | 363 | if(!ReadProcessMemory(processHandle, 364 | dataTable.FullDllName.Buffer, 365 | tmpData, 366 | dataTable.FullDllName.Length, 367 | &read)) 368 | { 369 | printf("Byte read : %lu\n", (unsigned long) read); 370 | DisplayLastError(); 371 | break; 372 | } 373 | 374 | ANSI_STRING tmpStr = CreateAnsiStringDataFromUnicode(tmpData, read); 375 | printf("DLL Full Name : %s\n", tmpStr.Buffer); 376 | free(tmpStr.Buffer); 377 | 378 | memset(tmpData, 0, dataTable.FullDllName.Length * sizeof(WCHAR)); 379 | 380 | currentModule = nextModule.Flink; 381 | }while(currentModule != moduleStart); 382 | } 383 | 384 | CloseHandle(processHandle); 385 | FreePEBContent(peb); 386 | } 387 | */ 388 | -------------------------------------------------------------------------------- /src/LIB_INVADER/PEBContent.h: -------------------------------------------------------------------------------- 1 | #ifndef PEBCONTENT_H 2 | #define PEBCONTENT_H 3 | 4 | #include "AnsiString.h" 5 | #include "ProcessModule.h" 6 | 7 | 8 | struct CurdirContent 9 | { 10 | ANSI_STRING DosPath; 11 | void* Handle; 12 | }; 13 | typedef struct CurdirContent CurdirContent; 14 | 15 | struct RtlDriveLetterCurdirContent 16 | { 17 | unsigned short Flags; 18 | unsigned short Length; 19 | unsigned long TimeStamp; 20 | ANSI_STRING DosPath; 21 | }; 22 | typedef struct RtlDriveLetterCurdirContent RtlDriveLetterCurdirContent; 23 | 24 | struct RtlUserProcessParametersContent 25 | { 26 | unsigned long MaximumLength ; 27 | unsigned long Length ; 28 | unsigned long Flags ; 29 | unsigned long DebugFlags ; 30 | void* ConsoleHandle ; 31 | unsigned long ConsoleFlags ; 32 | void* StandardInput ; 33 | void* StandardOutput ; 34 | void* StandardError ; 35 | CurdirContent CurrentDirectory ; 36 | ANSI_STRING DllPath ; 37 | ANSI_STRING ImagePathName ; 38 | ANSI_STRING CommandLine ; 39 | void* Environment ; 40 | unsigned long StartingX ; 41 | unsigned long StartingY ; 42 | unsigned long CountX ; 43 | unsigned long CountY ; 44 | unsigned long CountCharsX ; 45 | unsigned long CountCharsY ; 46 | unsigned long FillAttribute ; 47 | unsigned long WindowFlags ; 48 | unsigned long ShowWindowFlags ; 49 | ANSI_STRING WindowTitle ; 50 | ANSI_STRING DesktopInfo ; 51 | ANSI_STRING ShellInfo ; 52 | ANSI_STRING RuntimeData ; 53 | RtlDriveLetterCurdirContent CurrentDirectories [32]; 54 | unsigned long long EnvironmentSize ; 55 | unsigned long long EnvironmentVersion ; 56 | void* PackageDependencyData ; 57 | unsigned long ProcessGroupId ; 58 | 59 | }; 60 | typedef struct RtlUserProcessParametersContent RtlUserProcessParametersContent; 61 | 62 | struct PEBLdrDataContent 63 | { 64 | unsigned long Length ; 65 | char Initialized ; 66 | HANDLE SsHandle ; 67 | LIST_ENTRY InLoadOrderModuleList ; 68 | LIST_ENTRY InMemoryOrderModuleList ; 69 | LIST_ENTRY InInitializationOrderModuleList ; 70 | void* EntryInProgress ; 71 | char ShutdownInProgress ; 72 | HANDLE ShutdownThreadId ; 73 | 74 | //Added 75 | ProcessModule* moduleList; 76 | 77 | }; 78 | typedef struct PEBLdrDataContent PEBLdrDataContent; 79 | 80 | 81 | struct PEBContent { 82 | 83 | char InheritedAddressSpace ; 84 | char ReadImageFileExecOptions ; 85 | char BeingDebugged ; 86 | 87 | union 88 | { 89 | char BitField ; 90 | struct 91 | { 92 | 93 | char ImageUsesLargePages :1; 94 | char IsProtectedProcess :1; 95 | char IsImageDynamicallyRelocated :1; 96 | char SkipPatchingUser32Forwarders :1; 97 | char IsPackagedProcess :1; 98 | char IsAppContainer :1; 99 | char IsProtectedProcessLight :1; 100 | char SpareBits :1; 101 | }; 102 | }; 103 | 104 | void* Mutant ; 105 | void* ImageBaseAddress ; 106 | PEBLdrDataContent* /* Ptr64 _PEB_LDR_DATA */ Ldr ; 107 | RtlUserProcessParametersContent* /* Ptr64 _RTL_USER_PROCESS_PARAMETERS */ ProcessParameters ; 108 | void* SubSystemData ; 109 | void* ProcessHeap ; 110 | void* /* Ptr64 _RTL_CRITICAL_SECTION */ FastPebLock ; 111 | void* AtlThunkSListPtr ; 112 | void* IFEOKey ; 113 | 114 | union 115 | { 116 | unsigned long CrossProcessFlags ; 117 | struct 118 | { 119 | unsigned long ProcessInJob :1; 120 | unsigned long ProcessInitializing :1; 121 | unsigned long ProcessUsingVEH :1; 122 | unsigned long ProcessUsingVCH :1; 123 | unsigned long ProcessUsingFTH :1; 124 | unsigned long ReservedBits0 :27; 125 | }; 126 | }; 127 | 128 | union 129 | { 130 | void* KernelCallbackTable ; 131 | void* UserSharedInfoPtr ; 132 | }; 133 | 134 | unsigned long SystemReserved [1]; 135 | unsigned long AtlThunkSListPtr32 ; 136 | void* ApiSetMap ; 137 | unsigned long TlsExpansionCounter ; 138 | void* TlsBitmap ; 139 | unsigned long TlsBitmapBits [2]; 140 | void* ReadOnlySharedMemoryBase ; 141 | void* SparePvoid0 ; 142 | void** ReadOnlyStaticServerData ; 143 | void* AnsiCodePageData ; 144 | void* OemCodePageData ; 145 | void* UnicodeCaseTableData ; 146 | unsigned long NumberOfProcessors ; 147 | unsigned long NtGlobalFlag ; 148 | unsigned long long CriticalSectionTimeout ; 149 | unsigned long long HeapSegmentReserve ; 150 | unsigned long long HeapSegmentCommit ; 151 | unsigned long long HeapDeCommitTotalFreeThreshold ; 152 | unsigned long long HeapDeCommitFreeBlockThreshold ; 153 | unsigned long NumberOfHeaps ; 154 | unsigned long MaximumNumberOfHeaps ; 155 | void** ProcessHeaps ; 156 | void* GdiSharedHandleTable ; 157 | void* ProcessStarterHelper ; 158 | unsigned long GdiDCAttributeList ; 159 | void* LoaderLock ; 160 | unsigned long OSMajorVersion ; 161 | unsigned long OSMinorVersion ; 162 | unsigned short OSBuildNumber ; 163 | unsigned short OSCSDVersion ; 164 | unsigned long OSPlatformId ; 165 | unsigned long ImageSubsystem ; 166 | unsigned long ImageSubsystemMajorVersion ; 167 | unsigned long ImageSubsystemMinorVersion ; 168 | unsigned long long ActiveProcessAffinityMask ; 169 | unsigned long GdiHandleBuffer [60]; 170 | void* PostProcessInitRoutine ; 171 | void* TlsExpansionBitmap ; 172 | unsigned long TlsExpansionBitmapBits [32]; 173 | unsigned long SessionId ; 174 | unsigned long long AppCompatFlags ; 175 | unsigned long long AppCompatFlagsUser ; 176 | void* pShimData ; 177 | void* AppCompatInfo ; 178 | ANSI_STRING CSDVersion ; 179 | void* ActivationContextData ; 180 | void* ProcessAssemblyStorageMap ; 181 | void* SystemDefaultActivationContextData ; 182 | void* SystemAssemblyStorageMap ; 183 | unsigned long long MinimumStackCommit ; 184 | void* FlsCallback ; 185 | LIST_ENTRY FlsListHead ; 186 | void* FlsBitmap ; 187 | unsigned long FlsBitmapBits [4]; 188 | unsigned long FlsHighIndex ; 189 | void* WerRegistrationData ; 190 | void* WerShipAssertPtr ; 191 | void* pUnused ; 192 | void* pImageHeaderHash ; 193 | union 194 | { 195 | unsigned long TracingFlags ; 196 | struct 197 | { 198 | unsigned long HeapTracingEnabled :1; 199 | unsigned long CritSecTracingEnabled :1; 200 | unsigned long LibLoaderTracingEnabled :1; 201 | unsigned long SpareTracingBits :29; 202 | }; 203 | }; 204 | 205 | unsigned long long CsrServerReadOnlySharedMemoryBase ; 206 | 207 | }; 208 | typedef struct PEBContent PEBContent; 209 | 210 | 211 | PEBContent* CreatePEBContent(); 212 | void DisplayPEBContent(PEBContent* peb); 213 | void DisplayModuleListHashTableListMethod(unsigned long pid); 214 | void FreePEBContent(PEBContent* peb); 215 | 216 | #endif // PEBCONTENT_H 217 | -------------------------------------------------------------------------------- /src/LIB_INVADER/PPVOID.h: -------------------------------------------------------------------------------- 1 | #ifndef PPVOID_H 2 | #define PPVOID_H 3 | 4 | typedef PVOID *PPVOID; 5 | 6 | #endif // PPVOID_H 7 | -------------------------------------------------------------------------------- /src/LIB_INVADER/PROCESSINFOCLASS.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCESSINFOCLASS_H 2 | #define PROCESSINFOCLASS_H 3 | 4 | typedef unsigned long PROCESSINFOCLASS; 5 | 6 | #endif // PROCESSINFOCLASS_H 7 | -------------------------------------------------------------------------------- /src/LIB_INVADER/PoolType.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_POOLTYPE 2 | #define DEF_POOLTYPE 3 | 4 | typedef enum _POOL_TYPE 5 | { 6 | NonPagedPool, 7 | PagedPool, 8 | NonPagedPoolMustSucceed, 9 | DontUseThisType, 10 | NonPagedPoolCacheAligned, 11 | PagedPoolCacheAligned, 12 | NonPagedPoolCacheAlignedMustS 13 | } POOL_TYPE, *PPOOL_TYPE; 14 | 15 | #endif // DEF_POOLTYPE 16 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ProcessBasicInformation.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCESSBASICINFORMATION_H 2 | #define PROCESSBASICINFORMATION_H 3 | 4 | #include "_RTL_BALANCED_NODE.h" 5 | #include "_LDR_DLL_LOAD_REASON.h" 6 | #include "_PEB_LDR_DATA.h" 7 | 8 | #include "PPVOID.h" 9 | #include "UnicodeString.h" 10 | 11 | #define FLS_MAXIMUM_AVAILABLE 128 12 | 13 | // 32-bit definitions 14 | //#define WOW64_POINTER(Type) ULONG 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | //module name : ntdll 24 | struct _LDR_DATA_TABLE_ENTRY 25 | { /* +0x000 */ LIST_ENTRY InLoadOrderLinks ; 26 | /* +0x010 */ LIST_ENTRY InMemoryOrderLinks ; 27 | union 28 | { 29 | /* +0x020 */ LIST_ENTRY InInitializationOrderLinks ; 30 | /* +0x020 */ LIST_ENTRY InProgressLinks ; 31 | }; 32 | /* +0x030 */ PVOID /* Ptr64 Void */ DllBase ; 33 | /* +0x038 */ PVOID /* Ptr64 Void */ EntryPoint ; 34 | /* +0x040 */ ULONG SizeOfImage ; 35 | /* +0x048 */ UNICODE_STRING FullDllName ; 36 | /* +0x058 */ UNICODE_STRING BaseDllName ; 37 | 38 | union 39 | { 40 | /* +0x068 */ BYTE FlagGroup [4]; 41 | /* +0x068 */ ULONG Flags ; 42 | struct 43 | { 44 | /* +0x068 */ ULONG PackagedBinary :1; 45 | /* +0x068 */ ULONG MarkedForRemoval :1; 46 | /* +0x068 */ ULONG ImageDll :1; 47 | /* +0x068 */ ULONG LoadNotificationsSent :1; 48 | /* +0x068 */ ULONG TelemetryEntryProcessed :1; 49 | /* +0x068 */ ULONG ProcessStaticImport :1; 50 | /* +0x068 */ ULONG InLegacyLists :1; 51 | /* +0x068 */ ULONG InIndexes :1; 52 | /* +0x068 */ ULONG ShimDll :1; 53 | /* +0x068 */ ULONG InExceptionTable :1; 54 | /* +0x068 */ ULONG ReservedFlags1 :2; 55 | /* +0x068 */ ULONG LoadInProgress :1; 56 | /* +0x068 */ ULONG ReservedFlags2 :1; 57 | /* +0x068 */ ULONG EntryProcessed :1; 58 | /* +0x068 */ ULONG ReservedFlags3 :3; 59 | /* +0x068 */ ULONG DontCallForThreads :1; 60 | /* +0x068 */ ULONG ProcessAttachCalled :1; 61 | /* +0x068 */ ULONG ProcessAttachFailed :1; 62 | /* +0x068 */ ULONG CorDeferredValidate :1; 63 | /* +0x068 */ ULONG CorImage :1; 64 | /* +0x068 */ ULONG DontRelocate :1; 65 | /* +0x068 */ ULONG CorILOnly :1; 66 | /* +0x068 */ ULONG ReservedFlags5 :3; 67 | /* +0x068 */ ULONG Redirected :1; 68 | /* +0x068 */ ULONG ReservedFlags6 :2; 69 | /* +0x068 */ ULONG CompatDatabaseProcessed :1; 70 | }; 71 | }; 72 | 73 | /* +0x06c */ USHORT ObsoleteLoadCount ; 74 | /* +0x06e */ USHORT TlsIndex ; 75 | /* +0x070 */ LIST_ENTRY HashLinks ; 76 | /* +0x080 */ ULONG TimeDateStamp ; 77 | /* +0x088 */ PVOID /* Ptr64 _ACTIVATION_CONTEXT */ EntryPointActivationContext ; 78 | /* +0x090 */ PVOID /* Ptr64 Void */ Spare ; 79 | /* +0x098 */ PVOID /* Ptr64 _LDR_DDAG_NODE */ DdagNode ; 80 | /* +0x0a0 */ LIST_ENTRY NodeModuleLink ; 81 | /* +0x0b0 */ PVOID /* Ptr64 _LDRP_DLL_SNAP_CONTEXT */ SnapContext ; 82 | /* +0x0b8 */ PVOID /* Ptr64 Void */ ParentDllBase ; 83 | /* +0x0c0 */ PVOID /* Ptr64 Void */ SwitchBackContext ; 84 | /* +0x0c8 */ RTL_BALANCED_NODE BaseAddressIndexNode ; 85 | /* +0x0e0 */ RTL_BALANCED_NODE MappingInfoIndexNode ; 86 | /* +0x0f8 */ ULONGLONG OriginalBase ; 87 | /* +0x100 */ LARGE_INTEGER LoadTime ; 88 | /* +0x108 */ ULONG BaseNameHashValue ; 89 | /* +0x10c */ LDR_DLL_LOAD_REASON LoadReason ; 90 | /* +0x110 */ ULONG ImplicitPathOptions ; 91 | 92 | }; 93 | typedef struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY; 94 | 95 | typedef struct _STRING 96 | { 97 | USHORT Length; 98 | USHORT MaximumLength; 99 | CHAR * Buffer; 100 | } STRING, *PSTRING; 101 | 102 | typedef struct _RTL_DRIVE_LETTER_CURDIR 103 | { 104 | USHORT Flags; 105 | USHORT Length; 106 | ULONG TimeStamp; 107 | STRING DosPath; 108 | } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; 109 | 110 | 111 | typedef struct _CURDIR 112 | { 113 | UNICODE_STRING DosPath; 114 | PVOID Handle; 115 | } CURDIR, *PCURDIR; 116 | 117 | 118 | #define RTL_MAX_DRIVE_LETTERS 32 119 | 120 | //module name : ntdll 121 | struct _RTL_USER_PROCESS_PARAMETERS 122 | { /* +0x000 */ ULONG MaximumLength ; 123 | /* +0x004 */ ULONG Length ; 124 | /* +0x008 */ ULONG Flags ; 125 | /* +0x00c */ ULONG DebugFlags ; 126 | /* +0x010 */ PVOID /* Ptr64 Void */ ConsoleHandle ; 127 | /* +0x018 */ ULONG ConsoleFlags ; 128 | /* +0x020 */ PVOID /* Ptr64 Void */ StandardInput ; 129 | /* +0x028 */ PVOID /* Ptr64 Void */ StandardOutput ; 130 | /* +0x030 */ PVOID /* Ptr64 Void */ StandardError ; 131 | /* +0x038 */ CURDIR CurrentDirectory ; 132 | /* +0x050 */ UNICODE_STRING DllPath ; 133 | /* +0x060 */ UNICODE_STRING ImagePathName ; 134 | /* +0x070 */ UNICODE_STRING CommandLine ; 135 | /* +0x080 */ PVOID /* Ptr64 Void */ Environment ; 136 | /* +0x088 */ ULONG StartingX ; 137 | /* +0x08c */ ULONG StartingY ; 138 | /* +0x090 */ ULONG CountX ; 139 | /* +0x094 */ ULONG CountY ; 140 | /* +0x098 */ ULONG CountCharsX ; 141 | /* +0x09c */ ULONG CountCharsY ; 142 | /* +0x0a0 */ ULONG FillAttribute ; 143 | /* +0x0a4 */ ULONG WindowFlags ; 144 | /* +0x0a8 */ ULONG ShowWindowFlags ; 145 | /* +0x0b0 */ UNICODE_STRING WindowTitle ; 146 | /* +0x0c0 */ UNICODE_STRING DesktopInfo ; 147 | /* +0x0d0 */ UNICODE_STRING ShellInfo ; 148 | /* +0x0e0 */ UNICODE_STRING RuntimeData ; 149 | /* +0x0f0 */ RTL_DRIVE_LETTER_CURDIR CurrentDirectories [32]; 150 | /* +0x3f0 */ ULONGLONG EnvironmentSize ; 151 | /* +0x3f8 */ ULONGLONG EnvironmentVersion ; 152 | /* +0x400 */ PVOID /* Ptr64 Void */ PackageDependencyData ; 153 | /* +0x408 */ ULONG ProcessGroupId ; 154 | 155 | }; 156 | typedef struct _RTL_USER_PROCESS_PARAMETERS RTL_USER_PROCESS_PARAMETERS; 157 | typedef struct _RTL_USER_PROCESS_PARAMETERS *PRTL_USER_PROCESS_PARAMETERS; 158 | 159 | 160 | //module name : ntdll 161 | struct _PEB_32 162 | { /* +0x000 */ BYTE InheritedAddressSpace ; 163 | /* +0x001 */ BYTE ReadImageFileExecOptions ; 164 | /* +0x002 */ BYTE BeingDebugged ; 165 | union 166 | { 167 | /* +0x003 */ BYTE BitField ; 168 | struct 169 | { 170 | /* +0x003 */ BYTE ImageUsesLargePages :1; 171 | /* +0x003 */ BYTE IsProtectedProcess :1; 172 | /* +0x003 */ BYTE IsImageDynamicallyRelocated :1; 173 | /* +0x003 */ BYTE SkipPatchingUser32Forwarders :1; 174 | /* +0x003 */ BYTE IsPackagedProcess :1; 175 | /* +0x003 */ BYTE IsAppContainer :1; 176 | /* +0x003 */ BYTE IsProtectedProcessLight :1; 177 | /* +0x003 */ BYTE SpareBits :1; 178 | }; 179 | }; 180 | 181 | /* +0x004 */ BYTE Padding0 [4]; 182 | /* +0x008 */ PVOID /* Ptr64 Void */ Mutant ; 183 | /* +0x010 */ PVOID /* Ptr64 Void */ ImageBaseAddress ; 184 | /* +0x018 */ PPEB_LDR_DATA /* Ptr64 _PEB_LDR_DATA */ Ldr ; 185 | /* +0x020 */ PRTL_USER_PROCESS_PARAMETERS /* Ptr64 _RTL_USER_PROCESS_PARAMETERS */ ProcessParameters ; 186 | /* +0x028 */ PVOID /* Ptr64 Void */ SubSystemData ; 187 | /* +0x030 */ PVOID /* Ptr64 Void */ ProcessHeap ; 188 | /* +0x038 */ PRTL_CRITICAL_SECTION /* Ptr64 _RTL_CRITICAL_SECTION */ FastPebLock ; 189 | /* +0x040 */ PVOID /* Ptr64 Void */ AtlThunkSListPtr ; 190 | /* +0x048 */ PVOID /* Ptr64 Void */ IFEOKey ; 191 | union 192 | { 193 | /* +0x050 */ ULONG CrossProcessFlags ; 194 | struct 195 | { 196 | /* +0x050 */ ULONG ProcessInJob :1; 197 | /* +0x050 */ ULONG ProcessInitializing :1; 198 | /* +0x050 */ ULONG ProcessUsingVEH :1; 199 | /* +0x050 */ ULONG ProcessUsingVCH :1; 200 | /* +0x050 */ ULONG ProcessUsingFTH :1; 201 | /* +0x050 */ ULONG ReservedBits0 :27; 202 | }; 203 | }; 204 | 205 | /* +0x054 */ BYTE Padding1 [4]; 206 | union 207 | { 208 | /* +0x058 */ PVOID /* Ptr64 Void */ KernelCallbackTable ; 209 | /* +0x058 */ PVOID /* Ptr64 Void */ UserSharedInfoPtr ; 210 | }; 211 | /* +0x060 */ ULONG SystemReserved [1]; 212 | /* +0x064 */ ULONG AtlThunkSListPtr32 ; 213 | /* +0x068 */ PVOID /* Ptr64 Void */ ApiSetMap ; 214 | /* +0x070 */ ULONG TlsExpansionCounter ; 215 | /* +0x074 */ BYTE Padding2 [4]; 216 | /* +0x078 */ PVOID /* Ptr64 Void */ TlsBitmap ; 217 | /* +0x080 */ ULONG TlsBitmapBits [2]; 218 | /* +0x088 */ PVOID /* Ptr64 Void */ ReadOnlySharedMemoryBase ; 219 | /* +0x090 */ PVOID /* Ptr64 Void */ SparePvoid0 ; 220 | /* +0x098 */ PPVOID /* Ptr64 Ptr64 Void */ ReadOnlyStaticServerData ; 221 | /* +0x0a0 */ PVOID /* Ptr64 Void */ AnsiCodePageData ; 222 | /* +0x0a8 */ PVOID /* Ptr64 Void */ OemCodePageData ; 223 | /* +0x0b0 */ PVOID /* Ptr64 Void */ UnicodeCaseTableData ; 224 | /* +0x0b8 */ ULONG NumberOfProcessors ; 225 | /* +0x0bc */ ULONG NtGlobalFlag ; 226 | /* +0x0c0 */ LARGE_INTEGER CriticalSectionTimeout ; 227 | /* +0x0c8 */ ULONGLONG HeapSegmentReserve ; 228 | /* +0x0d0 */ ULONGLONG HeapSegmentCommit ; 229 | /* +0x0d8 */ ULONGLONG HeapDeCommitTotalFreeThreshold ; 230 | /* +0x0e0 */ ULONGLONG HeapDeCommitFreeBlockThreshold ; 231 | /* +0x0e8 */ ULONG NumberOfHeaps ; 232 | /* +0x0ec */ ULONG MaximumNumberOfHeaps ; 233 | /* +0x0f0 */ PPVOID /* Ptr64 Ptr64 Void */ ProcessHeaps ; 234 | /* +0x0f8 */ PVOID /* Ptr64 Void */ GdiSharedHandleTable ; 235 | /* +0x100 */ PVOID /* Ptr64 Void */ ProcessStarterHelper ; 236 | /* +0x108 */ ULONG GdiDCAttributeList ; 237 | /* +0x10c */ BYTE Padding3 [4]; 238 | /* +0x110 */ PRTL_CRITICAL_SECTION /* Ptr64 _RTL_CRITICAL_SECTION */ LoaderLock ; 239 | /* +0x118 */ ULONG OSMajorVersion ; 240 | /* +0x11c */ ULONG OSMinorVersion ; 241 | /* +0x120 */ USHORT OSBuildNumber ; 242 | /* +0x122 */ USHORT OSCSDVersion ; 243 | /* +0x124 */ ULONG OSPlatformId ; 244 | /* +0x128 */ ULONG ImageSubsystem ; 245 | /* +0x12c */ ULONG ImageSubsystemMajorVersion ; 246 | /* +0x130 */ ULONG ImageSubsystemMinorVersion ; 247 | /* +0x134 */ BYTE Padding4 [4]; 248 | /* +0x138 */ ULONGLONG ActiveProcessAffinityMask ; 249 | /* +0x140 */ ULONG GdiHandleBuffer [60]; 250 | /* +0x230 */ PVOID /* Ptr64 void */ PostProcessInitRoutine ; 251 | /* +0x238 */ PVOID /* Ptr64 Void */ TlsExpansionBitmap ; 252 | /* +0x240 */ ULONG TlsExpansionBitmapBits [32]; 253 | /* +0x2c0 */ ULONG SessionId ; 254 | /* +0x2c4 */ BYTE Padding5 [4]; 255 | /* +0x2c8 */ ULARGE_INTEGER AppCompatFlags ; 256 | /* +0x2d0 */ ULARGE_INTEGER AppCompatFlagsUser ; 257 | /* +0x2d8 */ PVOID /* Ptr64 Void */ pShimData ; 258 | /* +0x2e0 */ PVOID /* Ptr64 Void */ AppCompatInfo ; 259 | /* +0x2e8 */ UNICODE_STRING CSDVersion ; 260 | /* +0x2f8 */ PVOID /* Ptr64 _ACTIVATION_CONTEXT_DATA */ ActivationContextData ; 261 | /* +0x300 */ PVOID/* Ptr64 _ASSEMBLY_STORAGE_MAP */ ProcessAssemblyStorageMap ; 262 | /* +0x308 */ PVOID/* Ptr64 _ACTIVATION_CONTEXT_DATA */ SystemDefaultActivationContextData ; 263 | /* +0x310 */ PVOID/* Ptr64 _ASSEMBLY_STORAGE_MAP */ SystemAssemblyStorageMap ; 264 | /* +0x318 */ ULONGLONG MinimumStackCommit ; 265 | /* +0x320 */ PVOID/* Ptr64 _FLS_CALLBACK_INFO */ FlsCallback ; 266 | /* +0x328 */ LIST_ENTRY FlsListHead ; 267 | /* +0x338 */ PVOID /* Ptr64 Void */ FlsBitmap ; 268 | /* +0x340 */ ULONG FlsBitmapBits [4]; 269 | /* +0x350 */ ULONG FlsHighIndex ; 270 | /* +0x358 */ PVOID /* Ptr64 Void */ WerRegistrationData ; 271 | /* +0x360 */ PVOID /* Ptr64 Void */ WerShipAssertPtr ; 272 | /* +0x368 */ PVOID /* Ptr64 Void */ pUnused ; 273 | /* +0x370 */ PVOID /* Ptr64 Void */ pImageHeaderHash ; 274 | union 275 | { 276 | /* +0x378 */ ULONG TracingFlags ; 277 | struct 278 | { 279 | /* +0x378 */ ULONG HeapTracingEnabled :1; 280 | /* +0x378 */ ULONG CritSecTracingEnabled :1; 281 | /* +0x378 */ ULONG LibLoaderTracingEnabled :1; 282 | /* +0x378 */ ULONG SpareTracingBits :29; 283 | }; 284 | }; 285 | 286 | /* +0x37c */ BYTE Padding6 [4]; 287 | /* +0x380 */ ULONGLONG CsrServerReadOnlySharedMemoryBase ; 288 | 289 | }; 290 | typedef struct _PEB_32 PEB; 291 | typedef PEB *PPEB; 292 | 293 | typedef struct _PROCESS_BASIC_INFORMATION { 294 | PVOID ExitStatus; 295 | PPEB PebBaseAddress; 296 | PVOID AffinityMask; 297 | PVOID BasePriority; 298 | ULONG_PTR UniqueProcessId; 299 | ULONG InheritedFromUniqueProcessId; 300 | } PROCESS_BASIC_INFORMATION; 301 | 302 | #endif // PROCESSBASICINFORMATION_H 303 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ProcessInformation.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_PROCESSINFORMATION 2 | #define DEF_PROCESSINFORMATION 3 | 4 | struct ProcessInformation { 5 | unsigned long pid, handleCount; 6 | unsigned int threadCount; 7 | char name[1024]; 8 | }; 9 | typedef struct ProcessInformation ProcessInformation; 10 | 11 | struct ProcessInformationList { 12 | ProcessInformation* data; 13 | unsigned int length; 14 | }; 15 | typedef struct ProcessInformationList ProcessInformationList; 16 | 17 | struct ProcessWithHandlesList { 18 | ProcessInformation dataProcess; 19 | char fullHandleName[512]; 20 | char handleType[256]; 21 | struct ProcessWithHandlesList* next; 22 | }; 23 | typedef struct ProcessWithHandlesList ProcessWithHandlesList; 24 | 25 | struct HandleProcessInformation { 26 | unsigned long processPid; 27 | char name[1024], type[256], processName[256]; 28 | struct HandleProcessInformation* next; 29 | }; 30 | typedef struct HandleProcessInformation HandleProcessInformation; 31 | 32 | void FreeHandleProcessInformation(HandleProcessInformation* handle); 33 | HandleProcessInformation* CreateHandleProcessInformation(); 34 | void DisplayHandleProcessInformation(HandleProcessInformation* handle); 35 | 36 | #endif // DEF_PROCESSINFORMATION 37 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ProcessModule.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ProcessBasicInformation.h" 4 | #include "ProcessModule.h" 5 | #include "AnsiString.h" 6 | 7 | ProcessModule* CreateSingleProcessModuleFromDataTable(LDR_DATA_TABLE_ENTRY* dataTable) 8 | { 9 | ProcessModule* result = (ProcessModule*) calloc(1, sizeof(ProcessModule)); 10 | 11 | result->BaseDllName.Buffer = (char*) dataTable->BaseDllName.Buffer; 12 | result->FullDllName.Buffer = (char*) dataTable->FullDllName.Buffer; 13 | 14 | result->BaseNameHashValue = dataTable->BaseNameHashValue; 15 | result->DdagNode = dataTable->DdagNode; 16 | result->DllBase = dataTable->DllBase; 17 | result->EntryPoint = dataTable->EntryPoint; 18 | result->EntryPointActivationContext = dataTable->EntryPointActivationContext; 19 | result->HashLinks = dataTable->HashLinks.Flink; 20 | result->ImplicitPathOptions = dataTable->ImplicitPathOptions; 21 | result->InLoadOrderLinks = dataTable->InLoadOrderLinks.Flink; 22 | result->InMemoryOrderLinks = dataTable->InMemoryOrderLinks.Flink; 23 | result->LoadReason = dataTable->LoadReason; 24 | result->LoadTime = dataTable->LoadTime.QuadPart; 25 | result->NodeModuleLink = dataTable->NodeModuleLink.Flink; 26 | result->ObsoleteLoadCount = dataTable->ObsoleteLoadCount; 27 | result->OriginalBase = dataTable->OriginalBase; 28 | result->ParentDllBase = dataTable->ParentDllBase; 29 | result->SizeOfImage = dataTable->SizeOfImage; 30 | result->SnapContext = dataTable->SnapContext; 31 | result->Spare = dataTable->Spare; 32 | result->SwitchBackContext = dataTable->SwitchBackContext; 33 | result->TimeDateStamp = dataTable->TimeDateStamp; 34 | result->TlsIndex = dataTable->TlsIndex; 35 | 36 | return result; 37 | } 38 | 39 | void DisplayProcessModule(ProcessModule* list) 40 | { 41 | for(; list != NULL; list = (ProcessModule*) list->next) 42 | { 43 | printf("(%p) %s\n", list->FullDllName.Buffer, list->FullDllName.Buffer); 44 | printf("HashLinks : %p\n", list->HashLinks); 45 | } 46 | } 47 | 48 | void AddQueueProcessModule(ProcessModule* head, ProcessModule* toAdd) 49 | { 50 | ProcessModule* list; 51 | for(list = head; list->next; list = (ProcessModule*) list->next); 52 | 53 | list->next = toAdd; 54 | } 55 | 56 | 57 | void AddHeadProcessModule(ProcessModule** head, ProcessModule* toAdd) 58 | { 59 | toAdd->next = *head; 60 | *head = toAdd; 61 | } 62 | 63 | void FreeProcessModuleList(ProcessModule* list) 64 | { 65 | if(list) 66 | { 67 | free(list->BaseDllName.Buffer); 68 | free(list->FullDllName.Buffer); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ProcessModule.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCESSMODULE_H 2 | #define PROCESSMODULE_H 3 | 4 | #include "AnsiString.h" 5 | 6 | struct _ProcessModule { 7 | /* +0x000 */ void* InLoadOrderLinks ; 8 | /* +0x010 */ void* InMemoryOrderLinks ; 9 | union 10 | { 11 | /* +0x020 */ void* InInitializationOrderLinks ; 12 | /* +0x020 */ void* InProgressLinks ; 13 | }; 14 | /* +0x030 */ void* /* Ptr64 Void */ DllBase ; 15 | /* +0x038 */ void* /* Ptr64 Void */ EntryPoint ; 16 | /* +0x040 */ unsigned long SizeOfImage ; 17 | /* +0x048 */ ANSI_STRING FullDllName ; 18 | /* +0x058 */ ANSI_STRING BaseDllName ; 19 | 20 | union 21 | { 22 | /* +0x068 */ char FlagGroup [4]; 23 | /* +0x068 */ unsigned int Flags ; 24 | struct 25 | { 26 | /* +0x068 */ unsigned int PackagedBinary :1; 27 | /* +0x068 */ unsigned int MarkedForRemoval :1; 28 | /* +0x068 */ unsigned int ImageDll :1; 29 | /* +0x068 */ unsigned int LoadNotificationsSent :1; 30 | /* +0x068 */ unsigned int TelemetryEntryProcessed :1; 31 | /* +0x068 */ unsigned int ProcessStaticImport :1; 32 | /* +0x068 */ unsigned int InLegacyLists :1; 33 | /* +0x068 */ unsigned int InIndexes :1; 34 | /* +0x068 */ unsigned int ShimDll :1; 35 | /* +0x068 */ unsigned int InExceptionTable :1; 36 | /* +0x068 */ unsigned int ReservedFlags1 :2; 37 | /* +0x068 */ unsigned int LoadInProgress :1; 38 | /* +0x068 */ unsigned int ReservedFlags2 :1; 39 | /* +0x068 */ unsigned int EntryProcessed :1; 40 | /* +0x068 */ unsigned int ReservedFlags3 :3; 41 | /* +0x068 */ unsigned int DontCallForThreads :1; 42 | /* +0x068 */ unsigned int ProcessAttachCalled :1; 43 | /* +0x068 */ unsigned int ProcessAttachFailed :1; 44 | /* +0x068 */ unsigned int CorDeferredValidate :1; 45 | /* +0x068 */ unsigned int CorImage :1; 46 | /* +0x068 */ unsigned int DontRelocate :1; 47 | /* +0x068 */ unsigned int CorILOnly :1; 48 | /* +0x068 */ unsigned int ReservedFlags5 :3; 49 | /* +0x068 */ unsigned int Redirected :1; 50 | /* +0x068 */ unsigned int ReservedFlags6 :2; 51 | /* +0x068 */ unsigned int CompatDatabaseProcessed :1; 52 | }; 53 | }; 54 | 55 | /* +0x06c */ unsigned short ObsoleteLoadCount ; 56 | /* +0x06e */ unsigned short TlsIndex ; 57 | /* +0x070 */ void* HashLinks ; 58 | /* +0x080 */ unsigned int TimeDateStamp ; 59 | /* +0x088 */ void* /* Ptr64 _ACTIVATION_CONTEXT */ EntryPointActivationContext ; 60 | /* +0x090 */ void* /* Ptr64 Void */ Spare ; 61 | /* +0x098 */ void* /* Ptr64 _LDR_DDAG_NODE */ DdagNode ; 62 | /* +0x0a0 */ void* NodeModuleLink ; 63 | /* +0x0b0 */ void* /* Ptr64 _LDRP_DLL_SNAP_CONTEXT */ SnapContext ; 64 | /* +0x0b8 */ void* /* Ptr64 Void */ ParentDllBase ; 65 | /* +0x0c0 */ void* /* Ptr64 Void */ SwitchBackContext ; 66 | // /* +0x0c8 */ RTL_BALANCED_NODE BaseAddressIndexNode ; 67 | // /* +0x0e0 */ RTL_BALANCED_NODE MappingInfoIndexNode ; 68 | /* +0x0f8 */ unsigned long long OriginalBase ; 69 | /* +0x100 */ unsigned long long LoadTime ; 70 | /* +0x108 */ unsigned long BaseNameHashValue ; 71 | /* +0x10c */ LDR_DLL_LOAD_REASON LoadReason ; 72 | /* +0x110 */ unsigned long ImplicitPathOptions ; 73 | 74 | struct _ProcessModule* next; 75 | }; 76 | typedef struct _ProcessModule ProcessModule; 77 | 78 | ProcessModule* CreateSingleProcessModuleFromDataTable(LDR_DATA_TABLE_ENTRY* dataTable); 79 | void DisplayProcessModule(ProcessModule* list); 80 | void AddQueueProcessModule(ProcessModule* list, ProcessModule* toAdd); 81 | void AddHeadProcessModule(ProcessModule** head, ProcessModule* toAdd); 82 | void FreeProcessModuleList(ProcessModule* list); 83 | 84 | #endif // PROCESSMODULE_H 85 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ProcessUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "ProcessUtils.h" 8 | 9 | #pragma comment(lib, "version.lib" ) 10 | 11 | typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); 12 | 13 | LPFN_ISWOW64PROCESS fnIsWow64Process; 14 | 15 | int IsWow64ProcessCaller(HANDLE hProcess) 16 | { 17 | BOOL bIsWow64 = FALSE; 18 | 19 | fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress( 20 | GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); 21 | 22 | if(fnIsWow64Process != NULL) 23 | { 24 | if (!fnIsWow64Process(hProcess,&bIsWow64)) 25 | { 26 | printf("Erreur lors du test de profondeur de bits du processus\n"); 27 | //Erreur : par défaut on choisi 32 bits 28 | return -1; 29 | } 30 | } 31 | else 32 | { 33 | //IsWow64Process introuvable : OS 32 bits 34 | return 2; 35 | } 36 | 37 | //Si bisWow64 == 1, OS 64 bits sinon impossible de savoir 38 | return bIsWow64 ? 1 : 0; 39 | } 40 | 41 | bool GetOSVersionString(OSVersion* version) 42 | { 43 | WCHAR path[_MAX_PATH]; 44 | if (!GetSystemDirectoryW(path, _MAX_PATH)) 45 | return false; 46 | 47 | wcscat_s(path, L"\\kernel32.dll"); 48 | 49 | // 50 | // Based on example code from this article 51 | // http://support.microsoft.com/kb/167597 52 | // 53 | 54 | DWORD handle; 55 | #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) 56 | DWORD len = GetFileVersionInfoSizeExW(FILE_VER_GET_NEUTRAL, path, &handle); 57 | #else 58 | DWORD len = GetFileVersionInfoSizeW(path, &handle); 59 | #endif 60 | if (!len) 61 | return false; 62 | 63 | std::unique_ptr buff(new (std::nothrow) uint8_t[len]); 64 | if (!buff) 65 | return false; 66 | 67 | #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) 68 | if (!GetFileVersionInfoExW(FILE_VER_GET_NEUTRAL, path, 0, len, buff.get())) 69 | #else 70 | if (!GetFileVersionInfoW(path, 0, len, buff.get())) 71 | #endif 72 | return false; 73 | 74 | VS_FIXEDFILEINFO *vInfo = nullptr; 75 | UINT infoSize; 76 | 77 | if (!VerQueryValueW(buff.get(), L"\\", reinterpret_cast(&vInfo), &infoSize)) 78 | return false; 79 | 80 | if (!infoSize) 81 | return false; 82 | 83 | version->osMajorVersion = HIWORD(vInfo->dwFileVersionMS); 84 | version->osMinorVersion = LOWORD(vInfo->dwFileVersionMS); 85 | 86 | return true; 87 | } 88 | 89 | int Is64Process(DWORD pid) 90 | { 91 | DWORD dwVersion, dwMajorVersion, dwMinorVersion = 2; 92 | OSVersion osVersion; 93 | GetOSVersionString(&osVersion); 94 | 95 | dwMajorVersion = osVersion.osMajorVersion; 96 | dwMinorVersion = osVersion.osMinorVersion; 97 | 98 | if((dwMajorVersion < 5 || (dwMajorVersion == 5 && dwMinorVersion == 1))) 99 | { 100 | return 2; 101 | } 102 | else 103 | { 104 | HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); 105 | if (hProcess == NULL) { 106 | printf("Erreur : impossible d'ouvrir le processus de pid %u\n", pid); 107 | } else { 108 | int wow64 = IsWow64ProcessCaller(hProcess); 109 | CloseHandle(hProcess); 110 | return !wow64; 111 | } 112 | return 0; 113 | } 114 | } 115 | 116 | 117 | BOOL Is64Os() 118 | { 119 | // printf("int* = %u\n", sizeof(int*)); 120 | return (sizeof(int*) == 8) || (Is64Process(GetCurrentProcessId()) == 0); 121 | } 122 | 123 | DWORD GetFirstProcessIdFromProcessName(const char* processName) 124 | { 125 | DWORD aProcesses[1024], cbNeeded, cProcesses; 126 | unsigned int i; 127 | 128 | if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) 129 | { 130 | printf("Erreur lors de l'enumeration des processus\n"); 131 | return -1; 132 | } 133 | 134 | cProcesses = cbNeeded / sizeof(DWORD); 135 | 136 | for ( i = 0; i < cProcesses; i++ ) 137 | { 138 | if( aProcesses[i] != 0 ) 139 | { 140 | HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | 141 | PROCESS_VM_READ, 142 | FALSE, aProcesses[i] ); 143 | if(hProcess != NULL) 144 | { 145 | char name[2048] = {'\0'}; 146 | GetModuleBaseNameA(hProcess, NULL, name, sizeof(name) - 1); 147 | printf("name = %s\npid = %u\n", name, (unsigned int) aProcesses[i]); 148 | if(strstr(name, processName) != NULL) 149 | { 150 | //printf("name = %s\npid = %u\n", name, aProcesses[i]); 151 | return aProcesses[i]; 152 | } 153 | } 154 | CloseHandle(hProcess); 155 | } 156 | } 157 | printf("Erreur : impossible de trouver le processus correspondant a \"%s\"\n", processName); 158 | return -1; 159 | } 160 | -------------------------------------------------------------------------------- /src/LIB_INVADER/ProcessUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef PROCESSUTILS_H 2 | #define PROCESSUTILS_H 3 | 4 | struct tagOSVersion { 5 | DWORD osMajorVersion; 6 | DWORD osMinorVersion; 7 | }; 8 | 9 | typedef struct tagOSVersion OSVersion; 10 | 11 | int Is64Process(DWORD pid); 12 | BOOL Is64Os(); 13 | DWORD GetFirstProcessIdFromProcessName(const char* processName); 14 | 15 | #endif // PROCESSUTILS_H 16 | -------------------------------------------------------------------------------- /src/LIB_INVADER/QueryOpenedFiles.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Scorbutics/InjectItx64/e9de011f8886f706b2cf1c3fa37cd23d112af873/src/LIB_INVADER/QueryOpenedFiles.cpp -------------------------------------------------------------------------------- /src/LIB_INVADER/QueryProcessInformation.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Scorbutics/InjectItx64/e9de011f8886f706b2cf1c3fa37cd23d112af873/src/LIB_INVADER/QueryProcessInformation.cpp -------------------------------------------------------------------------------- /src/LIB_INVADER/RegUtils.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Scorbutics/InjectItx64/e9de011f8886f706b2cf1c3fa37cd23d112af873/src/LIB_INVADER/RegUtils.cpp -------------------------------------------------------------------------------- /src/LIB_INVADER/RegUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_REGUTILS 2 | #define DEF_REGUTILS 3 | 4 | void DisplayValuesInKey(HKEY key); 5 | void GetKeyPathFromHKEY(HMODULE dll, HKEY key, TCHAR* keyPath); 6 | HKEY OpenKeySoftwaresStartup(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/LIB_INVADER/RtlDriveLetterCurdirContent.h: -------------------------------------------------------------------------------- 1 | #ifndef RTLDRIVELETTERCURDIRCONTENT_H 2 | #define RTLDRIVELETTERCURDIRCONTENT_H 3 | 4 | 5 | 6 | #endif // RTLDRIVELETTERCURDIRCONTENT_H 7 | -------------------------------------------------------------------------------- /src/LIB_INVADER/SystemInformationClass.h: -------------------------------------------------------------------------------- 1 | #ifndef DEF_UNICODE_STRING 2 | #define DEF_UNICODE_STRING 3 | 4 | typedef unsigned long SYSTEM_INFORMATION_CLASS; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/LIB_INVADER/SystemProcessInformation.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSTEMPROCESSINFORMATION_H_INCLUDED 2 | #define SYSTEMPROCESSINFORMATION_H_INCLUDED 3 | 4 | typedef DWORD KPRIORITY; // Thread priority 5 | 6 | typedef enum _KWAIT_REASON 7 | { 8 | Executive = 0, 9 | FreePage = 1, 10 | PageIn = 2, 11 | PoolAllocation = 3, 12 | DelayExecution = 4, 13 | Suspended = 5, 14 | UserRequest = 6, 15 | WrExecutive = 7, 16 | WrFreePage = 8, 17 | WrPageIn = 9, 18 | WrPoolAllocation = 10, 19 | WrDelayExecution = 11, 20 | WrSuspended = 12, 21 | WrUserRequest = 13, 22 | WrEventPair = 14, 23 | WrQueue = 15, 24 | WrLpcReceive = 16, 25 | WrLpcReply = 17, 26 | WrVirtualMemory = 18, 27 | WrPageOut = 19, 28 | WrRendezvous = 20, 29 | Spare2 = 21, 30 | Spare3 = 22, 31 | Spare4 = 23, 32 | Spare5 = 24, 33 | WrCalloutStack = 25, 34 | WrKernel = 26, 35 | WrResource = 27, 36 | WrPushLock = 28, 37 | WrMutex = 29, 38 | WrQuantumEnd = 30, 39 | WrDispatchInt = 31, 40 | WrPreempted = 32, 41 | WrYieldExecution = 33, 42 | WrFastMutex = 34, 43 | WrGuardedMutex = 35, 44 | WrRundown = 36, 45 | MaximumWaitReason = 37 46 | } KWAIT_REASON; 47 | 48 | typedef struct _CLIENT_ID { 49 | DWORD UniqueProcess; 50 | DWORD UniqueThread; 51 | } CLIENT_ID; 52 | 53 | typedef struct _VM_COUNTERS { 54 | #ifdef _WIN64 55 | SIZE_T PeakVirtualSize; 56 | SIZE_T PageFaultCount; 57 | SIZE_T PeakWorkingSetSize; 58 | SIZE_T WorkingSetSize; 59 | SIZE_T QuotaPeakPagedPoolUsage; 60 | SIZE_T QuotaPagedPoolUsage; 61 | SIZE_T QuotaPeakNonPagedPoolUsage; 62 | SIZE_T QuotaNonPagedPoolUsage; 63 | SIZE_T PagefileUsage; 64 | SIZE_T PeakPagefileUsage; 65 | SIZE_T VirtualSize; 66 | #else 67 | SIZE_T PeakVirtualSize; 68 | SIZE_T VirtualSize; 69 | ULONG PageFaultCount; 70 | SIZE_T PeakWorkingSetSize; 71 | SIZE_T WorkingSetSize; 72 | SIZE_T QuotaPeakPagedPoolUsage; 73 | SIZE_T QuotaPagedPoolUsage; 74 | SIZE_T QuotaPeakNonPagedPoolUsage; 75 | SIZE_T QuotaNonPagedPoolUsage; 76 | SIZE_T PagefileUsage; 77 | SIZE_T PeakPagefileUsage; 78 | #endif 79 | } VM_COUNTERS; 80 | 81 | typedef struct _SYSTEM_THREAD_INFORMATION { 82 | LARGE_INTEGER KernelTime; 83 | LARGE_INTEGER UserTime; 84 | LARGE_INTEGER CreateTime; 85 | ULONG WaitTime; 86 | PVOID StartAddress; 87 | CLIENT_ID ClientId; 88 | KPRIORITY Priority; 89 | LONG BasePriority; 90 | ULONG ContextSwitchCount; 91 | ULONG State; 92 | ULONG WaitReason; //KWAIT_REASON 93 | 94 | } SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; 95 | 96 | 97 | typedef struct _SYSTEM_PROCESS_INFORMATION { /* x86/x64 */ 98 | ULONG NextEntryOffset; /* 00/00 */ 99 | ULONG NumberOfThreads; /* 04/04 */ 100 | LARGE_INTEGER WorkingSetPrivateSize; /* 08/08 */ 101 | ULONG HardFaultCount; /* 12/12 */ 102 | ULONG NumberOfThreadsHighWatermark; /* 16/16 */ 103 | ULONGLONG CycleTime; /* 1A/1A */ 104 | LARGE_INTEGER CreateTime; /* 20/20 */ 105 | LARGE_INTEGER UserTime; /* 28/28 */ 106 | LARGE_INTEGER KernelTime; /* 30/30 */ 107 | UNICODE_STRING ImageName; /* 38/38 */ 108 | KPRIORITY BasePriority; /* 40/48 */ 109 | HANDLE ProcessId; /* 44/50 */ 110 | HANDLE InheritedFromProcessId; /* 48/58 */ 111 | ULONG HandleCount; /* 4C/60 */ 112 | DWORD Reserved2[2]; /* 50/64 */ 113 | //ULONG PrivatePageCount; 114 | VM_COUNTERS VirtualMemoryCounters; /* 58/70 */ 115 | IO_COUNTERS IoCounters; /* 88/D0 */ 116 | SYSTEM_THREAD_INFORMATION Threads[1]; /* B8/100 */ 117 | } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 118 | 119 | 120 | 121 | 122 | #endif // SYSTEMPROCESSINFORMATION_H_INCLUDED 123 | -------------------------------------------------------------------------------- /src/LIB_INVADER/UnicodeString.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "UnicodeString.h" 3 | 4 | void ConvertToCharArrayFromUnicodeString(UNICODE_STRING str, char* output, unsigned int maxLength) 5 | { 6 | unsigned int i; 7 | for(i = 0; i < str.Length && i < (maxLength-1); i++) 8 | { 9 | output[i] = str.Buffer[i]; 10 | } 11 | output[i] = '\0'; 12 | } 13 | 14 | void utf8_encode(LPCTSTR wstr, unsigned int size, char* output, unsigned int outputMaxLength) 15 | { 16 | if(outputMaxLength == 0) 17 | return; 18 | 19 | WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(wstr), size, output, outputMaxLength, NULL, NULL); 20 | output[outputMaxLength-1] = '\0'; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/LIB_INVADER/UnicodeString.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICODESTRING_H_INCLUDED 2 | #define UNICODESTRING_H_INCLUDED 3 | 4 | #include 5 | 6 | typedef struct _LSA_UNICODE_STRING { 7 | /* +0x000 */ USHORT Length; 8 | /* +0x002 */ USHORT MaximumLength; 9 | /* +0x008 */ PWSTR Buffer; 10 | } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; 11 | 12 | 13 | void ConvertToCharArrayFromUnicodeString(UNICODE_STRING str, char* output, unsigned int maxLength); 14 | void utf8_encode(LPCTSTR wstr, unsigned int size, char* output, unsigned int outputMaxLength); 15 | #endif 16 | -------------------------------------------------------------------------------- /src/LIB_INVADER/_LDR_DLL_LOAD_REASON.h: -------------------------------------------------------------------------------- 1 | #ifndef _LDR_DLL_LOAD_REASON_H 2 | #define _LDR_DLL_LOAD_REASON_H 3 | 4 | typedef enum _LDR_DLL_LOAD_REASON { 5 | LoadReasonStaticDependency = 0, 6 | LoadReasonStaticForwarderDependency = 1, 7 | LoadReasonDynamicForwarderDependency = 2, 8 | LoadReasonDelayloadDependency = 3, 9 | LoadReasonDynamicLoad = 4, 10 | LoadReasonAsImageLoad = 5, 11 | LoadReasonAsDataLoad = 6, 12 | LoadReasonUnknown = -1, 13 | } LDR_DLL_LOAD_REASON; 14 | 15 | #endif // _LDR_DLL_LOAD_REASON_H 16 | -------------------------------------------------------------------------------- /src/LIB_INVADER/_PEB_LDR_DATA.h: -------------------------------------------------------------------------------- 1 | #ifndef _PEB_LDR_DATA_H 2 | #define _PEB_LDR_DATA_H 3 | 4 | //module name : ntdll 5 | struct _PEB_LDR_DATA 6 | { /* +0x000 */ ULONG Length ; 7 | /* +0x004 */ BOOLEAN Initialized ; 8 | /* +0x008 */ HANDLE /* Ptr64 Void */ SsHandle ; 9 | /* +0x010 */ LIST_ENTRY InLoadOrderModuleList ; 10 | /* +0x020 */ LIST_ENTRY InMemoryOrderModuleList ; 11 | /* +0x030 */ LIST_ENTRY InInitializationOrderModuleList ; 12 | 13 | //InMemoryOrderModuleList 14 | //The head of a doubly-linked list that contains the loaded modules for the process. Each item in the list is a pointer to an LDR_DATA_TABLE_ENTRY structure. 15 | //For more information, see Remarks. 16 | 17 | /* +0x040 */ PVOID /* Ptr64 Void */ EntryInProgress ; 18 | /* +0x048 */ BOOLEAN ShutdownInProgress ; 19 | /* +0x050 */ HANDLE /* Ptr64 Void */ ShutdownThreadId ; 20 | 21 | }; 22 | typedef struct _PEB_LDR_DATA PEB_LDR_DATA; 23 | typedef PEB_LDR_DATA *PPEB_LDR_DATA; 24 | 25 | #endif // _PEB_LDR_DATA_H 26 | -------------------------------------------------------------------------------- /src/LIB_INVADER/_RTL_BALANCED_NODE.h: -------------------------------------------------------------------------------- 1 | #ifndef _RTL_BALANCED_NODE_H 2 | #define _RTL_BALANCED_NODE_H 3 | 4 | //module name : ntdll 5 | struct _RTL_BALANCED_NODE 6 | { union 7 | { 8 | /* +0x000 */ struct _RTL_BALANCED_NODE* /* Ptr64 _RTL_BALANCED_NODE */ Children [2]; 9 | struct { 10 | /* +0x000 */ struct _RTL_BALANCED_NODE* /* Ptr64 _RTL_BALANCED_NODE */ Left ; 11 | /* +0x008 */ struct _RTL_BALANCED_NODE* /* Ptr64 _RTL_BALANCED_NODE */ Right ; 12 | }; 13 | }; 14 | 15 | union 16 | { 17 | /* +0x010 */ ULONG_PTR /* Ptr64 _RTL_BALANCED_NODE */ Red :1; 18 | /* +0x010 */ ULONG_PTR /* Ptr64 _RTL_BALANCED_NODE */ Balance :2; 19 | /* +0x010 */ ULONG_PTR ParentValue ; 20 | }; 21 | 22 | }; 23 | typedef struct _RTL_BALANCED_NODE RTL_BALANCED_NODE; 24 | 25 | #endif // _RTL_BALANCED_NODE_H 26 | -------------------------------------------------------------------------------- /src/LoadLibraryInMem.asm: -------------------------------------------------------------------------------- 1 | EXTERN LoadLibraryA proc 2 | 3 | .code 4 | 5 | LoadLibraryInMemx64 proc 6 | 7 | PUSH RCX 8 | PUSH RDX 9 | PUSH RDI 10 | 11 | ;The second parameter passed to LoadLibraryInMemx64 is the address where we'll stock 12 | ;the LoadLibraryA returned value, and we copy it to RDI 13 | MOV RDI, RDX 14 | 15 | 16 | CALL LoadLibraryA 17 | 18 | ;Let's copy the Handle returned by LoadLibraryA in a memory Zone 19 | MOV QWORD PTR[RDI], RAX 20 | 21 | POP RDI 22 | POP RDX 23 | POP RCX 24 | 25 | 26 | LoadLibraryInMemx64 endp 27 | 28 | LoadLibraryInMemx86 proc 29 | 30 | PUSH EDI 31 | 32 | CALL LoadLibraryA 33 | MOV DWORD PTR[EDI], EAX 34 | 35 | POP EDI 36 | 37 | LoadLibraryInMemx86 endp 38 | 39 | end -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "LIB_INVADER/Injector.h" 6 | #include "LIB_INVADER/ProcessInformation.h" 7 | #include "LIB_INVADER/GetProcessInformation.h" 8 | #include "LIB_INVADER/DebugPrivileges.h" 9 | 10 | #include "LIB_INVADER/ArgUtils.h" 11 | 12 | const char* usageRules = "Utilisation : commandes\n" 13 | " -i : inject the dll to the process\n" 14 | " -pid : use a process id instead of providing a name\n" 15 | " -f : free the dll from the process\n" 16 | "Exemple : injectit.exe calc.exe -i injectdll.dll \n" 17 | "injecte un module \"injectdll.dll\" dans la calculatrice Windows\n"; 18 | 19 | void ProcessPidInjection(unsigned int pid, const char* nameInjected, const char* dllPathName, const char* argv[], int argc) 20 | { 21 | if (pid != 0) 22 | { 23 | if (FileExists(dllPathName)) 24 | { 25 | 26 | if (FindArg((const char**)argv, argc, "-iNt") != NULL) 27 | { 28 | printf("Injecting %s with %s... (using NtCreateThreadEx)\n", nameInjected, dllPathName); 29 | if (!InjectDllRemoteThread(pid, (char*)dllPathName, INJECTION_METHOD_NT)) 30 | { 31 | printf("Injection Failed\n"); 32 | } else { 33 | system("cls"); 34 | } 35 | } 36 | else if (FindArg((const char**)argv, argc, "-iRtl") != NULL) 37 | { 38 | printf("Injecting %s with %s... (using RtlCreateUserThread)\n", nameInjected, dllPathName); 39 | if (!InjectDllRemoteThread(pid, (char*)dllPathName, INJECTION_METHOD_RTL)) 40 | { 41 | printf("Injection Failed\n"); 42 | } else { 43 | system("cls"); 44 | } 45 | } 46 | else if (FindArg((const char**)argv, argc, "-i") != NULL) 47 | { 48 | printf("Injecting %s with %s... (using CreateRemoteThread)\n", nameInjected, dllPathName); 49 | if (!InjectDllRemoteThread(pid, (char*)dllPathName, INJECTION_METHOD_CreateRemoteThread)) 50 | { 51 | printf("Injection Failed\n"); 52 | } else { 53 | system("cls"); 54 | } 55 | } 56 | else if (FindArg((const char**)argv, argc, "-fNt") != NULL) 57 | { 58 | printf("Releasing %s in %s... (using NtCreateThreadEx)\n", dllPathName, nameInjected); 59 | ReleaseDllRemoteThread(pid, (char*)dllPathName, INJECTION_METHOD_NT); 60 | } 61 | else if (FindArg((const char**)argv, argc, "-fRtl") != NULL) 62 | { 63 | printf("Releasing %s in %s... (using RtlCreateUserThread)\n", dllPathName, nameInjected); 64 | ReleaseDllRemoteThread(pid, (char*)dllPathName, INJECTION_METHOD_RTL); 65 | } 66 | else if (FindArg((const char**)argv, argc, "-f") != NULL) 67 | { 68 | printf("Releasing %s in %s... (using CreateRemoteThread)\n", dllPathName, nameInjected); 69 | ReleaseDllRemoteThread(pid, (char*)dllPathName, INJECTION_METHOD_CreateRemoteThread); 70 | } 71 | else 72 | { 73 | puts(usageRules); 74 | } 75 | } 76 | else 77 | { 78 | printf("Erreur : impossible de trouver la dll specifiee (%s)\n", dllPathName); 79 | } 80 | } 81 | else 82 | { 83 | printf("Erreur : processus introuvable ou non valide\n"); 84 | } 85 | } 86 | 87 | int main(int argc, char* argv[]) 88 | { 89 | if (argc < 3) 90 | { 91 | puts(usageRules); 92 | return 1; 93 | } 94 | 95 | unsigned int pid = 0; 96 | const char *processPathName = FindExtensionPathName((const char **)argv, argc, ".exe"); 97 | const char *dllPathName = FindExtensionPathName((const char **)argv, argc, ".dll"); 98 | const char *pidPathName = FindPidPathName((const char **)argv, argc); 99 | const char *injectNtCS = FindArg((const char**)argv, argc, "-iNtCS"); 100 | const char *injectRtlCS = FindArg((const char**)argv, argc, "-iRtlCS"); 101 | const char *injectCS = FindArg((const char**)argv, argc, "-iCS"); 102 | 103 | BOOL mustBeActiveProcess = !injectNtCS && !injectRtlCS && !injectCS; 104 | 105 | if (dllPathName == NULL) 106 | { 107 | printf("Erreur : impossible de determiner quelle est la dll a injecter\n"); 108 | return 1; 109 | } 110 | 111 | EnableDebugPrivilege(TRUE); 112 | 113 | if ((pidPathName == NULL && processPathName == NULL) && mustBeActiveProcess) 114 | { 115 | printf("Erreur : impossible de determiner quel est le processus a subir l'injection\n"); 116 | return 1; 117 | } else if (!mustBeActiveProcess) { 118 | if (processPathName == NULL) { 119 | printf("Erreur : impossible de determiner quel est le processus a lancer et a subir l'injection\n"); 120 | return 1; 121 | } 122 | 123 | if (injectNtCS) { 124 | if (!InjectDllCreatingSuspendedProcess(processPathName, FindNextArg((const char **)argv, argc, "-cmdLine"), dllPathName, INJECTION_METHOD_NT)) { 125 | printf("Injection Failed\n"); 126 | return 1; 127 | } 128 | } else if (injectRtlCS) { 129 | if (!InjectDllCreatingSuspendedProcess(processPathName, FindNextArg((const char **)argv, argc, "-cmdLine"), dllPathName, INJECTION_METHOD_RTL)) { 130 | printf("Injection Failed\n"); 131 | return 1; 132 | } 133 | } else if (injectCS) { 134 | if (!InjectDllCreatingSuspendedProcess(processPathName, FindNextArg((const char **)argv, argc, "-cmdLine"), dllPathName, INJECTION_METHOD_CreateRemoteThread)) { 135 | printf("Injection Failed\n"); 136 | return 1; 137 | } 138 | } 139 | } else { 140 | 141 | if (pidPathName == NULL) 142 | { 143 | ProcessInformationList *pList = GetProcessInformationsFromName(NULL, (char*)processPathName); 144 | unsigned int i; 145 | printf("Processes found :\n"); 146 | for (i = 0; i < pList->length; i++) 147 | { 148 | printf("\tPID : %u\n\tName : %s\n", (unsigned int)pList->data[i].pid, pList->data[i].name); 149 | ProcessPidInjection(pList->data[i].pid, pList->data[i].name, dllPathName, (const char **)argv, argc); 150 | } 151 | 152 | free(pList->data); 153 | free(pList); 154 | } 155 | else 156 | { 157 | pid = atoi(pidPathName); 158 | ProcessPidInjection(pid, pidPathName, dllPathName, (const char **)argv, argc); 159 | } 160 | 161 | } 162 | 163 | 164 | return 0; 165 | } 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | --------------------------------------------------------------------------------