1+
2+ namespace StArray . ModManager . Runtime ;
13using System . Runtime . InteropServices ;
24using System . Text ;
35using StArray . ModManager . Native ;
46
5- namespace StArray . ModManager . Runtime ;
7+ /// <summary>搜索回调:在指定位置验证上下文,返回是否接受此匹配</summary>
8+ public delegate bool MatchValidator ( int offsetInText , byte [ ] textData , long textAddr ) ;
69
710public class NativeFuncResolver : IDisposable
811{
@@ -31,8 +34,11 @@ public NativeFuncResolver(string elfPath)
3134 out _dynStrAddr , out _dynStrOffset , out _dynStrSize ) ;
3235 }
3336
34- private ReadOnlySpan < byte > TextSpan =>
37+ public byte [ ] TextBytes =>
3538 _textBytes ??= _fileData . AsSpan ( ( int ) _textOffset , ( int ) _textSize ) . ToArray ( ) ;
39+ public long TextBaseAddress => _textAddr ;
40+
41+ private ReadOnlySpan < byte > TextSpan => TextBytes ;
3642
3743 // ===================== 统一入口 =====================
3844
@@ -153,31 +159,34 @@ public long[] FindAllRva(params byte?[] pattern)
153159 return result . ToArray ( ) ;
154160 }
155161
162+ /// <summary>带验证器的搜索:找到 byte 模式后调用 validator 决定是否接受</summary>
163+ public long [ ] FindAllRva ( byte ? [ ] pattern , MatchValidator validator )
164+ {
165+ var text = TextSpan ;
166+ var result = new List < long > ( ) ;
167+ int pos = 0 ;
168+ while ( ( pos = Search ( text , pattern , pos ) ) >= 0 )
169+ {
170+ if ( validator ( pos , _fileData , _textAddr ) )
171+ result . Add ( _textAddr + pos ) ;
172+ pos ++ ;
173+ }
174+ return result . ToArray ( ) ;
175+ }
176+
156177 // ===================== 库加载 =====================
157178
158179 public void Load ( )
159180 {
160181 if ( _loadedHandle != IntPtr . Zero ) return ;
161- if ( OperatingSystem . IsWindows ( ) ) _loadedHandle = NativeLibrary . Load ( FilePath ) ;
162- else
163- {
164- var filename = Path . GetFileName ( FilePath ) ;
165- _loadedHandle = DL . GetBaseAddress ( filename ) ;
166- if ( _loadedHandle == IntPtr . Zero )
167- {
168- DL . Open ( filename , DL . RTLDFlags . RTLD_LAZY ) ;
169- _loadedHandle = DL . GetBaseAddress ( filename ) ;
170- }
171- if ( _loadedHandle == IntPtr . Zero )
172- throw new DllNotFoundException ( $ "Failed to get base address of '{ FilePath } '") ;
173- }
182+ _loadedHandle = DL . Open ( FilePath , DL . RTLDFlags . RTLD_NOW | DL . RTLDFlags . RTLD_LOCAL ) ;
174183 }
175184
176185 public IntPtr GetFuncPtr ( long rva )
177186 {
178187 if ( _loadedHandle == IntPtr . Zero )
179188 throw new InvalidOperationException ( "Library not loaded. Call Load() first." ) ;
180- return new IntPtr ( ( long ) _loadedHandle + rva ) ;
189+ return IntPtr . Add ( _loadedHandle , ( int ) rva ) ;
181190 }
182191
183192 public void Dispose ( )
@@ -202,7 +211,7 @@ public void Dispose()
202211
203212 // ===================== 私有方法 =====================
204213
205- private static int Search ( ReadOnlySpan < byte > data , byte ? [ ] pattern , int start = 0 )
214+ public static int Search ( ReadOnlySpan < byte > data , byte ? [ ] pattern , int start = 0 )
206215 {
207216 for ( int i = start ; i <= data . Length - pattern . Length ; i ++ )
208217 {
@@ -264,4 +273,4 @@ string SecName(int idx)
264273 if ( dynSymSize == 0 ) throw new InvalidDataException ( ".dynsym section not found" ) ;
265274 if ( dynStrSize == 0 ) throw new InvalidDataException ( ".dynstr section not found" ) ;
266275 }
267- }
276+ }
0 commit comments