mrexodia Posted January 14, 2014 Posted January 14, 2014 (edited) Hello everyone,Here is a small SDK example for TitanEngine Community Edition. It covers far from all features, but enough to get you started.This is the code: #include <windows.h>#include <stdio.h>#include <psapi.h>#include "TitanEngine\TitanEngine.h"PROCESS_INFORMATION* fdProcessInfo;LPVOID lpBaseOfImage;char szDumpName[MAX_PATH]="";static void log(const char* format, ...){ va_list args; va_start(args, format); char msg[1024]=""; vsprintf(msg, format, args); puts(msg);}static void cbOep(){ long long rip=GetContextData(UE_RIP); log("> OEP 0x%llX reached!", rip); log("> Dumping..."); DeleteFileA(szDumpName); //Dump the process (notice that szDumpName need to be a full path) if(!DumpProcess(fdProcessInfo->hProcess, lpBaseOfImage, szDumpName, rip)) { log("> DumpProcess failed..."); StopDebug(); return; } log("> Dumping done!"); log("> Fixing imports..."); ULONG_PTR iatStart=0; ULONG_PTR iatSize=0; //Search for IAT (Search start is 'OEP' in Scylla) ImporterAutoSearchIAT(fdProcessInfo->dwProcessId, szDumpName, rip, &iatStart, &iatSize); if(!iatStart || !iatSize) { log("> IAT not found..."); StopDebug(); return; } log("> IAT Start: 0x%llX, IAT Size: 0x%llX", iatStart, iatSize); char szSectionName[]=".unp64"; //Auto fix the file (append a section & fix IAT) if(!ImporterExportIATEx(szDumpName, szDumpName, szSectionName)) { log("> ImporterExportIATEx failed..."); StopDebug(); return; } log("> Imports fixed!"); //Stop debugging StopDebug();}static void cbNearOep(){ log("> Near OEP!"); //Step using the trap flag StepInto((void*)cbOep);}static void cbPeSpin(){ //Set a hardware breakpoint at RSP with size 8 on read/write SetHardwareBreakPoint(GetContextData(UE_RSP), UE_DR0, UE_HARDWARE_READWRITE, 8, (void*)cbNearOep);}static void cbEntry(){ //Get RIP register long long rip=GetContextData(UE_RIP); log("> Entry point 0x%llX reached!", rip); //Search for MPRESS pattern unsigned char pattern[4]= {0x5D, 0x5B, 0xC3,0xE9}; BYTE wildcard=0; long long found=Find((void*)rip, 0x1000, pattern, 4, &wildcard); if(!found) { //Search for PESpin pattern unsigned char pespin[4]= {0xFF, 0x64, 0x24, 0xF8}; long long found=Find((void*)rip, 0x1000, pespin, 4, &wildcard); if(!found) { log("> MPRESS/PESpin pattern NOT found..."); StopDebug(); return; } log("> PESpin pattern found on 0x%llX!", found); //Step over StepOver((void*)cbPeSpin); return; } //Set a simple INT3 breakpoint SetBPX(found+3, UE_BREAKPOINT, (void*)cbNearOep); log("> MPRESS pattern found on 0x%llX!", found);}static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo){ //Get the loaded base lpBaseOfImage=CreateProcessInfo->lpBaseOfImage; log("> Process created on 0x%llX!", lpBaseOfImage);}static bool DevicePathToPath(const char* devicepath, char* path, size_t path_size){ if(!devicepath || !path) return false; char curDrive[3]=" :"; char curDevice[MAX_PATH]=""; for(char drive='C'; drive<='Z'; drive++) { *curDrive=drive; if(!QueryDosDeviceA(curDrive, curDevice, MAX_PATH)) continue; size_t curDevice_len=strlen(curDevice); if(!_strnicmp(devicepath, curDevice, curDevice_len)) //we match the device { if(strlen(devicepath)-curDevice_len>=path_size) return false; sprintf(path, "%s%s", curDrive, devicepath+curDevice_len); return true; } } return false;}static bool GetFileNameFromHandle(HANDLE hFile, char* szFileName){ if(!GetFileSize(hFile, 0)) return false; HANDLE hFileMap=CreateFileMappingA(hFile, 0, PAGE_READONLY, 0, 1, 0); if(!hFileMap) return false; void* pFileMap=MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1); if(!pFileMap) { CloseHandle(hFileMap); return false; } char szMappedName[MAX_PATH]=""; if(GetMappedFileNameA(GetCurrentProcess(), pFileMap, szMappedName, MAX_PATH)) { DevicePathToPath(szMappedName, szFileName, MAX_PATH); UnmapViewOfFile(pFileMap); CloseHandle(hFileMap); return true; } UnmapViewOfFile(pFileMap); CloseHandle(hFileMap); return false;}static void unpack(char* szFileName){ //Set an engine variable (hide console window of created process) SetEngineVariable(UE_ENGINE_NO_CONSOLE_WINDOW, true); //Get full file path HANDLE hFile=CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if(hFile==INVALID_HANDLE_VALUE) { log("> File \"%s\" doesn't exist...", szFileName); return; } GetFileNameFromHandle(hFile, szDumpName); CloseHandle(hFile); log("> Unpack of file \"%s\" started...", szFileName); FILE_STATUS_INFO inFileStatus= {}; if(IsPE32FileValidEx(szFileName, UE_DEPTH_DEEP, &inFileStatus) && inFileStatus.FileIs64Bit && !inFileStatus.FileIsDLL) { log("> 64-bit PE file detected!"); //Make name of dumped file int len=strlen(szDumpName); while(szDumpName[len]!='.' && len) len--; if(!len) len=strlen(szDumpName); strcpy(szDumpName+len, "_unp64.exe"); //Start the process fdProcessInfo=(PROCESS_INFORMATION*)InitDebugEx(szFileName, 0, 0, (void*)cbEntry); if(fdProcessInfo) { log("> InitDebug OK!"); //Set a custom handler SetCustomHandler(UE_CH_CREATEPROCESS, (void*)cbCreateProcess); //Start debug loop DebugLoop(); } else log("> InitDebug failed..."); } else { log("> Invalid/x86/DLL file..."); } log("> Unpack ended");}int main(int argc, char* argv[]){ puts("unp64 v0.1\n\nSupported packers:\nMPRESS v2.19\nPESpin v1.22 (Packer only)\n"); if(argc<2) puts("usage: unp64 [file.exe]"); else unpack(argv[1]); Sleep(2500); return 0;}Example output:unp64 v0.1Supported packers:MPRESS v2.19PESpin v1.22 (Packer only)> Unpack of file "mpress.exe" started...> 64-bit PE file detected!> InitDebug OK!> Process created on 0x140000000!> Entry point 0x14000F0F3 reached!> MPRESS pattern found on 0x14000FBD7!> Near OEP!> OEP 0x140005DC8 reached!> Dumping...> Dumping done!> Fixing imports...> IAT Start: 0x14000F048, IAT Size: 0x38> Imports fixed!> Unpack endedProject files + Binaries attached.Greetings,Mr. eXoDiaunp64.rar Edited January 14, 2014 by Mr. eXoDia 11 1
mudlord Posted February 25, 2014 Posted February 25, 2014 Thank you very much!Always wanted to see how TitanEngine handles unpacking...
Liquid Posted March 22, 2014 Posted March 22, 2014 Hmm.. Does anything like this exist for 32 bit files? The file I need to unpack is a 32 bit .exe packed with Mpress v2.17..
mrexodia Posted March 26, 2014 Author Posted March 26, 2014 @Liquid: probably, unpacking MPRESS is not that a big deal... Greetings
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now