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

Searching For Key Words In Strings

Started by jay5476, 24 July 2013 - 03:31 AM
jay5476 #1
Posted 24 July 2013 - 05:31 AM
Hi computercraft users, i was wondering how to search for key words in string or file for an anti-virus program's so if it found an fs.delete() or other things in the file it would be classified as dangerous. Explanation of how it works would be appreciated
Kingdaro #2
Posted 24 July 2013 - 05:57 AM
You can use either string.find, or string.match.

string.find returns the start and end position at which the word was found.

local str = 'hello world'
print(str:find('world')) --> 7 12

string.match returns the actual word.

local str = 'hello world'
print(str:match('world')) --> world
theoriginalbit #3
Posted 24 July 2013 - 06:07 AM
Since an answer has been posted, I'll cover another issue…

Sadly an anti-virus is a very difficult thing to do with just keyword searching. There are two problems with them.

The first:
SpoilerIf you were to search for "fs.delete"


if string.find(fileContents, "fs.delete") then
  print("You have fs.delete")
end

this is all well and good if someone has the following code

fs.delete("some file")

however it is also bypassed easy, let me list a few ways to bypass it
  • fs["delete"]
  • fs['delete']
  • _G["fs"].delete
  • _G['fs'].delete
  • _G["fs"]["delete"]
  • _G["_G"]["fs"].delete
  • _G._G["fs"].delete
I hope what I'm trying to get at here is coming through, there are lots of ways you can call things from tables, and the fact that _G is stored inside itself, means that it could be infinitely bypassed (_G._G._G._G._G._G._G._G._G._G._G["fs"]["delete"])… it is just way too hard to account for these…

The second problem with checking for keywords;
Spoilerwell, not all programs with those keywords are malicious. for example I've had many a script that is an installer/updater, so it will delete some files when they're no longer needed.

So you cannot automatically assume that a certain keyword is being used for malicious intent

The easiest method of checking for malicious code is to setup an empty environment, where a program is run inside that environment (where it doesn't actually do anything) and when those `malicious` calls are made you will be able to detect them without them having bad side effects. Using this method no matter how they call it (fs.delete, fs["delete"], etc) it would be detected… however this solution is quite advanced and also still contains the issue with not all keywords are used for malicious intent…

In summary, the best way is if you're making an OS to have an antivirus which prevents modification (and detects attempts of modification) of the key OS files and/or APIs and then flags a warning to that file. Short of making it for your own very specific OS an antivirus can just be too problematic.
jay5476 #4
Posted 24 July 2013 - 07:27 AM
If say i wanted a search files would a simple program like
 
files = ("/")
For i = 1, #file do
If (file[i]:match("my search ") == true) then
Print(file[i])
Sleep(0.001)
End
End
Basiclly i want to test if that result comes up true and print the full result can i put the code and then == true or do i have to do something else
LBPHacker #5
Posted 24 July 2013 - 04:18 PM
Nah. A simple table like files = {"/"} doesn't contain anything apart from the first index which is a string. (The "/") But fs.list (which lists the files in a directory) indeed returns a table which contains the names of the files (not the absolulte path, just the names).
local directory = "/"
local files = fs.list(directory)
local filter = "o"

local result = {}
for ixFile = 1, #files do if files[ixFile]:find(filter) then table.insert(result, files[ixFile]) end end
result will contain every filename in the directory that contains the filter.

BTW: You can check if an entry in the files table is a directory or not:
if fs.isDir(fs.combine(directory, files[ixFile])) then
    -- do something
end
jay5476 #6
Posted 24 July 2013 - 05:57 PM
okay thanks it was late at night and I meant to do fs.list("/") ill try out different things and also one more question, is it possible to get all strings that are global in my program
LBPHacker #7
Posted 24 July 2013 - 06:02 PM
get all strings that are global in my program
After reading that part three times, I've come to this:
local globalStrings = {}
for key, value in pairs(getfenv()) do if type(value) == "string" then globalStrings[key] = value end end
Though - based on the topic - I would be really surprised if you wanted this…
albrat #8
Posted 24 July 2013 - 06:05 PM
local directory = "/"
local files = fs.list(directory)
local filter = "o"

local result = {}
for ixFile = 1, #files do if files[ixFile]:find(filter) then table.insert(result, files[ixFile]) end end
result will contain every filename in the directory that contains the filter.

BTW: You can check if an entry in the files table is a directory or not:
if fs.isDir(fs.combine(directory, files[ixFile])) then
	-- do something
end

local directory = "/"
local files = fs.list(directory)
local filter = "o"

local result = {}
for ixFile = 1, #files do
  for search = 1, #searchtable do   -- new for loop to check the table of search items
	if files[ixFile]:find(searchtable[search]) then  -- check against sarchtable (all entries) per file.
	  table.insert(result, files[ixFile])
	end
  end
end

You would have to define your table searchtable = { "delete", "move", "rn", "DELETE"; } etc…
LBPHacker #9
Posted 24 July 2013 - 06:16 PM
-snip-
Was writing that snippet with another topic in mind, sorry. But your snippet isn't better than mine, since it still doesn't answer the question in the OP - though it allows the user to search for multiple files. (Actually I thought you want to search for invidual files by their names applying a filter…)

About the antivirus: SANDBOX IT! Bit has already explained how it'd work.