Пример #1
0
func (cp *ConstantPool) readConstant(c *Constant, br *binary.BinaryReader) error {
	if err := br.ReadInterface(&c.Tag); err != nil {
		return err
	} else {
		switch c.Tag {
		case CONSTANT_String:
			fallthrough
		case CONSTANT_MethodType:
			fallthrough
		case CONSTANT_Class:
			return br.ReadInterface(&c.Index[0])
		case CONSTANT_Fieldref:
			fallthrough
		case CONSTANT_Methodref:
			fallthrough
		case CONSTANT_NameAndType:
			fallthrough
		case CONSTANT_InvokeDynamic:
			fallthrough
		case CONSTANT_InterfaceMethodref:
			if err := br.ReadInterface(&c.Index[0]); err != nil {
				return err
			} else {
				return br.ReadInterface(&c.Index[1])
			}
		case CONSTANT_Integer:
			var v int32
			return br.ReadInterface(&v)
		case CONSTANT_Float:
			var v float32
			return br.ReadInterface(&v)
		case CONSTANT_Long:
			var v int64
			return br.ReadInterface(&v)
		case CONSTANT_Double:
			var v float64
			return br.ReadInterface(&v)
		case CONSTANT_Utf8:
			var length u2
			if err := br.ReadInterface(&length); err != nil {
				return err
			} else if d, err := br.Read(int(length)); err != nil {
				return err
			} else {
				c.Value = string(d)
			}
		case CONSTANT_MethodHandle:
			var ref_kind u1
			if err := br.ReadInterface(&ref_kind); err != nil {
				return err
			} else {
				c.Index[0] = u2(ref_kind)
				return br.ReadInterface(&c.Index[1])
			}
		default:
			return errors.New(fmt.Sprintf("Unimplemented tag: %d", c.Tag))
		}
	}
	return nil
}
Пример #2
0
func (mh *MetadataHeader) MetadataUtil(br *binary.BinaryReader) (*MetadataUtil, error) {
	var (
		ret MetadataUtil
	)

	off, err := br.Seek(0, 1)
	if err != nil {
		return nil, err
	}
	base := off
	for _, h := range mh.StreamHeaders {
		switch h.Name {
		case "#~":
			off += int64(h.Offset)
		case "#Strings":
			if _, err := br.Seek(base+int64(h.Offset), 0); err != nil {
				return nil, err
			} else if ret.StringHeap.data, err = br.Read(int(h.Size)); err != nil {
				return nil, err
			}
			ret.StringHeap.Rows = h.Size
		case "#Blob":
			if _, err := br.Seek(base+int64(h.Offset), 0); err != nil {
				return nil, err
			} else if ret.BlobHeap.data, err = br.Read(int(h.Size)); err != nil {
				return nil, err
			}
			ret.BlobHeap.Rows = h.Size
		case "#GUID":
			if _, err := br.Seek(base+int64(h.Offset), 0); err != nil {
				return nil, err
			} else if ret.GuidHeap.data, err = br.Read(int(h.Size)); err != nil {
				return nil, err
			}
			ret.GuidHeap.Rows = h.Size
		}
	}
	if _, err := br.Seek(off, 0); err != nil {
		return nil, err
	}
	h := hash_tilde_stream_header{}
	if err := br.ReadInterface(&h); err != nil {
		return nil, err
	}

	if h.HeapSizes&bit_stringHeapIndexSize != 0 {
		ret.StringHeap.RowSize = 4
	} else {
		ret.StringHeap.RowSize = 2
	}
	if h.HeapSizes&bit_blobHeapIndexSize != 0 {
		ret.BlobHeap.RowSize = 4
	} else {
		ret.BlobHeap.RowSize = 2
	}
	if h.HeapSizes&bit_guidHeapIndexSize != 0 {
		ret.GuidHeap.RowSize = 4
	} else {
		ret.GuidHeap.RowSize = 2
	}

	for i := range ret.Tables {
		if valid := (h.Valid >> uint(i)) & 1; valid == 0 {
			continue
		}
		if ret.Tables[i].Rows, err = br.Uint32(); err != nil {
			return nil, err
		}
		ret.Tables[i].RowType = table_row_type_lut[i]
	}

	for i := range ret.Tables {
		if ret.Tables[i].Rows == 0 {
			continue
		}
		size, err := ret.Size(ret.Tables[i].RowType)
		if err != nil {
			return nil, err
		}
		ret.Tables[i].RowSize = uint32(size)
		if ret.Tables[i].data, err = br.Read(int(ret.Tables[i].RowSize * ret.Tables[i].Rows)); err != nil {
			return nil, err
		}
	}
	return &ret, nil
}
Пример #3
0
func (ie *InfoEntry) data(form DW_FORM, br binary.BinaryReader) interface{} {
	if form == DW_FORM_ref_addr && ie.header.Version < 3 {
		form = DW_FORM_addr
	}
	switch form {
	case DW_FORM_flag_present:
		return true
	case DW_FORM_exprloc, DW_FORM_block:
		var size LEB128
		br.ReadInterface(&size)
		r, _ := br.Read(int(size))
		return r
	case DW_FORM_block1:
		size, _ := br.Uint8()
		r, _ := br.Read(int(size))
		return r
	case DW_FORM_block2:
		size, _ := br.Uint16()
		r, _ := br.Read(int(size))
		return r
	case DW_FORM_block4:
		size, _ := br.Uint32()
		r, _ := br.Read(int(size))
		return r
	case DW_FORM_addr:
		if ie.header.AddressSize == 8 {
			v, _ := br.Uint64()
			return v
		} else {
			v, _ := br.Uint32()
			return uint64(v)
		}
	case DW_FORM_ref_addr, DW_FORM_strp, DW_FORM_sec_offset:
		if ie.header.is64 {
			v, _ := br.Uint64()
			return v
		} else {
			v, _ := br.Uint32()
			return uint64(v)
		}
	case DW_FORM_ref1, DW_FORM_flag, DW_FORM_data1:
		v, _ := br.Uint8()
		return uint64(v)
	case DW_FORM_ref2, DW_FORM_data2:
		v, _ := br.Uint16()
		return uint64(v)
	case DW_FORM_ref4, DW_FORM_data4:
		v, _ := br.Uint32()
		return uint64(v)
	case DW_FORM_ref8, DW_FORM_data8:
		v, _ := br.Uint64()
		return v
	case DW_FORM_sdata, DW_FORM_udata:
		var r LEB128
		br.ReadInterface(&r)
		return uint64(r)
	case DW_FORM_string:
		buf := make([]byte, 4096)

		for i := range buf {
			if v, err := br.Uint8(); err != nil {
				return err
			} else if v == 0 {
				buf = buf[:i]
				break
			} else {
				buf[i] = byte(v)
			}
		}
		return string(buf)
	}
	panic(fmt.Errorf("Unimplemented format: %s", form))
}