예제 #1
0
func (mt *MetadataTable) Index(index uint32) ([]byte, error) {
	if mt.Rows == 0 {
		return nil, errors.New("Trying to dereference a nil table")
	}
	index--
	if index >= mt.Rows {
		return nil, errors.New(fmt.Sprintf("Index outside of bounds: %x >= %x", index, mt.Rows))
	}
	return mt.data[index*mt.RowSize:], nil
}
예제 #2
0
func (o *optional_header) Validate() error {
	if o.Magic != pe32 && o.Magic != pe32p {
		return errors.New(fmt.Sprintf("Unkown optional header magic: %x", o.Magic))
	}
	if len(o.RVAS) != 16 || o.RVAS[14].VirtualAddress == 0 || o.RVAS[14].Size == 0 {
		return ErrNotAssembly
	}
	return nil
}
func (r *BinaryReader) Read(size int) ([]byte, error) {
	data := make([]byte, size)
	if size == 0 {
		return data, nil
	}
	if n, err := r.Reader.Read(data); err != nil {
		return nil, err
	} else if n != len(data) {
		return nil, errors.New("Didn't read the expected number of bytes")
	}
	return data, nil
}
func (r *BinaryReader) ReadInterface(v interface{}) error {
	if ri, ok := v.(Reader); ok {
		return ri.Read(r)
	}
	t := reflect.ValueOf(v)
	if t.Kind() != reflect.Ptr {
		return errors.New(fmt.Sprintf("Expected a pointer not %s", t.Kind()))
	}
	v2 := t.Elem()
	switch v2.Kind() {
	case reflect.Uint64:
		if d, err := r.Uint64(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Uint32:
		if d, err := r.Uint32(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Uint16:
		if d, err := r.Uint16(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Uint8:
		if d, err := r.Uint8(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Int64:
		if d, err := r.Int64(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Int32:
		if d, err := r.Int32(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Int16:
		if d, err := r.Int16(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Int8:
		if d, err := r.Int8(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Float32:
		if f, err := r.Float32(); err != nil {
			return err
		} else {
			v2.SetFloat(float64(f))
		}
	case reflect.Float64:
		if f, err := r.Float64(); err != nil {
			return err
		} else {
			v2.SetFloat(f)
		}
	case reflect.Struct:
		for i := 0; i < v2.NumField(); i++ {
			var (
				f    = v2.Field(i)
				f2   = v2.Type().Field(i)
				size = -1
				err  error
			)
			if fi := f2.Tag.Get("if"); fi != "" {
				var e expression.EXPRESSION
				if !e.Parse(fi) {
					return e.Error()
				} else if ev, err := expression.Eval(&v2, e.RootNode()); err != nil {
					return err
				} else if ev == 0 {
					continue
				}
			}
			if l := f2.Tag.Get("length"); l != "" {
				switch l {
				case "uint8":
					if s, err := r.Uint8(); err != nil {
						return err
					} else {
						size = int(s)
					}
				case "uint16":
					if s, err := r.Uint16(); err != nil {
						return err
					} else {
						size = int(s)
					}
				case "uint32":
					if s, err := r.Uint32(); err != nil {
						return err
					} else {
						size = int(s)
					}
				case "uin64":
					if s, err := r.Uint64(); err != nil {
						return err
					} else {
						size = int(s)
					}
				default:
					var e expression.EXPRESSION
					if !e.Parse(l) {
						return e.Error()
					} else if ev, err := expression.Eval(&v2, e.RootNode()); err != nil {
						return err
					} else {
						size = ev
					}
				}
			}

			switch f.Type().Kind() {
			case reflect.String:
				var data []byte
				if size >= 0 {
					if data, err = r.Read(size); err != nil {
						return err
					}
					for i, v := range data {
						if v == '\u0000' {
							data = data[:i]
							break
						}
					}
				} else {
					var max = math.MaxInt32
					if m := f2.Tag.Get("max"); m != "" {
						var e expression.EXPRESSION
						if !e.Parse(m) {
							return e.Error()
						} else if ev, err := expression.Eval(&v2, e.RootNode()); err != nil {
							return err
						} else {
							max = ev
						}
					}

					for i := 0; i < max; i++ {
						if u, err := r.Uint8(); err != nil {
							return err
						} else if u == '\u0000' {
							size = i + 1
							break
						} else {
							data = append(data, u)
						}
					}
				}
				f.SetString(string(data))
			case reflect.Slice:
				if size == -1 {
					return fmt.Errorf("SliceHeader require a known length, %+v", v)
				}
				if f.Type().Elem().Kind() == reflect.Int8 {
					if b, err := r.Read(size); err != nil {
						return err
					} else {
						f.Set(reflect.ValueOf(b))
					}
				} else {
					var v3 = reflect.MakeSlice(f.Type(), size, size)
					for i := 0; i < size; i++ {
						if err = r.ReadInterface(v3.Index(i).Addr().Interface()); err != nil {
							return err
						}
					}
					f.Set(v3)
				}
			case reflect.Array:
				for i := 0; i < f.Type().Len(); i++ {
					if err = r.ReadInterface(f.Index(i).Addr().Interface()); err != nil {
						return err
					}
				}
			default:
				if err := r.ReadInterface(f.Addr().Interface()); err != nil {
					return fmt.Errorf("%+v: %s", v, err)
				} else {
					size = int(f.Type().Size())
				}
			}

			if al := f2.Tag.Get("align"); al != "" {
				var (
					e     expression.EXPRESSION
					align int
					seek  int
				)
				if !e.Parse(al) {
					return e.Error()
				} else if ev, err := expression.Eval(&v2, e.RootNode()); err != nil {
					return err
				} else {
					align = ev
				}
				if align < size {
					seek = ((size + (align - 1)) &^ (align - 1)) - size
				} else if align > size {
					seek = align - size
				}
				if seek > 0 {
					if _, err := r.Seek(int64(seek), 1); err != nil {
						return err
					}
				}
			}
		}
	default:
		return errors.New(fmt.Sprintf("Don't know how to read type %s", v2.Kind()))
	}
	if val, ok := v.(Validateable); ok {
		return val.Validate()
	}
	return nil
}
예제 #5
0
func (m *MetadataUtil) Size(t reflect.Type) (uint, error) {
	size := uint(0)
	name := t.Name()
	switch name {
	case "StringIndex":
		size = uint(m.StringHeap.RowSize)
	case "Guid":
		size = uint(m.GuidHeap.RowSize)
	case "BlobIndex":
		size = uint(m.BlobHeap.RowSize)
	default:
		if strings.HasSuffix(name, "EncodedIndex") {
			id := idx_name_lut[name]
			var (
				tables = enc_lut[id]
				rows   uint32
			)
			for _, t := range tables {
				if t == id_nullTable {
					continue
				}
				if s2 := m.Tables[t].Rows; s2 > rows {
					rows = s2
				}
			}
			if rows<<util.Bits(len(tables)) < 1<<16 {
				size = 2
			} else {
				size = 4
			}
		} else if strings.HasSuffix(name, "Index") {
			if m.Tables[idx_name_lut[name]].Rows < 1<<16 {
				size = 2
			} else {
				size = 4
			}
		} else {
			switch t.Kind() {
			case reflect.Struct:
				for i := 0; i < t.NumField(); i++ {
					f := t.Field(i)
					if s, err := m.Size(f.Type); err != nil {
						return 0, err
					} else {
						size += s
					}
				}
			case reflect.Uint8:
				return 1, nil
			case reflect.Uint16:
				return 2, nil
			case reflect.Uint32:
				return 4, nil
			case reflect.Uint64:
				return 8, nil
			default:
				return 0, errors.New(fmt.Sprintf("Don't know the size of: %s, %s", t.Name(), t.Kind()))
			}
		}
	}
	return size, nil
}
예제 #6
0
func (m *MetadataUtil) Create(br *binary.BinaryReader, v interface{}) error {
	t := reflect.ValueOf(v)
	if t.Kind() != reflect.Ptr {
		return errors.New(fmt.Sprintf("Expected a pointer not %s", t.Kind()))
	}
	v2 := t.Elem()
	name := v2.Type().Name()

	if name == "StringIndex" {
		size := m.StringHeap.RowSize
		index, err := m.ReadIndex(br, uint(size))
		if err != nil {
			return err
		}
		data := m.StringHeap.data[index:m.StringHeap.Rows]

		for i := range data {
			if data[i] == '\u0000' {
				data = data[:i]
				break
			}
		}
		v2.SetString(string(data))
	} else if name == "Guid" {
		size := m.GuidHeap.RowSize
		if index, err := m.ReadIndex(br, uint(size)); err != nil {
			return err
		} else if index != 0 {
			index = (index - 1) * 16
			g := Guid(m.GuidHeap.data[index : index+16])
			v2.Set(reflect.ValueOf(g))
		}
	} else if strings.HasSuffix(name, "EncodedIndex") {
		size, err := m.Size(v2.Type())
		if err != nil {
			return err
		}
		idx, err := m.ReadIndex(br, size)
		if err != nil {
			return err
		}
		var (
			tables = enc_lut[idx_name_lut[name]]
			b      = util.Bits(len(tables))
			mask   = uint32(0xffff << b)
			tbl    = idx &^ mask
			ti     ConcreteTableIndex
		)
		idx = idx >> b
		ti.index = idx
		ti.table = tables[int(tbl)]
		ti.metadataUtil = m
		v2.Set(reflect.ValueOf(&ti))
	} else if strings.HasSuffix(name, "Index") {
		size, err := m.Size(v2.Type())
		if err != nil {
			return err
		}
		var ti ConcreteTableIndex
		if ti.index, err = m.ReadIndex(br, size); err != nil {
			return err
		}
		if name == "BlobIndex" {
			ti.table = id_Blob
		} else {
			ti.table = idx_name_lut[name]
		}
		ti.metadataUtil = m
		v2.Set(reflect.ValueOf(&ti))
	} else {
		if v2.Kind() != reflect.Struct {
			return br.ReadInterface(v)
		}
		for i := 0; i < v2.NumField(); i++ {
			f := v2.Field(i)
			a := f.Addr()
			if err := m.Create(br, a.Interface()); err != nil {
				return err
			}
		}
	}
	return nil
}
예제 #7
0
	id_StandAloneSig          = 0x11 // II.22.36
	id_TypeDef                = 0x02 // II.22.37
	id_TypeRef                = 0x01 // II.22.38
	id_TypeSpec               = 0x1B // II.22.39
	id_nullTable              = 0x100
	id_Blob                   = 0x101
)

const (
	bit_stringHeapIndexSize = (1 << iota)
	bit_guidHeapIndexSize
	bit_blobHeapIndexSize
)

var (
	ErrMetadata        = errors.New("Metadata header isn't in the expected format")
	table_row_type_lut = map[int]reflect.Type{
		id_Assembly:               reflect.TypeOf(AssemblyRow{}),
		id_AssemblyOS:             reflect.TypeOf(AssemblyOSRow{}),
		id_AssemblyProcessor:      reflect.TypeOf(AssemblyProcessorRow{}),
		id_AssemblyRef:            reflect.TypeOf(AssemblyRefRow{}),
		id_AssemblyRefOS:          reflect.TypeOf(AssemblyRefOSRow{}),
		id_AssemblyRefProcessor:   reflect.TypeOf(AssemblyRefProcessorRow{}),
		id_ClassLayout:            reflect.TypeOf(ClassLayoutRow{}),
		id_Constant:               reflect.TypeOf(ConstantRow{}),
		id_CustomAttribute:        reflect.TypeOf(CustomAttributeRow{}),
		id_DeclSecurity:           reflect.TypeOf(DeclSecurityRow{}),
		id_EventMap:               reflect.TypeOf(EventMapRow{}),
		id_Event:                  reflect.TypeOf(EventRow{}),
		id_ExportedType:           reflect.TypeOf(ExportedTypeRow{}),
		id_Field:                  reflect.TypeOf(FieldRow{}),
예제 #8
0
func (r *BinaryReader) ReadInterface(v interface{}) error {
	if ri, ok := v.(Reader); ok {
		return ri.Read(r)
	}
	t := reflect.ValueOf(v)
	if t.Kind() != reflect.Ptr {
		return errors.New(fmt.Sprintf("Expected a pointer not %s", t.Kind()))
	}
	v2 := t.Elem()
	switch v2.Kind() {
	case reflect.Uint64:
		if d, err := r.Uint64(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Uint32:
		if d, err := r.Uint32(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Uint16:
		if d, err := r.Uint16(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Uint8:
		if d, err := r.Uint8(); err != nil {
			return err
		} else {
			v2.SetUint(uint64(d))
		}
	case reflect.Int64:
		if d, err := r.Int64(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Int32:
		if d, err := r.Int32(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Int16:
		if d, err := r.Int16(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Int8:
		if d, err := r.Int8(); err != nil {
			return err
		} else {
			v2.SetInt(int64(d))
		}
	case reflect.Float32:
		if f, err := r.Float32(); err != nil {
			return err
		} else {
			v2.SetFloat(float64(f))
		}
	case reflect.Float64:
		if f, err := r.Float64(); err != nil {
			return err
		} else {
			v2.SetFloat(f)
		}
	case reflect.Struct:
		for i := 0; i < v2.NumField(); i++ {
			var (
				f    = v2.Field(i)
				f2   = v2.Type().Field(i)
				size = -1
				err  error
			)
			if fi := f2.Tag.Get("if"); fi != "" {
				arr := strings.Split(fi, ",")
				if f3 := v2.FieldByName(arr[0]); !f3.IsValid() {
					return errors.New(fmt.Sprintf("No such field: %s in %s", arr[0], v2.Type().Name()))
				} else if test, err := strconv.ParseUint(arr[1], 0, 64); err != nil {
					return err
				} else {
					if f3.Uint() != test {
						continue
					}
				}
			}
			if l := f2.Tag.Get("length"); l != "" {
				if v3 := v2.FieldByName(l); v3.IsValid() {
					size = int(v3.Uint())
				} else if size, err = strconv.Atoi(l); err != nil {
					return err
				}
			}

			switch f.Type().Kind() {
			case reflect.String:
				var data []byte
				if size >= 0 {
					if data, err = r.Read(size); err != nil {
						return err
					}
				} else {
					var max = math.MaxInt32
					if m := f2.Tag.Get("max"); m != "" {
						if max, err = strconv.Atoi(m); err != nil {
							return err
						}
					}

					for i := 0; i < max; i++ {
						if u, err := r.Uint8(); err != nil {
							return err
						} else if u == '\u0000' {
							size = i + 1
							break
						} else {
							data = append(data, u)
						}
					}
				}
				f.SetString(string(data))
			case reflect.Slice:
				if size == -1 {
					return errors.New("SliceHeader require a known length")
				}
				if f.Type().Elem().Kind() == reflect.Int8 {
					if b, err := r.Read(size); err != nil {
						return err
					} else {
						f.Set(reflect.ValueOf(b))
					}
				} else {
					var v3 = reflect.MakeSlice(f.Type(), size, size)
					for i := 0; i < size; i++ {
						if err = r.ReadInterface(v3.Index(i).Addr().Interface()); err != nil {
							return err
						}
					}
					f.Set(v3)
				}
			case reflect.Array:
				for i := 0; i < f.Type().Len(); i++ {
					if err = r.ReadInterface(f.Index(i).Addr().Interface()); err != nil {
						return err
					}
				}
			default:
				if err := r.ReadInterface(f.Addr().Interface()); err != nil {
					return err
				} else {
					size = int(f.Type().Size())
				}
			}

			if al := f2.Tag.Get("align"); al != "" {
				if a, err := strconv.Atoi(al); err != nil {
					return err
				} else if seek := ((size + (a - 1)) &^ (a - 1)) - size; seek > 0 {
					if _, err := r.Seek(int64(seek), 1); err != nil {
						return err
					}
				}
			}
		}
	default:
		return errors.New(fmt.Sprintf("Don't know how to read type %s", v2.Kind()))
	}
	if val, ok := v.(Validateable); ok {
		return val.Validate()
	}
	return nil
}
예제 #9
0
func (coff *coff_file_header) Validate() error {
	if bytes.Compare(coff.Magic, pe_magic) != 0 {
		return errors.New(fmt.Sprintf("PE Magic mismatch: %v", coff.Magic))
	}
	return nil
}
예제 #10
0
func (h *hash_tilde_stream_header) Validate() error {
	if h.Reserved != 0 || h.MajorVersion != 2 || h.MinorVersion != 0 /*|| h.Reserved2 != 1*/ { //TODO: Hmm spec says Reserved2 should be 1, but it appears to be 0x10?
		return errors.New(fmt.Sprintf("This does not appear to be a valid #~ stream header: %#v", h))
	}
	return nil
}
예제 #11
0
func (s *stream_header) Validate() error {
	if s.Name[0] != '#' {
		return errors.New(fmt.Sprintf("This does not appear to be a valid stream header: %#v", s))
	}
	return nil
}
예제 #12
0
func (s *section_table) Validate() error {
	if s.Name[0] != '.' {
		return errors.New(fmt.Sprintf("This does not appear to be a valid section header: %#v", s))
	}
	return nil
}