Trying to learn what some code does (Lua) - lua

What does this code do?
It's all Lua for World of Warcraft 3.5.5
function __(r) local d = string.sub(r,0x0001,string.len(r)-0x0040) local k = string.sub(r,string.len(r)-0x003F, string.len(r)) d = string.gsub(d, '[^'..k..'=]', '') return (d:gsub('.', function(x) if (x == '=') then return '' end local r,f='',(k:find(x)-1) for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end return r; end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x) if (#x ~= 8) then return '' end local c=0 for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end return string.char(c) end)) end _={_=_G} _._["\108\111\097\100\115\116\114\105\110\103"](_._["\095\095"]("SuperLongStringThatWasRemovedForPrivacyReasons"))()
Now what I am guessing is that this is some sort of encrypted code or something? I am not really sure. What do you guys think it is? / Do you know what this code would do when ran?
NOTE: The really long string... really is long. It's about 150,000 characters long.

The code is equivalent to
loadstring(
decode_from_base64(
("SuperLongStringThatWasRemovedForPrivacyReasons"):sub(1, -65)
)
)()
So, SuperLongStringThatWasRemovedForPrivacyReasons is actually a base-64 encoded Lua program (program may be Lua source or Lua bytecode).
You can easily decode it yourself, there are a lot of online base-64 decoders available.

Related

How to cut and convert bytes in micropython

I am trying to decode Can frames with micropython. I miss a lot of functions from python 3.x. I get 8 hex long bytes from the Rx SPI buffer of an MCP2515. For information, I'm on openMV IDE. I would like to extract the 1st and 2nd to make an integer, the 3rd and 4th to make another one, etc...
Along my researches, I found a function that convert a byte to signed integer (as the sign=True argument is not implemented in the from_byte function).
The main problem is that the solutions provided on others python's forum are only concerning python 3.x for pc but not micropython and a lot of solutions end with "function doesn't exist".
byte = b'\x12\x34\x56\x78\x9A\xBC\xDE\xFF'
def byte2int(bList, signed:bool=False):
if signed :
r = 0
for i in range(2):
d = 32 - ((i + 1) * 8)
r += bList[i] << d
return r
else : return int.from_bytes(byte, 'big')
Moreover, I don't think that I can trust the print function as print(b) return :
> print(b)
b'\x124Vx\x9a\xbc\xde\xff'
I don't understand why does the 3 vanished and was replaced by a 'V' after the 4 ! Sometime, my MCP2515 return some '|', '?', '.', '>', '<' or '=' when I print the can frames which are not hex characters !?
My hypothesis is that these are corrupted frames or SPI transmission.
Please, can someone help me to understand why micropython give me these messy results ?
Thank you very for your help.
I wrote something. Maybe not the best optimization possible, but I have to deal with micropython which is not as advanced than Python 3.x
This is a solution (surely not the most optimal). But it seems to work.
byte = b'\xFF\xC8\x56\x78\x9A\xBC\xDE\xFF'
byte2 = b'\x00\x00\x00#\x00\x00\x00\x00'
def extract(trame, signed:bool=False):
r = [0,0,0,0]
trame = [int(x) for x in bytearray(byte)]
for i in range(len(trame)/2):
val = (trame[i*2]<<8)+trame[i*2+1]
if signed and val > 0x8000 :
r[i] = -(65535-int(val)+1)
else :
r[i] = int(val)
return r
print(extract(byte, True))

bitwise operators in lua to create string

New user to LUA creating a protocol dissector for Wireshark.
referring to Lua - Bitwise Logical Operations,
I need a function in Lua to create a string based on a converted hex value:
local function HexToCircuitID(val)
-- input: 0x9D81
-- output: "630.1.01"
local e = ((val >> 4) & 0x3) + 1
local f = val & 0xF
local g = val >> 6
return string.format("%d.%d.%02d",e,f,g)
end
the interpreter has a problem with "unexpected symbol near '>' " for the first line with the right-shift operator.
Also, I'm not sure the string format function will operate the same as in C (new to Lua). This function is to create a ProtoField that appears as:
CircuitId: 630.1.01
where the actual value of the field is 0x9D81.
You can use bit.rshift(x, n) to right shift and bit.band(x1[,x2...]) to &.
The function then becomes:
local function HexToCircuitID(val)
-- input: 0x9D81
-- output: "630.1.01"
local e = bit.band(bit.rshift(val, 4), 0x3) + 1
local f = bit.band(val, 0xF)
local g = bit.rshift(val, 6)
--return string.format("%d.%d.%02d",e,f,g)
return string.format("%d.%d.%02d",g,f,e)
end
To get the order right I had to change e,f,g to g,f,e.
This will work in the latest version of Wireshark, which uses Lua 5.2. As Nifim mentioned, you have to use the bit library rather than bitwise operators, as they were introduced in Lua 5.3.

Call stack has exceeded maximum of depth of 100 ,Lua

function findWord(s,i)
-- find first word in given text
local j = i+1
while not _isWhite(s:byte(j)) and j < #s do -- getting error here
j = j + 1
end
return s:sub(i,j), j
end
function splitText(s,maxLen)
-- split text into chunks of maxLen length
rs ={}
local function _g(s,i,c,rs)
-- recursively split text
local function _f(s,i,c)
-- recursively find words and add each word to a chunk
local w,i = findWord(s,i)
if i == #s then return c..w end
if #(c..w) <= maxLen then
c = c..w
s = s:sub(i+1,#s,true)
return _f(s,1,c)
else
return c
end
end
rs[#rs+1] = _f(s,1,'')
i = i+#rs[#rs]
if i < #s then
local s = s:sub(i,#s,true)
return _g(s,1,'',rs)
else
return rs
end
end
return _g(s,1,'',rs)
end
I have above function to split a string, It has been working earlier but this time it started giving error "call stack has exceeded maximum of depth of 100, verify a function is not calling itself by accident."
Any idea why I might be getting this error, this behaviour seems random since I am quite sure about rest of the script and same split function has been working fine as well.
EDIT:
Yes, isWhiteSpace was provided to me and has the following code, I am not supposed to change it since it worked earlier . Here is isWhite function:
function _isWhite(byte)
return byte == 32 or byte == 9
end
So both _g and _f call themselves, and _g calls _f. So clearly the recursion-stop conditions you have are too weak. In _g I see
if i < #s then
local s = ...
return _g(s,1,'',rs)
else
return rs
end
which will stop when i >= #s. If this never happens, you will get infinite recursion. It is hard to say by looking at the code how i varies, but based on this line:
i = i+#rs[#rs]
it appears to by some value, but can't say if there is guarantee that stop condition will ever be reached. With _f it is worse: the stop recursion conditions are
if i == #s then return c..w end
and
#(c..w) > maxLen
Again very hard to say if this is strong enough: what if i is greater than #s, does the rest of the function work? Although findWord() returns i<#s for non empty s, not sure what will happen if s empty.
Best way to find out is to put some print statements that give you a trace of _g and _f and the parameters received, this will tell you clearly what stop conditions are being missed.

Hello metatable.__len world

A beginner's question about Lua and metatables, with a example as simple as an Hello‑World, involving the len event, which unfortunately does not returns the expected result (I'm using Lua 5.1 installed from Ubuntu's official repository).
The case
Here is the example:
Test_Type = {};
function Test_Type.__len (o)
return 1;
end;
function new_test ()
local result = {};
setmetatable(result, Test_Type);
return result;
end;
do
local a_test = new_test();
print (#a_test);
print(getmetatable(a_test).__len(a_test));
end;
And the result I get:
0
1
I was expecting the first print statement to display 1, but it displays 0, to my big surprise.
What did I missed?
According to Lua Reference Manual — Metatables and Metamethods, the # is equivalent to this:
function len_event (op)
if type(op) == "string" then
return strlen(op) -- primitive string length
else
local h = metatable(op).__len
if h then
return (h(op)) -- call handler with the operand
elseif type(op) == "table" then
return #op -- primitive table length
else -- no handler available: error
error(···)
end
end
end
So print (#a_test); and print(getmetatable(a_test).__len(a_test)); should result into the same, isn't it?
By the way, why is the above excerpt from the Reference Manual refers to metatable(op) while it should be getmetatable(op)? At least I've tried print(metatable(a_test).__len(a_test));, and it ends into an error.
Answer
As Nneonneo noticed, this is an issue with the Lua version in use. Lua 5.2 seems to be required for the above to work.
From http://lua-users.org/wiki/LuaFaq:
Why doesn't the __gc and __len metamethods work on tables?
__len on tables is scheduled to be supported in 5.2. See LuaFiveTwo.
Since you're using 5.1, __len on tables does not work. Indeed, running your code on Lua 5.2 produces
1
1
as expected.

How do I use the bitwise operator XOR in Lua?

How can I implement bitwise operators in Lua language?
Specifically, I need a XOR operator/method.
In Lua 5.2, you can use functions in bit32 library.
In Lua 5.3, bit32 library is obsoleted because there are now native bitwise operators.
print(3 & 5) -- bitwise and
print(3 | 5) -- bitwise or
print(3 ~ 5) -- bitwise xor
print(7 >> 1) -- bitwise right shift
print(7 << 1) -- bitwise left shift
print(~7) -- bitwise not
Output:
1
7
6
3
14
-8
In Lua 5.2, you can use the bit32.bxor function.
Since you're referencing the floor function 3 times, using an excessive number of loops for most operations (numbers less than 2^31 don't need all 31 loops), are using the ^ operator, and aren't capitalizing on the fact that a and b might be wildly different numbers with different magnitudes, you're losing a lot of efficiency. The function also isn't localized, and you're doing two more division operations than you need to. I wrote this to be reasonably fast.
In general, you're going to see improvements of about 3 to 20 times.
local function BitXOR(a,b)--Bitwise xor
local p,c=1,0
while a>0 and b>0 do
local ra,rb=a%2,b%2
if ra~=rb then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
if a<b then a=b end
while a>0 do
local ra=a%2
if ra>0 then c=c+p end
a,p=(a-ra)/2,p*2
end
return c
end
If you need more than this, say AND, OR, and NOT, then I've got you covered there, too.
local function BitOR(a,b)--Bitwise or
local p,c=1,0
while a+b>0 do
local ra,rb=a%2,b%2
if ra+rb>0 then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
return c
end
local function BitNOT(n)
local p,c=1,0
while n>0 do
local r=n%2
if r<1 then c=c+p end
n,p=(n-r)/2,p*2
end
return c
end
local function BitAND(a,b)--Bitwise and
local p,c=1,0
while a>0 and b>0 do
local ra,rb=a%2,b%2
if ra+rb>1 then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
return c
end
Don't worry, you won't need to change anything.
If you're needing an efficient way to do bitwise shifts, I wrote an article about that a while ago. Here's some functions which wrap the technique:
function lshift(x, by)
return x * 2 ^ by
end
function rshift(x, by)
return math.floor(x / 2 ^ by)
end
Try:
function xor(a,b)
return (a or b) and not (a and b)
end
From the OP; moved from question into this answer.
This is how I implemented XOR in Lua:
local floor = math.floor
function bxor (a,b)
local r = 0
for i = 0, 31 do
local x = a / 2 + b / 2
if x ~= floor (x) then
r = r + 2^i
end
a = floor (a / 2)
b = floor (b / 2)
end
return r
end
This is very simple. use NAND logic.
https://en.wikipedia.org/wiki/NAND_logic
function xor(a,b)
return not( not( a and not( a and b ) ) and not( b and not( a and b ) ) )
end
if you also need 1,0 inputs insert the following to the function
a = a==1 or a == true -- to accept nil, 1, 0, true or false
b = b==1 or b == true -- to accept nil, 1, 0, true or false
Hope this helps someone.

Resources