0

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 is bytecode for

print"h"

I need a way to make a compiler that can turn any bytecode into a semi accurate script. I've already made one but its very bad and it only supports the Clouse, getglobal, setglobal, loadk, loadnil, loadnumber, loadbool, call, gettablek, clearstack, init, vararg, return and length. Most of the time it will come out wrong..

Code:

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

}
sweetpeps
  • 23
  • 2
  • 6
  • Paste your code in the question itself, instead of the link. Also, please provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) as your code seems to be large. –  Apr 16 '20 at 05:23
  • Okay, I can't really make it any smaller.. I've tried that before and I could do a switch in the if statements but thats all.. – sweetpeps Apr 16 '20 at 05:35
  • Where is such bytecode in use? Where can I get more pairs (script + its bytecode)? – Egor Skriptunoff Apr 16 '20 at 05:43
  • This bytecode is being used in a game that has a modified version of lua – sweetpeps Apr 16 '20 at 06:40
  • Take a look at the decompiler in the [residualvm-tools project](https://github.com/residualvm/residualvm-tools/blob/master/tools/delua.cpp) – Botje Apr 16 '20 at 07:21
  • I see but what I'm using is different than normal lua bytecode so how would I make it work with this custom one? – sweetpeps Apr 16 '20 at 23:47

0 Answers0