Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- typedef struct{
- // first 48 bytes of memory (0x00 -> 0x30)
- uint64_t uint64arr[6];
- // from 48 to 60 bytes (0x30 -> 0x40)
- uint32_t uint32arr[4];
- // last 4 bytes (0x40 -> 0x44)
- uint8_t uint8arr[4];
- } StructOne;
- StructOne* structOneCtor(void){
- StructOne* pStructOne = (StructOne*)malloc(sizeof(StructOne));
- memset((void*)pStructOne, 0, 0x40);
- // then we setting some selected indices in this array
- pStructOne->uint32arr[1] = 0x13371000;
- pStructOne->uint32arr[2] = 0xcafe3ffc;
- pStructOne->uint32arr[3] = 0xcafe3ffc;
- pStructOne->uint8arr[0] = 4;
- return pStructOne;
- }
- typedef struct SectionHeader{
- char* pName; // 0x00
- uint8_t* pByteCode; // 0x08
- uint32_t size; // 0x10
- uint32_t bcd2; // 0x14
- uint32_t f18; // 0x18
- uint32_t bcd3; // 0x1c
- uint32_t currentReadAddress; // 0x20
- uint32_t f24; // 0x24
- struct SectionHeader* pNext; // 0x28
- } SectionHeader; // total = 0x30
- SectionHeader* sectionHeaderCtor(){
- SectionHeader* pSectionHeader = (SectionHeader*)(malloc(sizeof(SectionHeader)));
- pSectionHeader->pName = 0;
- pSectionHeader->pByteCode = 0;
- pSectionHeader->size = 0;
- pSectionHeader->bcd2 = 0;
- pSectionHeader->f18 = 0;
- pSectionHeader->bcd3 = 1;
- pSectionHeader->currentReadAddress = 0;
- pSectionHeader->pNext = NULL;
- return pSectionHeader;
- }
- typedef struct{
- // this is actually a linked list
- struct SectionHeader *pSectionHeader;
- uint32_t* arrUint32;
- }StructThree;
- typedef struct{
- uint32_t* magicValue;
- uint64_t* arr1;
- StructThree *pStructThree;
- FILE* pFile;
- } XVMHeader;
- XVMHeader* xvmHeaderCtor(){
- XVMHeader* pXVMHeader = (XVMHeader*)(malloc(sizeof(XVMHeader)));
- pXVMHeader->magicValue = (uint32_t*)(malloc(sizeof(uint32_t) * 5));
- pXVMHeader->magicValue[0] = 0x036d7678;
- pXVMHeader->magicValue[0] = 0x13371000;
- pXVMHeader->magicValue[0] = 0;
- pXVMHeader->magicValue[0] = 0;
- pXVMHeader->magicValue[0] = 0;
- pXVMHeader->arr1 = (uint64_t*)(malloc(sizeof(uint64_t) * 2));
- if(pXVMHeader->arr1 != NULL){
- pXVMHeader->arr1[0] = 0;
- pXVMHeader->arr1[1] = 0;
- }
- pXVMHeader->pStructThree = (StructThree*)(malloc(sizeof(StructThree)));
- pXVMHeader->pStructThree->pSectionHeader = NULL;
- pXVMHeader->pStructThree->arrUint32 = NULL;
- pXVMHeader->pFile = NULL;
- return pXVMHeader;
- }
- int32_t closeFileIfOpened(XVMHeader* pXVMHeader){
- if(pXVMHeader == NULL) return -1;
- if(pXVMHeader->pFile == NULL) return 0;
- fclose(pXVMHeader->pFile);
- pXVMHeader->pFile = NULL;
- return 0;
- }
- // this is fcn_46f4
- int32_t checkIfFileIsOpen(XVMHeader* pXVMHeader, const char* filename){
- // var_8h is pStructThree
- // var_10h is pSectionHeaderName
- if(pXVMHeader == NULL) return -1;
- // check if file is already open
- if(pXVMHeader->pFile != NULL){
- closeFileIfOpened(pXVMHeader);
- }
- // open file
- pXVMHeader->pFile = fopen(filename, "r");
- // check if file was opened or not
- if(pXVMHeader->pFile == NULL){
- return -1;
- }
- return 0;
- }
- // renamed it
- int32_t checkValidXVMByteCode(XVMHeader* pXVMHeader){
- if(pXVMHeader->magicValue == NULL){
- return -1;
- }
- // seek to beginning of file
- fseek(pXVMHeader->pFile, 0, 0);
- // read magic values from file
- fread(pXVMHeader->magicValue+0, 1, 4, pXVMHeader->pFile);
- fread(pXVMHeader->magicValue+4, 1, 4, pXVMHeader->pFile);
- fread(pXVMHeader->magicValue+8, 1, 4, pXVMHeader->pFile);
- fread(pXVMHeader->magicValue+12, 1, 4, pXVMHeader->pFile);
- fread(pXVMHeader->magicValue+16, 1, 4, pXVMHeader->pFile);
- // check if valid xvm
- // if you convert "03 6d 76 78" into ascii, you will get "?mvx"
- if(pXVMHeader->magicValue[0] != 0x36d7678){
- fwrite("[\x1b[31m-\x1b[0m] Corrupted Bytecode\n", 1, 0x20, stderr);
- exit(-1);
- }
- return 0;
- }
- // renamed from fcn_4ff1
- void copySectionHeader(SectionHeader* pSectionHeader, char* pSectionHeaderName, uint32_t size, uint32_t bcd2, uint32_t bcd3){
- if((size & 0xfff) != 0){
- size = ((size >> 0xc) + 1) << 0xc;
- }
- if(size <= 0x10000) size = 0x10000;
- if(pSectionHeaderName != NULL){
- if(pSectionHeader->pName != NULL){
- // pName is actually a char*, see below in "else" block
- pSectionHeader->pName = (uint64_t)realloc((void*)pSectionHeader->pName, 0x20);
- strncpy((char*)pSectionHeader->pName, pSectionHeaderName, 0x20);
- }else{
- // wow, so pSectionHeader is actually the section header itself
- // the first field is section name
- // and the last field points to next section header
- // we will change this on our next refactor
- pSectionHeader->pName = (uint64_t)(strdup(pSectionHeaderName));
- }
- }
- pSectionHeader->size = size;
- pSectionHeader->bcd2 = bcd2;
- pSectionHeader->bcd3 = bcd3;
- pSectionHeader->currentReadAddress = 0;
- pSectionHeader->f18 = 0;
- // I think size is the size of this section header
- pSectionHeader->pByteCode = (uint64_t)realloc((void*)pSectionHeader->pByteCode, size);
- pSectionHeader->pNext = NULL;
- }
- // reamed from fcn_5315
- SectionHeader* makeSectionHeader(StructThree* pStructThree, char* pSectionHeaderName, uint32_t size, uint32_t bcd2, uint32_t bcd3){
- if((size & 0xfff) != 0){
- size = ((size >> 0xc) + 1) << 0xc;
- }
- if(size >= 0x10000){
- size = 0x10000;
- }
- if(size == 0){
- size = 0x1000;
- }
- if(((uint64_t)size + (uint64_t)bcd2) > 0x100000000){
- return 0;
- }else{
- if(pStructThree == NULL){
- return 0;
- }else{
- if(pStructThree->pSectionHeader == NULL){
- pStructThree->pSectionHeader = sectionHeaderCtor();
- pStructThree->arrUint32[0] = pStructThree->arrUint32[0] + 1;
- copySectionHeader(pStructThree->pSectionHeader, pSectionHeaderName, size, bcd2, bcd3);
- return pStructThree->pSectionHeader;
- }else{
- SectionHeader* var_18h = pStructThree->pSectionHeader;
- SectionHeader* var_10h = 0;
- if(size + bcd2 < var_18h->bcd2){
- SectionHeader* var_8h = sectionHeaderCtor();
- pStructThree->arrUint32[0] = pStructThree->arrUint32[0] + 1;
- copySectionHeader(var_8h, pSectionHeaderName, size, bcd2, bcd3);
- var_8h->pNext = pStructThree->pSectionHeader;
- pStructThree->pSectionHeader = var_8h;
- return var_8h;
- }else{
- while(var_18h != NULL){
- if((bcd2 >= var_18h->bcd2) && (bcd2 < var_18h->bcd2 + var_18h->size)){
- if((size != var_18h->size) && (var_18h->pNext != 0)){
- if((size + var_18h->bcd2) < var_18h->pNext->bcd2){
- var_10h->pByteCode = (uint64_t)realloc((void*)(var_18h->pByteCode), size);
- }else{
- if(bcd3 != var_18h->bcd3){
- var_10h->bcd3 = bcd3;
- return var_18h;
- }
- }
- }else{
- return var_18h;
- }
- }else{
- if((var_10h == 0) && (bcd2 <= var_18h->bcd2 + var_18h->size)){
- var_10h = var_18h;
- var_18h = var_18h->pNext;
- }
- if(size + bcd2 < var_18h->bcd2){
- break;
- }
- }
- }
- var_10h->pNext = sectionHeaderCtor();
- pStructThree->arrUint32[0] = pStructThree->arrUint32[0] + 1;
- copySectionHeader(var_10h->pNext, pSectionHeaderName, size, bcd2, bcd3);
- var_10h->pNext->pNext = var_18h;
- return var_10h->pNext;
- }
- }
- }
- }
- }
- void fcn_64bc(uint32_t arg1, SectionHeader *pSectionHeader, uint32_t arg3){
- // arg1 = [rbp - 0x4]
- // arg2 = [rbp - 0x10]
- // arg3 = [rbp - 0x8]
- // write to stderr
- // this means that this function will be called when
- // the program encounters an error
- fwrite("[\x1b[31m-\x1b[0m] Segmentation Fault : ", 1, 0x22, stderr);
- if(pSectionHeader != NULL){
- // esi = pSectionHeader->bcd2
- // ecx = pSectionHeader->bcd3
- // rdx = pSectionHeader->pName
- // r8d = esi (lower 32-bit part of r8)
- fprintf(stderr, "%s-%d-0x%x : ", (const char*)pSectionHeader->pNext, pSectionHeader->bcd3, pSectionHeader->bcd2);
- }
- if(arg1 != 3){
- // here it must not be "<=" because we already checked
- // that it is not equal to 3
- if(arg1 < 3){
- if(arg1 != 2){
- // same here, we already checked it is not 2
- if(arg1 < 2){
- if(arg1 != 0){
- if(arg1 != 1){
- // 65e0
- fwrite("XVM BRUH MOMENT\n", 1, 0x10, stderr);
- }else{ // arg1 == 1
- // 65a0
- // so arg3 is an address in our xvm bytecode!
- // one also, not that useful information is revealed here
- // it's that our bytecode is a 32 bit program
- // not useful because you might've already guessed
- // it's bytecode!
- fprintf(stderr, "Invalid Write @ 0x%x\n", arg3);
- }
- }else{ // arg1 == 0
- // 6580
- fprintf(stderr, "Invalid Read @ 0x%x\n", arg3);
- }
- }else{ // arg1 > 2
- // 65e0
- fwrite("XVM BRUH MOMENT\n", 1, 0x10, stderr);
- }
- }else{ // arg1 == 2
- // 65c0
- fprintf(stderr, "Invalid Code @ 0x%x\n", arg3);
- }
- }else{ // arg1 > 3
- // 65e0
- fwrite("XVM BRUH MOMENT\n", 1, 0x10, stderr);
- }
- }else{ // arg1 == 3
- // 655d
- // looks like this function might be called from many functions
- // so just in case let's store the function where it is called
- // with the arguments and which block will get executed
- //
- // 1 > CALLED FROM : fcn_4c61
- // fcn_64bc(3, pSectionHeader, pSectionHeader->currentReadAddress + pSectionHeader->bcd2);
- //
- fprintf(stderr, "Invalid Address @ 0x%x\n", arg3);
- }
- // arg1 == 3 [means invalid address]
- // arg1 > 3 prints "bruh moment"
- // arg1 < 3 checks further
- // arg1 == 2 [means invalid code]
- // arg1 > 2 prints "bruh moment"
- // arg1 < 2 checks further
- // arg1 == 0 [means invalid read]
- // arg1 == 1 [means invalid write]
- // arg1 != 1 prints bruh moment
- // exit
- // this means that arg1 is our error code
- exit(arg1);
- // below is the exit sequence I guess
- // .
- // .
- // .
- }
- // renamed from fcn_4c61
- uint32_t updateByteCode(SectionHeader* pSectionHeader, uint8_t arg2){
- if(pSectionHeader->currentReadAddress >= pSectionHeader->size){
- fcn_64bc(3, pSectionHeader, pSectionHeader->currentReadAddress + pSectionHeader->bcd2);
- }
- pSectionHeader->pByteCode[pSectionHeader->currentReadAddress] = arg2;
- pSectionHeader->currentReadAddress = pSectionHeader->currentReadAddress + 1;
- return 1;
- }
- // renamed fcn_422f to readByteCodeData;
- int32_t readByteCodeData(XVMHeader* pXVMHeader, const char* filename){
- if(pXVMHeader == NULL){
- return -1;
- }
- // fcn_46f4
- if(checkIfFileIsOpen(pXVMHeader, filename) == -1){
- fprintf(stderr, "[\x1b[31m-\x1b[0m] Cannot open \"%s\"\n", filename);
- exit(-1);
- }
- // fcn_3fff
- checkValidXVMByteCode(pXVMHeader);
- // maybe magicValue[2] contains the total number of elements in this char** array
- // this var_18h maybe pointer to the bytecode data!
- uint32_t* var_18h = (uint32_t*)malloc(pXVMHeader->magicValue[2] << 3);
- uint32_t i = 0;
- while(i < pXVMHeader->magicValue[2]){
- fread((void*)(var_18h + i*8), 4, 1, pXVMHeader->pFile);
- i++;
- }
- // var_10h is pointer to a uint64_t array as seen by it's use below
- SectionHeader* var_10h = NULL;
- char* pSectionHeaderName = NULL;
- size_t length = 0;
- uint32_t sectionHeaderData1 = 0;
- uint32_t sectionHeaderData2 = 0;
- uint32_t sectionHeaderData3 = 0;
- uint32_t sectionHeaderData4 = 0;
- uint32_t var_40h = 0;
- uint32_t j = 0;
- while(j < pXVMHeader->magicValue[2]){
- fread((void*)(&var_40h), 4, 1, pXVMHeader->pFile);
- // if you look at the hexdump of "pyaz.xvm", you will find "beef dead" in it
- // in the beginning
- if(var_40h != 0xdeadbeef){
- // so this is checking for the validity of section header
- // that means this function will read section header
- // awesome
- fwrite("[\x1b[31m-\x1b[0m] Corrupted Section Headers\n", 1, 0x27, stderr);
- exit(1);
- }
- // reads section header name
- if(getdelim(&pSectionHeaderName, &length, 0, pXVMHeader->pFile) < 0){
- fwrite("[\x1b[31m-\x1b[0m] Corrupted Section Headers\n", 1, 0x27, stderr);
- exit(1);
- }
- fread((void*)(§ionHeaderData1), 4, 1, pXVMHeader->pFile);
- fread((void*)(§ionHeaderData2), 4, 1, pXVMHeader->pFile);
- fread((void*)(§ionHeaderData3), 4, 1, pXVMHeader->pFile);
- fread((void*)(§ionHeaderData4), 4, 1, pXVMHeader->pFile);
- if(sectionHeaderData1 > 0x10000){
- sectionHeaderData1 = 0x10000;
- }
- if(sectionHeaderData4 > 0x10000){
- sectionHeaderData4 = 0x10000;
- }
- // this means value of sectionHeaderData4 lies between
- // sectionHeaderData1 and 0x10000
- if(sectionHeaderData4 <= sectionHeaderData1){
- sectionHeaderData4 = sectionHeaderData1;
- }
- // guess this reads infromation about that section header by using it's name
- var_10h = makeSectionHeader(pXVMHeader->pStructThree, pSectionHeaderName, sectionHeaderData1, sectionHeaderData2, sectionHeaderData3);
- if(var_10h == NULL){
- fprintf(stderr, "[\x1b[31m-\x1b[0m] Cannot Load Section (\"%s\") : FATAL @ 0x%x\n", pSectionHeaderName, sectionHeaderData2);
- exit(-1);
- }
- uint32_t var_34h = 0;
- uint8_t c = 0;
- // 0xff is same as -1 when casted from uint8 to int8
- while(c != 0xff){
- // c is treated as character value here
- fcn_4c61(var_10h, c);
- var_34h++;
- if(var_34h < sectionHeaderData4){
- c = fgetc(pXVMHeader->pFile);
- }
- }
- j++;
- }
- // free must be called after calling getdelim
- free((void*)pSectionHeaderName);
- pSectionHeaderName = NULL;
- // guess this is reading data section
- // this might be our clue to find the password
- var_10h = fcn_55db(pXVMHeader->pStructThree, ".data");
- if(var_10h == NULL){
- fwrite("[\x1b[31m-\x1b[0m] Corrupted section headers: \".data\" Not Found\n", 1, 0x3a, stderr);
- exit(-1);
- }
- uint32_t k = 0;
- while(k < pXVMHeader->magicValue[2]){
- // type of var_18h is ambiguous at this point because
- // it's sometimes used as a pointer to uint64_t
- // and sometimes uint32_t
- // it will be clear once we start decoding other functions!
- // so let it be as it is for now
- if(var_18h[2*k] > var_10h[4]){
- fprintf(stderr, "[\x1b[31m-\x1b[0m] Corrupted section headers: symbol offset (0x%x) is out of bounds for \".data\" section\n", var_18h[k]);
- exit(-1);
- }
- fcn_3b29(pXVMHeader->arr1, var_18h[k] + var_10h[1], var_18h[2*k+1]);
- k++;
- }
- free((void*)var_18h);
- var_18h = NULL;
- // stack check
- return 0;
- }
- int main(int argc , char** argv){
- int32_t var14_h = argc;
- int64_t var20_h = (uint64_t)argv;
- if(var14_h != 2){
- fwrite("xvm <bytecode>\n" , 1, 0x16 , stderr);
- exit(-1);
- }
- setbuf(stdin, NULL);
- setbuf(stdout, NULL);
- // constructors
- StructOne* pStructOne = structOneCtor();
- XVMHeader* pXVMHeader = xvmHeaderCtor();
- readByteCodeData(pXVMHeader, argv[1]);
- makeSectionHeader(pXVMHeader->pStructThree, "stack", 0x3000, 0xcafe3000, 3);
- pStructOne->uint64arr[1] = pXVMHeader->magicValue[1];
- pStructOne->uint64arr[3] = 0xcafe3ffc;
- fcn_1997(pStructOne->uint64arr, pXVMHeader->magicValue);
- // I suspect these may be destructors!
- fcn_19de(pStructOne);
- pStructOne = NULL;
- fcn_47b3(pXVMHeader);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement