Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bdd7b9b

Browse filesBrowse files
author
Timo Schmid
committed
better unmarshalling with new types
1 parent f4a2c7f commit bdd7b9b
Copy full SHA for bdd7b9b

File tree

Expand file treeCollapse file tree

1 file changed

+51
-20
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+51
-20
lines changed
Open diff view settings
Collapse file

‎javaobj.py‎

Copy file name to clipboardExpand all lines: javaobj.py
+51-20Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,11 @@ def __init__(self, stream=None):
221221
self.TC_CLASSDESC: self.do_classdesc,
222222
self.TC_OBJECT: self.do_object,
223223
self.TC_STRING: self.do_string,
224+
self.TC_LONGSTRING: self.do_string_long,
224225
self.TC_ARRAY: self.do_array,
225226
self.TC_CLASS: self.do_class,
226227
self.TC_BLOCKDATA: self.do_blockdata,
228+
self.TC_BLOCKDATALONG: self.do_blockdata_long,
227229
self.TC_REFERENCE: self.do_reference,
228230
self.TC_ENUM: self.do_enum,
229231
self.TC_ENDBLOCKDATA: self.do_null, # note that we are reusing of do_null
@@ -234,6 +236,7 @@ def __init__(self, stream=None):
234236
self.object_stream = stream
235237
self._readStreamHeader()
236238
self.object_transformers = []
239+
self.data_left = True
237240

238241
def readObject(self):
239242
try:
@@ -244,8 +247,10 @@ def readObject(self):
244247
if len(the_rest):
245248
log_error("Warning!!!!: Stream still has %s bytes left. Enable debug mode of logging to see the hexdump." % len(the_rest))
246249
log_debug(self._create_hexdump(the_rest))
250+
self.data_left = True
247251
else:
248252
log_debug("Java Object unmarshalled succesfully!")
253+
self.data_left = False
249254
self.object_stream.seek(position_bak)
250255

251256
return res
@@ -275,11 +280,11 @@ def _readStruct(self, unpack):
275280
length = struct.calcsize(unpack)
276281
ba = self.object_stream.read(length)
277282
if len(ba) != length:
278-
raise RuntimeError("Stream has been ended unexpectedly while unmarshaling.")
283+
raise RuntimeError("Stream has been ended unexpectedly while unmarshaling. (%d vs %d)" % (len(ba), length))
279284
return struct.unpack(unpack, ba)
280285

281-
def _readString(self):
282-
(length, ) = self._readStruct(">H")
286+
def _readString(self, mod="H"):
287+
(length, ) = self._readStruct(">" + mod)
283288
ba = self.object_stream.read(length)
284289
return ba
285290

@@ -307,8 +312,9 @@ def do_classdesc(self, parent=None, ident=0):
307312
(serialVersionUID, newHandle, classDescFlags) = self._readStruct(">LLB")
308313
clazz.serialVersionUID = serialVersionUID
309314
clazz.flags = classDescFlags
315+
clazz.handle = newHandle
310316

311-
self._add_reference(clazz)
317+
self._add_reference(clazz, ident)
312318

313319
log_debug("Serial: 0x%X newHandle: 0x%X. classDescFlags: 0x%X" % (serialVersionUID, newHandle, classDescFlags), ident)
314320
(length, ) = self._readStruct(">H")
@@ -324,14 +330,14 @@ def do_classdesc(self, parent=None, ident=0):
324330

325331
if field_type == self.TYPE_ARRAY:
326332
opcode, field_type = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_STRING, self.TC_REFERENCE])
327-
assert type(field_type) is str
333+
assert type(field_type) is JavaString
328334
# if field_type is not None:
329335
# field_type = "array of " + field_type
330336
# else:
331337
# field_type = "array of None"
332338
elif field_type == self.TYPE_OBJECT:
333339
opcode, field_type = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_STRING, self.TC_REFERENCE])
334-
assert type(field_type) is str
340+
assert type(field_type) is JavaString
335341

336342
log_debug("FieldName: 0x%X" % typecode + " " + str(field_name) + " " + str(field_type), ident)
337343
assert field_name is not None
@@ -361,14 +367,22 @@ def do_blockdata(self, parent=None, ident=0):
361367
ba = self.object_stream.read(length)
362368
return ba
363369

370+
def do_blockdata_long(self, parent=None, ident=0):
371+
# TC_BLOCKDATALONG (int)<size> (byte)[size]
372+
log_debug("[blockdata]", ident)
373+
(length, ) = self._readStruct(">I")
374+
ba = self.object_stream.read(length)
375+
return ba
376+
377+
364378
def do_class(self, parent=None, ident=0):
365379
# TC_CLASS classDesc newHandle
366380
log_debug("[class]", ident)
367381

368382
# TODO: what to do with "(ClassDesc)prevObject". (see 3rd line for classDesc:)
369383
opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE])
370384
log_debug("Classdesc: %s" % classdesc, ident)
371-
self._add_reference(classdesc)
385+
self._add_reference(classdesc, ident)
372386
return classdesc
373387

374388
def do_object(self, parent=None, ident=0):
@@ -381,7 +395,7 @@ def do_object(self, parent=None, ident=0):
381395
opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE])
382396
# self.TC_REFERENCE hasn't shown in spec, but actually is here
383397

384-
self._add_reference(java_object)
398+
self._add_reference(java_object, ident)
385399

386400
# classdata[]
387401

@@ -430,7 +444,7 @@ def do_object(self, parent=None, ident=0):
430444
# Transform object
431445
for transformer in self.object_transformers:
432446
tmp_object = transformer.transform(java_object)
433-
if tmp_object != java_object:
447+
if tmp_object is not java_object:
434448
java_object = tmp_object
435449
break
436450

@@ -439,18 +453,24 @@ def do_object(self, parent=None, ident=0):
439453

440454
def do_string(self, parent=None, ident=0):
441455
log_debug("[string]", ident)
442-
ba = self._readString()
443-
self._add_reference(str(ba))
444-
return str(ba)
456+
ba = JavaString(self._readString())
457+
self._add_reference(ba, ident)
458+
return ba
459+
460+
def do_string_long(self, parent=None, ident=0):
461+
log_debug("[long string]", ident)
462+
ba = JavaString(self._readString("Q"))
463+
self._add_reference(ba, ident)
464+
return ba
445465

446466
def do_array(self, parent=None, ident=0):
447467
# TC_ARRAY classDesc newHandle (int)<size> values[size]
448468
log_debug("[array]", ident)
449469
opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE])
450470

451-
array = []
471+
array = JavaArray(classdesc)
452472

453-
self._add_reference(array)
473+
self._add_reference(array, ident)
454474

455475
(size, ) = self._readStruct(">i")
456476
log_debug("size: " + str(size), ident)
@@ -482,11 +502,14 @@ def do_null(self, parent=None, ident=0):
482502

483503
def do_enum(self, parent=None, ident=0):
484504
# TC_ENUM classDesc newHandle enumConstantName
485-
enum = JavaObject()
505+
enum = JavaEnum()
486506
opcode, classdesc = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_CLASSDESC, self.TC_PROXYCLASSDESC, self.TC_NULL, self.TC_REFERENCE])
487-
self._add_reference(enum)
507+
enum.classdesc = classdesc
508+
self._add_reference(enum, ident)
488509
opcode, enumConstantName = self._read_and_exec_opcode(ident=ident+1, expect=[self.TC_STRING, self.TC_REFERENCE])
489-
return enumConstantName
510+
511+
enum.constant = enumConstantName
512+
return enum
490513

491514
def _create_hexdump(self, src, length=16):
492515
FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])
@@ -500,6 +523,7 @@ def _create_hexdump(self, src, length=16):
500523

501524
def _read_value(self, field_type, ident, name = ""):
502525
if len(field_type) > 1:
526+
cls = field_type[1:]
503527
field_type = field_type[0] # We don't need details for arrays and objects
504528

505529
if field_type == self.TYPE_BOOLEAN:
@@ -518,7 +542,13 @@ def _read_value(self, field_type, ident, name = ""):
518542
elif field_type == self.TYPE_DOUBLE:
519543
(res, ) = self._readStruct(">d")
520544
elif field_type == self.TYPE_OBJECT or field_type == self.TYPE_ARRAY:
521-
opcode, res = self._read_and_exec_opcode(ident=ident+1)
545+
try:
546+
opcode, res = self._read_and_exec_opcode(ident=ident+1)
547+
except RuntimeError:
548+
if cls == 'java/lang/String;':
549+
res = JavaString(self._readString())
550+
else:
551+
raise
522552
else:
523553
raise RuntimeError("Unknown typecode: %s" % field_type)
524554
log_debug("* %s %s: " % (field_type, name) + str(res), ident)
@@ -534,14 +564,15 @@ def _convert_char_to_type(self, type_char):
534564
else:
535565
raise RuntimeError("Typecode %s (%s) isn't supported." % (type_char, typecode))
536566

537-
def _add_reference(self, obj):
567+
def _add_reference(self, obj, ident=0):
568+
log_debug('## New reference handle 0x%X' % (len(self.references) + self.BASE_REFERENCE_IDX,), ident)
538569
self.references.append(obj)
539570

540571
def _oops_dump_state(self):
541572
log_error("==Oops state dump" + "=" * (30 - 17))
542573
log_error("References: %s" % str(self.references))
543574
log_error("Stream seeking back at -16 byte (2nd line is an actual position!):")
544-
self.object_stream.seek(-16, mode=1)
575+
self.object_stream.seek(-16, 1)
545576
the_rest = self.object_stream.read()
546577
if len(the_rest):
547578
log_error("Warning!!!!: Stream still has %s bytes left." % len(the_rest))

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.