Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

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

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

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

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

श्रेणियाँ

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

fnprint

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

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

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

सभी देखें →

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

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

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

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

fnprint

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

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

अभी के लिए केवल x86-64 ELF। भरोसा करने से पहले सीमाएँ देखें।

मुझे दिखाओ

fnprint naming functions in a stripped, differently-compiled binary

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

root@kitploit:~
$ 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
named 9 function(s):
  0x000022f9  100.0%  adler32_z
  0x00002a8d  100.0%  compress2
  0x0000ad5d  100.0%  inflateBackEnd
  0x0000adc4   86.7%  inflate_fast
  0x00002e67   80.5%  crc32_z
  ...

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

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

root@kitploit:~
$ fnprint match old.so new.so
compared 84 functions present in both
  unchanged:  53
  changed:    1
  low-signal: 31 (too small to judge)

changed behavior (lowest similarity first):
   61.7%  deflate_stored

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

root@kitploit:~
$ 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 फ़ंक्शन्स दोनों संस्करणों में समान हैं, वे जानबूझकर inconclusive लौटाते हैं, उन्हें किसी भी पक्ष से नहीं जोड़ा जा सकता और उन्हें फ़्लैग नहीं किया जाना चाहिए। --margin और --min-sim नियंत्रित करते हैं कि कमिट करने से पहले दोनों पक्षों को कितना अलग होना पड़ेगा।

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

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

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

कोई ट्रेनिंग डेटा नहीं, कोई मॉडल नहीं। यही विचार साहित्य में Blanket Execution (Egele et al, USENIX Security 2014) के रूप में मिलता है; fnprint इसका एक व्यावहारिक, मेंटेन किया गया रूप है जिसमें एक CLI है जिसे आप वास्तव में उपयोग कर सकते हैं।

इंस्टॉल

एक rust टूलचेन और unicorn + capstone लाइब्रेरीज़ चाहिए।

root@kitploit:~
# debian/ubuntu/kali
sudo apt install libunicorn-dev libcapstone-dev

cargo install --path cli
# or just
cargo build --release   # binary at target/release/fnprint

उपयोग

root@kitploit:~
fnprint index <binary> [-o out.db]      fingerprint every function, optionally to a db
fnprint match <a> <b>                   diff two binaries (or .db files) by behavior
fnprint query <target> --corpus <db>    name unknown functions from a corpus
fnprint triage <t> --vuln <db> --patched <db>   rank a build against vuln vs patched corpora
fnprint eval <a> <b>                     accuracy metrics using symbol names as truth
fnprint dump <binary> <func>            print the recorded effect trace (debugging)

match और query या तो एक ELF लेते हैं या एक .db जिसे आपने index से बनाया है, ताकि आप एक कॉर्पस को एक बार फ़िंगरप्रिंट कर सकें और उसे दोबारा उपयोग कर सकें।

मशीन आउटपुट

प्रत्येक कमांड एक ग्लोबल --format लेता है:

root@kitploit:~
fnprint query mystery.so --corpus corpus.db --format json > names.json
fnprint query mystery.so --corpus corpus.db --format r2   > fnprint.r2

json स्क्रिप्ट्स के लिए एक स्थिर स्कीमा है (और contrib/ में Ghidra इम्पोर्ट स्टब), r2 afn रीनेम कमांड्स उत्सर्जित करता है जिन्हें आप rizin/radare2 के अंदर . fnprint.r2 के साथ चलाते हैं। टारगेट से सिंबल नामों को दोनों में से किसी में भी पहुँचने से पहले सैनिटाइज़ किया जाता है, ताकि एक तैयार किया गया नाम r2 कमांड्स इंजेक्ट न कर सके। स्कीमाज़ और सेटअप docs/integrations.md में हैं।

इंडेक्सिंग डिफ़ॉल्ट रूप से सिंगल-प्रोसेस है। FNPRINT_SHARDS=N fnprint index ... एक बड़े इंडेक्स को N jailed वर्कर्स में फैला देता है; कॉर्पस बाइट-समान रहता है चाहे N कुछ भी हो। यह केवल बड़ी, फ़ंक्शन-समृद्ध बाइनरीज़ पर मदद करता है, इसलिए जब तक आप इसे न माँगें यह बंद रहता है।

सटीकता

rank-1 सटीकता यह है: बिल्ड A के किसी फ़ंक्शन के लिए, बिल्ड B के प्रत्येक फ़ंक्शन को समानता से रैंक करें, क्या शीर्ष हिट सही है। यह ठीक वही स्ट्रिप्ड-नेमिंग कार्य है। zlib 1.3.1 (84 फ़ंक्शन्स) पर मापा गया, bench/run.sh के साथ पुनरुत्पादनीय:

pairrank-1precision
gcc O0 -> O197.1%93.8%
gcc O0 -> O293.1%83.3%
gcc O0 -> O391.3%100.0%
gcc/clang O097.7%97.1%
gcc O2 -> O356.5%66.7%
gcc/clang O259.1%50.0%

पूरी तालिका और एक दूसरी लाइब्रेरी (lua) bench/NUMBERS.md में।

eval recall@3 / recall@5 और एक abstention दर भी रिपोर्ट करता है, क्योंकि अकेले rank-1 बहुत कुछ छिपा देता है। gcc O0 -> O2 पर शीर्ष हिट 93% समय सही होता है लेकिन सही फ़ंक्शन 96.6% समय शीर्ष 5 में होता है, इसलिए एक छोटा समीक्षा बजट अधिकांश अंतर को भर देता है। यह उन जोड़ों पर जिनके बारे में इसे भरोसा नहीं है, अनुमान लगाने के बजाय abstain भी करता है (एक आत्मविश्वासी "same" कॉल से इनकार करता है), यही कारण है कि precision ऊँची बनी रहती है जबकि उसी थ्रेशोल्ड पर recall कम होता है।

ईमानदार पाठ: जब कम से कम एक पक्ष में कुछ व्यवहारिक समृद्धि होती है (कुछ भी -O0/-O1 के साथ, या -O0 पर एक क्रॉस-कंपाइलर जोड़ा) तो यह 80-98% रेंज में आता है। जब दोनों पक्ष भारी रूप से ऑप्टिमाइज़्ड होते हैं तो जो व्यवहार हम देख सकते हैं वह पतला हो जाता है और यह सिक्का उछालने की ओर गिर जाता है। यह एक सिंगल पास, ट्रेनिंग-रहित मैचर के लिए कठिन सीमा है और यह इसके विपरीत होने का दिखावा नहीं करता।

यह किसमें खराब है

  • छोटे फ़ंक्शन्स। थंक्स और एक-पंक्ति वाले एक्सेसर्स फ़िंगरप्रिंट करने के लिए पर्याप्त नहीं करते, इसलिए यह उन्हें रोक देता है (यही "low-signal" और "with enough signal" गिनतियाँ हैं)।
  • शुद्ध गणना। दो चेकसम जो दोनों एक बफ़र पढ़ते हैं और एक संख्या लौटाते हैं, एक जैसे दिखते हैं, क्योंकि बाहर से वे लगभग वैसे ही हैं।
  • एक वास्तविक पूर्व-शर्त के पीछे की गहरी लॉजिक। कचरा इनपुट के साथ microexecution किसी फ़ंक्शन के प्रवेश व्यवहार का अभ्यास करता है। किसी ऐसी स्थिति में दबा हुआ परिवर्तन जिस तक हम कचरा इनपुट के साथ कभी नहीं पहुँचते, match में नहीं दिखेगा। यह संरचनात्मक और शुरुआती-पथ परिवर्तनों को पकड़ता है, हर गहरे बदलाव को नहीं।
  • दोनों पक्षों पर भारी ऑप्टिमाइज़ेशन, जैसा कि ऊपर के आँकड़े दिखाते हैं।
  • भारी ऑब्फ़स्केशन (विशेषकर vm-आधारित) इसे बर्बाद कर देगा।

पूर्व कला, और यह कहाँ बैठता है

  • FLIRT / FunctionID / Lumina: बाइट सिग्नेचर्स। सटीक, तेज़, रीकंपाइल पर टूट जाते हैं।
  • BinDiff / Diaphora: ग्राफ़ संरचना। अच्छे, लेकिन ऑप्ट और आर्क में नाज़ुक।
  • Ghidra BSim: डीकंपाइलर फ़ीचर वेक्टर्स। भावना में करीब, लगभग सिंगल-आर्क।
  • Asm2Vec / SAFE / jTrans: सीखे गए एम्बेडिंग्स। मज़बूत, लेकिन ट्रेनिंग चाहिए और उन आर्किटेक्चर्स पर सामान्यीकृत नहीं होते जिन पर किसी ने ट्रेनिंग नहीं की।
  • microexecution (Godefroid, 2014) और Blanket Execution (Egele et al, 2014): इस दृष्टिकोण की अकादमिक जड़ें। किसी मेंटेन किए गए टूल ने इसे शिप नहीं किया।

fnprint ट्रेनिंग-रहित, व्यवहार-प्रथम विकल्प है। इफ़ेक्ट मॉडल पहले से ही आर्किटेक्चर-न्यूट्रल है, जो CPU के आर-पार मैचिंग के लिए आधार है।

रोडमैप

  • arm64 और mips, ताकि आप x86 पर किसी फ़ंक्शन को फ़िंगरप्रिंट कर सकें और उसे एक स्ट्रिप्ड राउटर फ़र्मवेयर में ढूँढ सकें। इफ़ेक्ट मॉडल पहले से ही आर्क-न्यूट्रल है, यह ज़्यादातर प्रति-आर्क एमुलेटर प्लंबिंग है।
  • बेहतर पथ कवरेज। कोड में naive ब्रांच फ़्लिपिंग है (explore_depth, डिफ़ॉल्ट रूप से बंद) लेकिन यह असंभव पथों पर बिल्ड-विशिष्ट शोर जोड़ता है और परीक्षण में क्रॉस-बिल्ड सटीकता को नुकसान पहुँचाता है, इसलिए इसके अपना स्थान अर्जित करने से पहले एक पथ-संगति फ़िल्टर चाहिए।
  • pe और mach-o लोडर्स।
  • rizin/radare2 एक्सपोर्ट अब शिप होता है (--format r2); एक असली ghidra प्लगइन अगला है। इस बीच contrib/ में एक प्रायोगिक jython इम्पोर्ट स्टब है।

लाइसेंस

MIT। LICENSE देखें।

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