1

I paid an untrusted developer for a script. And as I thought he scammed me. He did send me code, but he obfuscated the script. It is for a game called "Roblox" that uses Lua, the code will be down below. As from I can tell by running it, it might work. But I would need to change the script for it to work. Does anyone know to to decode the obfuscation?

https://pastebin.com/B8SZmZGE

local ilIillllII1i1lliliI = assert local II1ll1iliIIIIillIli = select local lIlillIlIi11I1lIIi11I = tonumber local i1li1IIIII1IIilIil1 = unpack local iIl1IIlI11i1il1ilII = pcall local lIlI1IiiIlIl1i11ll1Il = setfenv local iIIlilIlllIliiIili1 = setmetatable local ii1Iiill11ii1IIIill = type local lIll1I1ll1lliilII1Il1 = getfenv local IiIi1llliiIIllllI1i = tostring local Ii1IIill1ilI1lilIiI = error local iilli1lIi11lllIli1l = string.sub local lIlI1li1ll1lliliIlI = string.byte local lIli1Ill1liIlilIIIiiI = string.char local I1ii1iIIl1lI1Iii1iI = string.rep local iiiIiI11IIllIiliI1I = string.gsub local illlIIIllliill1l1ll = string.match local iIi1l1liili1I11l1II = 1 local function lIll1iillI1ll1iiIiIll(IIiiiIiiIllIl1i1i1I, iIililIlliIII11illi) local i1iiI1I1iII1iiIiil1 IIiiiIiiIllIl1i1i1I = iiiIiI11IIllIiliI1I(iilli1lIi11lllIli1l(IIiiiIiiIllIl1i1i1I, 5), "..", function(llii1Ii11lI1llilill) if lIlI1li1ll1lliliIlI(llii1Ii11lI1llilill, 2) == 71 then i1iiI1I1iII1iiIiil1 = lIlillIlIi11I1lIIi11I(iilli1lIi11lllIli1l(llii1Ii11lI1llilill, 1, 1)) return
Egor Skriptunoff
  • 23,359
  • 2
  • 34
  • 64
jonah robberts
  • 29
  • 1
  • 1
  • 2
  • 1
    [deobfuscated](https://pastebin.com/pEAJ3uaT) – Egor Skriptunoff Dec 01 '19 at 11:10
  • @EgorSkriptunoff Would you happen to be in the possession of either Luraph's custom bytecode or a Luraph deobfuscator? – Taazar Feb 21 '20 at 15:26
  • @Taazar - I don't have deobfuscator. But Luraph is not very hard to deobfuscate manually. Its custom bytecode is different every time, so you should look into VM code, not only into bytecode. – Egor Skriptunoff Feb 21 '20 at 17:21
  • 1
    @EgorSkriptunoff I'll look into it over the weekend, should be a good research project. Do you have anywhere you'd recommend I start? – Taazar Feb 21 '20 at 17:29
  • 1
    @Taazar - Start with looking into [this](https://github.com/JustAPerson/lbi) project. Luraph is just a modified version of lbi. – Egor Skriptunoff Feb 21 '20 at 17:32

7 Answers7

5

Ok so I am turtsis and I see that people have been stealing my answer and posting it on v3rmillion as there own. So I will post another answer but this time a better one on how to actually get contents of it. So basically if you didn’t read my other answer then don’t and just read this one:

Luraph is a custom lbi which is a lua bytecode interpreter. If you do string.dump(function) you will get luaQ as the output. That is why people use unluaC or luadec to get the source to these dumps. This is called bytecode which is different then string:byte() as it is a non readable lua format in lua 5.1 and up. To be able to use these encoded strings/functions you will need a lbi. What a lbi does is it interpreted the bits and deserialzes them. Here is a example of a commonly used lbi https://github.com/JustAPerson/lbi/blob/master/src/lbi.lua

Ok so now to the part where you get contents of it.

In lua (and other coding languages) there is things called opcodes. Opcodes control the base of lua and there is quite a few of them. Some of the most commonly known and most useful ones are these:

LOADK - loads a constant to the register LOADBOOL - loads a bool to the register LOADNIL - loads a nil to the register JMP - jump ADD - Adds a new thing to the register SUB - Subtracts something from the register

There is many more but those are the main ones we will be focusing on.

Ok so to get those normally you would need a external program called unluac or luadec but for this we will be doing it in base lua. I recommend using repl.it to run the code.

So the main thing we will need is LOADK as it loads a constant

A constant is a variable or anything really that doesn’t change ex: local value = 1

Now what isn’t a constant is something that changes.

Now you probaly have heard of iron brew and synapse xen both are very known lua obfuscators created by 3ds and Defcon42

Iron brew and xen have something in common (well the base) they aren’t lbis so you don’t usually get the opcodes from them. But they have a table that has all the constants in them (xen is encrypted) to get these tables there is a whole process with table.concat and global but that’s not luraph that’s other obfuscators. Luraph is different Though because it is a lbi so there is no need for a table with all the constants in it. Instead to get the constants we need a way to get the instructions from a script. Opcodes are instructions. They are instructions because opcodes tell lua what to do with code. Ok so how do we get these instructions?

Here is a article on opcodes and instructions: http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf

So they all have signatures: "sBx" "A" "A", "B" "A", "Bx" "A", "C" "A", "sBx" "A", "B", "C” You get opcodes args from these instructions. Now different obfuscators have different opcodes instructions so for luraph you will have to find them. Ok so use a dissembler or make Your own but here is a disassembler made by my friend: https://github.com/op0x59/reddisassembler

You will need to go onto repl.it and make a repo then add the code and format it etc with the settings. Where in the settings it has opcodes you will need to manually get these from luraph.

So there you go that’s how you can do it. If you need more help dm me on discord: turtsis#6969 Or turtsis#2785

ALSO WHOEVER IS STEALING MY ANSWERS ON HERE AND POSTING THEM ON V3RMILLION WITH OUT CREDITING ME PLEASE STOP OR GIVE ME CREDIT.

turtsis
  • 51
  • 1
  • 1
3

Basically it uses bytecode (\144\22\99\88) but it has a custom interpreter and a custom bytecode vm to make it have a bytecode like this: LPH|3EE5491D2B1A00192574A22B510A02002GE5E7E9E42GE5F53GE5F53GE5CD3GE5FDE42GE5C13GE5F934B71

So you will need to rename the variables and functions into something like variable1, variable2 so that you are able to read it. Then find parts that are junk code like

function 1iiii1i1i(i1i1ijj1jijij)
local 1j1j1jj1j1jijijij = (((10*2)/2)-3/9)
end
1iiii1i1i(90, 0)

Which are completely useless and are meant to trick decompilers into looping random number functions. to check if stuff like: iIi1l1liili1I11l1II = iIi1l1liili1I11l1II + 4 return Ii1IiI1I111I1II1IIi * 16777216 + iIII1iIiI1l1IlIIlii * 65536 + IIill111lli111ll1li * 256

These are junk code just look for it in the rest of the code (using ctrl+F) and look if it has a use. If it does, then check if that use has a use and so on until you find if it is part of the vm. The thing is though is that it might loadstring another loadstring for many times until it will take VERY LONG to decompile this. So if you really need the source contact me on discord and I can hook you up (turtsis#2785) or put a couple of hours into this

Using a Lua beautfier can make it easier to understand.

Such as: [http://blackmiaool.com/lua-beautify/][1] (https://github.com/blackmiaool/lua-beautify)

Alvin
  • 2,533
  • 33
  • 45
turtsis
  • 31
  • 1
0

This question is 5 months old but here you go anyway:

local L3_0, L4_1, L5_2, L6_3, L7_4
L3_0 = "rebel alience"
L4_1 = "Wasp"
L5_2 = "Bottom Small Mining Laser"
L6_3 = "Adamantite Ore"
for _FORV_7_ = 1, 10 do
workspace.Ships[L3_0][L4_1][L5_2].RemoteFireCommand:InvokeServer(CFrame.new(0, 0, 0,0.996030748, -7.7674794E-4, 0.0890064985, 0, 0.999961913, 0.00872653536, -0.0890098885,-0.00869189762, 0.995992839), workspace.Asteroids[L6_3],workspace.Asteroids[L6_3], workspace.Asteroids[L6_3].CenterPoint)
wait(3)
end

It's a simple remote event.

You can find the tool used here, it's open source: https://github.com/TheGreatSageEqualToHeaven/LuraphDeobfuscator

Defalt
  • 41
  • 3
0

The script is

local L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19, L20, L21, L22
L0 = "rebel alience"
L1 = "Wasp"
L2 = "Bottom Small Mining Laser"
L3 = "Adamantite Ore"
for L7 = L4, L5, L6 do
  L8 = Workspace
  L8 = L8.Ships
  L8 = L8[L0]
  L8 = L8[L1]
  L8 = L8[L2]
  L8 = L8.RemoteFireCommand
  L9 = L8
  L8 = L8.InvokeServer
  L10 = CFrame
  L10 = L10.new
  L11 = 0
  L12 = 0
  L13 = 0
  L14 = 0.996030748
  L15 = -7.7674794E-4
  L16 = 0.0890064985
  L17 = 0
  L18 = 0.999961913
  L19 = 0.00872653536
  L20 = -0.0890098885
  L21 = -0.00869189762
  L22 = 0.995992839
  L10 = L10(L11, L12, L13, L14, L15, L16, L17, L18, L19, L20, L21, L22)
  L11 = Workspace
  L11 = L11.Asteroids
  L11 = L11[L3]
  L12 = Workspace
  L12 = L12.Asteroids
  L12 = L12[L3]
  L13 = Workspace
  L13 = L13.Asteroids
  L13 = L13[L3]
  L13 = L13.CenterPoint
  L8(L9, L10, L11, L12, L13)
  L8 = wait
  L9 = 3
  L8(L9)
end

The variables are not the normal variables and it may appear a bit confusing because I was using an auto deobfuscator

0

i might be late but

  1. rebel alience
  2. Wasp
  3. Bottom Small Mining Laser
  4. Adamantite Ore
  5. 1
  6. 10
  7. Workspace
  8. Ships
  9. RemoteFireCommand
  10. InvokeServer
  11. CFrame
  12. new
  13. 0
  14. 0.996030748
  15. -0.00077674794
  16. 0.0890064985
  17. 0.999961913
  18. 0.00872653536
  19. -0.0890098885
  20. -0.00869189762
  21. 0.995992839
  22. Asteroids
  23. CenterPoint
  24. wait
  25. 3
  26. 1337
picocode
  • 113
  • 2
  • 7
-1

I have a luraph dumper the dumped version of that script is only showing one variable which is "1337" I hope this helped!

-2

One of the easiest things to do is to create a script destroying all the Luraph's scripts. Deleting those junk codes would still be a better option, but this would do its work for some time.

What it does, is that it basically destroys these scripts forever. One of the most fun things is that it doesn't even have to destroy them forever. Luraph scripts have a limited number, how many times they could multiply making Luraph's scripts crash.

local condition = true
local Oofer = workspace.Camera 
while condition do 
    workspace.Camera:ClearAl1Children () 
    wait (2)
end
Uwuman
  • 1