@@ -10,7 +10,7 @@ pub mod vs_version_info;
1010
1111use std:: {
1212 io,
13- io:: { Error , Read , Seek , SeekFrom } ,
13+ io:: { Error , Read , Seek , SeekFrom , Take } ,
1414} ;
1515
1616pub use coff:: CoffHeader ;
@@ -23,7 +23,9 @@ pub use vs_version_info::VSVersionInfo;
2323use crate :: {
2424 analysis:: installers:: pe:: {
2525 optional_header:: DataDirectory ,
26- resource:: { ImageResourceDataEntry , ResourceDirectory , SectionReader } ,
26+ resource:: {
27+ IdOrName , ImageResourceDataEntry , ResourceDirectory , ResourceIter , SectionReader ,
28+ } ,
2729 } ,
2830 read:: ReadBytesExt ,
2931} ;
@@ -68,6 +70,17 @@ impl PE {
6870 } )
6971 }
7072
73+ pub fn resources < R : Read + Seek > ( & self , reader : R ) -> io:: Result < ResourceIter < R > > {
74+ let section_reader = self
75+ . resource_table ( )
76+ . ok_or_else ( || Error :: other ( "No resource table" ) ) ?
77+ . section_reader ( reader, & self . section_table ) ?;
78+
79+ let resource_directory = ResourceDirectory :: new ( section_reader) ?;
80+
81+ Ok ( ResourceIter :: new ( resource_directory) )
82+ }
83+
7184 pub fn find_section ( & self , name : [ u8 ; 8 ] ) -> Option < & SectionHeader > {
7285 self . section_table
7386 . sections ( )
@@ -104,6 +117,23 @@ impl PE {
104117 self . optional_header . data_directories . resource_table ( )
105118 }
106119
120+ pub fn find_resource_by_name < R > ( & self , mut reader : R , name : & str ) -> io:: Result < Take < R > >
121+ where
122+ R : Read + Seek ,
123+ {
124+ let resource = self
125+ . resources ( & mut reader) ?
126+ . find ( |resource| resource. name ( ) == Some ( name) )
127+ . ok_or_else ( || Error :: other ( format ! ( "Resource not found: {name}" ) ) ) ?;
128+
129+ let resource_offset = self
130+ . section_table
131+ . to_file_offset ( resource. offset_to_data ( ) ) ?;
132+
133+ reader. seek ( SeekFrom :: Start ( resource_offset. into ( ) ) ) ?;
134+ Ok ( reader. take ( resource. size ( ) . into ( ) ) )
135+ }
136+
107137 pub fn vs_version_info < R > ( & self , mut reader : R ) -> io:: Result < Vec < u8 > >
108138 where
109139 R : Read + Seek ,
@@ -123,11 +153,10 @@ impl PE {
123153
124154 let mut resource_directory = ResourceDirectory :: new ( section_reader) ?;
125155
126- let _version_info = resource_directory. find_version_info ( ) ?;
156+ let directory_table = resource_directory. navigate_to_version_info ( ) ?;
127157
128- let version_entry = resource_directory
129- . current_directory_table ( )
130- . entries ( )
158+ let version_entry = directory_table
159+ . id_entries ( )
131160 . next ( )
132161 . ok_or_else ( || Error :: other ( "No manifest entry found" ) ) ?;
133162
@@ -137,7 +166,7 @@ impl PE {
137166 . ok_or_else ( || Error :: other ( "No manifest directory table found" ) ) ?;
138167
139168 let version_directory = version_directory_table
140- . entries ( )
169+ . id_entries ( )
141170 . next ( )
142171 . ok_or_else ( || Error :: other ( "No manifest directory found" ) ) ?;
143172
@@ -177,11 +206,10 @@ impl PE {
177206
178207 let mut resource_directory = ResourceDirectory :: new ( section_reader) ?;
179208
180- let _manifest = resource_directory. find_manifest ( ) ?;
209+ let manifest_directory_table = resource_directory. navigate_to_manifest ( ) ?;
181210
182- let manifest_entry = resource_directory
183- . current_directory_table ( )
184- . entries ( )
211+ let manifest_entry = manifest_directory_table
212+ . id_entries ( )
185213 . next ( )
186214 . ok_or_else ( || Error :: other ( "No manifest entry found" ) ) ?;
187215
@@ -191,7 +219,7 @@ impl PE {
191219 . ok_or_else ( || Error :: other ( "No manifest directory table found" ) ) ?;
192220
193221 let manifest_directory = manifest_directory_table
194- . entries ( )
222+ . id_entries ( )
195223 . next ( )
196224 . ok_or_else ( || Error :: other ( "No manifest directory found" ) ) ?;
197225
0 commit comments