@@ -23,6 +23,7 @@ class JavaObjectMarshaller:
2323 STREAM_MAGIC = 0xaced
2424 STREAM_VERSION = 0x05
2525
26+ TC_NULL = 0x70
2627 TC_REFERENCE = 0x71
2728 TC_CLASSDESC = 0x72
2829 TC_OBJECT = 0x73
@@ -41,16 +42,18 @@ class JavaObjectMarshaller:
4142
4243 def __init__ (self , stream ):
4344 self .opmap = {
44- self .TC_CLASSDESC : self .do_classdesc ,
45- self .TC_OBJECT : self .do_object ,
46- self .TC_STRING : self .do_string ,
47- self .TC_CLASS : self .do_class ,
48- self .TC_BLOCKDATA : self .do_blockdata ,
49- self .TC_REFERENCE : self .do_reference
45+ self .TC_NULL : self .do_null ,
46+ self .TC_CLASSDESC : self .do_classdesc ,
47+ self .TC_OBJECT : self .do_object ,
48+ self .TC_STRING : self .do_string ,
49+ self .TC_CLASS : self .do_class ,
50+ self .TC_BLOCKDATA : self .do_blockdata ,
51+ self .TC_REFERENCE : self .do_reference
5052 }
5153 self .object_stream = stream
5254 self ._readStreamHeader ()
5355 self .finalValue = True
56+ self .current_object = None
5457
5558 def _readStreamHeader (self ):
5659 (magic , version ) = self ._readStruct (">HH" , 4 )
@@ -60,8 +63,13 @@ def _readStreamHeader(self):
6063 def readObject (self ):
6164 (opid , ) = self ._readStruct (">B" , 1 )
6265 print "OpCode: 0x%X" % opid
63- self .opmap .get (opid , self .do_default_stuff )()
64- return self .finalValue
66+ res = self .opmap .get (opid , self .do_default_stuff )()
67+ return res
68+
69+ def read_and_exec_opcode (self ):
70+ (opid , ) = self ._readStruct (">B" , 1 )
71+ print "OpCode: 0x%X" % opid
72+ return self .opmap .get (opid , self .do_default_stuff )()
6573
6674 def _readStruct (self , unpack , length ):
6775 ba = self .object_stream .read (length )
@@ -80,58 +88,95 @@ def do_classdesc(self, parent=None):
8088 # (byte) // Defined in Terminal Symbols and Constants
8189 # fields:
8290 # (short)<count> fieldDesc[count]
83-
91+
8492 # fieldDesc:
8593 # primitiveDesc
8694 # objectDesc
8795 # primitiveDesc:
8896 # prim_typecode fieldName
8997 # objectDesc:
9098 # obj_typecode fieldName className1
99+ class JavaClass (object ):
100+ def __init__ (self ):
101+ self .name = None
102+ self .serialVersionUID = None
103+ self .flags = None
104+ self .fields_names = []
105+ self .fields_types = []
106+
107+ def __str__ (self ):
108+ return "[%s:0x%X]" % (self .name , self .serialVersionUID )
109+
110+ clazz = JavaClass ()
91111 print "[classdesc]"
92112 ba = self ._readString ()
113+ clazz .name = ba
93114 print "Class name:" , ba
94115 (serialVersionUID , newHandle , classDescFlags ) = self ._readStruct (">LLB" , 4 + 4 + 1 )
116+ clazz .serialVersionUID = serialVersionUID
117+ clazz .flags = classDescFlags
95118 print "Serial: 0x%X newHanle: 0x%X. classDescFlags: 0x%X" % (serialVersionUID , newHandle , classDescFlags )
96119 (length , ) = self ._readStruct (">H" , 2 )
97120 print "Fields num: 0x%X" % length
98121
99- fields_vals = []
100- fields_type = []
122+ fields_names = []
123+ fields_types = []
101124 for fieldId in range (length ):
102125 (type , ) = self ._readStruct (">B" , 1 )
103126 ba = self ._readString ()
104127 print "FieldType: 0x%X" % type , ba
105128 (opid , ) = self ._readStruct (">B" , 1 )
106129 print "OpCode: 0x%X" % opid
107130 res = self .opmap .get (opid , self .do_default_stuff )()
108- fields_vals .append (res )
109- fields_type .append (type )
131+ fields_names .append (ba )
132+ fields_types .append (res )
110133 if parent :
111- parent .__setattr__ ("__fields" , fields_vals )
112- parent .__setattr__ ("__types" , fields_types )
134+ parent .__fields = fields_names
135+ parent .__types = fields_types
136+ # classAnnotation
137+ (opid , ) = self ._readStruct (">B" , 1 )
138+ if opid != self .TC_ENDBLOCKDATA :
139+ raise NotImplementedError ("classAnnotation isn't implemented yet" )
140+ print "OpCode: 0x%X" % opid
141+ # superClassDesc
142+ (opid , ) = self ._readStruct (">B" , 1 )
143+ print "OpCode: 0x%X" % opid
144+ self .opmap .get (opid , self .do_default_stuff )()
145+
146+ return clazz
113147
114148 def do_blockdata (self , parent = None ):
115149 # TC_BLOCKDATA (unsigned byte)<size> (byte)[size]
116150 print "[blockdata]"
117151 (length , ) = self ._readStruct (">B" , 1 )
118152 ba = self .object_stream .read (length )
119- self . finalValue = ba
153+ return ba
120154
121155 def do_class (self , parent = None ):
122156 # TC_CLASS classDesc newHandle
123157 print "[class]"
158+ clazz = self .read_and_exec_opcode ()
159+ print "Class:" , clazz
160+ return clazz
124161
125162 def do_object (self , parent = None ):
163+ # TC_OBJECT classDesc newHandle classdata[] // data for each class
126164 class JavaObject (object ):
127165 pass
128- object = JavaObject ()
129- # TC_OBJECT classDesc newHandle classdata[] // data for each class
166+ self .current_object = JavaObject ()
130167 print "[object]"
131168 (opid , ) = self ._readStruct (">B" , 1 )
132169 print "OpCode: 0x%X" % opid
133- res = self .opmap .get (opid , self .do_default_stuff )(object )
170+ res = self .opmap .get (opid , self .do_default_stuff )(self . current_object )
134171 self .finalValue = res
172+ # classdata[]
173+
174+ for field_name in self .current_object .__fields :
175+ (opid , ) = self ._readStruct (">B" , 1 )
176+ print "OpCode: 0x%X" % opid
177+ res = self .opmap .get (opid , self .do_default_stuff )(self .current_object )
178+ self .current_object .__setattr__ (field_name , res )
179+ return self .current_object
135180
136181 def do_string (self , parent = None ):
137182 print "[string]"
@@ -141,7 +186,9 @@ def do_string(self, parent=None):
141186
142187 def do_reference (self , parent = None ):
143188 (handle , reference ) = self ._readStruct (">HH" , 4 )
144- pass
189+
190+ def do_null (self , parent = None ):
191+ return None
145192
146193 def do_default_stuff (self , parent = None ):
147194 raise RuntimeError ("Unknown opcode" )
0 commit comments