22using PESupport ;
33using SharpPdb . Native ;
44using System ;
5+ using System . Threading . Tasks ;
56using System . Collections . Generic ;
7+ using System . Data . SQLite ;
68using System . IO ;
79using System . Linq ;
810using System . Runtime . InteropServices ;
@@ -70,7 +72,8 @@ private static void DeprecatedMain(DeprecatedOptions options) {
7072 new Config . PrefixFilter ( "?$TSS" ) ,
7173 new Config . RegexFilter ( "std@@[QU]" ) ,
7274 } ) ;
73- var cfg = new Config {
75+ var cfg = new Config
76+ {
7477 InputFile = options . InputFile ,
7578 OutputFile = options . OutputFile ,
7679 PdbFile = options . PdbFile ,
@@ -90,21 +93,63 @@ private static void RealMain(Config config, bool verbose) {
9093 using var exp = File . CreateText ( config . DefFile ) ;
9194 using var action = new PEAction ( file ) ;
9295 using var pdb = new PdbFileReader ( config . PdbFile ) ;
96+ using var db = new SQLiteConnection ( "" + new SQLiteConnectionStringBuilder
97+ {
98+ DataSource = config . FilterOutDatabase ,
99+ SyncMode = SynchronizationModes . Off ,
100+ NoSharedFlags = true ,
101+ FailIfMissing = false
102+ } ) ;
103+ db . Open ( ) ;
104+ var filterout = new SortedDictionary < string , uint > ( StringComparer . Ordinal ) ;
93105 var symdb = new SymbolDatabase ( ) ;
94106 Console . WriteLine ( "filtering ({0})" , pdb . PublicSymbols . Length ) ;
95107
96108 // Collect all symbols
97- foreach ( var item in pdb . PublicSymbols . Where ( item => config . Filter ? . Filter ( item . IsCode , item . Name ) ?? true ) )
98- symdb . Add ( ( uint ) item . RelativeVirtualAddress , item . Name ) ;
109+ Parallel . ForEach ( pdb . PublicSymbols , ( item ) => {
110+ if ( config . Filter ? . Filter ( item . IsCode , item . Name ) ?? true ) {
111+ lock ( symdb ) { symdb . Add ( ( uint ) item . RelativeVirtualAddress , item . Name ) ; }
112+ } else {
113+ lock ( filterout ) { filterout . Add ( item . Name , ( uint ) item . RelativeVirtualAddress ) ; }
114+ }
115+ } ) ;
99116
100- Console . WriteLine ( "symbols collected: {0}" , symdb . Count ( ) ) ;
117+ Console . WriteLine ( "symbols collected: {0}, filtered: {1} " , symdb . Count ( ) , filterout . Count ( ) ) ;
101118
102119 // Exclude imported symbols
103120 foreach ( var sym in action . GetImportSymbols ( ) )
104121 if ( symdb . RemoveName ( sym ) && verbose )
105122 Console . WriteLine ( "Removed {0}" , sym ) ;
123+ else if ( filterout . Remove ( sym ) && verbose )
124+ Console . WriteLine ( "Removed {0} (filtered)" , sym ) ;
106125
107- Console . WriteLine ( "symbols filtered: {0}" , symdb . Count ( ) ) ;
126+ Console . WriteLine ( "symbols fixed: {0}, filtered fixed: {1}" , symdb . Count ( ) , filterout . Count ( ) ) ;
127+
128+ // Write to filter out db
129+ using ( var transition = db . BeginTransaction ( ) ) {
130+ using ( var dropCommand = db . CreateCommand ( ) ) {
131+ dropCommand . CommandText = "DROP TABLE IF EXISTS symbols" ;
132+ dropCommand . Transaction = transition ;
133+ dropCommand . ExecuteNonQuery ( ) ;
134+ }
135+ using ( var createCommand = db . CreateCommand ( ) ) {
136+ createCommand . CommandText = "CREATE TABLE symbols(symbol TEXT PRIMARY KEY, rva INTEGER) WITHOUT ROWID" ;
137+ createCommand . Transaction = transition ;
138+ createCommand . ExecuteNonQuery ( ) ;
139+ }
140+ using ( var insertCommand = db . CreateCommand ( ) ) {
141+ insertCommand . CommandText = "INSERT INTO symbols VALUES ($symbol, $rva)" ;
142+ insertCommand . Transaction = transition ;
143+ foreach ( var item in filterout ) {
144+ insertCommand . Parameters . AddWithValue ( "$symbol" , item . Key ) ;
145+ insertCommand . Parameters . AddWithValue ( "$rva" , item . Value ) ;
146+ insertCommand . ExecuteNonQuery ( ) ;
147+ insertCommand . Parameters . Clear ( ) ;
148+ insertCommand . Reset ( ) ;
149+ }
150+ }
151+ transition . Commit ( ) ;
152+ }
108153
109154 // Build cache
110155 var cache = symdb . ToArray ( ) ;
@@ -120,8 +165,8 @@ private static void RealMain(Config config, bool verbose) {
120165
121166 // Calculate append length
122167 uint length = 0 ;
123- var expdirlength = ( uint ) Marshal . SizeOf < ExportDir > ( ) ;
124- var dllnamelength = ( uint ) ( config . DllName . Length + 1 ) ;
168+ var expdirlength = ( uint ) Marshal . SizeOf < ExportDir > ( ) ;
169+ var dllnamelength = ( uint ) ( config . DllName . Length + 1 ) ;
125170 var NumberOfFunctions = ( uint ) cache . Count ( ) ;
126171 var functionslength = NumberOfFunctions * 4 ;
127172 var NumberOfNames = ( uint ) cache . Select ( item => item . Value . Count ) . Aggregate ( 0 , ( a , b ) => a + b ) ;
@@ -141,11 +186,11 @@ private static void RealMain(Config config, bool verbose) {
141186
142187 // Start modify header
143188 var VirtualEnd = action . GetEnding ( ) ;
144- var OriginalSize = ( uint ) file . Length ;
189+ var OriginalSize = ( uint ) file . Length ;
145190 action . PatchNtHeader ( GetAlign ( length ) ) ;
146191 action . PatchDir ( 0 , VirtualEnd , length ) ;
147192 {
148- var header = new SectionHeader { } ;
193+ var header = new SectionHeader { } ;
149194 header . SetName ( ".hacked" ) ;
150195 header . Misc . VirtualSize = length ;
151196 header . VirtualAddress = VirtualEnd ;
@@ -158,7 +203,7 @@ private static void RealMain(Config config, bool verbose) {
158203 // Write export table
159204 file . SetLength ( OriginalSize + GetAlign ( length ) ) ;
160205 {
161- var expdir = new ExportDir { } ;
206+ var expdir = new ExportDir { } ;
162207 expdir . Name = VirtualEnd + expdirlength ;
163208 expdir . Base = 1 ;
164209 expdir . NumberOfFunctions = NumberOfFunctions ;
@@ -175,7 +220,7 @@ private static void RealMain(Config config, bool verbose) {
175220 action . Writer . WriteStruct ( new Ordinal { Value = idx } ) ;
176221 {
177222 var strscache = new List < uint > ( ) ;
178- var baseoff = ( uint ) file . Position ;
223+ var baseoff = ( uint ) file . Position ;
179224 var baserva = VirtualEnd + expdirlength + dllnamelength + functionslength + ordinalslength ;
180225 foreach ( var ( name , _) in sorted ) {
181226 strscache . Add ( ( uint ) file . Position - baseoff + baserva ) ;
0 commit comments