-
Notifications
You must be signed in to change notification settings - Fork 0
/
eset_vm_disasm.cpp
115 lines (100 loc) · 3.4 KB
/
eset_vm_disasm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <fstream>
#include <vector>
#include <cstdint>
#include <iostream>
#include <algorithm>
#include <bitset>
#include <sstream>
#include <cstring>
#include <iomanip>
#include <chrono>
#include "bit_istream.hpp"
#include "evm_parser.hpp"
struct Header {
char magic[8];
uint32_t codeSize;
uint32_t dataSize;
uint32_t initialDataSize;
};
int main(int argc, char* argv[])
{
std::string inputFilePath;
std::stringstream outAsmCodeStream;
std::string outFileName;
if (argc == 2)
{
inputFilePath = argv[1];
}
else
{
std::cout << "Usage: eset_vm_disasm in_file.evm" << std::endl;
return 0;
}
// open input file
std::ifstream inputFile(inputFilePath, std::ios::binary);
if (!inputFile.is_open()) {
std::cerr << "Failed to open input file." << std::endl;
return 1;
}
// Read and parse the header
Header header;
inputFile.read(reinterpret_cast<char*>(&header), sizeof(header));
if (!inputFile || (*reinterpret_cast<uint64_t*>(header.magic)
!= *reinterpret_cast<const uint64_t*>("ESET-VM2")))
{
std::cerr << "Wrong input file header." << std::endl;
inputFile.close();
exit(1);//error
}
//print header
outAsmCodeStream << ".dataSize " << header.dataSize << std::endl;
// Read code buffer
std::vector<uint8_t> codeBuffer(header.codeSize);
inputFile.read(reinterpret_cast<char*>(codeBuffer.data()), header.codeSize);
if (!inputFile)
{
std::cerr << "Error reading code buffer from file." << std::endl;
inputFile.close();
exit(1);//error
}
auto time_begin = std::chrono::steady_clock::now();
/////////////////////////////////////////
// read initial data buffer
if (header.initialDataSize)
{
std::vector<uint8_t> dataBuffer(header.initialDataSize);
inputFile.read(reinterpret_cast<char*>(dataBuffer.data()), dataBuffer.size());
if (!inputFile)
{
std::cerr << "Error reading input file initial data." << std::endl;
inputFile.close();
exit(1);//error
}
//disassamble binary data to HEX string lines
outAsmCodeStream << ".data";
std::ios_base::fmtflags streamFlags(outAsmCodeStream.flags());
outAsmCodeStream << std::hex;
for (size_t i = 0; i < dataBuffer.size(); i++)
{
char delim = (i % 16 == 0) ? '\n' : ' ';
outAsmCodeStream << delim << std::setfill('0')
<< std::setw(2) << (int)dataBuffer[i];
}
outAsmCodeStream.flags(streamFlags);
outAsmCodeStream << std::endl;
}
// disassemble code buffer
BitStream codeBitStream(codeBuffer.data(), header.codeSize);
EvmParser codeParser(&codeBitStream);
codeParser.parse(outAsmCodeStream);
if (codeParser.getErrorStatus() != EvmParser::ErrorStatus::NoError)
{
std::cerr << "Parse error" << std::endl;
exit((int)codeParser.getErrorStatus());
}
auto time_end = std::chrono::steady_clock::now();
auto elapsed_ms = std::chrono::duration_cast<std::chrono::nanoseconds>(time_end - time_begin);
std::cerr << "Parse time elapsed: " << elapsed_ms.count() << std::endl;
std::cout << outAsmCodeStream.str();
return 0;
}