Jump to content
View in the app

A better way to browse. Learn more.

Tuts 4 You

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[SDK Example] x64 MPRESS/PESpin Unpacker

Featured Replies

Posted

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 ended
Project files + Binaries attached.

Greetings,

Mr. eXoDia

unp64.rar

Edited by Mr. eXoDia

  • 1 month later...

Thank you very much!


Always wanted to see how TitanEngine handles unpacking...


  • 4 weeks later...

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..


  • Author

@Liquid: probably, unpacking MPRESS is not that a big deal...

Greetings

Create an account or sign in to comment

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.