2

Is it possible to change strings (content and size) in Lua bytecode so that it will still be correct? It's about translating strings in Lua bytecode. Of course, not every language has the same size for each word...

Kamiccolo
  • 7,758
  • 3
  • 34
  • 47
lesderid
  • 3,388
  • 8
  • 39
  • 65
  • See also http://stackoverflow.com/questions/19242617/is-it-possible-to-change-a-value-inside-a-lua-bytecode-how-any-idea. – lhf Mar 19 '14 at 00:22

3 Answers3

3

Yes, it is if you know what you're doing. Strings are prefixed by their size stored as an int. The size and endianness of that int is platform-dependent. But why do you have to edit bytecode? Have you lost the sources?

lhf
  • 70,581
  • 9
  • 108
  • 149
  • Where are there sizes stored? Is there any application which automatically changes the lengths after them being edited? I didn't make the sources. The bytecode is available to the general public for free and the changes that I'll make are going to be for personal use. – lesderid Sep 08 '10 at 16:44
  • 1
    Like I said, the strings are prefixed by their size. Try an hexdump of the bytecode files you have. – lhf Sep 08 '10 at 20:04
  • So if you just change the prefix, it should work? No errors with calling those strings or something (because of the changed locations)? – lesderid Sep 09 '10 at 15:25
  • 1
    If you change the strings and correct the size accordingly, then it should work. Note that strings contain a NUL byte at the end. – lhf Sep 09 '10 at 17:22
  • Isn't there any hashing to check the strings? – lesderid Sep 10 '10 at 19:42
  • Strings are hashed when loaded. – lhf Sep 10 '10 at 20:35
1

After some diving throught Lua source-code I found such a solution:

#include "lua.h"
#include "lauxlib.h"

#include "lopcodes.h"
#include "lobject.h"
#include "lundump.h"

/* Definition from luac.c: */
#define toproto(L,i) (clvalue(L->top+(i))->l.p)

writer_function(lua_State* L, const void* p, size_t size, void* u)
{
    UNUSED(L);
    return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
}

static void
lua_bytecode_change_const(lua_State *l, Proto *f_proto,
                   int const_index, const char *new_const)
{
    TValue *tmp_tv = NULL;
    const TString *tmp_ts = NULL;

    tmp_ts = luaS_newlstr(l, new_const, strlen(new_const));
    tmp_tv = &f_proto->k[INDEXK(const_index)];
    setsvalue(l, tmp_tv, tmp_ts);

    return;
}

int main(void)
{
    lua_State *l = NULL;
    Proto *lua_function_prototype = NULL;
    FILE *output_file_hnd = NULL;

    l = lua_open();
    luaL_loadfile(l, "some_input_file.lua");
    lua_proto = toproto(l, -1);
    output_file_hnd = fopen("some_output_file.luac", "w");

    lua_bytecode_change_const(l, lua_function_prototype, some_const_index, "some_new_const");
    lua_lock(l);
    luaU_dump(l, lua_function_prototype, writer_function, output_file_hnd, 0);
    lua_unlock(l);

    return 0;
}

Firstly, we have start Lua VM and load the script we want to modify. Compiled or not, doesn't matter. Then build a Lua function prototype, parse and change it's constant table. Dump Prototype to a file.

I hope You got that for the basic idea.

Kamiccolo
  • 7,758
  • 3
  • 34
  • 47
0

You can try using the decompiler LuaDec. The decompiler would allow the strings to be modified in generated Lua code similar to the original source.

ChunkSpy has A No-Frills Introduction to Lua 5.1 VM Instructions that may help you understand the compiled chunk format and make the changes directly to bytecode if necessary.

gwell
  • 2,695
  • 20
  • 20