int PE_(read_nt_headers)(RBuffer *b, ut64 addr, PE_(image_nt_headers) *headers) {
	st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
	if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
		return -1;
	}
	headers->Signature = r_buf_read_le32 (b);
	headers->file_header.Machine = r_buf_read_le16 (b);
	headers->file_header.NumberOfSections = r_buf_read_le16 (b);
	headers->file_header.TimeDateStamp = r_buf_read_le32 (b);
	headers->file_header.PointerToSymbolTable = r_buf_read_le32 (b);
	headers->file_header.NumberOfSymbols = r_buf_read_le32 (b);
	headers->file_header.SizeOfOptionalHeader = r_buf_read_le16 (b);
	headers->file_header.Characteristics = r_buf_read_le16 (b);
	headers->optional_header.Magic = r_buf_read_le16 (b);
	headers->optional_header.MajorLinkerVersion = r_buf_read8 (b);
	headers->optional_header.MinorLinkerVersion = r_buf_read8 (b);
	headers->optional_header.SizeOfCode = r_buf_read_le32 (b);
	headers->optional_header.SizeOfInitializedData = r_buf_read_le32 (b);
	headers->optional_header.SizeOfUninitializedData = r_buf_read_le32 (b);
	headers->optional_header.AddressOfEntryPoint = r_buf_read_le32 (b);
	headers->optional_header.BaseOfCode = r_buf_read_le32 (b);
#ifdef R_BIN_PE64
	headers->optional_header.ImageBase = r_buf_read_le64 (b);
#else
	headers->optional_header.BaseOfData = r_buf_read_le32 (b);
	headers->optional_header.ImageBase = r_buf_read_le32 (b);
#endif
	headers->optional_header.SectionAlignment = r_buf_read_le32 (b);
	headers->optional_header.FileAlignment = r_buf_read_le32 (b);
	headers->optional_header.MajorOperatingSystemVersion = r_buf_read_le16 (b);
	headers->optional_header.MinorOperatingSystemVersion = r_buf_read_le16 (b);
	headers->optional_header.MajorImageVersion = r_buf_read_le16 (b);
	headers->optional_header.MinorImageVersion = r_buf_read_le16 (b);
	headers->optional_header.MajorSubsystemVersion = r_buf_read_le16 (b);
	headers->optional_header.MinorSubsystemVersion = r_buf_read_le16 (b);
	headers->optional_header.Win32VersionValue = r_buf_read_le32 (b);
	headers->optional_header.SizeOfImage = r_buf_read_le32 (b);
	headers->optional_header.SizeOfHeaders = r_buf_read_le32 (b);
	headers->optional_header.CheckSum = r_buf_read_le32 (b);
	headers->optional_header.Subsystem = r_buf_read_le16 (b);
	headers->optional_header.DllCharacteristics = r_buf_read_le16 (b);
#ifdef R_BIN_PE64
	headers->optional_header.SizeOfStackReserve = r_buf_read_le64 (b);
	headers->optional_header.SizeOfStackCommit = r_buf_read_le64 (b);
	headers->optional_header.SizeOfHeapReserve = r_buf_read_le64 (b);
	headers->optional_header.SizeOfHeapCommit = r_buf_read_le64 (b);
#else
	headers->optional_header.SizeOfStackReserve = r_buf_read_le32 (b);
	headers->optional_header.SizeOfStackCommit = r_buf_read_le32 (b);
	headers->optional_header.SizeOfHeapReserve = r_buf_read_le32 (b);
	headers->optional_header.SizeOfHeapCommit = r_buf_read_le32 (b);
#endif
	headers->optional_header.LoaderFlags = r_buf_read_le32 (b);
	headers->optional_header.NumberOfRvaAndSizes = r_buf_read_le32 (b);
	int i;
	for (i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES; i++) {
		headers->optional_header.DataDirectory[i].VirtualAddress = r_buf_read_le32 (b);
		headers->optional_header.DataDirectory[i].Size = r_buf_read_le32 (b);
	}
	if (r_buf_seek (b, o_addr, R_BUF_SET) < 0) {
		return -1;
	}
	return sizeof (PE_(image_nt_headers));
}