@@ -64,6 +64,7 @@ struct AnalysisReport {
6464 suspicious_apis : Vec < String > ,
6565 strings_found : Vec < String > ,
6666 mitre_techniques : Vec < String > ,
67+ yara_matches : Vec < String > ,
6768}
6869
6970#[ derive( Debug , Serialize , Clone ) ]
@@ -190,6 +191,7 @@ fn main() {
190191 "T1129" . to_string( ) ,
191192 "T1082" . to_string( ) ,
192193 ] ,
194+ yara_matches : scan_with_yara ( & file_data) ,
193195 } ;
194196
195197 // Sezgisel Kurallar
@@ -249,6 +251,9 @@ fn calculate_risk_score(report: &mut AnalysisReport) {
249251 score += 15 ;
250252 }
251253
254+ // YARA matches: +25 each
255+ score += ( report. yara_matches . len ( ) as u32 ) * 25 ;
256+
252257 report. risk_score = score. min ( 100 ) ;
253258 report. risk_level = match report. risk_score {
254259 0 ..=30 => "LOW" ,
@@ -285,6 +290,37 @@ fn extract_strings(data: &[u8]) -> Vec<String> {
285290 matches
286291}
287292
293+ fn scan_with_yara ( data : & [ u8 ] ) -> Vec < String > {
294+ let mut matches = Vec :: new ( ) ;
295+ if let Ok ( mut compiler) = yara:: Compiler :: new ( ) {
296+ let rule = r#"
297+ rule UPX_Packed {
298+ strings:
299+ $upx1 = "UPX0"
300+ $upx2 = "UPX1"
301+ condition:
302+ $upx1 and $upx2
303+ }
304+ rule Suspicious_MZ {
305+ strings:
306+ $mz = "MZ"
307+ condition:
308+ $mz at 0
309+ }
310+ "# ;
311+ if let Ok ( compiler) = compiler. add_rules_str ( rule) {
312+ if let Ok ( rules) = compiler. compile_rules ( ) {
313+ if let Ok ( results) = rules. scan_mem ( data, 10 ) {
314+ for m in results {
315+ matches. push ( m. identifier . to_string ( ) ) ;
316+ }
317+ }
318+ }
319+ }
320+ }
321+ matches
322+ }
323+
288324fn generate_html_report ( report : & AnalysisReport ) -> String {
289325 let color = match report. risk_level . as_str ( ) {
290326 "LOW" => "#28a745" ,
@@ -323,6 +359,7 @@ fn generate_html_report(report: &AnalysisReport) -> String {
323359 <h3>Tespit Edilen Şüpheli API ve Stringler</h3>
324360 <p><b>APIler:</b> {}</p>
325361 <p><b>Stringler:</b> {}</p>
362+ <p><b>YARA Tespiti:</b> {}</p>
326363 </div>
327364 </body></html>"# ,
328365 color,
@@ -333,7 +370,12 @@ fn generate_html_report(report: &AnalysisReport) -> String {
333370 report. risk_score,
334371 sections_html,
335372 report. suspicious_apis. join( ", " ) ,
336- report. strings_found. join( ", " )
373+ report. strings_found. join( ", " ) ,
374+ if report. yara_matches. is_empty( ) {
375+ "Bulunamadı" . to_string( )
376+ } else {
377+ report. yara_matches. join( ", " )
378+ }
337379 )
338380}
339381
@@ -363,6 +405,9 @@ fn render_terminal_report(report: &AnalysisReport) {
363405 if !report. suspicious_apis . is_empty ( ) {
364406 println ! ( " [!] Şüpheli APIler: {:?}" , report. suspicious_apis) ;
365407 }
408+ if !report. yara_matches . is_empty ( ) {
409+ println ! ( " [!] YARA Eşleşmeleri: {:?}" , report. yara_matches) ;
410+ }
366411}
367412
368413// ─────────────────────────────────────────────────────────────
@@ -516,9 +561,10 @@ mod tests {
516561 suspicious_apis : vec ! [ "VirtualAlloc" . into( ) ] ,
517562 strings_found : vec ! [ "http" . into( ) ] ,
518563 mitre_techniques : vec ! [ ] ,
564+ yara_matches : vec ! [ "UPX_Packed" . into( ) ] ,
519565 } ;
520566 calculate_risk_score ( & mut report) ;
521- assert_eq ! ( report. risk_score, 20 + 10 + 15 ) ; // Packed(20) + API(10) + String(15) = 45
522- assert_eq ! ( report. risk_level, "MEDIUM " ) ;
567+ assert_eq ! ( report. risk_score, 20 + 10 + 15 + 25 ) ; // Packed(20) + API(10) + String(15) + YARA(25) = 70
568+ assert_eq ! ( report. risk_level, "HIGH " ) ;
523569 }
524570}
0 commit comments