Skip to content
KitploitKITPLOIT
उपकरणएक्सप्लॉइटब्लॉग
Log in
जमा करें
उपकरणएक्सप्लॉइटब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

फ़ीडसंपर्कगोपनीयता© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
fnprint — बाइनरी में फ़ंक्शन का मिलान उनके कार्य के आधार पर करें, न कि उनके बाइट्स की संरचना के आधार पर। माइक्रोएक्ज़ीक्यूशन के माध्यम से व्यवहार-आधारित फ़ंक्शन फ़िंगरप्रिंटिंग। | Kitploit
उपकरण/GitHubGitHub/1rhino2/fnprint
भेद्यता विश्लेषणगतिशील कोड विश्लेषण (DAST)रिवर्स इंजीनियरिंगमालवेयर विश्लेषणबाइनरी विश्लेषणफर्मवेयर विश्लेषण
GitHub1rhino2/fnprint

fnprint

बाइनरी में फ़ंक्शन का मिलान उनके कार्य के आधार पर करें, न कि उनके बाइट्स की संरचना के आधार पर। माइक्रोएक्ज़ीक्यूशन के माध्यम से व्यवहार-आधारित फ़ंक्शन फ़िंगरप्रिंटिंग।

रिपॉजिटरी देखें
5547012 दिन पहलेKitploit द्वारा समीक्षित
वेबसाइट

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

fnprint

fnprint फ़ंक्शन्स को बाइनरीज़ में इस आधार पर मैच करता है कि वे क्या करते हैं, न कि उनके बाइट्स या कंट्रोल-फ़्लो ग्राफ़ कैसे दिखते हैं। यह प्रत्येक फ़ंक्शन को एक छोटे एमुलेटर में बनाए गए इनपुट्स के साथ चलाता है, उसके द्वारा उत्पन्न साइड इफ़ेक्ट्स को रिकॉर्ड करता है, और उस व्यवहार को एक फ़िंगरप्रिंट में हैश करता है। दो फ़ंक्शन्स जो एक जैसा व्यवहार करते हैं, उन्हें समान फ़िंगरप्रिंट मिलते हैं, भले ही वे किसी भिन्न कंपाइलर द्वारा, किसी भिन्न ऑप्टिमाइज़ेशन स्तर पर, या किसी भिन्न CPU के लिए बनाए गए हों।

इसे इस तरह करने का उद्देश्य: बाइट सिग्नेचर्स (FLIRT, FunctionID) कोड के रीकंपाइल होते ही टूट जाते हैं, और CFG मैचर्स (BinDiff, Diaphora) -O0 बनाम -O3 में डगमगा जाते हैं और आर्किटेक्चर के पार हार मान लेते हैं। व्यवहार इन सब में बहुत बेहतर तरीके से टिका रहता है। कोई ट्रेनिंग डेटा नहीं, कोई मॉडल नहीं, एक स्टैटिक बाइनरी।

तीन चीज़ें जो यह करता है जो अन्य नहीं करते:

  • इसे मैलवेयर पर इंगित करना सुरक्षित है। एमुलेटर एक प्रिविलेज-सेपरेटेड वर्कर में seccomp जेल के अंदर चलता है जो exec, sockets, file opens, और executable memory को पूरी तरह मना करता है (unicorn को no-JIT इंटरप्रेटर के रूप में बनाया गया है ताकि इसे कभी इसकी आवश्यकता न पड़े)। एक तैयार की गई बाइनरी जो एमुलेटर को तोड़ती है, उसे एक ऐसी प्रोसेस मिलती है जो गणना कर सकती है और कुछ नहीं। देखें SECURITY.md। BinDiff, Diaphora, BSim, FLIRT और ML मैचर्स सभी शत्रुतापूर्ण बाइट्स को इन-प्रोसेस पार्स करते हैं।
  • यह आर्किटेक्चर के पार मैच करता है। जिस x86-64 बिल्ड के लिए आपके पास सिंबल्स हैं उसे इंडेक्स करें, स्ट्रिप्ड aarch64 फ़र्मवेयर को नाम दें। इफ़ेक्ट मॉडल कभी ISA नहीं देखता। zlib x86-64 -O0 बनाम aarch64 -O0: 97.7% फ़ंक्शन्स सही नामित।
  • triage आपको एक निर्णय देता है, डिफ़ नहीं। दो कॉर्पोरा (ज्ञात-भेद्य, पैच किया गया), एक मार्जिन, और उन फ़ंक्शन्स की समीक्षा कतार जो भेद्य की ओर झुके हैं। यही n-day वर्कफ़्लो एक कमांड के रूप में है।

x86-64 और aarch64 ELF। इस पर भरोसा करने से पहले सीमाएँ देखें।

मुझे दिखाओ

fnprint एक स्ट्रिप्ड, भिन्न रूप से कंपाइल की गई बाइनरी में फ़ंक्शन्स को नाम देता है

इसे एक स्ट्रिप्ड बाइनरी और उन चीज़ों के कॉर्पस पर इंगित करें जिनके नाम आपके पास पहले से हैं:

$ strip --strip-all mystery.so
$ nm mystery.so
nm: mystery.so: no symbols

$ fnprint index libz.so -o corpus.db          # a build you have symbols for
$ fnprint query mystery.so --corpus corpus.db --threshold 0.6
named 27 function(s):
  addr        sim    graph  name
  0x000022f9  100.0%     0%  adler32_z  (libz.so)
  0x00002a8d  100.0%     0%  compress2  (libz.so)
  0x00004500  100.0%     0%  deflateStateCheck  (libz.so)
  0x0000ad5d  100.0%     0%  inflateBackEnd  (libz.so)
  0x0000b69c  100.0%     0%  inflateStateCheck  (libz.so)
  0x00012f8c  100.0%     0%  _tr_tally  (libz.so)
  ...

वह रन एक पूरी तरह से स्ट्रिप्ड -O0 बिल्ड है जिसे -O2 कॉर्पस से नाम दिया गया है। भिन्न ऑप्टिमाइज़ेशन स्तर, शून्य सिंबल्स शेष, 27 नाम वापस आते हैं और सभी 27 सही हैं। यह उस पर नाम देता है जिस पर उसे भरोसा है और बाकी पर चुप रहता है। (ऊपर का gif 0.5 से है, जिसने 9 पाए; 0.6 उन स्टैटिक फ़ंक्शन्स को भी पुनः प्राप्त करता है जिन्हें एक स्ट्रिप्ड .so अपने एक्सपोर्ट्स के पीछे छिपाता है।)

CPU के पार भी वही चीज़। x86-64 बिल्ड से कॉर्पस, लक्ष्य उसी सोर्स का aarch64 बिल्ड है, सिंबल्स गए:

$ fnprint index libz_x86_64.so -o corpus.db
$ fnprint query libz_arm64_stripped.so --corpus corpus.db
named 42 function(s):
  addr        sim    graph  name
  0x00001af4  100.0%     0%  adler32_z  (libz_x86_64.so)
  0x0000263c  100.0%     0%  compress2  (libz_x86_64.so)
  0x00002958  100.0%   100%  x2nmodp  (libz_x86_64.so)
  0x00002a98  100.0%     0%  crc32_z  (libz_x86_64.so)
  0x000034c4  100.0%   100%  crc32_combine64  (libz_x86_64.so)
  ...

42 नामित, 42 सही, एक भिन्न CPU के लिए बनाए गए कॉर्पस से।

दूसरी चीज़ जो यह करता है वह दो बिल्ड्स को डिफ़ करना और आपको बताना है कि कौन से फ़ंक्शन्स का व्यवहार बदला, जो तब उपयोगी होता है जब कोई विक्रेता नया फ़र्मवेयर जारी करता है और आप जानना चाहते हैं कि वास्तव में क्या बदला। यह सिंबल नामों के साथ या बिना काम करता है: उनके साथ यह नाम से अलाइन करता है, उनके बिना यह दोनों बिल्ड्स को व्यवहार और कॉल ग्राफ़ पर अलाइन करता है, इसलिए दो पूरी तरह से स्ट्रिप्ड फ़र्मवेयर इमेजेज़ भी डिफ़ होती हैं:

$ fnprint match old.so new.so
aligned 38 function pairs by behavior + call graph (no symbol names needed)
  unchanged:  31
  changed:    7
  low-signal: 57 (too small to judge)

changed behavior (lowest similarity first):
   30.5%  compress_block
   43.0%  deflate_rle -> deflate_huff
   68.8%  deflate_slow

वास्तविक n-day काम के लिए triage है। किसी फ़ंक्शन के ज्ञात भेद्य संस्करण से एक कॉर्पस और पैच किए गए संस्करण से एक कॉर्पस बनाएँ, फिर एक अज्ञात बिल्ड को दोनों के विरुद्ध रैंक करें। भेद्य पक्ष के करीब और पैच किए गए पक्ष से स्पष्ट रूप से अलग एक फ़ंक्शन वही है जो आप किसी मानव के सामने रखना चाहते हैं, न कि केवल एक मैच स्कोर जिसकी आपको व्याख्या करनी पड़े:

$ fnprint index vuln.so    -o vuln.db
$ fnprint index patched.so -o patched.db
$ fnprint triage mystery.so --vuln vuln.db --patched patched.db
43 functions triaged: 1 look vulnerable, 0 patched, 42 inconclusive

review queue (vuln-leaning, strongest first):
   addr         vuln%  patched%  margin  matches
   0x000022f9  100.0     27.3   +72.7  adler32_z vs crc32_z

जो 42 फ़ंक्शन्स दोनों संस्करणों में समान हैं वे जानबूझकर अनिर्णायक वापस आते हैं, उन्हें किसी भी पक्ष से नहीं जोड़ा जा सकता और उन्हें फ़्लैग नहीं किया जाना चाहिए। --margin और --min-sim नियंत्रित करते हैं कि प्रतिबद्ध होने से पहले दोनों पक्षों को कितनी कठोरता से अलग होना है।

यह कैसे काम करता है

प्रत्येक फ़ंक्शन के लिए:

  • बाइनरी को मैप करें और आर्ग्युमेंट रजिस्टर्स में कचरा डालकर फ़ंक्शन पर जाएँ।
  • मेमोरी से कोई भी रीड जिसे हमने सेट नहीं किया, एक नियतात्मक मान लौटाती है और पेज को उड़ते हुए मैप कर दिया जाता है। जंगली पॉइंटर्स कभी रन को क्रैश नहीं करते, और वही इनपुट हमेशा वही ट्रेस देता है। यह Godefroid की microexecution ट्रिक है।
  • अन्य फ़ंक्शन्स के कॉल्स को स्टब कर दिया जाता है (रिकॉर्ड किया जाता है, फिर छोड़ दिया जाता है) ताकि हम कभी libc में न उतरें और रन इस फ़ंक्शन के बारे में ही रहे।
  • हम इफ़ेक्ट्स की एक आर्क-न्यूट्रल स्ट्रीम लॉग करते हैं: यह कौन से आर्ग्युमेंट बफ़र्स और स्ट्रक्ट फ़ील्ड्स पढ़ता और लिखता है, किस मान वर्ग को लिखता है (किसी इनपुट की एक प्रति, एक छोटा स्थिरांक, एक पॉइंटर), यह कौन से कॉल करता है, कौन सी ब्रांच लेता है, क्या लौटाता है। एब्सोल्यूट एड्रेस फेंक दिए जाते हैं, केवल ऑफ़सेट और आकार रखे जाते हैं।
  • उस स्ट्रीम को शिंगल्स और एक minhash सिग्नेचर में बदला जाता है। समानता मैचिंग minhash स्लॉट्स का अंश है, जो अनुमान लगाता है कि दो फ़ंक्शन्स का व्यवहार कितना ओवरलैप करता है। एक LSH बैंड इंडेक्स क्वेरीज़ को हर चीज़ की हर चीज़ से तुलना करने से रोकता है।
  • कॉल्स को केवल इम्पोर्ट टेबल से नाम दिया जाता है (plt stubs, got slots), क्योंकि यही वह हिस्सा है जो strip में बचता है। आंतरिक कॉल्स प्रिंट में अनाम रहते हैं और इसके बजाय कॉल-ग्राफ़ एज बन जाते हैं, बॉडी के एक स्टैटिक स्वीप से।
  • नामकरण और डिफ़िंग एक वैश्विक 1:1 अलाइनमेंट है, न कि प्रति-फ़ंक्शन बेस्ट-हिट लुकअप: एक कॉर्पस फ़ंक्शन को एक बार दावा किया जा सकता है, सबसे अच्छी जोड़ी पहले, फिर असाइनमेंट को एक कॉल-ग्राफ़ टर्म के साथ दो बार रीस्कोर किया जाता है (एक जोड़ी के कितने पेयर्ड कॉलर्स और कैलीज़ एक-दूसरे के साथ पेयर्ड हैं)। यही दो व्यवहारिक जुड़वाँ बच्चों को अलग बताता है, और यही 27 -O2 फ़ंक्शन्स को जो सभी एक ही स्टेट चेक को इनलाइन करते हैं, सभी को उस पर दावा करने से रोकता है।

कोई ट्रेनिंग डेटा नहीं, कोई मॉडल नहीं। यही विचार साहित्य में Blanket Execution (Egele et al, USENIX Security 2014) के रूप में दिखाई देता है; fnprint इसका एक व्यावहारिक, मेंटेन किया गया रूप है जिसमें एक CLI है जिसे आप वास्तव में उपयोग कर सकते हैं। इफ़ेक्ट मॉडल निर्माण से ही आर्क-न्यूट्रल है, यही कारण है कि एक ही सोर्स के x86-64 और aarch64 प्रिंट्स बिना कुछ सीखे मेल खाते हैं।

इंस्टॉल

टूल डाउनलोड करें