Alakazard12

Reverse GPS Client

Dec 29th, 2015
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.07 KB | None | 0 0
  1. local cChannel = 15150
  2.  
  3. local tArgs = {...}
  4.  
  5. local function transmit(channel, reply, message)
  6.     local modem = peripheral.find("modem")
  7.     if modem then
  8.         modem.transmit(channel, reply, message)
  9.     end
  10. end
  11.  
  12. local function openChannel(channel)
  13.     for i,v in pairs(peripheral.getNames()) do
  14.         if peripheral.getType(v) == "modem" then
  15.             peripheral.call(v, "open", channel)
  16.         end
  17.     end
  18.  
  19.     transmit(cChannel, 0, {
  20.         openChannel = true;
  21.         channel = channel;
  22.     })
  23. end
  24.  
  25. local function closeChannel(channel)
  26.     for i,v in pairs(peripheral.getNames()) do
  27.         if peripheral.getType(v) == "modem" then
  28.             peripheral.call(v, "close", channel)
  29.         end
  30.     end
  31.  
  32.     transmit(cChannel, 0, {
  33.         closeChannel = true;
  34.         channel = channel;
  35.     })
  36. end
  37.  
  38. local function update(what)
  39.     what = what or "all"
  40.     if what == "gps" or what == "all" then
  41.         local res = http.get("http://pastebin.com/raw/MNBLDRZK")
  42.         transmit(cChannel, 0, {
  43.             update = true;
  44.             source = res.readAll();
  45.         })
  46.         print("updated gps")
  47.     end
  48.  
  49.     if what == "client" or what == "all" then
  50.         local file = fs.open(shell.getRunningProgram(), "w")
  51.         local res = http.get("http://pastebin.com/raw/ehejuAyW")
  52.         file.write(res.readAll())
  53.         file.close()
  54.         print("updated client")
  55.     end
  56.  
  57.     if what == "api" or what == "all" then
  58.         local file = fs.open("/gapi", "w")
  59.         local res = http.get("http://pastebin.com/raw/5BRyXSRg")
  60.         file.write(res.readAll())
  61.         file.close()
  62.         print("updated api")
  63.     end
  64. end
  65.  
  66. local function closeAll()
  67.     for i,v in pairs(peripheral.getNames()) do
  68.         if peripheral.getType(v) == "modem" then
  69.             peripheral.call(v, "closeAll")
  70.         end
  71.     end
  72.  
  73.     transmit(cChannel, 0, {
  74.         closeAll = true;
  75.     })
  76. end
  77.  
  78. local function transmitRequest(channel, reply, id)
  79.     transmit(cChannel, 0, {
  80.         getDistance = true;
  81.         channel = channel;
  82.         reply = reply;
  83.         id = id;
  84.     })
  85. end
  86.  
  87. for i,v in pairs(peripheral.getNames()) do
  88.     if peripheral.getType(v) == "modem" then
  89.         peripheral.call(v, "open", cChannel)
  90.     end
  91. end
  92.  
  93. local defaultColor = colors.white
  94. local function log(...)
  95.     local str = ""
  96.     local text = {...}
  97.     term.setTextColor(defaultColor)
  98.     for _,val in ipairs(text) do
  99.         if type(val) == "number" then
  100.             term.setTextColor(val)
  101.         else
  102.             str = str .. tostring(val)
  103.             write(val)
  104.         end
  105.     end
  106.     term.setTextColor(defaultColor)
  107.  
  108.     local file = fs.open("log", "a")
  109.     file.writeLine(str)
  110.     file.close()
  111. end
  112.  
  113. os.loadAPI("gapi")
  114.  
  115. if tArgs[1] == "open" then
  116.     local channel = tonumber(tArgs[2] or rednet.CHANNEL_BROADCAST) or rednet.CHANNEL_BROADCAST
  117.  
  118.     local file = fs.open("channels", "r")
  119.     local chans = {}
  120.     if file then
  121.         chans = textutils.unserialize(file.readAll())
  122.         if type(chans) ~= "table" then
  123.             chans = {}
  124.         end
  125.         file.close()
  126.     end
  127.  
  128.     table.insert(chans, channel)
  129.     file = fs.open("channels", "w")
  130.     file.write(textutils.serialize(chans))
  131.     file.close()
  132.  
  133.     return
  134. elseif tArgs[1] == "close" then
  135.     local channel = tonumber(tArgs[2] or rednet.CHANNEL_BROADCAST) or rednet.CHANNEL_BROADCAST
  136.     closeChannel(channel)
  137.  
  138.     local file = fs.open("channels", "r")
  139.     local chans = {}
  140.     if file then
  141.         chans = textutils.unserialize(file.readAll())
  142.         if type(chans) ~= "table" then
  143.             chans = {}
  144.         end
  145.         file.close()
  146.     end
  147.    
  148.     local toRemove = {}
  149.     for i, chan in ipairs(chans) do
  150.         if chans[i] == channel then
  151.             table.insert(toRemove, 1, i)
  152.         end
  153.     end
  154.     for _,i in ipairs(toRemove) do
  155.         table.remove(chans, i)
  156.     end
  157.     file = fs.open("channels", "w")
  158.     file.write(textutils.serialize(chans))
  159.     file.close()
  160.     return
  161. elseif tArgs[1] == "closeAll" then
  162.     closeAll()
  163.     file = fs.open("channels", "w")
  164.     file.write(textutils.serialize("{}"))
  165.     file.close()
  166.     return
  167. elseif tArgs[1] == "update" then
  168.     update(tArgs[2])
  169.     return
  170. end
  171.  
  172. local replies = {}
  173. local repeated = {}
  174. local queue = {}
  175.  
  176. local p1, p2
  177. local wId
  178.  
  179. local timer
  180. local running = true
  181.  
  182. local chatNicks = {}
  183.  
  184. local protocolHandlers = {
  185.     ["dns"] = function(channel, reply, message)
  186.         local msg = message.message
  187.         local str
  188.         if type(msg) == "table" then
  189.             if msg.sType == "lookup" then
  190.                 str = "(lookup) protocol: " .. tostring(msg.sProtocol) .. ". hostname: " .. tostring(msg.sHostname)
  191.             elseif msg.sType == "lookup response" then
  192.                 str = "(lookup response) protocol: " .. tostring(msg.sProtocol) .. ". hostname: " .. tostring(msg.sHostname)
  193.             else
  194.                 str = textutils.serialize(msg)
  195.             end
  196.         end
  197.         log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (dns) ", colors.white, str)
  198.     end;
  199.  
  200.     ["chat"] = function(channel, reply, message)
  201.         local msg = message.message
  202.  
  203.         local str = ""
  204.         if type(msg) == "table" then
  205.             if msg.sType == "ping to client" then
  206.                 return true
  207.                 -- str = "ping to client (user id " .. msg.nUserID .. ")"
  208.             elseif msg.sType == "pong to client" then
  209.                 return true
  210.                 -- str = "pong to client (user id " .. msg.nUserID .. ")"
  211.             elseif msg.sType == "ping to server" then
  212.                 return true
  213.                 -- str = "ping to server (user id " .. msg.nUserID .. ")"
  214.             elseif msg.sType == "pong to server" then
  215.                 return true
  216.                 -- str = "pong to server (user id " .. msg.nUserID .. ")"
  217.             elseif msg.sType == "text" then
  218.                 str = msg.sText
  219.             elseif msg.sType == "chat" and msg.sText then
  220.                 if chatNicks[message.nRecipient] and chatNicks[message.nRecipient][msg.nUserID] then
  221.                     str = "(" .. chatNicks[message.nRecipient][msg.nUserID] .. ") "
  222.                 end
  223.                 str = str .. msg.sText
  224.             elseif msg.sType == "kick" then
  225.                 if chatNicks[message.nRecipient] and chatNicks[message.nRecipient][msg.nUserID] then
  226.                     str = "(" .. chatNicks[message.nRecipient][msg.nUserID] .. ") "
  227.                 end
  228.                 str = str .. "kick (user id " .. tostring(msg.nUserID) .. ")"
  229.             elseif msg.sType == "logout" then
  230.                 if chatNicks[message.nRecipient] and chatNicks[message.nRecipient][msg.nUserID] then
  231.                     str = "(" .. chatNicks[message.nRecipient][msg.nUserID] .. ") "
  232.                     chatNicks[message.nRecipient][msg.nUserID] = nil
  233.                 end
  234.                 str = str .. "logout (user id " .. tostring(msg.nUserID) .. ")"
  235.             elseif msg.sType == "login" then
  236.                 if not chatNicks[message.nRecipient] then
  237.                     chatNicks[message.nRecipient] = {}
  238.                 end
  239.  
  240.                 chatNicks[message.nRecipient][msg.nUserID] = msg.sUsername
  241.                 str = "login " .. msg.sUsername .. " (user id " .. msg.nUserID .. ")"
  242.             else
  243.                 str = textutils.serialize(msg)
  244.             end
  245.         end
  246.  
  247.         log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (chat) ", colors.white, str)
  248.     end;
  249. }
  250.  
  251. local function requestPos(channel, reply)
  252.     p1, p2 = nil, nil
  253.     wId = math.random()
  254.     replies = {}
  255.  
  256.     transmitRequest(channel, reply, wId)
  257.     timer = os.startTimer(1)
  258. end
  259.  
  260. local function discardPos(channel, reply)
  261.     transmit(cChannel, 0, {
  262.         discard = true;
  263.         channel = channel;
  264.         reply = reply;
  265.     })
  266. end
  267.  
  268. local function handleMessage(channel, reply, message)
  269.     local logged = false
  270.     if type(message) == "table" then
  271.         if message.nRecipient and message.message and message.nMessageID then -- rednet
  272.             if not repeated[message.nMessageID] or repeated[message.nMessageID] <= os.clock() - 3 then
  273.                 repeated[message.nMessageID] = os.clock()
  274.                 if message.sProtocol and protocolHandlers[message.sProtocol] then
  275.                     if not protocolHandlers[message.sProtocol](channel, reply, message) then
  276.                         requestPos(channel, reply)
  277.                     else
  278.                         discardPos(channel, reply)
  279.                     end
  280.                 elseif channel == 65535 then -- broadcast
  281.                     log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (broadcast) ", colors.white, textutils.serialize(message.message))
  282.                     requestPos(channel, reply)
  283.                 elseif channel == 65533 then -- repeater
  284.                     log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (repeat) ", colors.white, "(hidden)") -- .. textutils.serialize(message.message))
  285.                     requestPos(channel, reply)
  286.                 else
  287.                     log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (send) ", colors.white, textutils.serialize(message.message))
  288.                     requestPos(channel, reply)
  289.                 end
  290.             else
  291.                 discardPos(channel, reply)
  292.             end
  293.             logged = true
  294.         elseif #message == 3 and reply == 65534 then -- gps
  295.             log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.cyan, " (gps) ", colors.white, "(" .. message[1] .. ", " .. message[2] .. ", " .. message[3] .. ")")
  296.             logged = true
  297.             requestPos(channel, reply)
  298.         end
  299.     elseif channel == 65534 and message == "PING" then
  300.         log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.cyan, " (gps) ", colors.white, message)
  301.         logged = true
  302.         requestPos(channel, reply)
  303.     end
  304.     if not logged then
  305.         log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " " .. textutils.serialize(message))
  306.         requestPos(channel, reply)
  307.     end
  308. end
  309.  
  310. local function locationFound(p)
  311.     log(colors.orange, " (" .. p:tostring() .. ")\n")
  312.     p1, p2 = nil, nil
  313.     replies = {}
  314.     timer = nil
  315.     wId = nil
  316. end
  317.  
  318. local monitor = peripheral.find("monitor")
  319. if monitor then
  320.     term.redirect(monitor)
  321.     monitor.setTextScale(0.5)
  322. end
  323.  
  324. term.setBackgroundColor(colors.gray)
  325. term.clear()
  326. term.setCursorPos(1, 1)
  327.  
  328. transmit(cChannel, 0, {
  329.     clear = true;
  330. })
  331.  
  332. local channels
  333.  
  334. do
  335.     channels = {}
  336.     local file = fs.open("channels", "r")
  337.     if file then
  338.         channels = textutils.unserialize(file.readAll())
  339.         if type(channels) ~= "table" then
  340.             channels = {}
  341.         end
  342.         file.close()
  343.     end
  344.  
  345.     for _, channel in ipairs(channels) do
  346.         openChannel(channel)
  347.     end
  348. end
  349.  
  350. log("Started sniffer\n")
  351.  
  352. while running do
  353.     local success, err = pcall(function()
  354.         if #queue ~= 0 and not timer then
  355.             handleMessage(table.unpack(queue[1]))
  356.             table.remove(queue, 1)
  357.         end
  358.         local event, side, channel, reply, message, distance = os.pullEventRaw()
  359.         if event == "modem_message" then
  360.             if channel == cChannel and reply == 1 and type(message) == "table" then
  361.                 if message[3] == wId then
  362.                     table.insert(replies, {
  363.                         vPosition = vector.new(message[1][1], message[1][2], message[1][3]);
  364.                         nDistance = message[2];
  365.                     })
  366.                     if not p1 and #replies >= 3 then
  367.                         p1, p2 = gapi.trilaterate(replies[1], replies[2], replies[#replies])
  368.                         if p1 and not p2 then
  369.                             locationFound(p1)
  370.                         elseif p1 and p2 then
  371.                             table.remove(replies, 1)
  372.                             table.remove(replies, 1)
  373.                             table.remove(replies, #replies)
  374.  
  375.                             local toRemove = {}
  376.                             if #replies ~= 0 then
  377.                                 for i, reply in ipairs(replies) do
  378.                                     p1, p2 = gapi.narrow(p1, p2, reply)
  379.                                     if not p2 then
  380.                                         locationFound(p1)
  381.                                         break
  382.                                     end
  383.                                 end
  384.                             end
  385.  
  386.                             replies = {}
  387.                         end
  388.                     elseif p1 and p2 then
  389.                         p1, p2 = gapi.narrow(p1, p2, replies[1])
  390.                         table.remove(replies, 1)
  391.                         if not p2 then
  392.                             locationFound(p1)
  393.                         end
  394.                     end
  395.                 end
  396.             else
  397.                 if not timer then
  398.                     handleMessage(channel, reply, message)
  399.                 else
  400.                     table.insert(queue, {channel, reply, message})
  401.                 end
  402.             end
  403.         elseif event == "timer" and side == timer then
  404.             if p1 then
  405.                 log(colors.orange, " (" .. p1:tostring() .. ") or (" .. p2:tostring() .. ")\n")
  406.             else
  407.                 log(colors.orange, " Could not determine position\n")
  408.             end
  409.             timer = nil
  410.             if #queue ~= 0 then
  411.                 handleMessage(table.unpack(queue[1]))
  412.                 table.remove(queue, 1)
  413.             end
  414.         elseif event == "key" then
  415.             if side == keys.q then
  416.                 os.pullEvent("char")
  417.                 running = false
  418.             end
  419.         elseif event == "peripheral" then
  420.             if peripheral.getType(side) == "modem" then
  421.                 for _,channel in pairs(channels) do
  422.                     peripheral.call(side, "open", channel)
  423.                 end
  424.                 peripheral.call(side, "open", cChannel)
  425.             end
  426.         end
  427.     end)
  428.  
  429.     if not success then
  430.         log(colors.red, "Error: " .. err .. "\n")
  431.     end
  432. end
Add Comment
Please, Sign In to add comment