Beispiel #1
0
func LoadAssembly(r io.ReadSeeker) (*Assembly, error) {

	var (
		br        = binary.BinaryReader{r, binary.LittleEndian}
		err       error
		pe_offset uint32
		coff      coff_file_header
		cor20     image_cor20
		t         MetadataHeader
	)

	if _, err := r.Seek(pe_signature_offset, 0); err != nil {
		return nil, err
	}

	if pe_offset, err = br.Uint32(); err != nil {
		return nil, err
	} else if _, err := r.Seek(int64(pe_offset), 0); err != nil {
		return nil, err
	}

	if err := br.ReadInterface(&coff); err != nil {
		return nil, err
	}
	net := coff.OptionalHeader.RVAS[14]
	off := coff.VirtualToFileOffset(net.VirtualAddress)
	if _, err := br.Seek(int64(off), 0); err != nil {
		return nil, err
	}

	if err := br.ReadInterface(&cor20); err != nil {
		return nil, err
	}
	off = coff.VirtualToFileOffset(cor20.MetaData.VirtualAddress)
	if _, err := br.Seek(int64(off), 0); err != nil {
		return nil, err
	}
	if err := br.ReadInterface(&t); err != nil {
		return nil, err
	}
	if _, err := br.Seek(int64(off), 0); err != nil {
		return nil, err
	}
	md, err := t.MetadataUtil(&br)
	if err != nil {
		return nil, err
	}
	a := Assembly{*md, make(map[string]*TypeDef)}
	idx := ConcreteTableIndex{&a.MetadataUtil, 0, id_TypeDef}
	for i := uint32(0); i < a.Tables[id_TypeDef].Rows; i++ {
		idx.index = 1 + i
		if td, err := TypeDefFromIndex(&idx); err == nil {
			a.typelut[td.Name().Absolute] = td
		}
	}
	return &a, nil
}
Beispiel #2
0
func (m *Model) parse() (err error) {
	reader := binary.BinaryReader{Reader: m.reader, Endianess: binary.LittleEndian}

	if err = reader.ReadInterface(&m.Header); err != nil {
		return
	}

	reader.Seek(int64(m.Header.HeaderSize)-0x10, 1)

	offset := int64(m.Header.HeaderSize)
	for err == nil {
		entry := ModelEntry{}

		if err = reader.ReadInterface(&entry); err != nil {
			if err == io.EOF {
				return nil
			}
			return
		}

		entry.Data = io.NewSectionReader(util.ReaderAt(m.reader), offset+0x0c, int64(entry.Size)-0x04)
		offset += 0x08 + int64(entry.Size)

		m.Entries = append(m.Entries, entry)

		switch entry.SubType {
		case "NODE": // Bone data

		case "NODO": // More bone things

		case "VSET": // Vertex data shit
			err = parseModelEntryVSET(&entry)
		}
	}

	return
}
Beispiel #3
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
}
Beispiel #4
0
func (ie *InfoEntry) Read(br *binary.BinaryReader) error {
	ret := br.ReadInterface(&ie.id)
	ie.debugInfoOffset, _ = br.Seek(0, 1)
	return ret
}
Beispiel #5
0
func (lh *lineHeader) Read(br *binary.BinaryReader) error {
	start, _ := br.Seek(0, 1)
	err := br.ReadInterface(&lh.Header)
	if err != nil {
		return err
	}
	if lh.is64 {
		lh.header_length, err = br.Int64()
	} else {
		var v uint32
		v, err = br.Uint32()
		lh.header_length = int64(v)
	}
	if err != nil {
		return err
	}
	if lh.minimum_instruction_length, err = br.Uint8(); err != nil {
		return err
	}
	lh.maximum_operations_per_instruction = 1
	// TODO:
	// if lh.maximum_operations_per_instruction, err = br.Uint8(); err != nil {
	// 	return err
	// }
	if err = br.ReadInterface(&lh.default_is_stmt); err != nil {
		return err
	} else if lh.line_base, err = br.Int8(); err != nil {
		return err
	} else if lh.line_range, err = br.Uint8(); err != nil {
		return err
	} else if lh.opcode_base, err = br.Uint8(); err != nil {
		return err
	}
	lh.standard_opcode_lengths = make([]uint8, lh.opcode_base-1)
	if err := br.ReadInterface(&lh.standard_opcode_lengths); err != nil {
		return err
	}
	for {
		var s string
		if err := br.ReadInterface(&s); err != nil {
			return err
		} else if s == "" {
			break
		} else {
			lh.include_directories = append(lh.include_directories, s)
		}
	}

	for {
		var f fileEntry
		pos, _ := br.Seek(0, 1)
		if v, err := br.Uint8(); err != nil {
			return err
		} else if v == '\u0000' {
			break
		} else {
			br.Seek(pos, 0)
		}
		if err := br.ReadInterface(&f); err != nil {
			return err
		} else {
			lh.file_names = append(lh.file_names, f)
		}
	}
	var s state
	s.header = lh
	s.reset()
	pos, _ := br.Seek(0, 1)
	for (pos - 4 - start) < int64(lh.Length) {
		var op DW_LNS
		if err := br.ReadInterface(&op); err != nil {
			return err
		}
		if op == 0 {
			var length LEB128
			if err := br.ReadInterface(&length); err != nil {
				return err
			}

			var op2 DW_LNE
			if err := br.ReadInterface(&op2); err != nil {
				return err
			}
			s.executeLNE(op2, length-1, br)
		} else {
			s.execute(op, br)
		}
		pos, _ = br.Seek(0, 1)
	}

	return nil
}