How to bring debugging information when encryption then lua code use luac - lua

I wrote the following code in the file "orgin.lua"
if test==nil then
print(aa["bb"]["cc"]) -- to produce a crash
end
print(1120)
when it crash ,it will generate the following information:
lua: origin.lua:3: attempt to index global 'aa' (a nil value)
In order to prevent decompilation and make sure the code is safe,I use the following command to convert my code:
luac -o -s test.lua origin.lua
I know the argument -s is strip debug information, then it do not show the number of rows when crash:
lua: ?:0: attempt to index global 'aa' (a nil value)
but how to bring debugging information when encryption then lua code use luac?Is there any solution?

There is no way to do this built into Lua, but there are some work-arounds.
If you only need line numbers, then one option is to leave the line numbers in the chunk. Line numbers are not that useful for reverse engineering (unluac currently doesn't use them at all), so it shouldn't affect security. Lua doesn't provide an option for this, but it is easy to modify Lua to leave them in when stripping. From ldump.c
n = (D->strip) ? 0 : f->sizelineinfo;
can be changed to
n = f->sizelineinfo;
(Disclaimer: untested)
A more complicated option would be to modify the Lua runtime to output the virtual machine program counter instead of the line number, and also output information describing the location of the current function in the chunk (e.g. top level, first function, second function nested in third function, etc). Then the line number could be looked up by the developer in a non-stripped version of the chunk. (Here is a reference to someone using this approach on lua-l -- no source code was provided, though.)
Note that preventing decompilation is not true security. It may help against casual attacks, but Lua bytecode is not hard to read.

luac does not encrypt the output. It compiles your Lua source code to bytecode, that's all. The code is neither encrypted nor does it run any faster, only the loadtime is shorter since the compilation step is not needed.
If you want your code to be encrypted, I suggest to encrypt the bytecode using e.g. AES-256 and then decode it in memory just before handing it to the Lua state. This way the bytecode is encrypted on disk, but decripted in memory.
The overhead is low. We use this technique since years.

Related

What can i get from the lua bytecode retrivied via string.dump()?

I’m using lua + luajit 2.0.4 and I’m wondering - Is it possible to restore the original parts of the code from the dumps of lua functions?
function a(l)
if l > 3 then
print(l*l)
end
end
local b = string.dump(a)
In this example, I am doing the string.dump of the 'a' function, and here I come to the questions like:
Is it possible to write this dump into a .txt file?
Is it possible to get the original names of functions, variables, and upvalues?
Is it possible to get strings, numbers, tables?
Is it possible to restore it to the full code, and if not, is it possible to get a disassembled listing?
"Yes" to all questions with a couple of caveats. For (1), make sure that "b" is used as part of the "mode" parameter in io.open on Windows, as the output of string.dump will have some binary content. For (2), it's only true when string.dump is used without the strip option, which was added in LuaJIT:
string.dump(f [,strip])
An extra argument has been added to string.dump(). If set to true,
'stripped' bytecode without debug information is generated. This
speeds up later bytecode loading and reduces memory usage.
For (4), I found this document to be very useful: http://files.catwell.info/misc/mirror/lua-5.2-bytecode-vm-dirk-laurie/lua52vm.html (it's for Lua 5.2, but most of the content applies to LuaJIT as well); it also include a section on the difference between full and stripped bytecode that may answer some of your questions.

COBOL - Microfocus - Generic I/O

I am responsible for converting an old UNIX based COBOL batch application that was developed by a consultant back in the 1990s to a Windows environment but still in COBOL using Microfocus (Eclipse, etc).
This is a pretty straight-forward task except for one little glitch.
The old application never did any explicit file handling within the COBOL. That is there are no FDs, OPENs, READs, WRITEs or CLOSE commands in the COBOL programs. Instead they wrote a C program that would do one of those different functions based on parameters passed to it (including, but not limited to file name, rec length, and the function desired.)
I would like to rewrite that subroutine in COBOL, which would require very little modifications to the COBOL main programs being converted. That is, it would still call that subroutine, but it would now be in COBOL instead of C.
But the challenge is how to write that subroutine so that it is able to act on most any file. I would think I have to go the route of variable length records because they could literally be any length up to to-be-determined maximum size, but seems like it would be vulnerable to error (as it tries to open different types of files).
Does anybody have any experience on this or ideas on a task like this? If not,l I may have to go the blunt force route of replacing each call statement to that subroutine with the specific COBOL command (Open, Read, etc) that needs to be performed and obviously FD and SELECT for every file would need to be added to the main program.
Thanks in advance.
You might be able to
CALL "subprogram" USING fd-name
where fd-name is
FD fd-name.
...
So, yes? maybe?, you might be able to pull off a subprogram that can take generic COBOL files. But, then you get into matching record layouts and other fun things, so, be wary. This might not work COBOL to COBOL, but it does work COBOL to C and back, as you end up passing a reference to the file control block.
You'll likely be better off looking into stock system libraries. Things like CBL_OPEN_FILE and CBL_READ_FILE if they are available. This will give you a much closer match to streaming IO that will be assumed in the current C subprogram.
Or, as Bill is suggesting in the comments, try and figure out why C was used and if you don't want the foreign functions, just dig in and write new COBOL procedures, as that will likely read better in the end.

Is it possible to change a value inside a Lua bytecode? How? Any idea?

I got a script that is no longer supported and I'm looking for a way to change the value of a variable in it... The script is encrypted (loadstring/bytecode/something like that) e.g.: loadstring('\27\76\117\97\81\0\1\4\4\4\8\0\')
I can find what I want to change (through notepad after I compile the script), but if I try to change the value, the script won't work, if I change and try to recompile it still won't work: "luac: Testing09.lua: unexpected end in precompiled chunk" ...
Any ideas? I did something like that with a program long a go using ollydbg but I can't use it with lua scripts... I'm kinda lost here, doing some Googling for quite a while couldn't find a way... Any ideas?
It is easy to change a string in a Lua bytecode. You just have to adjust the length of the string after you change it. The length comes before the string. It probably takes four or eight bytes just before the string, depending on whether you have a 32-bit or 64-bit platform. The length is stored in the endianness of the machine where the bytecode was generated. Note that strings include a trailing '\0' and this counts in the length.
Perhaps it is easier to just copy some bytes directly. Write this file
return "this is the new string you want"
Generate bytecode from it with luac and look at an dump of luac.out and locate the string and its length. Copy those bytes to the original file.
I don't know whether notepad handles binary data. if it doesn't, you'll need an hex editor to do this.
Another solution is to write a Lua program that reads the bytecode as a strings, generate bytecode for return "this is the new string you want", perform the change in the original bytecode using string operations and write it back to file.
You can also try my bytecode inspector library lbci, which allows you to change constants in functions. You'd load the bytecode (but not execute it), and use setconstant after locating the constant that has the string you want to change.
In all, there is some fun to be had here...

Handle large numbers with precision in Redis Lua

I need to handle large numbers in Lua which goes with Redis. Normally you would do that like:
require"bc"
bc.mul(...)
bc.mod(...)
etc.
But unfortunately Redis Lua doesn't support "require". The only approach I've found is inserting a large numbers library written in lua itself directly into the script.
The only such library I could get my hands on: oss.digirati.com.br/luabignum/index.htm
I can strip the library for the purposes of a concrete script but it still remains huge. Is there any way to handle large numbers in Redis Lua more efficiently?
UPDATE1: What if I save the whole library into a key and then access it like:
local BigNumLib = KEYS[1];
BigNumLib.BigNum.mul(KEYS[2],KEYS[3]);
I'm not sure of the syntax and perhaps I'll need to enclose all the library in a lua table {}.
I'm not familiar with how Redis handles Lua code, but why is inserting the library itself into your code is a problem? you should be able to do something like this:
local bc = function()
-- insert the code of BigNum.lua here
return BigNum
end
bc.mul(....)
The code has probably been written before Lua 5.1, so I don't know if there are any compatibility issues, but this should at least give you a start.

timer:tc with argument

Given the following module:
run(N)->
timer:tc(?MODULE,fct,[N]).
I call it by run(100). from a shell and I have this:
{1,
{'EXIT',{undef,[{parser,loop,"d"},
{timer,tc,3},
{erl_eval,do_apply,5},
{shell,exprs,7},
{shell,eval_exprs,7},
{shell,eval_loop,3}]}}}
100 is interpreted as a char ($d = 100) and not as an integer !
Where is my fault ?
In Erlang, [100] and "d" are indistinguishable, the code you show above isn't the problem. The Erlang shell is being helpful (for certain values of help) and printing [100] as "d" because it's a list containing only integers representing printable characters.
The real problem is the undef error in the above, my guess is that your parser module doesn't contain a function parser:loop/1 that you call via parser:fct/1.
Did you get any warnings on your compilation ? I suspect you will see at least one message about an unused function. As you are learning, if you see a warning message then investigate it, understand it and correct it. Generally speaking, you want your code to have no warning messages.
If a function is called in MFA style then it has to be exported in the source code. From what you've shown it's not clear if it is named "fct" or "loop". So, make sure your naming is consistent, and make sure it is exported : You need this in your source code (assuming the function is called "loop" and takes 1 argument) :
-export([loop/1]).
Error messages in Erlang can be tricky to decipher at first. Take some time to read more and become more familiar with them and you will save yourself lots of time going forward.

Resources