diff options
Diffstat (limited to 'nselib/nsedebug.lua')
-rw-r--r-- | nselib/nsedebug.lua | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/nselib/nsedebug.lua b/nselib/nsedebug.lua new file mode 100644 index 0000000..9effa39 --- /dev/null +++ b/nselib/nsedebug.lua @@ -0,0 +1,131 @@ +--- +-- Debugging functions for Nmap scripts. +-- +-- This module contains various handy functions for debugging. These should +-- never be used for actual results, only during testing. +-- +-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html + +local coroutine = require "coroutine" +local debug = require "debug" +local io = require "io" +local math = require "math" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +_ENV = stdnse.module("nsedebug", stdnse.seeall) + +local EMPTY = {}; -- Empty constant table + +--- +-- Converts an arbitrary data type into a string. Will recursively convert +-- tables. This can be very useful for debugging. +-- +--@param data The data to convert. +--@param indent (optional) The number of times to indent the line. Default +-- is 0. +--@return A string representation of a data, will be one or more full lines. +function tostr(data, indent) + local str + + if(indent == nil) then + indent = 0 + end + + -- Check the type + local typ = type(data) + if(typ == "nil" or typ == "number" or typ == "boolean" or typ == "function" or typ == "thread" or typ == "userdata") then + str = {(" "):rep(indent), tostring(data), "\n"} + elseif(type(data) == "string") then + str = {(" "):rep(indent), string.format("%q", data), "\n"} + elseif(type(data) == "table") then + local i, v + str = {} + for i, v in pairs(data) do + -- Check for a table in a table + str[#str+1] = (" "):rep(indent) + str[#str+1] = tostring(i) + if(type(v) == "table") then + str[#str+1] = ":\n" + str[#str+1] = tostr(v, indent + 2) + else + str[#str+1] = ": " + str[#str+1] = tostr(v, 0) + end + end + else + stdnse.debug1("Error: unknown data type: %s", type(data)) + end + + return table.concat(str) +end + +--- Print out a string in hex, for debugging. +-- +--@param str The data to print in hex. +function print_hex(str) + + -- Prints out the full lines + for line=1, #str/16, 1 do + io.write(string.format("%08x ", (line - 1) * 16)) + + -- Loop through the string, printing the hex + for char=1, 16, 1 do + local ch = string.byte(str, ((line - 1) * 16) + char) + io.write(string.format("%02x ", ch)) + end + + io.write(" ") + + -- Loop through the string again, this time the ascii + for char=1, 16, 1 do + local ch = string.byte(str, ((line - 1) * 16) + char) + if ch < 0x20 or ch > 0x7f then + ch = string.byte(".", 1) + end + io.write(string.format("%c", ch)) + end + + io.write("\n") + end + + -- Prints out the final, partial line + if (#str % 16 ~= 0) then + local line = math.floor((#str/16)) + 1 + io.write(string.format("%08x ", (line - 1) * 16)) + + for char=1, #str % 16, 1 do + local ch = string.byte(str, ((line - 1) * 16) + char) + io.write(string.format("%02x ", ch)) + end + io.write(string.rep(" ", 16 - (#str % 16))); + io.write(" ") + + for char=1, #str % 16, 1 do + local ch = string.byte(str, ((line - 1) * 16) + char) + if ch < 0x20 or ch > 0x7f then + ch = string.byte(".", 1) + end + io.write(string.format("%c", ch)) + end + + io.write("\n") + end + + -- Print out the length + io.write(string.format(" Length: %d [0x%x]\n", #str, #str)) + +end + +---Print out a stacktrace. The stacktrace will naturally include this function call. +function print_stack() + local thread = coroutine.running() + local trace = debug.traceback(thread); + if trace ~= "stack traceback:" then + print(thread, "\n", trace, "\n"); + end +end + + + +return _ENV; |