mustyoshi
|
  |
 |
| Joined: 27 Dec 2007 |
| Total Posts: 41651 |
|
|
| 03 Aug 2012 12:21 PM |
By obfuscator, I mean variable renamer.
~Monica |
|
|
| Report Abuse |
|
|
|
| 03 Aug 2012 01:11 PM |
Or we could do something cooler
Like writing a bytecode interpreter so people can still use bytecode for legacy purposes (ROBLOX has so much legacy code), but without the h4xy exploits. |
|
|
| Report Abuse |
|
|
|
| 03 Aug 2012 01:13 PM |
| Or we can make a petetion for roblox to bring back OpenGL legacy. |
|
|
| Report Abuse |
|
|
mustyoshi
|
  |
 |
| Joined: 27 Dec 2007 |
| Total Posts: 41651 |
|
|
| 03 Aug 2012 01:17 PM |
You could use xLEGOx's LASM Compiler stuff to write the bytecode interpreter.
~Monica |
|
|
| Report Abuse |
|
|
Legend26
|
  |
| Joined: 08 Sep 2008 |
| Total Posts: 10586 |
|
|
| 03 Aug 2012 01:19 PM |
| Or we could just ignore it until it goes away which is most likely what sorcus wants. |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 03 Aug 2012 01:29 PM |
"You could use xLEGOx's LASM Compiler stuff to write the bytecode interpreter."
If you're going to write your VM why go to the trouble of making it the same as the Lua one, make it whatever is hardest to turn into normal Lua code. |
|
|
| Report Abuse |
|
|
|
| 03 Aug 2012 01:43 PM |
@mustyoshi: >You could use xLEGOx's LASM Compiler stuff to write the bytecode interpreter.
I've already modified/created my own LASM tools. But I don't think I'll be using too much of those. I plan to pre-decode the entire bytecode sequence and then interpret that.
I foresee closures being a pain to get right, but getting a basic interface working will be easy.
(I do not mean a complete LuaVM, it will be an interface between existing bytecode -> ROBLOX API)
|
|
|
| Report Abuse |
|
|
|
| 03 Aug 2012 01:47 PM |
| Stravant: I was actually thinking of making a Forth interpreter, so that would be fun |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 03 Aug 2012 01:57 PM |
@Necro
Have you seen my set of tools? (Outdated, but might be interesting to build off of) They're more compiling focused rather than decompiling focused, but for that they have a very nice readable syntax which is _in Lua_ so you can easily add your own macros of sorts to the syntax:
Sample: http://wiki.roblox.com/index.php/User:XLEGOx/lasm_example |
|
|
| Report Abuse |
|
|
|
| 03 Aug 2012 02:01 PM |
>Have you seen my set of tools? (Outdated, but might be interesting to build off of) They're more compiling focused rather than decompiling focused, but for that they have a very nice readable syntax which is in Lua so you can easily add your own macros of sorts to the syntax:
The ones you released years ago that still don't assemble the AsBx instructions properly :3? Yes.
I remember that one very well. Heck, I have a modified copy of it open already. I built my very first assembler on top of that. Ohh the memories.
But I don't need assembler tools. At most I'll use are the binary decoding functions from that. |
|
|
| Report Abuse |
|
|
mustyoshi
|
  |
 |
| Joined: 27 Dec 2007 |
| Total Posts: 41651 |
|
|
| 04 Aug 2012 12:33 PM |
Anybody write a parser? I thought about tokenizing everything.
~Monica |
|
|
| Report Abuse |
|
|
|
| 04 Aug 2012 12:40 PM |
| My idea of a variable renamer would set their names to a number of underscores. It would make big scripts almost unreadable. Detecting every variable definition and index would be hard though. Extreme string manipulation there. |
|
|
| Report Abuse |
|
|
lucas668
|
  |
| Joined: 18 Jun 2008 |
| Total Posts: 6183 |
|
|
| 04 Aug 2012 12:43 PM |
| Challenge accepted, I'm gonna make a plugin that does this to selected scripts now. |
|
|
| Report Abuse |
|
|
|
| 04 Aug 2012 04:55 PM |
Update on my bytecode interpreter: I've got 5 of 38 instructions implemented, and so far things are going well. I'm working on getting the following function's bytecode to run at the moment:
function() some_global = math.random(); end
Once I get enough instructions implemented (hopefully some math ones next), I'll post some benchmarks. I really hope it's within an order of magnitude as fast as normal Lua bytecode. |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 04 Aug 2012 05:07 PM |
"I really hope it's within an order of magnitude as fast as normal Lua bytecode."
I doubt you'll be able to get it to that point unless you JIT compile some of it back into normal Lua code. If you did that you might be able to get it to well within an order of magnitude, but you'd effectively be writing a decompiler at that point. |
|
|
| Report Abuse |
|
|
|
| 04 Aug 2012 05:41 PM |
I don't think there's anything to really JIT. There's no type checking to remove or anything. All that I could try is loop unrolling but I doubt that'd work for an interpretter loop.
It's a very bare interpretter loop. For example, here's the code for GETGLOBAL
[5] = function(instruction) -- GETGLOBAL local key = constants[instruction.Bx]; stack[instruction.A] = environment[key]; end,
While yes, GETGLOBAL is a relatively simple instruction, I want to point out how easy most of these are to implement at a high level. |
|
|
| Report Abuse |
|
|
|
| 05 Aug 2012 12:42 AM |
Double Post.
Update on my bytecode interpreter.
local function test() yooo = math.random(); return 1, 3, 5; end local bytecode = string.dump(test); local func = load_bytecode(bytecode); -- my library print("FUNC:", func()) --> 1, 3, 5 print(yooo); --> 0.0012512588885159
As for the speed... It's ~50x slower than native Lua bytecode. There's room for optimization in function calling and returning from a function (the two major things demonstrated here), and as Stravant said a JIT of some kind might be possible. (how easy without writing a complete decompiler, I'm not sure)
Current instructions implemented: LOADK, GETGLOBAL, GETTABLE, SETGLOBAL, CALL, RETURN
Anyway, tomorrow I'll implement a few more random instructions (probably math ones) will trying to optomize some things.
tl;dr bytecode is not dead yet. |
|
|
| Report Abuse |
|
|
RA2lover
|
  |
| Joined: 09 Nov 2008 |
| Total Posts: 1254 |
|
|
| 05 Aug 2012 02:43 PM |
| i'd simply encrypt the script and fetch the decryption key through a non-free model. |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 05 Aug 2012 04:03 PM |
"I don't think there's anything to really JIT"
There's lots to do, consider the following expression: game.Workspace.Model.Part.BrickColor = BrickColor.new(21)
IT would be _much_ faster to recognize the bytecode for that expression, and then emit the Lua code, loadstring it, and only execute that compiled chunk normally in the future.
Really, 99% of what's written in the bytecode will be directly translatable into normal Lua code, it's only a very few left-over bits that you actually _have_ to execute in software on your custom VM.
The question is just how far you're willing to go to decompile the bytecode back into Lua code. At the very least I think it would be easy enough to recognize expressions / indexing chains and pre-compile those (you can just search for opcodes which would immediately pop what the previous opcode pushed, and simplify those into an AST of sorts, which you can then write back to Lua code. I've done that with java bytecode before.) |
|
|
| Report Abuse |
|
|
|
| 05 Aug 2012 07:06 PM |
@Stravant:
That requires much more work as a decompiler than a JIT though.
because my interpretter is progressing well, I'll hold off on decompiling for now, which will probably be significantly more complex.
After much refactoring, I've reduced the 50x slowdown of the earlier example to 35x. But there's only so much that can be done for such a function. The function prologue for calling a bytecode wrapper isn't free, and CALL/RETURN are the most expensive instructions implemented so far.
I've also done some testing of the math instruction (ADD, SUB, MUL, DIV, MOD, POW), and those appear to be around ~35x slower as well. However, I need to test larger functions.
local function test(a, b) a = a + b; a = a + a * b; b = b / a; a = a ^ (b*4); b = a / b * 0.5; a = a % 1024; return a, b; end
local bytecode = ('').dump(test); local func = load_bytecode(bytecode); print("FUNC:", func(10, 5)) --> FUNC: 2.7181668598498 24.463501738648
|
|
|
| Report Abuse |
|
|
Parthax
|
  |
| Joined: 27 Apr 2011 |
| Total Posts: 6941 |
|
| |
|