@@ -4,16 +4,12 @@ use std::io::{Read, Seek};
44use byteorder:: { BigEndian , ByteOrder , LittleEndian , ReadBytesExt } ;
55
66use crate :: constants:: * ;
7- use crate :: header:: {
8- MachHeader , MachHeader32 , MachHeader64 , MH_CIGAM , MH_CIGAM_64 , MH_MAGIC , MH_MAGIC_64 ,
9- } ;
7+ use crate :: header:: * ;
108use crate :: load_commands:: * ;
119use crate :: mach_o:: MachO ;
1210use crate :: memory_utils:: { advance_to_next_load_command, get_file_offset} ;
1311
1412pub fn parse < R : Read + Seek > ( file : & mut R ) -> MachO {
15-
16-
1713 let magic = file. read_u32 :: < BigEndian > ( ) . unwrap ( ) ;
1814
1915 // TODO: use high order function to execute_with_endian(<func>, <magic>) to minimize boilerplate
@@ -51,41 +47,26 @@ fn parse_header<R: Read + Seek, E: ByteOrder>(file: &mut R, magic: u32) -> io::R
5147 match magic {
5248 MH_MAGIC | MH_CIGAM => MachHeader32 :: from_file :: < R , E > ( file, magic) ,
5349 MH_MAGIC_64 | MH_CIGAM_64 => MachHeader64 :: from_file :: < R , E > ( file, magic) ,
54- _ => {
55- return Err ( io:: Error :: new (
56- io:: ErrorKind :: InvalidData ,
57- "Invalid magic number!" ,
58- ) )
59- }
50+ _ => return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , "Invalid magic number!" ) )
6051 }
6152}
6253
63- fn parse_load_commands < R : Read + Seek , E : ByteOrder > (
64- file : & mut R ,
65- header : & MachHeader ,
66- ) -> io:: Result < ( Vec < LoadCommand > , Vec < LcStr > ) > {
54+ fn parse_load_commands < R : Read + Seek , E : ByteOrder > ( file : & mut R , header : & MachHeader ) -> io:: Result < ( Vec < LoadCommand > , Vec < LcStr > ) > {
6755 let mut load_commands: Vec < LoadCommand > = Vec :: new ( ) ;
6856 let mut load_commands_strings: Vec < LcStr > = Vec :: new ( ) ;
6957 for _ in 0 ..header. ncmds ( ) {
7058 let offset = get_file_offset ( file) ?;
7159 let load_command_prefix = LoadCommandPrefix :: from_file :: < R , E > ( file) ?;
72-
7360 let load_command = parse_command :: < R , E > ( file, & load_command_prefix) ?;
7461 let load_command_string = parse_load_command_string :: < R , E > ( file, & load_command, offset, load_command_prefix. cmdsize ) ?;
75-
7662 load_commands. push ( load_command) ;
7763 load_commands_strings. push ( load_command_string) ;
78-
7964 advance_to_next_load_command ( file, offset, load_command_prefix. cmdsize as u64 ) ?;
8065 }
81-
8266 Ok ( ( load_commands, load_commands_strings) )
8367}
8468
85- fn parse_command < R : Read , E : ByteOrder > (
86- file : & mut R ,
87- load_command_prefix : & LoadCommandPrefix ,
88- ) -> io:: Result < LoadCommand > {
69+ fn parse_command < R : Read , E : ByteOrder > ( file : & mut R , load_command_prefix : & LoadCommandPrefix ) -> io:: Result < LoadCommand > {
8970 match load_command_prefix. cmd {
9071 LC_SEGMENT => SegmentCommand32 :: from_file :: < R , E > ( file, load_command_prefix) ,
9172 LC_SYMTAB => SymtabCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
@@ -97,12 +78,8 @@ fn parse_command<R: Read, E: ByteOrder>(
9778 // TODO: LC_FVMFILE => (skip. apple's internal use),
9879 // TODO: LC_PREPAGE => (skip. apple's internal use),
9980 LC_DYSYMTAB => DynSymtabCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
100- LC_LOAD_DYLIB | LC_ID_DYLIB | LC_LOAD_WEAK_DYLIB | LC_REEXPORT_DYLIB => {
101- DylibCommand :: from_file :: < R , E > ( file, load_command_prefix)
102- }
103- LC_LOAD_DYLINKER | LC_ID_DYLINKER | LC_DYLD_ENVIRONMENT => {
104- DylinkerCommand :: from_file :: < R , E > ( file, load_command_prefix)
105- }
81+ LC_LOAD_DYLIB | LC_ID_DYLIB | LC_LOAD_WEAK_DYLIB | LC_REEXPORT_DYLIB => DylibCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
82+ LC_LOAD_DYLINKER | LC_ID_DYLINKER | LC_DYLD_ENVIRONMENT => DylinkerCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
10683 LC_PREBOUND_DYLIB => PreboundDylibCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
10784 LC_ROUTINES => RoutinesCommand32 :: from_file :: < R , E > ( file, load_command_prefix) ,
10885 LC_SUB_FRAMEWORK => SubFrameWorkCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
@@ -115,49 +92,24 @@ fn parse_command<R: Read, E: ByteOrder>(
11592 LC_ROUTINES_64 => RoutinesCommand64 :: from_file :: < R , E > ( file, load_command_prefix) ,
11693 LC_UUID => UuidCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
11794 LC_RPATH => RpathCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
118- LC_CODE_SIGNATURE
119- | LC_SEGMENT_SPLIT_INFO
120- | LC_FUNCTION_STARTS
121- | LC_DATA_IN_CODE
122- | LC_DYLIB_CODE_SIGN_DRS
123- | LC_LINKER_OPTIMIZATION_HINT => {
124- LinkeditDataCommand :: from_file :: < R , E > ( file, load_command_prefix)
125- }
95+ LC_CODE_SIGNATURE | LC_SEGMENT_SPLIT_INFO | LC_FUNCTION_STARTS | LC_DATA_IN_CODE | LC_DYLIB_CODE_SIGN_DRS | LC_LINKER_OPTIMIZATION_HINT => LinkeditDataCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
12696 // TODO: LC_LAZY_LOAD_DYLIB => (Maybe implement?),
12797 LC_ENCRYPTION_INFO => EncryptionInfoCommand32 :: from_file :: < R , E > ( file, load_command_prefix) ,
128- LC_DYLD_INFO | LC_DYLD_INFO_ONLY => {
129- DyldInfoCommand :: from_file :: < R , E > ( file, load_command_prefix)
130- }
98+ LC_DYLD_INFO | LC_DYLD_INFO_ONLY => DyldInfoCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
13199 // TODO: LC_LOAD_UPWARD_DYLIB => (Maybe implement?),
132- LC_VERSION_MIN_MACOSX
133- | LC_VERSION_MIN_IPHONEOS
134- | LC_VERSION_MIN_TVOS
135- | LC_VERSION_MIN_WATCHOS => SegmentCommand32 :: from_file :: < R , E > ( file, load_command_prefix) ,
100+ LC_VERSION_MIN_MACOSX | LC_VERSION_MIN_IPHONEOS | LC_VERSION_MIN_TVOS | LC_VERSION_MIN_WATCHOS => SegmentCommand32 :: from_file :: < R , E > ( file, load_command_prefix) ,
136101 LC_MAIN => EntryPointCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
137102 LC_SOURCE_VERSION => SourceVersionCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
138- LC_ENCRYPTION_INFO_64 => {
139- EncryptionInfoCommand64 :: from_file :: < R , E > ( file, load_command_prefix)
140- }
103+ LC_ENCRYPTION_INFO_64 => EncryptionInfoCommand64 :: from_file :: < R , E > ( file, load_command_prefix) ,
141104 LC_LINKER_OPTION => LinkerOptionCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
142105 LC_NOTE => NoteCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
143106 LC_BUILD_VERSION => BuildVersionCommand :: from_file :: < R , E > ( file, load_command_prefix) ,
144- _ => {
145- return Err ( io:: Error :: new (
146- io:: ErrorKind :: InvalidData ,
147- "unknown load command type!" ,
148- ) )
149- }
107+ _ => return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , "unknown load command type!" , ) )
150108 }
151109}
152110
153- fn parse_load_command_string < R : Read + Seek , E : ByteOrder > (
154- file : & mut R ,
155- load_command : & LoadCommand ,
156- lc_offset : u64 ,
157- cmdsize : u32 ,
158- ) -> io:: Result < LcStr > {
111+ fn parse_load_command_string < R : Read + Seek , E : ByteOrder > ( file : & mut R , load_command : & LoadCommand , lc_offset : u64 , cmdsize : u32 ) -> io:: Result < LcStr > {
159112 let mut load_command_string = Vec :: new ( ) ;
160-
161113 match load_command {
162114 LoadCommand :: DylibCommand ( _) => { }
163115 LoadCommand :: SubFrameWorkCommand ( _) => { }
@@ -169,14 +121,12 @@ fn parse_load_command_string<R: Read + Seek, E: ByteOrder>(
169121 LoadCommand :: RpathCommand ( _) => { }
170122 _ => return Ok ( load_command_string)
171123 }
172-
173124 let remaining_size = get_load_command_remaining_size ( lc_offset, cmdsize as u64 , get_file_offset ( file) ?) ?;
174125 if remaining_size > 0 {
175126 for _ in 0 ..remaining_size {
176127 load_command_string. push ( file. read_u8 ( ) ?) ;
177128 }
178129 }
179-
180130 Ok ( load_command_string)
181131}
182132
0 commit comments