Skip to main content

clr_assembler/formats/dll/reader/
mod.rs

1use crate::{
2    formats::dll::DllReadConfig,
3    program::{
4        ClrAccessFlags, ClrHeader, ClrMethod, ClrProgram, ClrType, ClrTypeReference, ClrVersion, DotNetAssemblyInfo,
5        MetadataHeader, StreamHeader,
6    },
7};
8use byteorder::{LittleEndian, ReadBytesExt};
9use gaia_types::{GaiaDiagnostics, GaiaError, SourceLocation};
10use pe_assembler::{
11    helpers::PeReader,
12    types::{PeHeader, PeProgram, SectionHeader},
13};
14use std::io::{Read, Seek, SeekFrom};
15use url::Url;
16
17#[derive(Debug)]
18pub struct DllReader<'config, R> {
19    /// 配置选项
20    options: &'config DllReadConfig,
21    reader: pe_assembler::formats::dll::reader::DllReader<R>,
22    /// 解析后的 CLR 头信息
23    clr_header: Option<ClrHeader>,
24    /// 解析后的元数据头信息
25    metadata_header: Option<MetadataHeader>,
26    /// 元数据流头信息列表(惰性加载)
27    stream_headers: Option<Vec<StreamHeader>>,
28    /// 提取的程序集基本信息(惰性加载)
29    assembly_info: Option<DotNetAssemblyInfo>,
30    /// 完整解析的 CLR 程序(惰性加载)
31    clr_program: Option<ClrProgram>,
32}
33
34impl<'config, R: Read + Seek> PeReader<R> for DllReader<'config, R> {
35    fn get_viewer(&mut self) -> &mut R {
36        self.reader.get_viewer()
37    }
38
39    fn add_diagnostics(&mut self, error: impl Into<GaiaError>) {
40        self.reader.add_diagnostics(error)
41    }
42
43    fn get_section_headers(&mut self) -> Result<&[SectionHeader], GaiaError> {
44        self.reader.get_section_headers()
45    }
46
47    fn get_pe_header(&mut self) -> Result<&PeHeader, GaiaError> {
48        self.reader.get_pe_header()
49    }
50
51    fn get_program(&mut self) -> Result<&PeProgram, GaiaError> {
52        self.reader.get_program()
53    }
54}
55
56impl<'config, R> DllReader<'config, R> {
57    /// 使用泛型 PE 读取器构造 .NET 读取器(DLL)
58    ///
59    /// 注意:这是惰性构造函数,不会立即执行解析工作流程
60    pub fn new(reader: R, options: &'config DllReadConfig) -> Self {
61        Self {
62            reader: pe_assembler::formats::dll::reader::DllReader::new(reader),
63            clr_header: None,
64            metadata_header: None,
65            stream_headers: None,
66            assembly_info: None,
67            clr_program: None,
68            options,
69        }
70    }
71}
72
73impl<'config, R> DllReader<'config, R>
74where
75    R: Read + Seek,
76{
77    /// 从文件读取 .NET 程序集
78    ///
79    /// 该方法读取并解析 .NET 程序集文件,步骤如下:
80    /// 1. 将整个文件读入内存
81    /// 2. 创建 PE 视图以访问 PE 结构
82    /// 3. 创建读取器实例
83    /// 4. 执行解析工作流程
84    ///
85    /// # 参数
86    /// * `file_path` - .NET 程序集文件路径
87    ///
88    /// # 返回
89    /// * `Ok(DotNetReader)` - 成功解析的读取器
90    /// * `Err(GaiaError)` - 读取或解析过程中的错误
91    // 便捷构造在专用 impl 中提供
92    /// 检查文件是否为 .NET 程序集
93    ///
94    /// 快速检查方法,无需完整解析,仅通过检查 PE 数据目录:
95    /// - 读取 PE 文件并创建视图
96    /// - 检查第 15 个数据目录(索引 14)是否为 CLR 运行时头
97    /// - 如果该目录存在且有效,则为 .NET 程序集
98    ///
99    /// # 参数
100    /// * `file_path` - 要检查的 PE 文件路径
101    ///
102    /// # 返回
103    /// * `Ok(true)` - 是 .NET 程序集
104    /// * `Ok(false)` - 不是 .NET 程序集
105    /// * `Err(GaiaError)` - 检查过程中的错误
106    // 便捷检查在专用 impl 中提供
107
108    /// 惰性读取程序集基本信息
109    ///
110    /// 仅读取程序集的基本标识信息,不解析完整的类型系统。
111    /// 适用于快速获取程序集名称、版本等信息的场景。
112    ///
113    /// # 返回
114    /// * `Ok(DotNetAssemblyInfo)` - 程序集基本信息
115    /// * `Err(GaiaError)` - 读取过程中的错误
116    pub fn get_assembly_info(&mut self) -> Result<DotNetAssemblyInfo, GaiaError> {
117        if self.assembly_info.is_none() {
118            self.ensure_assembly_info_parsed()?;
119        }
120
121        self.assembly_info
122            .as_ref()
123            .cloned()
124            .ok_or_else(|| GaiaError::syntax_error("程序集信息未解析".to_string(), SourceLocation::default()))
125    }
126
127    /// 完整解析为 CLR 程序
128    ///
129    /// 解析整个 .NET 程序集,包括所有类型、方法、字段等信息。
130    /// 这是一个重量级操作,会消耗较多内存和时间。
131    ///
132    /// # 返回
133    /// * `Ok(ClrProgram)` - 完整的 CLR 程序表示
134    /// * `Err(GaiaError)` - 解析过程中的错误
135    pub fn to_clr_program(&mut self) -> Result<ClrProgram, GaiaError> {
136        if let Some(ref program) = self.clr_program {
137            return Ok(program.clone());
138        }
139
140        // 执行完整解析
141        let program = self.parse_full_program()?;
142        self.clr_program = Some(program.clone());
143        Ok(program)
144    }
145
146    /// 验证程序集完整性
147    ///
148    /// 检查解析后的 .NET 程序集是否包含所有必需的组件:
149    /// - CLR 头:包含运行时信息
150    /// - 元数据头:描述类型系统
151    /// - 元数据流:包含实际的元数据
152    ///
153    /// # 返回
154    /// * `Ok(Vec<String>)` - 警告信息列表,空列表表示验证通过
155    /// * `Err(GaiaError)` - 验证过程中的错误
156    pub fn validate_assembly(&mut self) -> Result<Vec<String>, GaiaError> {
157        let mut warnings = Vec::new();
158
159        // 确保基本信息已解析
160        self.ensure_assembly_info_parsed()?;
161
162        // 验证 CLR 头 - 必需的核心头信息
163        if self.clr_header.is_none() {
164            warnings.push("缺少 CLR 头".to_string());
165        }
166
167        // 验证元数据头 - 描述类型系统的元数据
168        if self.metadata_header.is_none() {
169            warnings.push("缺少元数据头".to_string());
170        }
171
172        // 验证流头 - 包含实际的元数据流
173        if self.stream_headers.as_ref().map_or(true, |h| h.is_empty()) {
174            warnings.push("缺少元数据流".to_string());
175        }
176
177        Ok(warnings)
178    }
179
180    /// 获取程序集摘要信息
181    ///
182    /// 以友好的格式返回程序集的基本信息,适合用于显示或日志记录。
183    /// 如果程序集信息不可用,返回相应的错误消息。
184    ///
185    /// # 返回
186    /// * `String` - 格式化的程序集信息,包含名称、版本、文化、公钥标记和运行时版本
187    pub fn get_assembly_summary(&mut self) -> String {
188        match self.get_assembly_info() {
189            Ok(info) => {
190                format!(
191                    "程序集: {}\n版本: {}\n文化: {}\n公钥标记: {}\n运行时版本: {}",
192                    info.name,
193                    info.version,
194                    info.culture.as_deref().unwrap_or("neutral"),
195                    info.public_key_token.as_deref().unwrap_or("null"),
196                    info.runtime_version.as_deref().unwrap_or("unknown")
197                )
198            }
199            Err(_) => "无法获取程序集信息".to_string(),
200        }
201    }
202
203    /// 确保程序集信息已解析(惰性加载辅助方法)
204    fn ensure_assembly_info_parsed(&mut self) -> Result<(), GaiaError> {
205        if self.assembly_info.is_some() {
206            return Ok(());
207        }
208
209        // 按需执行解析工作流程
210        self.parse_clr_header()?;
211        self.parse_metadata()?;
212        self.extract_assembly_info()?;
213
214        Ok(())
215    }
216
217    /// 解析 CLR 头
218    ///
219    /// 这是解析流程的第一步,负责定位和读取 CLR 头信息。
220    /// CLR 头包含了 .NET 运行时所需的核心信息,如元数据位置、运行时版本等。
221    ///
222    /// # 返回
223    /// * `Ok(())` - 解析成功
224    /// * `Err(GaiaError)` - 解析过程中的错误
225    fn parse_clr_header(&mut self) -> Result<(), GaiaError> {
226        eprintln!("开始解析 CLR 头");
227        self.clr_header = self.find_and_read_clr_header()?;
228        eprintln!("find_and_read_clr_header 返回: {:?}", self.clr_header.is_some());
229        if self.clr_header.is_none() {
230            eprintln!("CLR 头为空,返回错误");
231            return Err(GaiaError::syntax_error("缺少 CLR 头", SourceLocation::default()));
232        }
233        eprintln!("CLR 头解析成功");
234        Ok(())
235    }
236
237    /// 解析元数据
238    ///
239    /// 这是解析流程的第二步,在 CLR 头解析成功后执行:
240    /// 1. 使用 CLR 头中的 metadata_rva 定位元数据位置
241    /// 2. 读取元数据头,获取元数据的基本信息
242    /// 3. 读取所有的流头,了解元数据的组织结构
243    ///
244    /// # 返回
245    /// * `Ok(())` - 解析成功(即使没有 CLR 头也不会报错)
246    /// * `Err(GaiaError)` - 解析过程中的错误
247    fn parse_metadata(&mut self) -> Result<(), GaiaError> {
248        if let Some(ref clr_header) = self.clr_header {
249            // 将元数据的 RVA 转换为文件偏移
250            let metadata_offset = self.rva_to_file_offset(clr_header.metadata_rva)?;
251            // 读取元数据头
252            self.metadata_header = Some(self.read_metadata_header(metadata_offset)?);
253            // 读取流头信息
254            self.stream_headers = Some(self.read_stream_headers(metadata_offset)?);
255        }
256
257        Ok(())
258    }
259
260    /// 提取程序集信息
261    ///
262    /// 这是解析流程的第三步,负责从元数据中提取程序集级别的信息。
263    /// 这些信息包括程序集名称、版本、文化、公钥标记等,用于标识和版本控制。
264    ///
265    /// # 返回
266    /// * `Ok(())` - 提取成功
267    /// * `Err(GaiaError)` - 提取过程中的错误
268    fn extract_assembly_info(&mut self) -> Result<(), GaiaError> {
269        // 依赖已解析的 CLR 头与元数据流头
270        let clr_header = match &self.clr_header {
271            Some(h) => *h,
272            None => return Ok(()),
273        };
274        let metadata_offset = self.rva_to_file_offset(clr_header.metadata_rva)?;
275
276        // 查找 #~ 和 #Strings 流
277        let mut tables_stream: Option<StreamHeader> = None;
278        let mut strings_stream: Option<StreamHeader> = None;
279        if let Some(ref stream_headers) = self.stream_headers {
280            for sh in stream_headers {
281                match sh.name.as_str() {
282                    "#~" => tables_stream = Some(sh.clone()),
283                    "#Strings" => strings_stream = Some(sh.clone()),
284                    _ => {}
285                }
286            }
287        }
288        if tables_stream.is_none() || strings_stream.is_none() {
289            return Ok(());
290        }
291        let tables_stream = tables_stream.unwrap();
292        let strings_stream = strings_stream.unwrap();
293
294        let tables_start = metadata_offset + tables_stream.offset;
295        let strings_start = metadata_offset + strings_stream.offset;
296
297        // 读取压缩的元数据表头
298        let mut cur = self.reader.get_viewer();
299        cur.seek(SeekFrom::Start(tables_start as u64))
300            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://table").unwrap()))?;
301
302        let _reserved =
303            cur.read_u32::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_hdr").unwrap()))?;
304        let _major = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_hdr").unwrap()))?;
305        let _minor = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_hdr").unwrap()))?;
306        let heap_sizes = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_hdr").unwrap()))?;
307        let _reserved2 = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_hdr").unwrap()))?;
308        let valid_mask =
309            cur.read_u64::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_hdr").unwrap()))?;
310        let _sorted_mask =
311            cur.read_u64::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_hdr").unwrap()))?;
312
313        // 堆索引大小
314        let str_idx_sz = if (heap_sizes & 0x01) != 0 { 4 } else { 2 };
315        let guid_idx_sz = if (heap_sizes & 0x02) != 0 { 4 } else { 2 };
316        let blob_idx_sz = if (heap_sizes & 0x04) != 0 { 4 } else { 2 };
317        let strings_size = strings_stream.size;
318
319        eprintln!("堆大小标志: 0x{:02x}", heap_sizes);
320        eprintln!("字符串索引大小: {}, GUID索引大小: {}, Blob索引大小: {}", str_idx_sz, guid_idx_sz, blob_idx_sz);
321        eprintln!("字符串流大小: {}", strings_size);
322        eprintln!("有效表掩码: 0x{:016x}", valid_mask);
323
324        // 读取行计数
325        let mut row_counts: [u32; 64] = [0; 64];
326        for tid in 0..64u8 {
327            if (valid_mask >> tid) & 1 == 1 {
328                row_counts[tid as usize] = cur
329                    .read_u32::<LittleEndian>()
330                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_rows").unwrap()))?;
331                eprintln!("表 0x{:02x} 行数: {}", tid, row_counts[tid as usize]);
332            }
333        }
334
335        // 计算相关编码索引大小
336        fn coded_size(rows: &[u32; 64], tags: &[u8]) -> u32 {
337            let max_rows = tags.iter().map(|&t| rows[t as usize]).max().unwrap_or(0);
338            let tag_bits = (tags.len() as f32).log2().ceil() as u32;
339            if (max_rows << tag_bits) < (1 << 16) {
340                2
341            }
342            else {
343                4
344            }
345        }
346        let type_def_or_ref_sz = coded_size(&row_counts, &[0x02, 0x01, 0x18]);
347        let resolution_scope_sz = coded_size(&row_counts, &[0x00, 0x01, 0x17, 0x23]);
348
349        // 常用表 row size
350        let module_row_size = 2 + str_idx_sz + guid_idx_sz + guid_idx_sz + guid_idx_sz;
351        let type_def_row_size = 4
352            + str_idx_sz
353            + str_idx_sz
354            + type_def_or_ref_sz
355            + (if row_counts[0x04] < (1 << 16) { 2 } else { 4 })
356            + (if row_counts[0x06] < (1 << 16) { 2 } else { 4 });
357        let methoddef_row_size = 4 + 2 + 2 + str_idx_sz + blob_idx_sz + (if row_counts[0x07] < (1 << 16) { 2 } else { 4 });
358        let typeref_row_size = resolution_scope_sz + str_idx_sz + str_idx_sz;
359        let assembly_row_size = 4 + 2 + 2 + 2 + 2 + 4 + blob_idx_sz + str_idx_sz + str_idx_sz;
360
361        // 数据区起始位置
362        let tables_data_start =
363            cur.stream_position().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_data").unwrap()))? as u32;
364        eprintln!("表数据区起始位置: 0x{:x}", tables_data_start);
365        // 表起始偏移映射
366        let mut table_start: [Option<u32>; 64] = [None; 64];
367        let mut table_row_size: [u32; 64] = [0; 64];
368        let mut running = tables_data_start;
369        for tid in 0..64u8 {
370            if (valid_mask >> tid) & 1 == 1 {
371                let rows = row_counts[tid as usize];
372                let row_size = match tid {
373                    0x00 => module_row_size,
374                    0x01 => typeref_row_size,
375                    0x02 => type_def_row_size,
376                    0x06 => methoddef_row_size,
377                    0x20 => assembly_row_size, // Assembly table is 0x20 per ECMA-335
378                    _ => 0,
379                } as u32;
380                table_start[tid as usize] = Some(running);
381                table_row_size[tid as usize] = row_size;
382                eprintln!(
383                    "表 0x{:02x}: 起始=0x{:x}, 行数={}, 行大小={}, 总大小={}",
384                    tid,
385                    running,
386                    rows,
387                    row_size,
388                    rows * row_size
389                );
390                running += rows * row_size;
391            }
392        }
393
394        // 解析程序集名称与版本
395        let mut name = String::from("Unknown");
396        let mut version = ClrVersion { major: 0, minor: 0, build: 0, revision: 0 };
397
398        // 首先尝试从Assembly表读取 (0x20)
399        if let Some(asm_start) = table_start[0x20] {
400            if row_counts[0x20] > 0 {
401                let mut c = self.reader.get_viewer();
402                c.seek(SeekFrom::Start(asm_start as u64))
403                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
404
405                // 读取Assembly表第一行 - 按照ECMA-335规范
406                let hash_alg =
407                    c.read_u32::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
408                version.major =
409                    c.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
410                version.minor =
411                    c.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
412                version.build =
413                    c.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
414                version.revision =
415                    c.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
416                let flags =
417                    c.read_u32::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
418                let pk_idx = read_heap_index(&mut c, blob_idx_sz)?;
419                let name_idx = read_heap_index(&mut c, str_idx_sz)?;
420                let culture_idx = read_heap_index(&mut c, str_idx_sz)?;
421
422                // 验证读取的数据是否合理
423                if hash_alg > 0x10000 || version.major > 100 || name_idx > strings_size {
424                    eprintln!("警告: Assembly表数据异常,可能表偏移计算错误");
425                    eprintln!(
426                        "HashAlg: 0x{:x}, Version: {}.{}.{}.{}, NameIdx: {}",
427                        hash_alg, version.major, version.minor, version.build, version.revision, name_idx
428                    );
429                }
430                else {
431                    let n = self.read_string_from_strings_heap(strings_start, strings_size, name_idx)?;
432                    if !n.is_empty() {
433                        name = n;
434                    }
435                }
436            }
437        }
438        else if let Some(mod_start) = table_start[0x00] {
439            // Module 表
440            if row_counts[0x00] > 0 {
441                let mut c = self.reader.get_viewer();
442                c.seek(SeekFrom::Start(mod_start as u64))
443                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://mod").unwrap()))?;
444                let _generation =
445                    c.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://mod").unwrap()))?;
446                let name_idx = read_heap_index(&mut c, str_idx_sz)?;
447                let _mvid_idx = read_heap_index(&mut c, guid_idx_sz)?;
448                let _enc_id_idx = read_heap_index(&mut c, guid_idx_sz)?;
449                let _enc_base_id_idx = read_heap_index(&mut c, guid_idx_sz)?;
450                let n = self.read_string_from_strings_heap(strings_start, strings_size, name_idx)?;
451                if !n.is_empty() {
452                    name = n;
453                }
454            }
455        }
456
457        // 运行时版本字符串
458        let runtime_version = self.metadata_header.as_ref().map(|h| h.version_string.clone());
459
460        // 保存信息
461        self.assembly_info = Some(DotNetAssemblyInfo {
462            name,
463            version: format!("{}.{}.{}.{}", version.major, version.minor, version.build, version.revision),
464            culture: None,
465            public_key_token: None,
466            runtime_version,
467        });
468
469        Ok(())
470    }
471
472    /// 解析完整的 CLR 程序
473    ///
474    /// 执行完整的程序集解析,包括所有类型、方法、字段等信息。
475    /// 这是一个重量级操作,会解析整个元数据表结构。
476    ///
477    /// # 返回
478    /// * `Ok(ClrProgram)` - 完整的 CLR 程序表示
479    /// * `Err(GaiaError)` - 解析过程中的错误
480    fn parse_full_program(&mut self) -> Result<ClrProgram, GaiaError> {
481        // 保护性检查:需要已解析的 CLR 头与元数据头
482        let metadata_rva = self
483            .clr_header
484            .as_ref()
485            .ok_or_else(|| GaiaError::syntax_error("缺少 CLR 头".to_string(), SourceLocation::default()))?
486            .metadata_rva;
487        let _version_string = self
488            .metadata_header
489            .as_ref()
490            .ok_or_else(|| GaiaError::syntax_error("缺少元数据头".to_string(), SourceLocation::default()))?
491            .version_string
492            .clone();
493
494        // 计算元数据起始文件偏移
495        let metadata_base = self.rva_to_file_offset(metadata_rva)?;
496
497        // 查找关键流:#~ (或 #-) 与 #Strings
498        let mut tables_stream: Option<StreamHeader> = None;
499        let mut strings_stream: Option<StreamHeader> = None;
500        if let Some(ref stream_headers) = self.stream_headers {
501            for sh in stream_headers {
502                match sh.name.as_str() {
503                    "#~" | "#-" => tables_stream = Some(sh.clone()),
504                    "#Strings" => strings_stream = Some(sh.clone()),
505                    _ => {}
506                }
507            }
508        }
509
510        let tables_stream = tables_stream
511            .ok_or_else(|| GaiaError::syntax_error("缺少元数据表流(#~/#-)".to_string(), SourceLocation::default()))?;
512        let strings_stream = strings_stream
513            .ok_or_else(|| GaiaError::syntax_error("缺少字符串流(#Strings)".to_string(), SourceLocation::default()))?;
514
515        // 便捷:将文件视为游标
516        let mut cur = self.reader.get_viewer();
517        // 表流起始与字符串流起始的绝对文件偏移
518        let tables_start = metadata_base + tables_stream.offset;
519        let strings_start = metadata_base + strings_stream.offset;
520
521        // 读取表头(压缩元数据格式,ECMA-335 II.24.2.6)
522        cur.seek(SeekFrom::Start(tables_start as u64))
523            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
524        let _reserved =
525            cur.read_u32::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
526        let _major = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
527        let _minor = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
528        let heap_sizes = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
529        let _reserved2 = cur.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
530        let valid_mask =
531            cur.read_u64::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
532        let _sorted_mask =
533            cur.read_u64::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
534
535        // 读取存在表的行数
536        let mut row_counts: [u32; 64] = [0; 64];
537        for tid in 0..64u8 {
538            if (valid_mask >> tid) & 1 == 1 {
539                let cnt = cur
540                    .read_u32::<LittleEndian>()
541                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables").unwrap()))?;
542                row_counts[tid as usize] = cnt;
543            }
544        }
545
546        // 计算堆索引大小
547        let str_idx_sz = if (heap_sizes & 0x01) != 0 { 4 } else { 2 };
548        let guid_idx_sz = if (heap_sizes & 0x02) != 0 { 4 } else { 2 };
549        let blob_idx_sz = if (heap_sizes & 0x04) != 0 { 4 } else { 2 };
550        let _ = guid_idx_sz; // 目前未用,避免警告
551
552        // 数据区起始位置(当前游标处)
553        let tables_data_start =
554            cur.stream_position().map_err(|e| GaiaError::io_error(e, Url::parse("memory://tables_data").unwrap()))? as u32;
555
556        // 计算简单索引大小(到指定表)
557        let mut simple_index_size = |table_id: u8| -> u32 {
558            let rows = row_counts[table_id as usize];
559            if rows < (1 << 16) {
560                2
561            }
562            else {
563                4
564            }
565        };
566
567        // 计算 MethodDef 行大小
568        let param_index_sz = simple_index_size(0x07); // Param
569        let methoddef_row_size = 4 /*RVA*/ + 2 /*ImplFlags*/ + 2 /*Flags*/ + str_idx_sz + blob_idx_sz + param_index_sz;
570
571        // 计算若干前置表的行大小以便累加到 MethodDef 的偏移
572        let field_row_size = 2 /*Flags*/ + str_idx_sz /*Name*/ + blob_idx_sz /*Signature*/;
573        let fieldptr_row_size = simple_index_size(0x04);
574        let methodptr_row_size = simple_index_size(0x06);
575        // TypeRef 行大小:ResolutionScope(编码索引) + Name(String) + Namespace(String)
576        // ResolutionScope 可指向:Module(0x00), ModuleRef(0x1A/0x17), AssemblyRef(0x20), TypeRef(0x01)
577        let rs_candidates = [0x00u8, 0x17u8, 0x20u8, 0x01u8];
578        let mut max_rs_rows = 0u32;
579        for &t in &rs_candidates {
580            max_rs_rows = max_rs_rows.max(row_counts[t as usize]);
581        }
582        let rs_tag_bits = 2u32;
583        let resolution_scope_sz = if max_rs_rows < (1 << (16 - rs_tag_bits)) { 2 } else { 4 };
584        let typeref_row_size = resolution_scope_sz + str_idx_sz + str_idx_sz;
585        // TypeDef 行大小:Flags(u32) + Name(String) + Namespace(String) + Extends(TypeDefOrRef) + FieldList(简单索引到 Field) + MethodList(简单索引到 MethodDef)
586        // TypeDefOrRef 编码索引候选:TypeDef(0x02), TypeRef(0x01), TypeSpec(0x1B/0x18)
587        let tdr_candidates = [0x02u8, 0x01u8, 0x18u8];
588        let mut max_tdr_rows = 0u32;
589        for &t in &tdr_candidates {
590            max_tdr_rows = max_tdr_rows.max(row_counts[t as usize]);
591        }
592        let tdr_tag_bits = 2u32;
593        let type_def_or_ref_sz = if max_tdr_rows < (1 << (16 - tdr_tag_bits)) { 2 } else { 4 };
594        let type_def_row_size =
595            4 /*Flags*/ + str_idx_sz + str_idx_sz + type_def_or_ref_sz + simple_index_size(0x04) + simple_index_size(0x06);
596        // Module 行大小:Generation(u16) + Name(String) + Mvid(Guid) + EncId(Guid) + EncBaseId(Guid)
597        let module_row_size = 2 + str_idx_sz + guid_idx_sz + guid_idx_sz + guid_idx_sz;
598
599        // 计算常用表的起始偏移与行大小映射
600        let mut table_start: [Option<u32>; 64] = [None; 64];
601        let mut table_row_size: [u32; 64] = [0; 64];
602        let mut running = tables_data_start;
603        for tid in 0..64u8 {
604            if (valid_mask >> tid) & 1 == 1 {
605                let rows = row_counts[tid as usize];
606                let row_size = match tid {
607                    0x00 => module_row_size,
608                    0x01 => typeref_row_size,
609                    0x02 => type_def_row_size,
610                    0x03 => fieldptr_row_size,
611                    0x04 => field_row_size,
612                    0x05 => methodptr_row_size,
613                    0x06 => methoddef_row_size,
614                    0x07 => 2 /*Flags*/ + str_idx_sz + blob_idx_sz, // Param
615                    0x08 => simple_index_size(0x02) + simple_index_size(0x01), // InterfaceImpl
616                    0x09 => resolution_scope_sz + str_idx_sz + blob_idx_sz, // MemberRef
617                    0x0A => 2 /*Type*/ + blob_idx_sz,               // Constant
618                    0x0B => simple_index_size(0x02) + simple_index_size(0x0A) + simple_index_size(0x0C), /* CustomAttribute(粗略) */
619                    0x0C => simple_index_size(0x04) + simple_index_size(0x07),                           // FieldMarshal
620                    0x0D => 2 + blob_idx_sz,                                                             // DeclSecurity
621                    0x0E => 2 + 4 + 4,                                                                   // ClassLayout
622                    0x0F => simple_index_size(0x04) + 4,                                                 // FieldLayout
623                    0x10 => blob_idx_sz,                                                                 // StandAloneSig
624                    0x11 => simple_index_size(0x02) + simple_index_size(0x12),                           // EventMap
625                    0x12 => 2 + str_idx_sz + simple_index_size(0x10),                                    // Event
626                    0x13 => simple_index_size(0x02) + simple_index_size(0x14),                           // PropertyMap
627                    0x14 => 2 + str_idx_sz + blob_idx_sz,                                                // Property
628                    0x15 => 2 + simple_index_size(0x06) + simple_index_size(0x14),                       // MethodSemantics
629                    0x16 => simple_index_size(0x02) + simple_index_size(0x06) + simple_index_size(0x01), // MethodImpl
630                    0x20 => 4 + 2 + 2 + 2 + 2 + 4 + blob_idx_sz + str_idx_sz + str_idx_sz,               // Assembly
631                    0x21 => 4 + 4,                                                                       // AssemblyProcessor
632                    0x22 => 4 + 4 + 4,                                                                   // AssemblyOS
633                    0x23 => 2 + 2 + 2 + 2 + 4 + blob_idx_sz + str_idx_sz + str_idx_sz + blob_idx_sz,     // AssemblyRef
634                    _ => 0,
635                } as u32;
636                table_start[tid as usize] = Some(running);
637                table_row_size[tid as usize] = row_size;
638                running += rows * row_size;
639            }
640        }
641        let methoddef_offset = table_start[0x06].unwrap_or(tables_data_start);
642
643        // 构建程序对象
644        let mut program = ClrProgram::new("UnknownAssembly");
645        program.version = ClrVersion { major: 1, minor: 0, build: 0, revision: 0 };
646        program.access_flags =
647            ClrAccessFlags { is_public: true, is_private: false, is_security_transparent: false, is_retargetable: false };
648
649        // 尝试从 Assembly 表填充名称与版本,否则使用 Module 名称
650        if let Some(asm_start) = table_start[0x20] {
651            // Assembly 表存在(0x20)
652            let asm_rows = row_counts[0x20];
653            if asm_rows > 0 {
654                let asm0 = asm_start; // 第一行偏移
655                let mut c2 = self.reader.get_viewer();
656                c2.seek(SeekFrom::Start(asm0 as u64))
657                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
658                let _hash_alg =
659                    c2.read_u32::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
660                let ver_major =
661                    c2.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
662                let ver_minor =
663                    c2.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
664                let ver_build =
665                    c2.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
666                let ver_rev =
667                    c2.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
668                let _flags =
669                    c2.read_u32::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://asm").unwrap()))?;
670                let _pk_idx = read_heap_index(&mut c2, blob_idx_sz)?;
671                let name_idx = read_heap_index(&mut c2, str_idx_sz)?;
672                let culture_idx = read_heap_index(&mut c2, str_idx_sz)?;
673                let _hash_idx = read_heap_index(&mut c2, blob_idx_sz)?;
674
675                let name = self.read_string_from_strings_heap(strings_start, strings_stream.size, name_idx)?;
676                let culture = if culture_idx != 0 {
677                    Some(self.read_string_from_strings_heap(strings_start, strings_stream.size, culture_idx)?)
678                }
679                else {
680                    None
681                };
682
683                if !name.is_empty() {
684                    program.name = name;
685                }
686                program.version = ClrVersion { major: ver_major, minor: ver_minor, build: ver_build, revision: ver_rev };
687            }
688        }
689        else if let Some(module_start) = table_start[0x00] {
690            // Module 表存在时使用名称
691            let mut cm = self.reader.get_viewer();
692            cm.seek(SeekFrom::Start(module_start as u64))
693                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://module").unwrap()))?;
694            let _generation =
695                cm.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://module").unwrap()))?;
696            let name_idx = read_heap_index(&mut cm, str_idx_sz)?;
697            let _mvid_idx = read_heap_index(&mut cm, guid_idx_sz)?;
698            let _encid = read_heap_index(&mut cm, guid_idx_sz)?;
699            let _encbase = read_heap_index(&mut cm, guid_idx_sz)?;
700            let mod_name = self.read_string_from_strings_heap(strings_start, strings_stream.size, name_idx)?;
701            if !mod_name.is_empty() {
702                program.name = mod_name;
703            }
704        }
705
706        // 读取 TypeDef 表
707        if let Some(typedef_start) = table_start[0x02] {
708            for i in 0..row_counts[0x02] {
709                let mut ct = self.reader.get_viewer();
710                ct.seek(SeekFrom::Start((typedef_start + i * type_def_row_size) as u64))
711                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://typedef").unwrap()))?;
712                let flags = ct
713                    .read_u32::<LittleEndian>()
714                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://typedef").unwrap()))?;
715                let name_idx = read_heap_index(&mut ct, str_idx_sz)?;
716                let ns_idx = read_heap_index(&mut ct, str_idx_sz)?;
717                let _extends_idx = read_type_def_or_ref_index(&mut ct, type_def_or_ref_sz)?;
718                let _field_list_idx = read_heap_index(&mut ct, (if row_counts[0x04] < (1 << 16) { 2 } else { 4 }))?;
719                let _method_list_idx = read_heap_index(&mut ct, (if row_counts[0x06] < (1 << 16) { 2 } else { 4 }))?;
720
721                let type_name = self.read_string_from_strings_heap(strings_start, strings_stream.size, name_idx)?;
722                let namespace = if ns_idx != 0 {
723                    Some(self.read_string_from_strings_heap(strings_start, strings_stream.size, ns_idx)?)
724                }
725                else {
726                    None
727                };
728
729                if !type_name.is_empty() {
730                    let mdef = ClrMethod::new(
731                        "DefaultMethod".to_string(),
732                        ClrTypeReference {
733                            name: "Void".to_string(),
734                            namespace: Some("System".to_string()),
735                            assembly: Some("mscorlib".to_string()),
736                            is_value_type: true,
737                            is_reference_type: false,
738                            generic_parameters: Vec::new(),
739                        },
740                    );
741                    let mut clr_type = ClrType::new(type_name, namespace);
742                    clr_type.access_flags.is_public = true;
743                    clr_type.add_method(mdef);
744                }
745            }
746        }
747
748        // 读取 MethodDef 表
749        if let Some(methoddef_start) = table_start[0x06] {
750            for i in 0..row_counts[0x06] {
751                let mut c3 = self.reader.get_viewer();
752                c3.seek(SeekFrom::Start((methoddef_start + i * methoddef_row_size) as u64))
753                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://methoddef").unwrap()))?;
754                let _rva = c3
755                    .read_u32::<LittleEndian>()
756                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://methoddef").unwrap()))?;
757                let _impl_flags = c3
758                    .read_u16::<LittleEndian>()
759                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://methoddef").unwrap()))?;
760                let _flags = c3
761                    .read_u16::<LittleEndian>()
762                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://methoddef").unwrap()))?;
763                let name_idx = read_heap_index(&mut c3, str_idx_sz)?;
764                let _sig_idx = read_heap_index(&mut c3, blob_idx_sz)?;
765                let _param_list_idx = read_heap_index(&mut c3, (if row_counts[0x07] < (1 << 16) { 2 } else { 4 }))?;
766
767                let method_name = self.read_string_from_strings_heap(strings_start, strings_stream.size, name_idx)?;
768
769                if !method_name.is_empty() {
770                    let _mdef = ClrMethod::new(
771                        method_name,
772                        ClrTypeReference {
773                            name: "Void".to_string(),
774                            namespace: Some("System".to_string()),
775                            assembly: Some("mscorlib".to_string()),
776                            is_value_type: true,
777                            is_reference_type: false,
778                            generic_parameters: Vec::new(),
779                        },
780                    );
781                    // TODO: 将方法添加到对应的类型中
782                }
783            }
784        }
785
786        // 读取 Field 表
787        if let Some(field_start) = table_start[0x04] {
788            for i in 0..row_counts[0x04] {
789                let mut c4 = self.reader.get_viewer();
790                c4.seek(SeekFrom::Start((field_start + i * field_row_size) as u64))
791                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://field").unwrap()))?;
792                let _flags =
793                    c4.read_u16::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://field").unwrap()))?;
794                let name_idx = read_heap_index(&mut c4, str_idx_sz)?;
795                let _sig_idx = read_heap_index(&mut c4, blob_idx_sz)?;
796
797                let name = self.read_string_from_strings_heap(strings_start, strings_stream.size, name_idx)?;
798
799                if !name.is_empty() {
800                    let _mdef = ClrMethod::new(
801                        "DefaultMethod".to_string(),
802                        ClrTypeReference {
803                            name: "Void".to_string(),
804                            namespace: Some("System".to_string()),
805                            assembly: Some("mscorlib".to_string()),
806                            is_value_type: true,
807                            is_reference_type: false,
808                            generic_parameters: Vec::new(),
809                        },
810                    );
811                    let mut _clr_type = ClrType::new(name, None);
812                    _clr_type.access_flags.is_public = true;
813                    _clr_type.add_method(_mdef);
814                }
815            }
816        }
817
818        // 解析外部程序集:严格依据 AssemblyRef 表
819        let mut external_assemblies: Vec<crate::program::ClrExternalAssembly> = Vec::new();
820        // AssemblyRef 表
821        if let Some(asmref_start) = table_start[0x23] {
822            // 计算到 AssemblyRef 表的偏移
823            let assemblyref_rows = row_counts[0x23];
824
825            // 解析 AssemblyRef 行:Version(4x u16) + Flags(u32) + PublicKeyOrToken(Blob) + Name(String) + Culture(String) + HashValue(Blob)
826            let row_size = table_row_size[0x23];
827            for i in 0..assemblyref_rows {
828                let row_off = asmref_start + i * row_size;
829                let mut c4 = self.reader.get_viewer();
830                c4.seek(SeekFrom::Start(row_off as u64))
831                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asmref").unwrap()))?;
832                let ver_major = c4
833                    .read_u16::<LittleEndian>()
834                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asmref").unwrap()))?;
835                let ver_minor = c4
836                    .read_u16::<LittleEndian>()
837                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asmref").unwrap()))?;
838                let ver_build = c4
839                    .read_u16::<LittleEndian>()
840                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asmref").unwrap()))?;
841                let ver_rev = c4
842                    .read_u16::<LittleEndian>()
843                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asmref").unwrap()))?;
844                let _flags = c4
845                    .read_u32::<LittleEndian>()
846                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://asmref").unwrap()))?;
847                let _pkt_idx = read_heap_index(&mut c4, blob_idx_sz)?;
848                let name_idx = read_heap_index(&mut c4, str_idx_sz)?;
849                let culture_idx = read_heap_index(&mut c4, str_idx_sz)?;
850                let _hash_idx = read_heap_index(&mut c4, blob_idx_sz)?;
851                let name = self.read_string_from_strings_heap(strings_start, strings_stream.size, name_idx)?;
852                if !name.is_empty() {
853                    external_assemblies.push(crate::program::ClrExternalAssembly {
854                        name,
855                        version: ClrVersion { major: ver_major, minor: ver_minor, build: ver_build, revision: ver_rev },
856                        public_key_token: None,
857                        culture: None,
858                        hash_algorithm: None,
859                    });
860                }
861            }
862        }
863
864        // 如果 AssemblyRef 未找到或为空,尝试从 #Strings 提取常见引用名作为降级(仅在确实出现时加入)
865        if external_assemblies.is_empty() {
866            let cfg = &self.options.assembly_ref_fallback_names;
867            let heap = self.read_strings_heap_data(strings_start, strings_stream.size)?;
868            for name in cfg.iter() {
869                if find_subslice(&heap, name.as_bytes()) {
870                    external_assemblies.push(crate::program::ClrExternalAssembly {
871                        name: name.to_string(),
872                        version: ClrVersion { major: 0, minor: 0, build: 0, revision: 0 },
873                        public_key_token: None,
874                        culture: None,
875                        hash_algorithm: None,
876                    });
877                }
878            }
879        }
880
881        for ea in external_assemblies {
882            program.add_external_assembly(ea);
883        }
884
885        // 设置运行时版本字符串(元数据头版本字符串)作为信息来源
886        let _ = _version_string.as_str();
887
888        Ok(program)
889    }
890
891    /// 查找并读取 CLR 头
892    ///
893    /// 该方法在 PE 文件中搜索 CLR 头。CLR 头包含:
894    /// - 大小和版本信息
895    /// - 元数据位置(RVA 和大小)
896    /// - 入口点标记
897    /// - 各种标志和配置
898    ///
899    /// # 返回
900    /// * `Ok(Some(ClrHeader))` - 成功找到并读取 CLR 头
901    /// * `Ok(None)` - 未找到 CLR 头(不是 .NET 程序集)
902    fn find_and_read_clr_header(&mut self) -> Result<Option<ClrHeader>, GaiaError> {
903        eprintln!("开始查找 CLR 头");
904
905        // 获取 PE 程序以访问数据目录
906        let pe_program = self.reader.get_program()?.clone();
907        eprintln!("获取 PE 程序成功");
908
909        // 检查数据目录数量
910        let data_dirs_count = pe_program.header.optional_header.data_directories.len();
911        eprintln!("数据目录数量: {}", data_dirs_count);
912
913        // 检查 CLR 数据目录是否存在(索引 14 是 CLR 运行时头)
914        if let Some(clr_dir) = pe_program.header.optional_header.data_directories.get(14) {
915            eprintln!("找到 CLR 数据目录 - RVA: 0x{:x}, 大小: {}", clr_dir.virtual_address, clr_dir.size);
916
917            if clr_dir.virtual_address == 0 || clr_dir.size == 0 {
918                eprintln!("CLR 数据目录为空");
919                return Ok(None);
920            }
921
922            // 将 RVA 转换为文件偏移
923            let file_offset = self.rva_to_file_offset(clr_dir.virtual_address)?;
924            eprintln!("CLR 头文件偏移: 0x{:x}", file_offset);
925
926            // 读取 CLR 头
927            let mut cursor = self.reader.get_viewer();
928            cursor
929                .seek(SeekFrom::Start(file_offset as u64))
930                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://clr_header").unwrap()))?;
931
932            let cb = cursor
933                .read_u32::<LittleEndian>()
934                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://clr_header").unwrap()))?;
935            let major_runtime_version = cursor
936                .read_u16::<LittleEndian>()
937                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://clr_header").unwrap()))?;
938            let minor_runtime_version = cursor
939                .read_u16::<LittleEndian>()
940                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://clr_header").unwrap()))?;
941            let metadata_rva = cursor
942                .read_u32::<LittleEndian>()
943                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://clr_header").unwrap()))?;
944            let metadata_size = cursor
945                .read_u32::<LittleEndian>()
946                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://clr_header").unwrap()))?;
947            let flags = cursor
948                .read_u32::<LittleEndian>()
949                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://clr_header").unwrap()))?;
950
951            eprintln!(
952                "成功读取 CLR 头 - cb: {}, 版本: {}.{}, 元数据 RVA: 0x{:x}, 大小: {}",
953                cb, major_runtime_version, minor_runtime_version, metadata_rva, metadata_size
954            );
955
956            Ok(Some(ClrHeader { cb, major_runtime_version, minor_runtime_version, metadata_rva, metadata_size, flags }))
957        }
958        else {
959            eprintln!("未找到 CLR 数据目录(索引 14)");
960            Ok(None)
961        }
962    }
963
964    /// 读取元数据头
965    ///
966    /// 该方法从指定的文件偏移位置读取元数据头。
967    /// 元数据头包含关于元数据结构的基本信息:
968    /// - 签名:表示 .NET 元数据的魔数(0x424A5342)
969    /// - 主次版本号
970    /// - 保留字段
971    /// - 版本字符串长度和内容
972    /// - 标志和流数量
973    ///
974    /// # 参数
975    /// * `offset` - 元数据头开始的文件偏移位置
976    ///
977    /// # Returns
978    /// * `Ok(MetadataHeader)` - 成功读取元数据头
979    /// * `Err(GaiaError)` - 读取过程中的错误
980    fn read_metadata_header(&mut self, offset: u32) -> Result<MetadataHeader, GaiaError> {
981        let mut cursor = self.reader.get_viewer();
982        cursor
983            .seek(SeekFrom::Start(offset as u64))
984            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
985
986        // 读取固定长度的头部字段
987        let signature = cursor
988            .read_u32::<LittleEndian>()
989            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
990        let major_version = cursor
991            .read_u16::<LittleEndian>()
992            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
993        let minor_version = cursor
994            .read_u16::<LittleEndian>()
995            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
996        let reserved = cursor
997            .read_u32::<LittleEndian>()
998            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
999        let version_length = cursor
1000            .read_u32::<LittleEndian>()
1001            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
1002
1003        // 读取版本字符串(可变长度)
1004        let mut version_bytes = vec![0u8; version_length as usize];
1005        cursor
1006            .read_exact(&mut version_bytes)
1007            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
1008        let version_string = String::from_utf8_lossy(&version_bytes).trim_end_matches('\0').to_string();
1009
1010        // 读取剩余的固定长度字段
1011        let flags = cursor
1012            .read_u16::<LittleEndian>()
1013            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
1014        let streams = cursor
1015            .read_u16::<LittleEndian>()
1016            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://metadata_header").unwrap()))?;
1017
1018        // 创建元数据头结构
1019        Ok(MetadataHeader { signature, major_version, minor_version, reserved, version_length, version_string, flags, streams })
1020    }
1021
1022    /// 读取流头信息
1023    ///
1024    /// 从元数据头之后的位置读取所有的流头信息。
1025    /// 流头紧跟在元数据头中的可变长度版本字符串之后。
1026    ///
1027    /// 流头的结构(每个流):
1028    /// - offset: 流在元数据中的偏移(4 字节)
1029    /// - size: 流的大小(4 字节)
1030    /// - name: 流的名称(以 null 结尾的字符串,长度对齐到 4 字节边界)
1031    ///
1032    /// 常见的流名称:
1033    /// - "#Strings": 字符串堆,包含各种名称
1034    /// - "#US": 用户字符串,包含字符串字面量
1035    /// - "#GUID": GUID 堆,包含 GUID 值
1036    /// - "#Blob": Blob 堆,包含二进制数据
1037    /// - "#~": 压缩的元数据表流
1038    /// - "#-": 未压缩的元数据表流
1039    ///
1040    /// # 参数
1041    /// * `metadata_offset` - 元数据头在文件中的起始偏移
1042    ///
1043    /// # 返回
1044    /// * `Ok(Vec<StreamHeader>)` - 成功读取的流头列表
1045    /// * `Err(GaiaError)` - 读取过程中的错误
1046    fn read_stream_headers(&mut self, metadata_offset: u32) -> Result<Vec<StreamHeader>, GaiaError> {
1047        let mut stream_headers = Vec::new();
1048
1049        if let Some(ref metadata_header) = self.metadata_header {
1050            let mut cursor = self.reader.get_viewer();
1051            // 计算流头的起始位置:跳过元数据头的固定部分(20 字节)和版本字符串
1052            let stream_start_offset = metadata_offset + 20 + metadata_header.version_length;
1053            cursor
1054                .seek(SeekFrom::Start(stream_start_offset as u64))
1055                .map_err(|e| GaiaError::io_error(e, Url::parse("memory://stream_headers").unwrap()))?;
1056
1057            // 读取每个流的头信息
1058            for _ in 0..metadata_header.streams {
1059                let offset = cursor
1060                    .read_u32::<LittleEndian>()
1061                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://stream_headers").unwrap()))?;
1062                let size = cursor
1063                    .read_u32::<LittleEndian>()
1064                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://stream_headers").unwrap()))?;
1065
1066                // 读取流名称(以 null 结尾的字符串)
1067                let mut name_bytes = Vec::new();
1068                loop {
1069                    let byte =
1070                        cursor.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://stream_headers").unwrap()))?;
1071                    if byte == 0 {
1072                        break;
1073                    }
1074                    name_bytes.push(byte);
1075                }
1076                let name = String::from_utf8_lossy(&name_bytes).to_string();
1077
1078                // 对齐到 4 字节边界
1079                let current_pos = cursor
1080                    .stream_position()
1081                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://stream_headers").unwrap()))?;
1082                let aligned_pos = (current_pos + 3) & !3;
1083                cursor
1084                    .seek(SeekFrom::Start(aligned_pos))
1085                    .map_err(|e| GaiaError::io_error(e, Url::parse("memory://stream_headers").unwrap()))?;
1086
1087                stream_headers.push(StreamHeader { offset, size, name });
1088            }
1089        }
1090
1091        Ok(stream_headers)
1092    }
1093
1094    /// 读取字符串堆的原始数据
1095    fn read_strings_heap_data(&mut self, strings_start: u32, strings_size: u32) -> Result<Vec<u8>, GaiaError> {
1096        let mut reader = self.reader.get_viewer();
1097        reader
1098            .seek(SeekFrom::Start(strings_start as u64))
1099            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://strings_heap").unwrap()))?;
1100
1101        let mut buffer = vec![0u8; strings_size as usize];
1102        reader.read_exact(&mut buffer).map_err(|e| GaiaError::io_error(e, Url::parse("memory://strings_heap").unwrap()))?;
1103
1104        Ok(buffer)
1105    }
1106
1107    /// 从字符串堆中读取字符串的辅助方法
1108    fn read_string_from_strings_heap(
1109        &mut self,
1110        strings_start: u32,
1111        strings_size: u32,
1112        index: u32,
1113    ) -> Result<String, GaiaError> {
1114        eprintln!("读取字符串 - 起始: {}, 大小: {}, 索引: {}", strings_start, strings_size, index);
1115
1116        if index == 0 {
1117            return Ok(String::new());
1118        }
1119
1120        let base = strings_start + index;
1121        let end = strings_start + strings_size;
1122
1123        eprintln!("计算位置 - base: {}, end: {}", base, end);
1124
1125        if base >= end {
1126            eprintln!("索引越界 - base {} >= end {}", base, end);
1127            return Err(GaiaError::syntax_error(format!("字符串索引 {} 超出堆范围", index), SourceLocation::default()));
1128        }
1129
1130        // 定位到字符串位置
1131        let viewer = self.reader.get_viewer();
1132        viewer
1133            .seek(SeekFrom::Start(base as u64))
1134            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://strings_heap").unwrap()))?;
1135
1136        // 读取以 null 结尾的字符串
1137        let mut bytes = Vec::new();
1138        loop {
1139            let byte = viewer.read_u8().map_err(|e| GaiaError::io_error(e, Url::parse("memory://strings_heap").unwrap()))?;
1140            if byte == 0 {
1141                break;
1142            }
1143            bytes.push(byte);
1144        }
1145
1146        let result = String::from_utf8_lossy(&bytes).to_string();
1147        eprintln!("成功读取字符串: '{}'", result);
1148        Ok(result)
1149    }
1150
1151    /// 将 RVA(相对虚拟地址)转换为文件偏移
1152    ///
1153    /// RVA(Relative Virtual Address)是 PE 文件中的重要概念:
1154    /// - RVA 是相对于映像基址的偏移量
1155    /// - 文件偏移是相对于文件开头的物理位置
1156    ///
1157    /// 转换过程:
1158    /// 1. 在 PE 节表中查找包含目标 RVA 的节
1159    /// 2. 计算 RVA 在节内的相对偏移
1160    /// 3. 将相对偏移加到节的文件偏移上,得到最终的文件偏移
1161    ///
1162    /// # 参数
1163    /// * `rva` - 要转换的相对虚拟地址
1164    ///
1165    /// # 返回
1166    /// * `Ok(u32)` - 成功转换的文件偏移
1167    /// * `Err(GaiaError)` - 找不到包含该 RVA 的节时的错误
1168    ///
1169    /// # 示例
1170    /// ```
1171    /// let file_offset = reader.rva_to_file_offset(0x2000)?;
1172    /// ```
1173    fn rva_to_file_offset(&mut self, rva: u32) -> Result<u32, GaiaError> {
1174        // 需要读取完整的 PE 程序以访问节信息
1175        let pe_program = self.reader.get_program()?.clone();
1176
1177        // 在节表中查找包含此 RVA 的节
1178        for section in &pe_program.sections {
1179            let section_start = section.virtual_address;
1180            let section_end = section_start + section.virtual_size;
1181
1182            // 检查 RVA 是否在该节的地址范围内
1183            if rva >= section_start && rva < section_end {
1184                // 计算 RVA 在节内的相对偏移
1185                let offset_in_section = rva - section_start;
1186                // 返回文件偏移 = 节的文件偏移 + 相对偏移
1187                return Ok(section.pointer_to_raw_data + offset_in_section);
1188            }
1189        }
1190
1191        // 找不到包含该 RVA 的节
1192        Err(GaiaError::syntax_error(format!("无法将 RVA 0x{:x} 转换为文件偏移", rva), SourceLocation::default()))
1193    }
1194}
1195
1196/// 读取堆索引(根据大小 2 或 4 字节)
1197fn read_type_def_or_ref_index<R: Read>(cursor: &mut R, idx_size: u32) -> Result<u32, GaiaError> {
1198    if idx_size == 2 {
1199        cursor
1200            .read_u16::<LittleEndian>()
1201            .map(|v| v as u32)
1202            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://type_def_or_ref_index").unwrap()))
1203    }
1204    else {
1205        cursor
1206            .read_u32::<LittleEndian>()
1207            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://type_def_or_ref_index").unwrap()))
1208    }
1209}
1210
1211fn read_heap_index<R: Read>(cursor: &mut R, idx_size: u32) -> Result<u32, GaiaError> {
1212    if idx_size == 2 {
1213        cursor
1214            .read_u16::<LittleEndian>()
1215            .map(|v| v as u32)
1216            .map_err(|e| GaiaError::io_error(e, Url::parse("memory://heap_index").unwrap()))
1217    }
1218    else if idx_size == 4 {
1219        cursor.read_u32::<LittleEndian>().map_err(|e| GaiaError::io_error(e, Url::parse("memory://heap_index").unwrap()))
1220    }
1221    else {
1222        Err(GaiaError::syntax_error("非法堆索引大小".to_string(), SourceLocation::default()))
1223    }
1224}
1225
1226/// 从 #Strings 堆读取字符串(以 0 结尾的 UTF-8)
1227fn read_string_from_heap(pe_data: &[u8], strings_start: u32, strings_size: u32, index: u32) -> Result<String, GaiaError> {
1228    if index == 0 {
1229        return Ok(String::new());
1230    }
1231    let base = strings_start + index;
1232    let end = strings_start + strings_size;
1233    if base >= end || (base as usize) >= pe_data.len() {
1234        return Ok(String::new());
1235    }
1236    let mut i = base as usize;
1237    let mut bytes = Vec::new();
1238    while i < pe_data.len() && (i as u32) < end {
1239        let b = pe_data[i];
1240        if b == 0 {
1241            break;
1242        }
1243        bytes.push(b);
1244        i += 1;
1245    }
1246    Ok(String::from_utf8_lossy(&bytes).to_string())
1247}
1248
1249/// 简单搜索子切片是否存在
1250fn find_subslice(haystack: &[u8], needle: &[u8]) -> bool {
1251    if needle.is_empty() {
1252        return true;
1253    }
1254    if haystack.len() < needle.len() {
1255        return false;
1256    }
1257    let n = needle.len();
1258    for i in 0..=haystack.len() - n {
1259        if &haystack[i..i + n] == needle {
1260            return true;
1261        }
1262    }
1263    false
1264}