Commit a9073a48 authored by BiOpenly's avatar BiOpenly

Initial disassembler commit.

Only handles a couple basic block types for parsing
parent 878f2a5c
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Binaries)
add_subdirectory(Source/)
#pragma once
#include <stdint.h>
constexpr uint32_t COOKIE(const char a[4])
{
return (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0];
};
// Block Types seen
//
// MPB1
// VERT
// MBS2
// VEHW
// CVER
// CMMN
// VELA
// SYMB
// TYPE
// TPGE
// KERN
// STR
// KWGS
// BFRE
// OBJC
// CCOM
// STRI
//
struct Block_MPB1
{
// MPB1
uint32_t cookie;
// Size of the file sub 0x8
uint32_t size;
uint32_t unk1;
uint32_t unk2;
};
struct Block_VERT
{
// VERT
uint32_t cookie;
uint32_t unk1;
};
struct Block_MBS2
{
// MBS2
uint32_t cookie;
uint32_t unk1;
uint32_t unk2;
};
struct Block_VEHW
{
// VEHW
uint32_t cookie;
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t unk4;
};
struct Block_CVER
{
// CVER
uint32_t cookie;
uint32_t unk1;
};
struct Block_CMMN
{
// CMMN
uint32_t cookie;
uint32_t unk1;
};
struct Block_VELA
{
// VELA
uint32_t cookie;
uint32_t unk1;
uint32_t unk2;
};
project(Disassembler)
set(SRCS Main.cpp)
add_executable(disasm ${SRCS})
#include <assert.h>
#include <stdio.h>
#include <string>
#include <vector>
#include "BlockInfo.h"
bool ReadFile(std::vector<uint8_t> *fileData, std::string filename)
{
FILE* fp = nullptr;
size_t filesize = 0;
fp = fopen(filename.c_str(), "rb");
if (!fp)
return false;
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
rewind(fp);
fileData->resize(filesize);
fread(fileData->data(), 1, filesize, fp);
fclose(fp);
return true;
err:
if (fp) {
fclose(fp);
}
return false;
}
void PrintFile(std::vector<uint8_t> *fileData, size_t offset = 0)
{
printf("file size is 0x%08llx\n", fileData->size());
uint32_t *data = reinterpret_cast<uint32_t*>(fileData->data() + offset);
size_t size = std::min(fileData->size() / 4, 50ul);
for (size_t i = 0; i < size; i++)
{
uint32_t word = data[i];
auto getL = [word](int off)
{
return (uint8_t)(word >> off);
};
printf("0x%08x: %c%c%c%c\n",
word,
getL(0), getL(8), getL(16), getL(24));
}
}
// Attempt to parse a single block with maxSize words
bool ParseSingleBlock(uint8_t* blockBlob, size_t *blockSize)
{
uint32_t cookie = *reinterpret_cast<uint32_t*>(blockBlob);
switch (cookie)
{
case COOKIE("MPB1"):
{
Block_MPB1* block = reinterpret_cast<Block_MPB1*>(blockBlob);
printf("Block_MPB1\n");
printf("\tSize: 0x%08x\n", block->size);
assert(block->unk1 == 2);
assert(block->unk2 == 0);
*blockSize = sizeof(Block_MPB1);
}
break;
case COOKIE("VERT"):
{
Block_VERT* block = reinterpret_cast<Block_VERT*>(blockBlob);
printf("Block_VERT\n");
assert(block->unk1 == 0x45c);
*blockSize = sizeof(Block_VERT);
}
break;
default:
{
auto getL = [cookie](int off)
{
return (uint8_t)(cookie >> off);
};
printf("Attempting 0x%08x: %c%c%c%c\n",
cookie,
getL(0), getL(8), getL(16), getL(24));
return false;
}
break;
};
return true;
}
void ParseBlocks(std::vector<uint8_t> *fileData)
{
uint8_t *data = fileData->data();
size_t size = fileData->size();
for (size_t i = 0; i < size;)
{
size_t blockSize = 0;
if (!ParseSingleBlock(&data[i], &blockSize))
{
printf("Couldn't parse block! Leaving!\n");
return;
}
i += blockSize;
}
}
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("Usage: %s <file.bin>\n", argv[0]);
return 0;
}
std::vector<uint8_t> file;
if (ReadFile(&file, argv[1]))
{
PrintFile(&file);
ParseBlocks(&file);
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment