01/02/05/70/72/69/6E/74/01/68/01/02/00/00/01/06/A3/00/00/00/A4/00/01/00/00/00/00/40/6F/01/02/00/9F/00/02/01/82/00/01/00/03/03/01/04/00/00/00/40/03/02/00/00/06/01/00/00/00/00/00/00/00
- это байт-код для
print"h"
Мне нужен способ создать компилятор, который может превратить любой байт-код в полуточный скрипт. Я уже сделал один, но он очень плохой, и он поддерживает только Clouse, getglobal, setglobal, loadk, loadnil, loadnumber, loadbool, call, gettablek, clearstack, init, vararg, return и length. В большинстве случаев это будет неправильно ..
Код:
#include <iostream>
#include <Windows.h>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <vector>
namespace opcodes {
std::string GETGLOBAL = "A4";
std::string SETGLOBAL = "18";
std::string GETTABLEK = "4D";
std::string SETTABLEK = "30";
std::string LOADK = "6F";
std::string RETURN = "82";
std::string LOADNUMBER = "8C";
std::string CALL = "9F";
std::string CLEARSTACK = "A3";
std::string LOADBOOL = "A9";
std::string LOADNIL = "C6";
std::string CLOSURE = "D9";
std::string INIT = "C0";
std::string LEN = "1C";
std::string SUB = "26";
std::string FORLOOP = "8B";
std::string FORPREP = "A8";
std::string VARARG = "DD";
std::string SETUPVAL = "DE";
};
std::vector<std::string> FuncsGlob;
std::vector<std::string> locals;
std::stringstream ss;
std::string inp = "";
std::vector<std::string> hexs;
std::string script;
std::string Value;
std::string lf = "";
std::string HTA(std::string hex)
{
// initialize the ASCII code string as empty.
std::string ascii = "";
for (size_t i = 0; i < hex.length(); i += 2)
{
// extract two characters from hex string
std::string part = hex.substr(i, 2);
// change it into base 16 and
// typecast as the character
char ch = stoul(part, nullptr, 16);
// add this char to final ASCII string
ascii += ch;
}
return ascii;
}
void Split(const std::string& s, char c,
std::vector<std::string>& v) {
std::string::size_type i = 0;
std::string::size_type j = s.find(c);
while (j != std::string::npos) {
v.push_back(s.substr(i, j - i));
i = ++j;
j = s.find(c, j);
if (j == std::string::npos)
v.push_back(s.substr(i, s.length()));
}
}
static bool isF(std::string func) {
std::vector<std::string> funcs = {"wait", "warn", "print"};
for (int i = 0; i < funcs.size(); i++)
{
if (funcs[i] == func)
{
return true;
}
}
return false;
}
int main()
{
std::cout << "Enter bytecode: ";
inp = "01/02/05/70/72/69/6E/74/01/68/01/02/00/00/01/06/A3/00/00/00/A4/00/01/00/00/00/00/40/6F/01/02/00/9F/00/02/01/82/00/01/00/03/03/01/04/00/00/00/40/03/02/00/00/06/01/00/00/00/00/00/00/00";
std::cout << std::endl;
Split(inp, '/', hexs);
if (hexs[0] == "01") {
int stringtables = std::stoi(hexs[1]);
int FSize = 2;
std::string ValueName;
int psr = 1;
int clsr = 0;
int init = 0;
int conv = 0;
int lk_r = 0;
int slitthroat = 0;
int b_s = std::stoi(hexs[FSize]);
for (unsigned int sti = 0; sti < stringtables; sti++) {
for (int cur = FSize + psr; cur < FSize + b_s + 1; cur++) {
ValueName = (std::string)HTA((std::string)hexs[cur]);
Value += ValueName;
conv = cur;
}
psr++;
b_s = std::stoi(hexs[conv + 1]) + 1;
FSize = conv++;
FuncsGlob.insert(FuncsGlob.end(), Value);
Value = "";
ValueName = "";
}
for (int nig = conv; nig < hexs.size(); ++nig) {
locals.resize(hexs.size() + 1);
FuncsGlob.resize(hexs.size() + 1);
if (hexs[nig] == opcodes::LOADK) {
script += "\"" + FuncsGlob[lk_r] + "\"";
slitthroat++;
lk_r++;
}
if (hexs[nig] == opcodes::GETGLOBAL) {
if (isF(FuncsGlob[lk_r]))
script += FuncsGlob[lk_r] + "(";
else
script += FuncsGlob[lk_r] + ".";
lk_r++;
}
if (hexs[nig] == opcodes::CALL) {
if (clsr == 0) {
if (script[script.length() - 1] == '.')
script = script.erase(script.length() - 1);
script += ")";
}
}
if (hexs[nig] == opcodes::CLEARSTACK) {
lk_r = 0;
}
if (hexs[nig] == opcodes::GETTABLEK) {
script += FuncsGlob[lk_r] + ".";
lk_r++;
}
if (hexs[nig] == opcodes::LOADNUMBER) {
script += std::stoi(hexs[nig + 2]);
}
if (hexs[nig] == opcodes::LOADBOOL) {
if (hexs[nig + 2] == "00") {
script += "false";
}
else if (hexs[nig + 2] == "01") {
script += "true";
}
}
if (hexs[nig] == opcodes::LOADNIL) {
script += "nil";
}
if (hexs[nig] == opcodes::INIT) {
init++;
}
if (hexs[nig] == opcodes::CLOSURE) {
if (init > 0) {
script = "(function() " + script + "end)()";
init--;
clsr++;
}
else {
script = "(function() " + script + "end)";
clsr++;
}
}
if (hexs[nig] == opcodes::RETURN) {
clsr = 0;
}
if (hexs[nig] == opcodes::VARARG) {
script += "...";
}
if (hexs[nig] == opcodes::LEN) {
script += "#";
}
}
std::cout << std::endl << script;
}
}