55using ELFSharp . ELF ;
66using ELFSharp . ELF . Sections ;
77
8- using ApplicationUtility ;
8+ namespace ApplicationUtility ;
99
1010class SharedLibrary : IAspect , IDisposable
1111{
1212 const uint ELF_MAGIC = 0x464c457f ;
1313
14- public static string AspectName { get ; } = "Native shared library" ;
15-
16- public bool HasAndroidPayload => payloadSize > 0 ;
17- public string Name => libraryName ;
18-
1914 readonly ulong payloadOffset ;
2015 readonly ulong payloadSize ;
2116 readonly string libraryName ;
2217 readonly bool is64Bit ;
2318 readonly Stream libraryStream ;
19+
2420 IELF elf ;
2521 bool disposed ;
22+ NativeArchitecture nativeArch = NativeArchitecture . Unknown ;
23+
24+ public static string AspectName { get ; } = "Native shared library" ;
25+
26+ public bool HasAndroidPayload => payloadSize > 0 ;
27+ public string Name => libraryName ;
28+ public NativeArchitecture TargetArchitecture => nativeArch ;
29+ public bool Is64Bit => is64Bit ;
30+
31+ protected IELF ELF => elf ;
2632
2733 protected SharedLibrary ( Stream stream , string libraryName )
2834 {
2935 this . libraryStream = stream ;
3036 this . libraryName = libraryName ;
31- ( elf , is64Bit ) = LoadELF ( stream , libraryName ) ;
37+ ( elf , is64Bit , nativeArch ) = LoadELF ( stream , libraryName ) ;
3238 ( payloadOffset , payloadSize ) = FindAndroidPayload ( elf ) ;
3339 }
3440
@@ -80,8 +86,10 @@ public Stream OpenAndroidPayload ()
8086 return new SubStream ( libraryStream , ( long ) payloadOffset , ( long ) payloadSize ) ;
8187 }
8288
83- protected static bool IsSupportedELFSharedLibrary ( Stream stream , string ? description )
89+ protected static bool IsSupportedELFSharedLibrary ( Stream stream , string ? description , out IELF ? elf )
8490 {
91+ elf = null ;
92+
8593 if ( stream . Length < 4 ) { // Less than that and we know there isn't room for ELF magic
8694 Log . Debug ( $ "SharedLibrary: stream ('{ description } ') is too short to be an ELF image.") ;
8795 return false ;
@@ -102,7 +110,7 @@ protected static bool IsSupportedELFSharedLibrary (Stream stream, string? descri
102110 return false ;
103111 }
104112
105- if ( ! ELFReader . TryLoad ( stream , shouldOwnStream : false , out IELF ? elf ) || elf == null ) {
113+ if ( ! ELFReader . TryLoad ( stream , shouldOwnStream : false , out elf ) || elf == null ) {
106114 Log . Debug ( $ "SharedLibrary: stream ('{ description } ') failed to load as an ELF image while checking support.") ;
107115 return false ;
108116 }
@@ -128,31 +136,38 @@ protected static bool IsSupportedELFSharedLibrary (Stream stream, string? descri
128136 string not = supported ? String . Empty : " not" ;
129137 Log . Debug ( $ "SharedLibrary: stream ('{ description } ') is{ not } a supported ELF architecture ('{ elf . Machine } ')") ;
130138
131- elf . Dispose ( ) ;
132139 return supported ;
133140 }
134141
142+ protected static bool IsSupportedELFSharedLibrary ( Stream stream , string ? description )
143+ {
144+ if ( ! IsSupportedELFSharedLibrary ( stream , description , out IELF ? elf ) || elf == null ) {
145+ return false ;
146+ }
147+
148+ elf . Dispose ( ) ;
149+ return true ;
150+ }
151+
135152 // We assume below that stream corresponds to a valid and supported by us ELF image. This should have been asserted by
136153 // the `LoadAspect` method.
137- ( IELF elf , bool is64bit ) LoadELF ( Stream stream , string ? libraryName )
154+ ( IELF elf , bool is64bit , NativeArchitecture nativeArch ) LoadELF ( Stream stream , string ? libraryName )
138155 {
139156 stream . Seek ( 0 , SeekOrigin . Begin ) ;
140157 if ( ! ELFReader . TryLoad ( stream , shouldOwnStream : false , out IELF ? elf ) || elf == null ) {
141158 Log . Debug ( $ "SharedLibrary: stream ('{ libraryName } ') failed to load as an ELF image.") ;
142159 throw new InvalidOperationException ( $ "Failed to load ELF library '{ libraryName } '.") ;
143160 }
144161
145- bool is64 = elf . Machine switch {
146- Machine . ARM => false ,
147- Machine . Intel386 => false ,
148-
149- Machine . AArch64 => true ,
150- Machine . AMD64 => true ,
151-
162+ ( bool is64 , NativeArchitecture arch ) = elf . Machine switch {
163+ Machine . ARM => ( false , NativeArchitecture . Arm ) ,
164+ Machine . Intel386 => ( false , NativeArchitecture . X86 ) ,
165+ Machine . AArch64 => ( true , NativeArchitecture . Arm64 ) ,
166+ Machine . AMD64 => ( true , NativeArchitecture . X64 ) ,
152167 _ => throw new NotSupportedException ( $ "Unsupported ELF architecture '{ elf . Machine } '")
153168 } ;
154169
155- return ( elf , is64 ) ;
170+ return ( elf , is64 , arch ) ;
156171 }
157172
158173 ( ulong offset , ulong size ) FindAndroidPayload ( IELF elf )
@@ -187,8 +202,13 @@ protected static bool IsSupportedELFSharedLibrary (Stream stream, string? descri
187202
188203 public bool HasSection ( string name , SectionType type = SectionType . Null )
189204 {
190- Log . Debug ( $ "Checking for section '{ name } ' with type { type } in library '{ libraryName } '") ;
191- if ( ! elf . TryGetSection ( name , out ISection ? section ) ) {
205+ return HasSection ( elf , libraryName , name , type ) ;
206+ }
207+
208+ protected static bool HasSection ( IELF elf , string libraryName , string sectionName , SectionType type = SectionType . Null )
209+ {
210+ Log . Debug ( $ "Checking for section '{ sectionName } ' with type { type } in library '{ libraryName } '") ;
211+ if ( ! elf . TryGetSection ( sectionName , out ISection ? section ) ) {
192212 Log . Debug ( "Section not found" ) ;
193213 return false ;
194214 }
0 commit comments