def parse (page, data, parent): ver_offset = 0x1a size_offset = 0x1c trlr_offset = 0x24 model = page.model add_pgiter(page,"Header","vsd","hdr",data[0:0x24],parent) version = ord(data[ver_offset]) page.version = version print "Version: %d"%version print "Size: %02x"%struct.unpack("<I",data[size_offset:size_offset+4])[0] if version > 6: lenhdr2 = 74 else: lenhdr2 = 4 add_pgiter(page,"Header part2","vsd","hdr2",data[0x36:0x36+lenhdr2],parent) tr_pntr = pointer() if version < 6: pdata = data[trlr_offset:trlr_offset+16] plen = 16 [tr_pntr.type] = struct.unpack('<h', pdata[0:2]) [tr_pntr.format] = struct.unpack('<h', pdata[2:4]) [tr_pntr.address] = struct.unpack('<L', pdata[4:8]) [tr_pntr.offset] = struct.unpack('<L', pdata[8:12]) [tr_pntr.length] = struct.unpack('<L', pdata[12:16]) else: pdata = data[trlr_offset:trlr_offset+18] plen = 18 [tr_pntr.type] = struct.unpack('<L', pdata[0:4]) [tr_pntr.address] = struct.unpack('<L', pdata[4:8]) [tr_pntr.offset] = struct.unpack('<L', pdata[8:12]) [tr_pntr.length] = struct.unpack('<L', pdata[12:16]) [tr_pntr.format] = struct.unpack('<h', pdata[16:18]) if tr_pntr.format&2 == 2 : #compressed res = inflate.inflate(tr_pntr, data) tr_pntr.shift = 4 else: res = data[tr_pntr.offset:tr_pntr.offset+tr_pntr.length] tr_pntr.shift = 0 tr_pntr.data = res # FIXME!!! Need to change add_pgiter to deal with "("vsd","pntr",tr_pntr.type)" iter1 = model.append(parent,None) model.set_value(iter1,0,"Trailer\t\t %04x\t"%(tr_pntr.length)) model.set_value(iter1,1,("vsd","pntr",tr_pntr.type)) model.set_value(iter1,2,plen) model.set_value(iter1,3,pdata) model.set_value(iter1,4,tr_pntr) model.set_value(iter1,6,model.get_string_from_iter(iter1)) if tr_pntr.format != 0: model.set_value(iter1,7,"%02x"%tr_pntr.format) iter2 = add_pgiter(page,"[Data referenced by trailer]","vsd","str5",res,iter1) model.set_value(iter2,5,"#96dfcf") try: ptr_search (page, data, version, iter1) except: print "ptr_search failed in trailer"
def parse (page, data, parent): ver_offset = 0x1a size_offset = 0x1c trlr_offset = 0x24 model = page.model add_pgiter(page,"Header","vsd","hdr",data[0:0x24],parent) version = ord(data[ver_offset]) page.version = version print("Version: %d"%version) print("Size: %02x"%struct.unpack("<I",data[size_offset:size_offset+4])[0]) if version > 6: lenhdr2 = 74 else: lenhdr2 = 4 add_pgiter(page,"Header part2","vsd","hdr2",data[0x36:0x36+lenhdr2],parent) tr_pntr = pointer() if version < 6: pdata = data[trlr_offset:trlr_offset+16] plen = 16 [tr_pntr.type] = struct.unpack('<h', pdata[0:2]) [tr_pntr.format] = struct.unpack('<h', pdata[2:4]) [tr_pntr.address] = struct.unpack('<L', pdata[4:8]) [tr_pntr.offset] = struct.unpack('<L', pdata[8:12]) [tr_pntr.length] = struct.unpack('<L', pdata[12:16]) else: pdata = data[trlr_offset:trlr_offset+18] plen = 18 [tr_pntr.type] = struct.unpack('<L', pdata[0:4]) [tr_pntr.address] = struct.unpack('<L', pdata[4:8]) [tr_pntr.offset] = struct.unpack('<L', pdata[8:12]) [tr_pntr.length] = struct.unpack('<L', pdata[12:16]) [tr_pntr.format] = struct.unpack('<h', pdata[16:18]) if tr_pntr.format&2 == 2 : #compressed res = inflate.inflate(tr_pntr, data) tr_pntr.shift = 4 else: res = data[tr_pntr.offset:tr_pntr.offset+tr_pntr.length] tr_pntr.shift = 0 tr_pntr.data = res # FIXME!!! Need to change add_pgiter to deal with "("vsd","pntr",tr_pntr.type)" iter1 = model.append(parent,None) model.set_value(iter1,0,"Trailer\t\t %04x\t"%(tr_pntr.length)) model.set_value(iter1,1,("vsd","pntr",tr_pntr.type)) model.set_value(iter1,2,plen) model.set_value(iter1,3,pdata) model.set_value(iter1,4,tr_pntr) model.set_value(iter1,6,model.get_string_from_iter(iter1)) if tr_pntr.format != 0: model.set_value(iter1,7,"%02x"%tr_pntr.format) iter2 = add_pgiter(page,"[Data referenced by trailer]","vsd","str5",res,iter1) model.set_value(iter2,5,"#96dfcf") try: ptr_search (page, data, version, iter1) except: print("ptr_search failed in trailer")
def read (self,data,ptrdata,offset,version): if version < 6: self.type,self.format,self.address,self.offset,self.length = struct.unpack('<hhLLL', ptrdata[offset:offset+16]) self.hex = ptrdata[offset:offset+16] else: self.type,self.address,self.offset,self.length,self.format = struct.unpack('<LLLLh', ptrdata[offset:offset+18]) self.hex = ptrdata[offset:offset+18] if self.format&2 == 2 : #compressed res = inflate.inflate(self, data) self.shift = 4 else: res = data[self.offset:self.offset+self.length] self.shift = 0 self.data = res
def ptr_search(page, data, version, parent): model = page.model namelist = 0 fontlist = 0 childlist = 0 ptr = model.get_value(parent, 4) shift = ptr.shift pdata = ptr.data vbaflag = 0 if ptr.type == 0xd: vbaflag = 1 vbadata = "" if version > 5: [offset] = struct.unpack('<L', pdata[shift:shift + 4]) if offset >= len(pdata): return 0 lnum = struct.unpack('<L', pdata[offset + shift - 4:offset + shift])[0] # FIXME! verify num = struct.unpack('<L', pdata[offset + shift:offset + shift + 4])[0] offset = offset + 8 + shift elif version > 2: lnum = struct.unpack('<H', pdata[0x6 + shift:0x6 + shift + 2])[0] num = struct.unpack('<H', pdata[0xa + shift:0xa + shift + 2])[0] offset = 0xa + shift + 2 if ptr.type == 0x14: num = struct.unpack('<H', pdata[0x82 + shift:0x82 + shift + 2])[0] offset = 0x82 + shift + 2 if ptr.type == 0x1d: num = struct.unpack('<H', pdata[0x1e + shift:0x1e + shift + 2])[0] offset = 0x1e + shift + 2 if ptr.type == 0x1e: num = struct.unpack('<H', pdata[0x36 + shift:0x36 + shift + 2])[0] offset = 0x36 + shift + 2 if ptr.type == 0x4e: num = struct.unpack('<H', pdata[0x1e + shift:0x1e + shift + 2])[0] offset = 0x1e + shift + 2 else: offset = 0xa + shift + 2 if ptr.type == 0x14: num = struct.unpack('<H', pdata[0x82 + shift:0x82 + shift + 2])[0] offset = 0x82 + shift + 2 if ptr.type == 0x1d or ptr.type > 0x45: num = struct.unpack('<H', pdata[0x1e + shift:0x1e + shift + 2])[0] offset = 0x1e + shift + 2 if ptr.type == 0x1e: num = struct.unpack('<H', pdata[0x36 + shift:0x36 + shift + 2])[0] offset = 0x36 + shift + 2 if ptr.type == 0x1a: num = struct.unpack('<H', pdata[0x12 + shift:0x12 + shift + 2])[0] offset = 0x12 + shift + 2 if ptr.type == 0x18: num = struct.unpack('<H', pdata[0x2e + shift:0x2e + shift + 2])[0] offset = 0x2e + shift + 2 if ptr.type == 0x15: num = struct.unpack('<H', pdata[0x42 + shift:0x42 + shift + 2])[0] offset = 0x42 + shift + 2 if ptr.type == 0x27: num = struct.unpack('<H', pdata[0x0a + shift:0x0a + shift + 2])[0] offset = 0x0a + shift + 2 for i in range(num): pntr = pointer() if version < 6: plen = 16 npdata = pdata[offset + i * plen:offset + i * plen + 16] pntr.type = struct.unpack('<h', npdata[0:2])[0] & 0xFF pntr.format = struct.unpack('<h', npdata[2:4])[0] & 0xFF [pntr.address] = struct.unpack('<L', npdata[4:8]) [pntr.offset] = struct.unpack('<L', npdata[8:12]) [pntr.length] = struct.unpack('<L', npdata[12:16]) else: plen = 18 npdata = pdata[offset + i * plen:offset + i * plen + 18] [pntr.type] = struct.unpack('<L', npdata[0:4]) [pntr.address] = struct.unpack('<L', npdata[4:8]) [pntr.offset] = struct.unpack('<L', npdata[8:12]) [pntr.length] = struct.unpack('<L', npdata[12:16]) [pntr.format] = struct.unpack('<h', npdata[16:18]) itername = '%02x\t %02x\t%04x' % (pntr.type, childlist, pntr.length) name2 = "%02x" % pntr.type if pntr.type == 0: namelist += 1 fontlist += 1 childlist += 1 else: idx = " %02x" % childlist if streamtype.has_key(pntr.type): if pntr.type == 0x33: idx = "%02x" % namelist namelist += 1 else: if pntr.type == 0xd7: idx = " %02x" % fontlist fontlist += 1 else: idx = " %02x" % childlist childlist += 1 if (pntr.type == 0x15 and pntr.format & 1 == 0): itername = "Page BG " + idx + '\t%04x' % (pntr.length) else: itername = streamtype[ pntr.type] + idx + '\t%04x' % (pntr.length) name2 = streamtype[pntr.type] else: childlist += 1 if vsdchunks.chunktype.has_key(pntr.type): itername = vsdchunks.chunktype[ pntr.type] + idx + '\t%04x' % (pntr.length) if pntr.format & 2 == 2: #compressed res = inflate.inflate(pntr, data) pntr.shift = 4 else: res = data[pntr.offset:pntr.offset + pntr.length] pntr.shift = 0 pntr.data = res # FIXME!!! same change for add_pgiter required to take "pntr.type" iter1 = model.append(parent, None) model.set_value(iter1, 0, itername) model.set_value(iter1, 1, ("vsd", "pntr", pntr.type)) model.set_value(iter1, 2, plen) model.set_value(iter1, 3, npdata) model.set_value(iter1, 4, pntr) model.set_value(iter1, 6, model.get_string_from_iter(iter1)) if pntr.format != 0: model.set_value(iter1, 7, "%02x" % pntr.format) if len(res) > 0: iter2 = model.append(iter1, None) model.set_value(iter2, 0, "[Data referenced by %s]" % name2) if pntr.format >> 4 == 4: model.set_value(iter2, 1, ("vsd", "str4", pntr.type)) else: model.set_value(iter2, 1, ("vsd", "str")) model.set_value(iter2, 2, len(res)) model.set_value(iter2, 3, res) model.set_value(iter2, 6, model.get_string_from_iter(iter2)) model.set_value(iter2, 5, "#96dfcf") if vbaflag == 1: vbadata += res[4:len(res)] # print "ptr type/fmt %02x %02x"%(pntr.type,pntr.format) if (pntr.format >> 4 == 5 and pntr.type != 0x16) or pntr.type == 0x40: if pntr.type == 0x1e: model.set_value(iter2, 1, ("vsd", "str4", pntr.type)) # it's not a stream4, but... try: ptr_search(page, data, version, iter1) except: print "ptr_search failed in %02x" % pntr.type if pntr.type == 0x16: get_colors(page, res, version, iter1) if pntr.format >> 4 > 7: vsdchunks.parse(page, version, iter1, pntr) if version < 5 and vsdchunks.chunklist.has_key(pntr.type): vsdchunks.v5parse(page, version, iter1, pntr) if vbaflag == 1: ole.open(vbadata, page, iter2) if ptr.format >> 4 == 5 and ptr.type != 0x45: if ptr.format & 6 == 6: hlen = struct.unpack("<I", pdata[4:8])[0] ch_data = pdata[8:4 + hlen] ch_id = struct.unpack("<I", ch_data[:4])[0] ch_name = key2txt(ch_id, vsdchunks.chunktype) ins_pgiter(page, ch_name, "vsd", "chnk %s" % ch_id, ch_data, parent, 1) prep_pgiter(page, "List", "vsd", "str5tail", pdata[offset + num * plen:], model.iter_nth_child(parent, 0))
def ptr_search (page, data, version, parent): model = page.model namelist = 0 fontlist = 0 childlist = 0 ptr = model.get_value (parent,4) shift = ptr.shift pdata = ptr.data vbaflag = 0 if ptr.type == 0xd: vbaflag = 1 vbadata = "" if version > 5: [offset] = struct.unpack ('<L', pdata[shift:shift+4]) if offset >= len(pdata): return 0 lnum = struct.unpack ('<L', pdata[offset+shift-4:offset+shift])[0] # FIXME! verify num = struct.unpack ('<L', pdata[offset+shift:offset+shift+4])[0] offset = offset+8+shift elif version > 2: lnum = struct.unpack ('<H', pdata[0x6+shift:0x6+shift+2])[0] num = struct.unpack ('<H', pdata[0xa+shift:0xa+shift+2])[0] offset = 0xa+shift+2 if ptr.type == 0x14: num = struct.unpack ('<H', pdata[0x82+shift:0x82+shift+2])[0] offset = 0x82+shift+2 if ptr.type == 0x1d: num = struct.unpack ('<H', pdata[0x1e+shift:0x1e+shift+2])[0] offset = 0x1e+shift+2 if ptr.type == 0x1e: num = struct.unpack ('<H', pdata[0x36+shift:0x36+shift+2])[0] offset = 0x36+shift+2 if ptr.type == 0x4e: num = struct.unpack ('<H', pdata[0x1e+shift:0x1e+shift+2])[0] offset = 0x1e+shift+2 else: offset = 0xa+shift+2 if ptr.type == 0x14: num = struct.unpack ('<H', pdata[0x82+shift:0x82+shift+2])[0] offset = 0x82+shift+2 if ptr.type == 0x1d or ptr.type > 0x45: num = struct.unpack ('<H', pdata[0x1e+shift:0x1e+shift+2])[0] offset = 0x1e+shift+2 if ptr.type == 0x1e: num = struct.unpack ('<H', pdata[0x36+shift:0x36+shift+2])[0] offset = 0x36+shift+2 if ptr.type == 0x1a: num = struct.unpack ('<H', pdata[0x12+shift:0x12+shift+2])[0] offset = 0x12+shift+2 if ptr.type == 0x18: num = struct.unpack ('<H', pdata[0x2e+shift:0x2e+shift+2])[0] offset = 0x2e+shift+2 if ptr.type == 0x15: num = struct.unpack ('<H', pdata[0x42+shift:0x42+shift+2])[0] offset = 0x42+shift+2 if ptr.type == 0x27: num = struct.unpack ('<H', pdata[0x0a+shift:0x0a+shift+2])[0] offset = 0x0a+shift+2 for i in range(num): pntr = pointer() if version < 6: plen = 16 npdata = pdata[offset+i*plen:offset+i*plen+16] pntr.type = struct.unpack ('<h', npdata[0:2])[0]&0xFF pntr.format = struct.unpack ('<h', npdata[2:4])[0]&0xFF [pntr.address] = struct.unpack ('<L', npdata[4:8]) [pntr.offset] = struct.unpack ('<L', npdata[8:12]) [pntr.length] = struct.unpack ('<L', npdata[12:16]) else: plen = 18 npdata = pdata[offset+i*plen:offset+i*plen+18] [pntr.type] = struct.unpack ('<L', npdata[0:4]) [pntr.address] = struct.unpack ('<L', npdata[4:8]) [pntr.offset] = struct.unpack ('<L', npdata[8:12]) [pntr.length] = struct.unpack ('<L', npdata[12:16]) [pntr.format] = struct.unpack ('<h', npdata[16:18]) itername = '%02x\t %02x\t%04x'%(pntr.type,childlist,pntr.length) name2 = "%02x"%pntr.type if pntr.type == 0: namelist += 1 fontlist += 1 childlist +=1 else: idx = " %02x"%childlist if streamtype.has_key (pntr.type): if pntr.type == 0x33: idx = "%02x"%namelist namelist += 1 else: if pntr.type == 0xd7: idx = " %02x"%fontlist fontlist += 1 else: idx = " %02x"%childlist childlist +=1 if (pntr.type == 0x15 and pntr.format&1 == 0): itername = "Page BG "+idx+'\t%04x'%(pntr.length) else: itername = streamtype[pntr.type]+idx+'\t%04x'%(pntr.length) name2 = streamtype[pntr.type] else: childlist +=1 if vsdchunks.chunktype.has_key(pntr.type): itername = vsdchunks.chunktype[pntr.type]+idx+'\t%04x'%(pntr.length) if pntr.format&2 == 2 : #compressed res = inflate.inflate(pntr, data) pntr.shift = 4 else: res = data[pntr.offset:pntr.offset+pntr.length] pntr.shift = 0 pntr.data = res # FIXME!!! same change for add_pgiter required to take "pntr.type" iter1 = model.append(parent,None) model.set_value(iter1,0,itername) model.set_value(iter1,1,("vsd","pntr",pntr.type)) model.set_value(iter1,2,plen) model.set_value(iter1,3,npdata) model.set_value(iter1,4,pntr) model.set_value(iter1,6,model.get_string_from_iter(iter1)) if pntr.format != 0: model.set_value(iter1,7,"%02x"%pntr.format) if len(res) > 0: iter2 = model.append(iter1,None) model.set_value(iter2,0,"[Data referenced by %s]"%name2) if pntr.format >>4 == 4: model.set_value(iter2,1,("vsd","str4",pntr.type)) else: model.set_value(iter2,1,("vsd","str")) model.set_value(iter2,2,len(res)) model.set_value(iter2,3,res) model.set_value(iter2,6,model.get_string_from_iter(iter2)) model.set_value(iter2,5,"#96dfcf") if vbaflag == 1: vbadata += res[4:len(res)] # print "ptr type/fmt %02x %02x"%(pntr.type,pntr.format) if (pntr.format>>4 == 5 and pntr.type != 0x16) or pntr.type == 0x40: if pntr.type == 0x1e: model.set_value(iter2,1,("vsd","str4",pntr.type)) # it's not a stream4, but... try: ptr_search (page, data, version, iter1) except: print "ptr_search failed in %02x"%pntr.type if pntr.type == 0x16: get_colors (page, res, version, iter1) if pntr.format >>4 > 7: vsdchunks.parse (page, version, iter1, pntr) if version < 5 and vsdchunks.chunklist.has_key (pntr.type): vsdchunks.v5parse (page, version, iter1, pntr) if vbaflag == 1: ole.open (vbadata, page, iter2) if ptr.format >> 4 == 5 and ptr.type != 0x45: if ptr.format&6 == 6: hlen = struct.unpack("<I",pdata[4:8])[0] ch_data = pdata[8:4+hlen] ch_id = struct.unpack("<I",ch_data[:4])[0] ch_name = key2txt(ch_id,vsdchunks.chunktype) ins_pgiter(page,ch_name,"vsd","chnk %s"%ch_id,ch_data,parent,1) prep_pgiter(page,"List","vsd","str5tail",pdata[offset+num*plen:],model.iter_nth_child(parent,0))