Advertisement
brightprogrammer

xvm-decompile-state-2

Sep 18th, 2021
531
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.13 KB | None | 0 0
  1. #include <stddef.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdint.h>
  6.  
  7. typedef struct{
  8.     // first 48 bytes of memory (0x00 -> 0x30)
  9.     uint64_t uint64arr[6];
  10.  
  11.     // from 48 to 60 bytes (0x30 -> 0x40)
  12.     uint32_t uint32arr[4];
  13.  
  14.     // last 4 bytes (0x40 -> 0x44)
  15.     uint8_t uint8arr[4];
  16. } StructOne;
  17.  
  18. StructOne* structOneCtor(void){
  19.     StructOne* pStructOne = (StructOne*)malloc(sizeof(StructOne));
  20.  
  21.     memset((void*)pStructOne, 0, 0x40);
  22.  
  23.     // then we setting some selected indices in this array
  24.     pStructOne->uint32arr[1] = 0x13371000;
  25.     pStructOne->uint32arr[2] = 0xcafe3ffc;
  26.     pStructOne->uint32arr[3] = 0xcafe3ffc;
  27.  
  28.     pStructOne->uint8arr[0] = 4;
  29.  
  30.     return pStructOne;
  31. }
  32.  
  33. typedef struct SectionHeader{
  34.     char* pName;                    // 0x00
  35.     uint8_t* pByteCode;             // 0x08
  36.     uint32_t size;                  // 0x10
  37.     uint32_t sectionOffset;         // 0x14
  38.     uint32_t f18;                   // 0x18
  39.     uint32_t bcd3;                  // 0x1c
  40.     uint32_t currentReadAddress;    // 0x20
  41.     uint32_t f24;                   // 0x24
  42.     struct SectionHeader* pNext;    // 0x28
  43. } SectionHeader;                    // total = 0x30
  44.  
  45. SectionHeader* sectionHeaderCtor(){
  46.     SectionHeader* pSectionHeader = (SectionHeader*)(malloc(sizeof(SectionHeader)));
  47.    
  48.     pSectionHeader->pName = 0;
  49.     pSectionHeader->pByteCode = 0;
  50.     pSectionHeader->size = 0;
  51.     pSectionHeader->sectionOffset = 0;
  52.     pSectionHeader->f18 = 0;
  53.     pSectionHeader->bcd3 = 1;
  54.     pSectionHeader->currentReadAddress = 0;
  55.     pSectionHeader->pNext = NULL;
  56.  
  57.     return pSectionHeader;
  58. }
  59.  
  60. typedef struct{
  61.     // this is actually a linked list
  62.     struct SectionHeader *pSectionHeader;
  63.     uint32_t* arrUint32;
  64. }StructThree;
  65.  
  66. typedef struct{
  67.     uint32_t* magicValue;
  68.     uint64_t* arr1;
  69.     StructThree *pStructThree;
  70.     FILE* pFile;
  71. } XVMHeader;
  72.  
  73. XVMHeader* xvmHeaderCtor(){
  74.     XVMHeader* pXVMHeader = (XVMHeader*)(malloc(sizeof(XVMHeader)));
  75.    
  76.     pXVMHeader->magicValue = (uint32_t*)(malloc(sizeof(uint32_t) * 5));
  77.     pXVMHeader->magicValue[0] = 0x036d7678;
  78.     pXVMHeader->magicValue[0] = 0x13371000;
  79.     pXVMHeader->magicValue[0] = 0;
  80.     pXVMHeader->magicValue[0] = 0;
  81.     pXVMHeader->magicValue[0] = 0;
  82.  
  83.     pXVMHeader->arr1 = (uint64_t*)(malloc(sizeof(uint64_t) * 2));
  84.     if(pXVMHeader->arr1 != NULL){
  85.         pXVMHeader->arr1[0] = 0;
  86.         pXVMHeader->arr1[1] = 0;
  87.     }
  88.  
  89.     pXVMHeader->pStructThree = (StructThree*)(malloc(sizeof(StructThree)));
  90.     pXVMHeader->pStructThree->pSectionHeader = NULL;
  91.     pXVMHeader->pStructThree->arrUint32 = NULL;
  92.  
  93.     pXVMHeader->pFile = NULL;
  94.  
  95.     return pXVMHeader;
  96. }
  97.  
  98. int32_t closeFileIfOpened(XVMHeader* pXVMHeader){
  99.     if(pXVMHeader == NULL) return -1;
  100.     if(pXVMHeader->pFile == NULL) return 0;
  101.     fclose(pXVMHeader->pFile);
  102.     pXVMHeader->pFile = NULL;
  103.     return 0;
  104. }
  105.  
  106. // this is fcn_46f4
  107. int32_t checkIfFileIsOpen(XVMHeader* pXVMHeader, const char* filename){
  108.     // var_8h is pStructThree
  109.     // var_10h is pSectionHeaderName
  110.  
  111.     if(pXVMHeader == NULL) return -1;
  112.  
  113.     // check if file is already open
  114.     if(pXVMHeader->pFile != NULL){
  115.         closeFileIfOpened(pXVMHeader);
  116.     }
  117.  
  118.     // open file
  119.     pXVMHeader->pFile = fopen(filename, "r");
  120.  
  121.     // check if file was opened or not
  122.     if(pXVMHeader->pFile == NULL){
  123.         return -1;
  124.     }
  125.  
  126.     return 0;
  127. }
  128.  
  129. // renamed it
  130. int32_t checkValidXVMByteCode(XVMHeader* pXVMHeader){
  131.     if(pXVMHeader->magicValue == NULL){
  132.         return -1;
  133.     }
  134.  
  135.     // seek to beginning of file
  136.     fseek(pXVMHeader->pFile, 0, 0);
  137.  
  138.     // read magic values from file
  139.     fread(pXVMHeader->magicValue+0, 1, 4, pXVMHeader->pFile);
  140.     fread(pXVMHeader->magicValue+4, 1, 4, pXVMHeader->pFile);
  141.     fread(pXVMHeader->magicValue+8, 1, 4, pXVMHeader->pFile);
  142.     fread(pXVMHeader->magicValue+12, 1, 4, pXVMHeader->pFile);
  143.     fread(pXVMHeader->magicValue+16, 1, 4, pXVMHeader->pFile);
  144.  
  145.     // check if valid xvm
  146.     // if you convert "03 6d 76 78" into ascii, you will get "?mvx"
  147.     if(pXVMHeader->magicValue[0] != 0x36d7678){
  148.         fwrite("[\x1b[31m-\x1b[0m] Corrupted Bytecode\n", 1, 0x20, stderr);
  149.         exit(-1);
  150.     }
  151.  
  152.     return 0;
  153. }
  154.  
  155. // renamed from fcn_4ff1
  156. void copySectionHeader(SectionHeader* pSectionHeader, char* pSectionHeaderName, uint32_t size, uint32_t sectionOffset, uint32_t bcd3){
  157.     if((size & 0xfff) != 0){
  158.         size = ((size >> 0xc) + 1) << 0xc;
  159.     }
  160.  
  161.     if(size <= 0x10000) size = 0x10000;
  162.  
  163.     if(pSectionHeaderName != NULL){
  164.         if(pSectionHeader->pName != NULL){
  165.             // pName is actually a char*, see below in "else" block
  166.             pSectionHeader->pName = (uint64_t)realloc((void*)pSectionHeader->pName, 0x20);
  167.             strncpy((char*)pSectionHeader->pName, pSectionHeaderName, 0x20);
  168.         }else{
  169.             // wow, so pSectionHeader is actually the section header itself
  170.             // the first field is section name
  171.             // and the last field points to next section header
  172.             // we will change this on our next refactor
  173.             pSectionHeader->pName = (uint64_t)(strdup(pSectionHeaderName));
  174.         }
  175.     }
  176.  
  177.     pSectionHeader->size = size;
  178.     pSectionHeader->sectionOffset = sectionOffset;
  179.     pSectionHeader->bcd3 = bcd3;
  180.     pSectionHeader->currentReadAddress = 0;
  181.     pSectionHeader->f18 = 0;
  182.     // I think size is the size of this section header
  183.     pSectionHeader->pByteCode = (uint64_t)realloc((void*)pSectionHeader->pByteCode, size);
  184.     pSectionHeader->pNext = NULL;
  185. }
  186.  
  187. // reamed from fcn_5315
  188. SectionHeader* makeSectionHeader(StructThree* pStructThree, char* pSectionHeaderName, uint32_t size, uint32_t sectionOffset, uint32_t bcd3){
  189.     if((size & 0xfff) != 0){
  190.         size = ((size >> 0xc) + 1) << 0xc;
  191.     }
  192.  
  193.     if(size >= 0x10000){
  194.         size = 0x10000;
  195.     }
  196.  
  197.     if(size == 0){
  198.         size = 0x1000;
  199.     }
  200.  
  201.     if(((uint64_t)size + (uint64_t)sectionOffset) > 0x100000000){
  202.         return 0;
  203.     }else{
  204.         if(pStructThree == NULL){
  205.             return 0;
  206.         }else{
  207.             if(pStructThree->pSectionHeader == NULL){
  208.                 pStructThree->pSectionHeader = sectionHeaderCtor();
  209.  
  210.                 pStructThree->arrUint32[0] = pStructThree->arrUint32[0] + 1;
  211.                 copySectionHeader(pStructThree->pSectionHeader, pSectionHeaderName, size, sectionOffset, bcd3);
  212.  
  213.                 return pStructThree->pSectionHeader;
  214.             }else{
  215.                 SectionHeader* var_18h = pStructThree->pSectionHeader;
  216.                 SectionHeader* var_10h = 0;
  217.  
  218.                 if(size + sectionOffset < var_18h->sectionOffset){
  219.                     SectionHeader* var_8h = sectionHeaderCtor();
  220.  
  221.                     pStructThree->arrUint32[0] = pStructThree->arrUint32[0] + 1;
  222.                     copySectionHeader(var_8h, pSectionHeaderName, size, sectionOffset, bcd3);
  223.                    
  224.                     var_8h->pNext = pStructThree->pSectionHeader;
  225.                     pStructThree->pSectionHeader = var_8h;
  226.  
  227.                     return var_8h;
  228.                 }else{
  229.                     while(var_18h != NULL){
  230.                         if((sectionOffset >= var_18h->sectionOffset) && (sectionOffset < var_18h->sectionOffset + var_18h->size)){
  231.                             if((size != var_18h->size) && (var_18h->pNext != 0)){
  232.                                 if((size + var_18h->sectionOffset) < var_18h->pNext->sectionOffset){
  233.                                     var_10h->pByteCode = (uint64_t)realloc((void*)(var_18h->pByteCode), size);
  234.                                 }else{
  235.                                     if(bcd3 != var_18h->bcd3){
  236.                                         var_10h->bcd3 = bcd3;
  237.                                         return var_18h;
  238.                                     }
  239.                                 }
  240.                             }else{
  241.                                 return var_18h;
  242.                             }
  243.                         }else{
  244.                             if((var_10h == 0) && (sectionOffset <= var_18h->sectionOffset + var_18h->size)){
  245.                                 var_10h = var_18h;
  246.                                 var_18h = var_18h->pNext;
  247.                             }
  248.  
  249.                             if(size + sectionOffset < var_18h->sectionOffset){
  250.                                 break;
  251.                             }
  252.                         }
  253.                     }
  254.  
  255.                     var_10h->pNext = sectionHeaderCtor();
  256.                     pStructThree->arrUint32[0] = pStructThree->arrUint32[0] + 1;
  257.                     copySectionHeader(var_10h->pNext, pSectionHeaderName, size, sectionOffset, bcd3);
  258.                     var_10h->pNext->pNext = var_18h;
  259.                     return var_10h->pNext;
  260.                 }
  261.             }
  262.         }
  263.     }
  264. }
  265.  
  266. // renamed from fcn_64bc
  267. void printError(uint32_t errorCode, SectionHeader *pSectionHeader, uint32_t byteAddress){
  268.     // errorCode = [rbp - 0x4]
  269.     // arg2 = [rbp - 0x10]
  270.     // byteAddress = [rbp - 0x8]
  271.  
  272.     // write to stderr
  273.     // this means that this function will be called when
  274.     // the program encounters an error
  275.     fwrite("[\x1b[31m-\x1b[0m] Segmentation Fault : ", 1, 0x22, stderr);
  276.  
  277.     if(pSectionHeader != NULL){
  278.         // esi = pSectionHeader->sectionOffset
  279.         // ecx = pSectionHeader->bcd3
  280.         // rdx = pSectionHeader->pName
  281.         // r8d = esi (lower 32-bit part of r8)
  282.  
  283.         fprintf(stderr, "%s-%d-0x%x : ", (const char*)pSectionHeader->pNext, pSectionHeader->bcd3, pSectionHeader->sectionOffset);
  284.     }
  285.  
  286.     if(errorCode != 3){
  287.         // here it must not be "<=" because we already checked
  288.         // that it is not equal to 3
  289.         if(errorCode < 3){
  290.             if(errorCode != 2){
  291.                 // same here, we already checked it is not 2
  292.                 if(errorCode < 2){
  293.                     if(errorCode != 0){
  294.                         if(errorCode != 1){
  295.                             // 65e0
  296.                             fwrite("XVM BRUH MOMENT\n", 1, 0x10, stderr);
  297.                         }else{ // errorCode == 1
  298.                             // 65a0
  299.                             // so byteAddress is an address in our xvm bytecode!
  300.                             // one also, not that useful information is revealed here
  301.                             // it's that our bytecode is a 32 bit program
  302.                             // not useful because you might've already guessed
  303.                             // it's bytecode!
  304.                             fprintf(stderr, "Invalid Write @ 0x%x\n", byteAddress);
  305.                         }
  306.                     }else{ // errorCode == 0
  307.                         // 6580
  308.                         fprintf(stderr, "Invalid Read @ 0x%x\n", byteAddress);
  309.                     }
  310.                 }else{ // errorCode > 2
  311.                     // 65e0
  312.                     fwrite("XVM BRUH MOMENT\n", 1, 0x10, stderr);
  313.                 }
  314.             }else{ // errorCode == 2
  315.                 // 65c0
  316.                 fprintf(stderr, "Invalid Code @ 0x%x\n", byteAddress);
  317.             }
  318.         }else{ // errorCode > 3
  319.             // 65e0
  320.             fwrite("XVM BRUH MOMENT\n", 1, 0x10, stderr);
  321.         }
  322.     }else{ // errorCode == 3
  323.         // 655d
  324.         // looks like this function might be called from many functions
  325.         // so just in case let's store the function where it is called
  326.         // with the arguments and which block will get executed
  327.         //
  328.         // 1 > CALLED FROM : updateByteCode
  329.         //         printError(3, pSectionHeader, pSectionHeader->currentReadAddress + pSectionHeader->sectionOffset);
  330.         //
  331.         fprintf(stderr, "Invalid Address @ 0x%x\n", byteAddress);
  332.     }
  333.  
  334.     // errorCode == 3    [means invalid address]
  335.     // errorCode > 3     prints "bruh moment"
  336.     // errorCode < 3     checks further
  337.     // errorCode == 2    [means invalid code]
  338.     // errorCode > 2     prints "bruh moment"
  339.     // errorCode < 2     checks further
  340.     // errorCode == 0    [means invalid read]
  341.     // errorCode == 1    [means invalid write]
  342.     // errorCode != 1    prints bruh moment
  343.  
  344.     // exit
  345.     // this means that errorCode is our error code
  346.     exit(errorCode);
  347.    
  348.     // below is the exit sequence I guess
  349.     // .
  350.     // .
  351.     // .
  352. }
  353.  
  354. // renamed from updateByteCode
  355. uint32_t updateByteCode(SectionHeader* pSectionHeader, uint8_t arg2){
  356.     if(pSectionHeader->currentReadAddress >= pSectionHeader->size){
  357.         printError(3, pSectionHeader, pSectionHeader->currentReadAddress + pSectionHeader->sectionOffset);
  358.     }
  359.  
  360.     pSectionHeader->pByteCode[pSectionHeader->currentReadAddress] = arg2;
  361.     pSectionHeader->currentReadAddress = pSectionHeader->currentReadAddress + 1;
  362.     return 1;
  363. }
  364.  
  365. // renamed fcn_422f to readByteCodeData;
  366. int32_t readByteCodeData(XVMHeader* pXVMHeader, const char* filename){
  367.     if(pXVMHeader == NULL){
  368.         return -1;        
  369.     }
  370.  
  371.     // fcn_46f4
  372.     if(checkIfFileIsOpen(pXVMHeader, filename) == -1){
  373.         fprintf(stderr, "[\x1b[31m-\x1b[0m] Cannot open \"%s\"\n", filename);
  374.         exit(-1);
  375.     }
  376.  
  377.     // fcn_3fff
  378.     checkValidXVMByteCode(pXVMHeader);
  379.  
  380.     // maybe magicValue[2] contains the total number of elements in this char** array
  381.     // this var_18h maybe pointer to the bytecode data!
  382.     uint32_t* var_18h = (uint32_t*)malloc(pXVMHeader->magicValue[2] << 3);
  383.     uint32_t i = 0;
  384.  
  385.     while(i < pXVMHeader->magicValue[2]){
  386.         fread((void*)(var_18h + i*8), 4, 1, pXVMHeader->pFile);
  387.         i++;
  388.     }
  389.  
  390.     // var_10h is pointer to a uint64_t array as seen by it's use below
  391.     SectionHeader* var_10h = NULL;
  392.     char* pSectionHeaderName = NULL;
  393.     size_t length = 0;
  394.    
  395.     uint32_t sectionHeaderData1 = 0;
  396.     uint32_t sectionHeaderData2 = 0;
  397.     uint32_t sectionHeaderData3 = 0;
  398.     uint32_t sectionHeaderData4 = 0;
  399.     uint32_t var_40h = 0;
  400.     uint32_t j = 0;
  401.  
  402.     while(j < pXVMHeader->magicValue[2]){
  403.         fread((void*)(&var_40h), 4, 1, pXVMHeader->pFile);
  404.        
  405.         // if you look at the hexdump of "pyaz.xvm", you will find "beef dead" in it
  406.         // in the beginning
  407.         if(var_40h != 0xdeadbeef){
  408.             // so this is checking for the validity of section header
  409.             // that means this function will read section header
  410.             // awesome
  411.             fwrite("[\x1b[31m-\x1b[0m] Corrupted Section Headers\n", 1, 0x27, stderr);
  412.             exit(1);
  413.         }
  414.  
  415.         // reads section header name
  416.         if(getdelim(&pSectionHeaderName, &length, 0, pXVMHeader->pFile) < 0){
  417.             fwrite("[\x1b[31m-\x1b[0m] Corrupted Section Headers\n", 1, 0x27, stderr);
  418.             exit(1);
  419.         }
  420.  
  421.         fread((void*)(&sectionHeaderData1), 4, 1, pXVMHeader->pFile);
  422.         fread((void*)(&sectionHeaderData2), 4, 1, pXVMHeader->pFile);
  423.         fread((void*)(&sectionHeaderData3), 4, 1, pXVMHeader->pFile);
  424.         fread((void*)(&sectionHeaderData4), 4, 1, pXVMHeader->pFile);
  425.  
  426.         if(sectionHeaderData1 > 0x10000){
  427.             sectionHeaderData1 = 0x10000;
  428.         }
  429.  
  430.         if(sectionHeaderData4 > 0x10000){
  431.             sectionHeaderData4 = 0x10000;
  432.         }
  433.  
  434.         // this means value of sectionHeaderData4 lies between
  435.         // sectionHeaderData1 and 0x10000
  436.         if(sectionHeaderData4 <= sectionHeaderData1){
  437.             sectionHeaderData4 = sectionHeaderData1;
  438.         }
  439.  
  440.         // guess this reads infromation about that section header by using it's name
  441.         var_10h = makeSectionHeader(pXVMHeader->pStructThree, pSectionHeaderName, sectionHeaderData1, sectionHeaderData2, sectionHeaderData3);
  442.         if(var_10h == NULL){
  443.             fprintf(stderr, "[\x1b[31m-\x1b[0m] Cannot Load Section (\"%s\") : FATAL @ 0x%x\n", pSectionHeaderName, sectionHeaderData2);
  444.             exit(-1);
  445.         }
  446.  
  447.         uint32_t var_34h = 0;
  448.         uint8_t c = 0;
  449.  
  450.         // 0xff is same as -1 when casted from uint8 to int8
  451.         while(c != 0xff){
  452.             // c is treated as character value here
  453.             updateByteCode(var_10h, c);
  454.             var_34h++;
  455.  
  456.             if(var_34h < sectionHeaderData4){
  457.                 c = fgetc(pXVMHeader->pFile);
  458.             }
  459.         }
  460.  
  461.         j++;
  462.     }
  463.  
  464.     // free must be called after calling getdelim
  465.     free((void*)pSectionHeaderName);
  466.     pSectionHeaderName = NULL;
  467.  
  468.     // guess this is reading data section
  469.     // this might be our clue to find the password
  470.     var_10h = fcn_55db(pXVMHeader->pStructThree, ".data");
  471.     if(var_10h == NULL){
  472.         fwrite("[\x1b[31m-\x1b[0m] Corrupted section headers: \".data\" Not Found\n", 1, 0x3a, stderr);
  473.         exit(-1);
  474.     }
  475.  
  476.     uint32_t k = 0;
  477.     while(k < pXVMHeader->magicValue[2]){
  478.         // type of var_18h is ambiguous at this point because
  479.         // it's sometimes used as a pointer to uint64_t
  480.         // and sometimes uint32_t
  481.         // it will be clear once we start decoding other functions!
  482.         // so let it be as it is for now
  483.         if(var_18h[2*k] > var_10h[4]){
  484.             fprintf(stderr, "[\x1b[31m-\x1b[0m] Corrupted section headers: symbol offset (0x%x) is out of bounds for \".data\" section\n", var_18h[k]);
  485.             exit(-1);
  486.         }
  487.  
  488.         fcn_3b29(pXVMHeader->arr1, var_18h[k] + var_10h[1], var_18h[2*k+1]);
  489.  
  490.         k++;
  491.     }
  492.  
  493.     free((void*)var_18h);
  494.     var_18h = NULL;
  495.  
  496.     // stack check
  497.  
  498.     return 0;
  499. }
  500.  
  501. int main(int argc , char** argv){
  502.     int32_t var14_h = argc;
  503.     int64_t var20_h = (uint64_t)argv;
  504.    
  505.     if(var14_h != 2){
  506.         fwrite("xvm <bytecode>\n" , 1, 0x16 , stderr);
  507.         exit(-1);
  508.     }
  509.  
  510.     setbuf(stdin, NULL);
  511.     setbuf(stdout, NULL);
  512.  
  513.     // constructors
  514.     StructOne* pStructOne = structOneCtor();
  515.     XVMHeader* pXVMHeader = xvmHeaderCtor();
  516.  
  517.     readByteCodeData(pXVMHeader, argv[1]);
  518.  
  519.     makeSectionHeader(pXVMHeader->pStructThree, "stack", 0x3000, 0xcafe3000, 3);
  520.  
  521.     pStructOne->uint64arr[1] = pXVMHeader->magicValue[1];
  522.     pStructOne->uint64arr[3] = 0xcafe3ffc;
  523.     fcn_1997(pStructOne->uint64arr, pXVMHeader->magicValue);
  524.  
  525.  
  526.     // I suspect these may be destructors!
  527.     fcn_19de(pStructOne);
  528.     pStructOne = NULL;
  529.     fcn_47b3(pXVMHeader);
  530. }
  531.  
  532.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement