This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
H4X0RZ's profile picture

Kinda "scary" variables in _G

Started by H4X0RZ, 14 April 2015 - 02:28 PM
H4X0RZ #1
Posted 14 April 2015 - 04:28 PM
I found some stuff in _G which I can't really explain to myself.

Here is a "dump" I got from _G:
Spoiler

redstone table: 129c7ea8
gps table: 599b148b
_VERSION Luaj-jse 2.0.3
keys table: 675e5306
printError function: 1df967aa
peripheral table: 6ce13383
assert assert
getfenv function: 6ddf4dd8
bit table: 780ce506
rawset rawset
tonumber tonumber
loadstring loadstring
error error
tostring tostring
type type
coroutine table: 2e1e199a
disk table: 4b065af1
window table: 5c207fc4
next next
unpack unpack
colours table: 431b8593
pcall pcall
sleep function: 1d9796a3
loadfile function: 64bf9632
math table: 3b3e0b3e
pairs pairs
fs table: 249636d7
rawget rawget
_G table: 5159e68
__inext __inext
read function: 1d0386fe
rednet table: 562f099b
ipairs ipairs
xpcall xpcall
os table: 439abd07
help table: 6a558dc2
io table: 6be0c200
rawequal rawequal
setfenv setfenv
rs table: 129c7ea8
http table: 452d6d36
write function: 53c99211
string table: 15342e37
setmetatable setmetatable
print function: 78291e53
getmetatable function: 564398bd
table table: 4985c17e
parallel table: 7d741bef
dofile function: 4d1f5994
textutils table: 753a6fa
term table: 60ba095f
colors table: 3d4cddc4
vector table: a28e000
select select
paintutils table: 1056f3c9

And these are the things I'm talking about:
Spoiler

assert assert
rawset rawset
tonumber tonumber
loadstring loadstring
error error
tostring tostring
type type
next next
unpack unpack
pcall pcall
pairs pairs
rawget rawget
_G table: 5159e68
__inext __inext
ipairs ipairs
xpcall xpcall
rawequal rawequal
setfenv setfenv
setmetatable setmetatable
select select

So, here are my questions:
  • Why are many of these functions only strings in _G?
  • Why does _G have a reference to itself? And why is this reference infinite?
  • what is "select" and "__inext"?
Edited on 14 April 2015 - 02:30 PM
valithor #2
Posted 14 April 2015 - 04:40 PM
Although I am unable to explain why they look like they are just strings, they are actually the functions. From what I understand it appears functions defined in the bios or in java appear like that, but ones loaded through os.loadAPI are normal.

for select : http://emmanueloga.com/2010/12/09/lua-select.html

I would assume _G would contain a reference to itself due to the fact anytime something is declared it is placed into the global environment, and thus _G. Since _G is a table it falls under this and would be placed within itself. The reference appears to be infinite because you are accessing the same table within itself over and over.

edit:

Someone else probably can and will come and explain it much better than I can with my limited experience.
Edited on 14 April 2015 - 02:41 PM
SquidDev #3
Posted 14 April 2015 - 04:51 PM
There was a similar question here. All built in functions (LuaJ but not CC) produce the name of the function when you tostring them. valithor is correct with his explanation for _G - its a global, so should be in the global environment, otherwise you wouldn't be able to access it at all.
Edited on 14 April 2015 - 02:53 PM
KingofGamesYami #4
Posted 14 April 2015 - 04:58 PM
If you want to know how _G does it, it's metatables. I did it to my own table once, just to figure it out.


local tbl = {}
tbl.tbl = setmetatable( {}, {__index = tbl}
H4X0RZ #5
Posted 14 April 2015 - 05:02 PM
There was a similar question here. All built in functions (LuaJ but not CC) produce the name of the function when you tostring them. valithor is correct with his explanation for _G - its a global, so should be in the global environment, otherwise you wouldn't be able to access it at all.
Although I am unable to explain why they look like they are just strings, they are actually the functions. From what I understand it appears functions defined in the bios or in java appear like that, but ones loaded through os.loadAPI are normal.

for select : http://emmanueloga.c...lua-select.html

I would assume _G would contain a reference to itself due to the fact anytime something is declared it is placed into the global environment, and thus _G. Since _G is a table it falls under this and would be placed within itself. The reference appears to be infinite because you are accessing the same table within itself over and over.

edit:

Someone else probably can and will come and explain it much better than I can with my limited experience.

Thanks for the help!

But what would happen if I replace _G? like completely overwrite it? will this cause everything to break, or do I have a "clean" environment then, and I could still do stuff with lua?
HDeffo #6
Posted 14 April 2015 - 05:06 PM
__inext is actually the iterator function. For example when you do ipairs(exampleTable) it will return the __inext function with the table of data it will return this way your for loop will keep running the function __inext and each time it returns the next item in the table
ardera #7
Posted 14 April 2015 - 05:20 PM
Built-in functions return their name instead of their memory address for safety and compatability reasons. In C lua, maybe one could modify the RAM directly and insert code at a specific memory address. But if you don't have the memory address you can't insert code. Also, maybe it's for identification reasons, like if you want to be completely sure that you have the original assert function, you can simply do tostring(assert)=="assert".

Your environment would stay the same. You wouldn't be able to access _G anymore, and every program or function would have problems accessing _G. Programs wouldn't be able to run (because os.run uses _G), and many other things would crash.
H4X0RZ #8
Posted 14 April 2015 - 05:27 PM
Built-in functions return their name instead of their memory address for safety and compatability reasons. In C lua, maybe one could modify the RAM directly and insert code at a specific memory address. But if you don't have the memory address you can't insert code. Also, maybe it's for identification reasons, like if you want to be completely sure that you have the original assert function, you can simply do tostring(assert)=="assert".

Your environment would stay the same. You wouldn't be able to access _G anymore, and every program or function would have problems accessing _G. Programs wouldn't be able to run (because os.run uses _G), and many other things would crash.

os.run is not much more than a combination of loadstring-ing a file and setting it's environment.

So, if I don't know the memory address of these functions, would there be a way to blindly set every address to nil?
Edited on 14 April 2015 - 03:27 PM
flaghacker #9
Posted 14 April 2015 - 08:59 PM
Yes, you can set them to nil by looping throught _G, but this wil break almost every program, including CraftOS itself.

Why do you want a "clean"/broken environment?
Edited on 14 April 2015 - 06:59 PM
ardera #10
Posted 16 April 2015 - 09:51 PM
So, if I don't know the memory address of these functions, would there be a way to blindly set every address to nil?
Apart from the fact that I don't even really know if it's possible to set rawly set memory, I think there is one. But it would take a very long time to do this.
Someone told me it's possible to do this in CC, but I don't think so.
H4X0RZ #11
Posted 17 April 2015 - 04:42 PM
Yes, you can set them to nil by looping throught _G, but this wil break almost every program, including CraftOS itself.

Why do you want a "clean"/broken environment?

Just because it's cool to do it :P/>

So, if I don't know the memory address of these functions, would there be a way to blindly set every address to nil?
Apart from the fact that I don't even really know if it's possible to set rawly set memory, I think there is one. But it would take a very long time to do this.
Someone told me it's possible to do this in CC, but I don't think so.

I once heard that someone was able to inject java code, but I'm not sure if it is possible (anymore).
flaghacker #12
Posted 17 April 2015 - 04:50 PM
I once heard that someone was able to inject java code, but I'm not sure is possible (anymore).

I highly doubt it. There are often people on this forum seeking attention by claiming they found some "crazy hackers exploit" in computercraft, usually without any details.

Edit:
And "injecting java code" seems completely inrealistic to me, as java code has to be compiled before it can run.
Edited on 17 April 2015 - 02:52 PM
H4X0RZ #13
Posted 17 April 2015 - 05:17 PM
I once heard that someone was able to inject java code, but I'm not sure is possible (anymore).

I highly doubt it. There are often people on this forum seeking attention by claiming they found some "crazy hackers exploit" in computercraft, usually without any details.

Edit:
And "injecting java code" seems completely inrealistic to me, as java code has to be compiled before it can run.

True.

What if I flood _G until the memory is full?
Lyqyd #14
Posted 17 April 2015 - 05:36 PM
Nothing exciting will happen, you'll just run Minecraft to its memory limit and it'll get rather sluggish, maybe non-responsive eventually. I'm not sure why you'd want to do that. It sounds like you're starting to take this topic in a malicious direction, which I would discourage. I'd rather not have to lock it.
H4X0RZ #15
Posted 17 April 2015 - 06:25 PM
Nothing exciting will happen, you'll just run Minecraft to its memory limit and it'll get rather sluggish, maybe non-responsive eventually. I'm not sure why you'd want to do that. It sounds like you're starting to take this topic in a malicious direction, which I would discourage. I'd rather not have to lock it.

Sorry if I'm taking this topic in a malicous direction. All I want to do is experiment with CC and Lua. I want to, well, get an "as-clean-as-possible" environment, so I can try to implement a custom "system". When there are artifacts of CraftOS, some user could maybe abuse this, to bypass said system. Yes, I know this "a diskdrive can break everything stuff.

I actually got an idea. If I make a local copy of _G (well, I think I'll need some stuff from here some time :D/>), then clear _G, and than overwrite every function/variable I don't want with ""/a clean function, a user I "put" into this environment shouldn't be able to access said functions.
flaghacker #16
Posted 17 April 2015 - 06:39 PM
What function are you talking about? Almost every function CAN be used maliciously…
H4X0RZ #17
Posted 17 April 2015 - 06:43 PM
What function are you talking about? Almost every function CAN be used maliciously…

I'm not talking about a specific function. I'm talking about overwriting functions (at said before, I don't mean a specific function) so it acts differently. I want this overwrite to be global, and irreversible (as in, until the next reboot). That means that said functions can't be modified either (you know, a read only table).
flaghacker #18
Posted 17 April 2015 - 06:45 PM
You'll have to use metatables if you want them to be unoverridable.
AgentE382 #19
Posted 19 April 2015 - 12:33 AM
Tru dat. It's a pretty neat experiment to create an unwritable table.

Real quick, there is a top-level override that clears out CraftOS and lets you run code with only bios.lua as a base. I'll find where it is on the forums again later.