1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::*;
use super::Wrap;

use std::slice;

/// Imported symbol.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
pub enum Import<'a> {
	/// Imported by name.
	///
	/// The hint is an index in the export names table that may contain the desired symbol.
	/// For more information see this [blog post](https://blogs.msdn.microsoft.com/oldnewthing/20100317-00/?p=14573) by Raymond Chen.
	ByName { hint: usize, name: &'a util::CStr },
	/// Imported by ordinal.
	ByOrdinal { ord: u16 },
}

/// Import directory.
impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::imports::Imports<'a, Pe32>, pe64::imports::Imports<'a, Pe64>> {
	/// Gets the PE instance.
	#[inline]
	pub fn pe(&self) -> Wrap<Pe32, Pe64> {
		match self {
			Wrap::T32(imports) => Wrap::T32(imports.pe()),
			Wrap::T64(imports) => Wrap::T64(imports.pe()),
		}
	}
	/// Returns the underlying import directory image array.
	#[inline]
	pub fn image(&self) -> &'a [image::IMAGE_IMPORT_DESCRIPTOR] {
		match self {
			Wrap::T32(imports) => imports.image(),
			Wrap::T64(imports) => imports.image(),
		}
	}
	/// Iterator over the import descriptors.
	#[inline]
	pub fn iter(&self) -> Wrap<pe32::imports::Iter<'a, Pe32>, pe64::imports::Iter<'a, Pe64>> {
		match self {
			Wrap::T32(imports) => Wrap::T32(imports.iter()),
			Wrap::T64(imports) => Wrap::T64(imports.iter()),
		}
	}
}
impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> IntoIterator for Wrap<pe32::imports::Imports<'a, Pe32>, pe64::imports::Imports<'a, Pe64>> {
	type Item = Wrap<pe32::imports::Desc<'a, Pe32>, pe64::imports::Desc<'a, Pe64>>;
	type IntoIter = Wrap<pe32::imports::Iter<'a, Pe32>, pe64::imports::Iter<'a, Pe64>>;
	#[inline]
	fn into_iter(self) -> Self::IntoIter {
		match self {
			Wrap::T32(imports) => Wrap::T32(imports.into_iter()),
			Wrap::T64(imports) => Wrap::T64(imports.into_iter()),
		}
	}
}

/// Import Address Table.
impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::imports::IAT<'a, Pe32>, pe64::imports::IAT<'a, Pe64>> {
	/// Gets the PE instance.
	#[inline]
	pub fn pe(&self) -> Wrap<Pe32, Pe64> {
		match self {
			Wrap::T32(iat) => Wrap::T32(iat.pe()),
			Wrap::T64(iat) => Wrap::T64(iat.pe()),
		}
	}
	/// Returns the underlying iat array.
	#[inline]
	pub fn image(&self) -> Wrap<&'a [u32], &'a [u64]> {
		match self {
			Wrap::T32(iat) => Wrap::T32(iat.image()),
			Wrap::T64(iat) => Wrap::T64(iat.image()),
		}
	}
	/// Iterate over the IAT.
	#[inline]
	pub fn iter(&self) -> Wrap<impl Clone + Iterator<Item = (&'a u32, Result<pe32::imports::Import<'a>>)>, impl Clone + Iterator<Item = (&'a u64, Result<pe64::imports::Import<'a>>)>> {
		match self {
			Wrap::T32(iat) => Wrap::T32(iat.iter()),
			Wrap::T64(iat) => Wrap::T64(iat.iter()),
		}
	}
}

/// Import library descriptor.
impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::imports::Desc<'a, Pe32>, pe64::imports::Desc<'a, Pe64>> {
	/// Gets the PE instance.
	#[inline]
	pub fn pe(&self) -> Wrap<Pe32, Pe64> {
		match self {
			Wrap::T32(desc) => Wrap::T32(desc.pe()),
			Wrap::T64(desc) => Wrap::T64(desc.pe()),
		}
	}
	/// Returns the underlying import descriptor image.
	#[inline]
	pub fn image(&self) -> &'a image::IMAGE_IMPORT_DESCRIPTOR {
		match self {
			Wrap::T32(desc) => desc.image(),
			Wrap::T64(desc) => desc.image(),
		}
	}
	/// Gets the name of the DLL imported from.
	#[inline]
	pub fn dll_name(&self) -> Result<&'a util::CStr> {
		match self {
			Wrap::T32(desc) => desc.dll_name(),
			Wrap::T64(desc) => desc.dll_name(),
		}
	}
	/// Gets the import address table.
	#[inline]
	pub fn iat(&self) -> Result<Wrap<slice::Iter<'a, u32>, slice::Iter<'a, u64>>> {
		match self {
			Wrap::T32(desc) => Wrap::T32(desc.iat()).transpose(),
			Wrap::T64(desc) => Wrap::T64(desc.iat()).transpose(),
		}
	}
	/// Gets the import name table.
	#[inline]
	pub fn int(&self) -> Result<impl Clone + Iterator<Item = Result<Import<'a>>>> {
		match self {
			Wrap::T32(desc) => Ok(Wrap::T32(desc.int()?).map(Wrap::into)),
			Wrap::T64(desc) => Ok(Wrap::T64(desc.int()?).map(Wrap::into)),
		}
	}
}