Skip to content

Commit de5a923

Browse files
OuyangHang33jyao1
authored andcommitted
Improve the method for getting Region 1~3 base and size
Signed-off-by: OuyangHang33 <[email protected]>
1 parent 03b1f7d commit de5a923

File tree

1 file changed

+40
-23
lines changed
  • td-shim-tools/src/bin/td-payload-reference-calculator

1 file changed

+40
-23
lines changed

td-shim-tools/src/bin/td-payload-reference-calculator/main.rs

+40-23
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,7 @@ pub const KERNEL_PARAM_SIZE: &str = "0x1000";
1919
// size of PE signature is 4: "PE\0\0"
2020
const IMAGE_PE_OFFSET: usize = 0x003c;
2121
const PE_SIGNATURE_SIZE: u32 = 4;
22-
const IMGAE_BEGIN_CHECKSUM_ADDR: usize = 0x0000;
23-
const IMGAE_BEGIN_CHECKSUM_SIZE: usize = 0x00da;
24-
const IMGAE_CERT_TABLE_ADDR: usize = 0x00de;
25-
const IMGAE_CERT_TABLE_SIZE: usize = 0x004c;
26-
const IMGAE_HEADERS_ADDR: usize = 0x0132;
27-
const IMGAE_HEADERS_SIZE: usize = 0x00ce;
22+
const IMGAE_BEGIN_ADDR: usize = 0x0000;
2823

2924
// Refer to https://www.kernel.org/doc/html/latest/arch/x86/boot.html#details-of-header-fields
3025
// Protocol version addr: 0x206, size: 2
@@ -38,8 +33,7 @@ fn kernel(path: &str, size: &str) -> Result<String> {
3833
bail!("File size should be less than `kernel-size`");
3934
}
4035
let buf = std::fs::read(path)?;
41-
let protocol = ((buf[IMAGE_PROTOCOL_ADDR as usize + 1] as u16) << 8)
42-
| buf[IMAGE_PROTOCOL_ADDR as usize] as u16;
36+
let protocol = ((buf[IMAGE_PROTOCOL_ADDR + 1] as u16) << 8) | buf[IMAGE_PROTOCOL_ADDR] as u16;
4337
if protocol < 0x206 {
4438
bail!("Protocol version should be 2.06+");
4539
}
@@ -60,8 +54,7 @@ fn qemu(path: &str, size: &str) -> Result<String> {
6054
bail!("File size should be less than `kernel-size`");
6155
}
6256
let buf = std::fs::read(path)?;
63-
let protocol = ((buf[IMAGE_PROTOCOL_ADDR as usize + 1] as u16) << 8)
64-
| buf[IMAGE_PROTOCOL_ADDR as usize] as u16;
57+
let protocol = ((buf[IMAGE_PROTOCOL_ADDR + 1] as u16) << 8) | buf[IMAGE_PROTOCOL_ADDR] as u16;
6558
if protocol < 0x206 {
6659
bail!("Protocol version should be 2.06+");
6760
}
@@ -101,22 +94,14 @@ fn qemu_patch(mut buf: Vec<u8>) -> Result<String> {
10194
}
10295

10396
fn get_image_regions(buf: &[u8]) -> (usize, Vec<usize>, Vec<usize>) {
104-
// These 3 regions are known.
97+
// Region 1~3 regions are known.
10598
let mut number_of_region_entry = 3;
106-
let mut regions_base = vec![
107-
IMGAE_BEGIN_CHECKSUM_ADDR,
108-
IMGAE_CERT_TABLE_ADDR,
109-
IMGAE_HEADERS_ADDR,
110-
];
111-
let mut regions_size = vec![
112-
IMGAE_BEGIN_CHECKSUM_SIZE,
113-
IMGAE_CERT_TABLE_SIZE,
114-
IMGAE_HEADERS_SIZE,
115-
];
99+
let mut regions_base = Vec::new();
100+
let mut regions_size = Vec::new();
116101

117102
// Refer to https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-file-header-object-and-image,
118103
// After the signature of an image file is COFF File Header, size is 20 bytes.
119-
// the NumberOfSections' offset is 2 and size is 2 bytes.
104+
// NumberOfSections Offset: 2 Size: 2
120105
let size_of_coff_file_header: u32 = 20;
121106

122107
let coff_file_header_offset = ((buf[IMAGE_PE_OFFSET + 3] as u32) << 24)
@@ -128,10 +113,42 @@ fn get_image_regions(buf: &[u8]) -> (usize, Vec<usize>, Vec<usize>) {
128113
| buf[coff_file_header_offset as usize + 2] as u16;
129114
number_of_region_entry += number_of_pecoff_entry as usize;
130115

131-
// the SizeOfOptionalHeader's offset is 16 and size is 2 bytes
116+
// SizeOfOptionalHeader Offset: 16 Size: 2
132117
let size_of_optional_header = ((buf[coff_file_header_offset as usize + 17] as u16) << 8)
133118
| buf[coff_file_header_offset as usize + 16] as u16;
134119

120+
let optional_header_addr: usize = (coff_file_header_offset + size_of_coff_file_header) as usize;
121+
122+
// Refer to https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-standard-fields-image-only
123+
// Only support PE32+
124+
// SizeOfHeaders Offset: 60 Size: 4
125+
// CheckSum Offset: 64 Size: 4
126+
// Cert table Offset: 144 Size: 8
127+
128+
let optional_size_of_headers_offset: usize = 0x003c;
129+
let optional_checksum_offset: usize = 0x0040;
130+
let optional_cert_table_offset: usize = 0x0090;
131+
132+
let size_of_headers =
133+
((buf[optional_header_addr + optional_size_of_headers_offset + 3] as u32) << 24)
134+
| ((buf[optional_header_addr + optional_size_of_headers_offset + 2] as u32) << 16)
135+
| ((buf[optional_header_addr + optional_size_of_headers_offset + 1] as u32) << 8)
136+
| buf[optional_header_addr + optional_size_of_headers_offset] as u32;
137+
138+
// Region 1: from file begin to CheckSum
139+
regions_base.push(IMGAE_BEGIN_ADDR);
140+
regions_size.push(optional_header_addr + optional_checksum_offset - IMGAE_BEGIN_ADDR);
141+
142+
// Region 2: from CheckSum end to certificate table entry
143+
regions_base.push(optional_header_addr + optional_checksum_offset + 4);
144+
regions_size.push(optional_cert_table_offset - (optional_checksum_offset + 4));
145+
146+
// Region 3: from cert table end to Header end
147+
regions_base.push(optional_header_addr + optional_cert_table_offset + 8);
148+
regions_size.push(
149+
size_of_headers as usize - (optional_header_addr + optional_cert_table_offset + 8) as usize,
150+
);
151+
135152
// Refer to https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
136153
// Size Of each Section is 40 bytes
137154
// SizeOfRawData Offset: 16 Size:4

0 commit comments

Comments
 (0)