Пользовательский lua байт-код / ​​код операции (компилятор / читатель / парсер / декомпилятор) - PullRequest
0 голосов
/ 16 апреля 2020

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;
    }

}
...