
EF/CF - अत्यंत तेज़ स्मार्ट कॉन्ट्रैक्ट फ़ज़िंग
EF/CF स्मार्ट कॉन्ट्रैक्ट फ़ज़िंग के लिए एक नया दृष्टिकोण है: नए कस्टम-निर्मित फ़ज़र के बजाय, यह C/C++ कोड के मौजूदा फ़ज़िंग इंफ्रास्ट्रक्चर को स्मार्ट कॉन्ट्रैक्ट्स पर पुनः उपयोग करता है। वर्तमान में, AFL++ मुख्य रूप से समर्थित फ़ज़र है, हालांकि libfuzzer और honggfuzz के लिए कुछ बहुत ही प्रारंभिक समर्थन भी है।
मौजूदा फ़ज़िंग इंफ्रास्ट्रक्चर का उपयोग क्यों करें?
रास्ते में हमें किन समस्याओं का सामना करना पड़ता है?
./src/ethmutator/./src/evm2cpp/यह रिपॉजिटरी EF/CF प्रोजेक्ट का प्राथमिक प्रवेश बिंदु है। इसमें सभी
प्रासंगिक कोड ./src/ में उप-प्रोजेक्ट्स के रूप में और कई सुविधाजनक स्क्रिप्ट्स
शामिल हैं: स्थापना के लिए, फ़ज़िंग अभियान शुरू करने के लिए, और विभिन्न डेटासेट जो
फ़ज़र का परीक्षण करने (और अन्य उपकरणों से तुलना करने) के लिए हैं।
./src/./data/ - मूल्यांकन के दौरान उपयोग किए गए डेटासेट शामिल हैं./scripts - प्रयोग, स्थापना आदि चलाने के लिए स्क्रिप्ट शामिल हैं./docker - कंटेनर-आधारित वर्कफ़्लो के लिए Dockerfile
./docker/tools/ में उन उपकरणों के लिए dockerfiles हैं जिनके विरुद्ध हमने EF/CF का मूल्यांकन किया।
हमने अपने पेपर में मूल्यांकित संस्करणों को dockerfiles में स्थिर करने की
पूरी कोशिश की।./EXPERIMENTS.md - एक मार्गदर्शिका शामिल है जो
हमारे पेपर के प्रयोगों को पुनः प्रस्तुत करने के लिए।./examples - EF/CF द्वारा उत्पादित उदाहरण आउटपुट शामिल हैंहम EF/CF की वास्तुकला, कार्यान्वयन का वर्णन करते हैं, और अपने मूल्यांकन परिणामों का सारांश अपने पेपर में प्रस्तुत करते हैं: arxiv.org प्रीप्रिंट
शैक्षणिक कार्य में EF/CF का उल्लेख करते समय कृपया निम्नलिखित bibtex प्रविष्टि का उपयोग करें उद्धरण के लिए:```bibtex @InProceedings{efcf2023, author = "Michael Rodler and David Paaßen and Wenting Li and Lukas Bernhard and Thorsten Holz and Ghassan Karame and Lucas Davi", title = "EF/CF: High Performance Smart Contract Fuzzing for Exploit Generation", booktitle = "{IEEE} European Symposium on Security and Privacy ({EuroS&P})", publisher = "{IEEE}", year = "2023", }
## Quickstart
अनुशंसित तरीका EF/CF को एक इंटरैक्टिव डॉकर कंटेनर के रूप में चलाना है।
1. शेल के साथ कंटेनर में प्रवेश करें ```
docker run --rm -it ghcr.io/uni-due-syssec/efcf-framework
या क्लोन की गई रिपॉजिटरी से कंटेनर बनाएँ ``` make gitmodules # to fetch the git submodules make container-enter
1. एक solidity कॉन्ट्रैक्ट को संकलित करें और फिर पहले क्रैश/बग का पता चलने तक
फ़ज़ करें: ```
efcfuzz --until-crash --out ./baby_bank_results/ --source ./data/examples/baby_bank.sol
गिट नहीं है? अगर आप tarball/docker release का उपयोग करते हैं, तो इसे अनदेखा करें।
पहले से क्लोन किए गए repositories में नवीनतम submodule commits प्राप्त करने के लिए git submodule update --init चलाएँ।
इसे ./src/eEVM में भी चलाना सुनिश्चित करें।```
git submodule update --init; cd src/eEVM/; git submodule update --init; cd ../../
*चेतावनी:* `git clone --recursive $repo` चलाना या `git sumbodule (update|init)` को `--recursive` तर्क देना git को AFL++ रिपॉजिटरी के सबमॉड्यूल्स में recursively जाने के लिए बाध्य करेगा, जो इस प्रोजेक्ट के लिए आवश्यक नहीं हैं। इसलिए कुछ स्थान बचाने के लिए recursive सबमॉड्यूल चेकआउट से बचना बेहतर है।
### कंटेनर
हम कंटेनर-आधारित वर्कफ़्लो के लिए निम्नलिखित सुविधाजनक make टारगेट प्रदान करते हैं:```sh
make container-build # build default efcf container
make container-enter # enter default efcf container in current working dir
यदि आप एक स्वच्छ बिल्ड सुनिश्चित करना चाहते हैं, तो आप निम्न कमांड का उपयोग कर सकते हैं```sh make container-build CLEAN_CHECKOUT=1
वैकल्पिक रूप से कंटेनर को निम्नलिखित डॉकर कमांड के साथ बनाया जा सकता है:```sh
docker build \
-f docker/ubuntu.Dockerfile \
-t efcf:latest \
.
ध्यान दें कि Archlinux और Fedora पर आधारित Dockerfile भी है। उन्हें भी काम करना चाहिए लेकिन उनका परीक्षण उतना अच्छी तरह से नहीं किया गया है।
docker image को मैन्युअल रूप से वितरित करने के लिए (जैसे, यदि कुछ स्थानीय परिवर्तन शामिल हैं), उपयोग करें:``` make container-release docker load -i ./efcf*.tar
हम लॉन्च करने के लिए निम्नलिखित docker विकल्पों की अनुशंसा करते हैं:
* `--security-opt seccomp=unconfined` - बेहतर fuzzing प्रदर्शन के लिए
* `--net=host` - स्थानीय ethereum नोड तक आसान पहुँच के लिए
* `--tmpfs "/tmp/efcf/":exec,size=6g` - यदि संभव हो तो EF/CF की अस्थायी फ़ाइलें ramdisk पर रखें (कम डिस्क घिसाव)
* `--privileged` - `afl-system-config` या `efcfuzz --configure-system` चलाने के लिए
* `-v` - EF/CF के आउटपुट डेटा को स्थायी रखने के लिए
### VM / बेयर-मेटल
VM या बेयर-मेटल-आधारित वर्कफ़्लो के लिए:```sh
make system-install # install efcf to current system (requires root or sudo rights)
ध्यान दें कि बहुत सारी स्क्रिप्टें वैसे भी सापेक्ष निर्देशिका लेआउट पर काम करती हैं, इसलिए
यह ज़्यादातर निर्भरताएँ (dependencies) और कुछ उपकरण (tools) इंस्टॉल करता है जो आपके
PATH में रखने के लिए उपयोगी हैं। हमने EF/CF को निम्नलिखित Linux वितरणों पर परीक्षण किया है:
(वितरण (Distro) ज़्यादा मायने नहीं रखता, हमने LLVM 13 और 14 का परीक्षण किया है और 14 को
पसंदीदा विकल्प माना है। LLVM 11 या 12 भी शायद अभी भी काम करें, लेकिन हमेशा की तरह - जितना नया उतना बेहतर।
महत्वपूर्ण बात यह है कि एक ऐसा LLVM होना चाहिए जो AFL++ के हमारे फोर्क (fork) के साथ संगत हो।)
हमने EF/CF का Mac OS पर मूल रूप से (natively) परीक्षण नहीं किया है। संभवतः चीज़ें काम नहीं करेंगी (जैसे, Mac OS पर afl-clang-lto काम नहीं करता प्रतीत होता है)। सबसे अच्छा विकल्प docker का उपयोग करना है।```sh
make gitmodules
docker pull ubuntu:jammy --platform linux/amd64
docker build -t efcf:latest -f docker/ubuntu.Dockerfile --platform linux/amd64 .
docker run --tmpfs "/tmp/efcf/":exec,size=8g --platform linux/amd64 --rm -it -v $(pwd):$(pwd) -w $(pwd) efcf:latest
हमने docker desktop v4.21.1 का उपयोग करके परीक्षण किया और बुनियादी EF/CF उपयोग काम करता है। हालाँकि, निम्नलिखित पर विचार करें:
* यदि आपको बिल्ड के दौरान segfaults दिखें: Mac OS पर docker द्वारा उपयोग की जाने वाली VM की मेमोरी सीमा बढ़ाने का प्रयास करें।
* docker में rosetta का उपयोग करके acceleration सक्षम करने का प्रयास करें - उम्मीद है कि यह थोड़ा तेज़ होगा।
### विकास सेटअप
उपकरणों को सामान्यतः स्थापित करने की आवश्यकता नहीं है। आवश्यक निर्भरताएँ
`system-install.sh` स्क्रिप्ट या Dockerfiles में दिए अनुसार स्थापित करें।
सुविधा के लिए हमारे पास आपका `PATH` अपडेट करने के लिए कुछ स्क्रिप्ट हैं:```sh
# POSIX-like shells (i.e., bash, ...)
source ./scripts/env.sh
# for the fish shell
source ./scripts/env.fish
कुछ स्क्रिप्ट्स को Etherscan सेवा से मेटाडेटा (जैसे ABI) प्राप्त करने के लिए API कुंजी की आवश्यकता होती है। यदि आपके पास API कुंजी है, तो आपको इसे स्क्रिप्ट्स तक पहुँचाने के लिए ETHERSCAN_API_KEY पर्यावरण चर सेट करना होगा। docker-आधारित वर्कफ़्लो के लिए आप या तो docker कंटेनर को --env फ्लैग के साथ लॉन्च कर सकते हैं या अपनी API कुंजी को .etherscan_api_key फ़ाइल में डाल सकते हैं, जो API कुंजी को docker कंटेनर में शामिल कर देगी।
सुविधा के लिए, हम एक रैपर स्क्रिप्ट का उपयोग करते हैं जो EF/CF फ़ज़र लॉन्च करते समय आपके लिए सभी विवरणों का ध्यान रखती है: efcfuzz
आप बिल्ड और फ़ज़िंग प्रक्रिया के संबंध में फ़ज़र के व्यवहार को कॉन्फ़िगर करने के लिए कई कमांड लाइन विकल्प सेट कर सकते हैं। विकल्पों की सूची के लिए efcfuzz --help देखें।
उदाहरण
Solidity सोर्स कोड को EF/CF नेटिव कोड में संकलित करें और 5 मिनट (अर्थात 300 सेकंड) के लिए फ़ज़िंग शुरू करें।```bash efcfuzz --timeout 300 --source ./data/examples/baby_bank.sol
वैकल्पिक रूप से, कम फ़ज़िंग आउटपुट के साथ लॉन्च करें (`--quiet` बेस
फ़ज़र का आउटपुट दबाता है, जबकि `--print-progress` फ़ज़िंग प्रगति का एक संक्षिप्त सारांश
प्रिंट करेगा), और फ़ज़र को 4 कोर पर लॉन्च करें।```bash
efcfuzz --quiet --print-progress --cores 4 --timeout 300 --source ./data/examples/baby_bank.sol
पहले से संकलित बाइटकोड का उपयोग करें और बाइटकोड को EF/CF नेटिव कोड में संकलित करें और फ़ज़िंग शुरू करें।```bash
pushd ./data/examples/; make baby_bank.combined.json; popd efcfuzz --timeout 300 --bin-runtime ./data/examples/baby_bank.combined.json
pushd ./data/examples/; make baby_bank; popd
efcfuzz --timeout 300
--bin-runtime ./data/examples/baby_bank.bin-runtime
--bin-deploy ./data/examples/baby_bank.bin
--abi ./data/examples/baby_bank.abi
रैपर किसी go-ethereum/erigon नोड से कॉन्ट्रैक्ट की स्थिति निर्यात कर सकता है और वहाँ से
फ़ज़िंग शुरू कर सकता है।```bash
$ efcfuzz --timeout 300 --live-state 0xfffF8D17CB019E0825c478c666B251A7099df3FD
इसके अलावा, आप निर्यात किए गए कॉन्ट्रैक्ट के स्टोरेज में अन्य खातों के पते खोजने और उन्हें भी स्टेट एक्सपोर्ट में शामिल करने के लिए --include-address-deps=y पास कर सकते हैं। हालाँकि, यह Solidity mapping प्रकारों में संग्रहीत अन्य कॉन्ट्रैक्ट्स को शामिल नहीं करता है। पूरे स्टेट को वास्तव में रिकर्सिव रूप से एक्सपोर्ट करने के लिए --include-mapping-deps=y फ्लैग भी पास करें।
लेकिन सावधान रहें, यह रिकर्सिव लुकअप लंबे कंपाइलेशन समय और खराब फज़िंग प्रदर्शन का कारण बन सकता है। विशेष रूप से, बार-बार उपयोग किए जाने वाले कॉन्ट्रैक्ट्स में बहुत अधिक आंतरिक स्टेट हो सकता है और उनके निर्यातित स्टेट का उपयोग करने से फज़िंग धीमी हो सकती है। जाँच करें कि क्या फज़र 1k execs/sec से अधिक प्राप्त कर सकता है। यदि नहीं, तो आपको एक कृत्रिम और छोटा स्टेट बनाने की कोशिश करनी चाहिए। एक स्थानीय go-ethereum नोड को --dev मोड में चलाने का प्रयास करें और अपने कॉन्ट्रैक्ट्स को वहाँ डिप्लॉय करें। फिर वहाँ से लाइव स्टेट एक्सपोर्ट करें।
रैपर बिल्ड को कैश करता है, इसलिए दूसरी फज़िंग रन बहुत तेज़ी से शुरू होनी चाहिए, क्योंकि प्रारंभिक कंपाइलेशन समय की अब आवश्यकता नहीं होती। यदि आप केवल बिल्ड करना चाहते हैं और इसे कैश में रखना चाहते हैं, तो आप --build-only तर्क पास कर सकते हैं।
उदाहरण: प्रॉपर्टीज़ के साथ फज़िंग
EF/CF उसी प्रॉपर्टी परिभाषा का उपयोग करके प्रॉपर्टी-आधारित फज़िंग का भी समर्थन करता है जैसा कि echidna फज़र करता है। प्रॉपर्टीज़ (या इनवेरिएंट्स) को solidity फ़ंक्शन के रूप में व्यक्त किया जाता है जो फज़र के लिए बग ओरेकल के रूप में कार्य करते हैं। उदाहरण के लिए, आप एक solidity फ़ंक्शन जोड़ सकते हैं:```solidity function test_property_balance() public view returns (bool) { return total_balance < 1000; }
जो इस गुण का प्रतिनिधित्व करता है कि total_balance हमेशा 1000 से नीचे होना चाहिए। EF/CF तब एक बग की रिपोर्ट करेगा यदि वह किसी ट्रांज़ैक्शन अनुक्रम का उपयोग करके इस गुण का उल्लंघन करने में सफल हो जाता है, अर्थात ओरेकल `false` लौटाता है।
EF/CF को यह बताने के लिए कि यह एक गुण है, आपको एक फ़ाइल में फ़ंक्शन सिग्नेचर की एक सूची निर्दिष्ट करनी होगी, जिसे EF/CF फ़ज़िंग के दौरान जाँचने के लिए गुणों की सूची के रूप में ले लेगा।
सबसे आसान तरीका है कि solidity कंपाइलर के `--hashes` फ़्लैग का उपयोग करके प्रासंगिक सिग्नेचर प्राप्त करें, उदाहरण के लिए,```
solc --hashes ./path/to/your.sol | grep test_property > property_list
अब आप फ़ज़र को इस प्रकार लॉन्च कर सकते हैं:``` efcfuzz --source ./path/to/your.sol --properties ./property_list -C
आप बिल्ट-इन ईथर-आधारित बग ओरेकल्स को अक्षम करने के लिए `--disable-detectors` भी जोड़ सकते हैं।
आप प्रॉपर्टी-आधारित फज़िंग के लिए निम्नलिखित उदाहरण आज़मा सकते हैं:```
efcfuzz \
--properties ./data/examples/harvey_baz_properties.signatures
--disable-detectors \
--until-crash --timeout 120 \
--source ./data/examples/harvey_baz.sol \
उदाहरण: ईवेंट्स के लिए फ़ज़िंग
EF/CF उन assertion उल्लंघनों के लिए फ़ज़िंग का समर्थन करता है जो ईवेंट्स के माध्यम से व्यक्त किए जाते हैं। वास्तव में, हम बग ओरेकल के रूप में मनमाने कस्टम ईवेंट्स का उपयोग करने का भी समर्थन करते हैं। डिफ़ॉल्ट रूप से, EF/CF एक बग की पहचान करेगा यदि लक्षित कॉन्ट्रैक्ट ने निम्नलिखित ईवेंट्स में से एक को लॉग किया है: AssertionFailed(), AssertionFailed(uint256), AssertionFailed(string), और Panic(uint256)।```
efcfuzz --event-assertions
--timeout 120 --until-crash
--source ./data/properties-assertions-tests/verifyfunwithnumbers.sol
आप अतिरिक्त कस्टम इवेंट टॉपिक/हैश भी निर्दिष्ट कर सकते हैं जिन्हें ध्यान में रखना है, एक फ़ाइल में `--event-assertions-list ./path/to/eventslist.txt` के साथ। पहले की प्रॉपर्टी सूची की तरह, आप `solc --hashes` का उपयोग करके प्रारूप प्राप्त कर सकते हैं और इवेंट हैश तथा नामों को इवेंट सूची फ़ाइल में कॉपी कर सकते हैं।
डिफ़ॉल्ट रूप से, EF/CF उन इवेंट्स को अनदेखा करेगा जो लक्षित कॉन्ट्रैक्ट द्वारा जारी नहीं किए गए थे। यदि आप इसे बदलना चाहते हैं तो `--event-assertions-target-only=n` का उपयोग करें।
(नोट: आप `--assertions` का उपयोग करके इवेंट और सॉलिडिटी एसर्शन दोनों की जाँच सक्षम कर सकते हैं)
**उदाहरण: Solidity ^0.8 एसर्शन के लिए फ़ज़िंग**
वर्तमान में, हम 0.8 से नीचे के solidity संस्करण के लिए solidity कोड में मनमाने एसर्शन की फ़ज़िंग का समर्थन नहीं करते हैं। पहले solidity एसर्शन केवल एक `invalid` ऑपकोड ट्रिगर करते थे, जिसके परिणामस्वरूप काफी ज़बरदस्त revert होता था। Solidity संस्करण 0.8 ने व्यवहार बदल दिया, `invalid` ऑपकोड का उपयोग करके ट्रांज़ैक्शन revert करने के बजाय, अब वे `revert` तंत्र का उपयोग करते हैं और त्रुटियों का संकेत कॉलर को वापस भेजते हैं। हम इस प्रकार के त्रुटि प्रसार को बग ओरेकल के रूप में EF/CF में उपयोग कर सकते हैं। वर्तमान में, EF/CF Solidity त्रुटि प्रकार `Panic(uint256)` की जाँच का समर्थन करता है। [Solidity त्रुटियों पर अधिक जानकारी।](https://docs.soliditylang.org/en/v0.8.0/control-structures.html?highlight=assert#panic-via-assert-and-error-via-require)```
efcfuzz --sol-assertions \
--timeout 120 --until-crash \
--source ./data/assertions-tests/overflow.sol
(नोट: आप --assertions का उपयोग करके इवेंट और सॉलिडिटी अभिकथन
जाँच दोनों को सक्षम कर सकते हैं)
सिस्टम स्पेक्स और कॉन्फ़िगरेशन
हम 4 से 16 कोर और प्रति कोर लगभग 1 GB मेमोरी आवंटित करने की अनुशंसा करते हैं। आप
--configure-system फ़्लैग का उपयोग करके अपने सिस्टम को उच्च गति
फ़ज़िंग के लिए कॉन्फ़िगर कर सकते हैं, या इसे स्वयं कॉन्फ़िगर कर सकते हैं। डॉकर कंटेनरों में आपको बेहतर प्रदर्शन के लिए होस्ट को भी कॉन्फ़िगर करना होगा।
यदि यह एक गैर-महत्वपूर्ण होस्ट है, तो आप कंटेनर को --privileged के रूप में लॉन्च कर सकते हैं और उच्च गति
फ़ज़िंग के लिए सिस्टम को कॉन्फ़िगर करने हेतु
/usr/local/bin/afl-system-config का उपयोग कर सकते हैं
(ध्यान दें कि यह अनिवार्य रूप से कंटेनर को रूट के रूप में चलाता है)।```
docker run --rm -it --privileged efcf afl-system-config
docker run --rm -it
--security-opt seccomp=unconfined
--tmpfs "/tmp/efcf/":exec,size=6g
efcf
## एक फ़ज़िंग प्रयोग चलाना
`data/tests/` डेटासेट पर प्रयोग चलाने के लिए आप निम्न
कमांड का उपयोग करके कॉन्ट्रैक्ट्स और उनके फ़ज़िंग हार्नेस को बना सकते हैं, और फिर
फ़ज़र को विभिन्न सेटिंग्स, कई दोहराव आदि के साथ चला सकते हैं।
चूँकि इसमें काफी समय लग सकता है, हम इन प्रयोगों को समानांतर रूप से चला सकते हैं। हम
फ़ज़िंग प्रयोगों को एक बिल्ड चरण और एक फ़ज़ चरण में विभाजित करते हैं। बिल्ड चरण
सभी स्मार्ट कॉन्ट्रैक्ट्स को अनुक्रमिक रूप से बनाएंगे (हालाँकि बिल्डिंग स्वयं कई कोर
का उपयोग करती है)। फिर हम पृष्ठभूमि में 8 फ़ज़र इंस्टेंस लॉन्च करते हैं, जो
बिल्ड चरण से बिल्ड आर्टिफैक्ट्स लेकर फ़ज़िंग रन शुरू करेंगे। Makefile
स्वचालित रूप से सब कुछ उचित कंटेनर में लॉन्च करने का प्रयास करेगा यदि
`docker` या `podman` उपलब्ध हो।```bash
make build-tests
make fuzz-tests CONTAINER_BACKGROUND=1 FUZZER_INSTANCES=8
हम पृष्ठभूमि में कंटेनर लॉन्च करते समय seccomp और नेटवर्क sandboxing को अक्षम कर देते हैं। seccomp sandboxing को अक्षम करने से फ़ज़िंग प्रदर्शन में सुधार होता है। होस्ट नेटवर्क का उपयोग करने से EF/CF बिना आगे कॉन्फ़िगरेशन के स्थानीय नेटवर्क में Ethereum नोड्स तक पहुंच सकते हैं।
हमने इन डेटासेट्स पर docker कंटेनरों के अंदर अन्य टूल्स को चलाने के लिए स्क्रिप्ट ./scripts/run-tools-on-dataset.py का उपयोग किया, उदाहरण के लिए multi डेटासेट के लिए इन कमांड्स के साथ:```bash
python3 ./scripts/run-tools-on-dataset.py ./data/multi/
cd ./results/tools-multi/
python3 ../../scripts/get-tools-on-dataset-stats.py
head stats.csv
You need to adapt the script to configure the tools and number of runs.
### फ़ज़िंग प्रयोग सेट करना
यहाँ, हम `tests` प्रयोग को उदाहरण के रूप में उपयोग करते हैं। निम्नलिखित चरणों में स्ट्रिंग `tests` को प्रयोग के नाम से बदल दें:
1. अपना डेटासेट `./data/` में इकट्ठा करें, उदा., टेस्ट कॉन्ट्रैक्ट्स के साथ `./data/tests` डेटासेट। Solidity कॉन्ट्रैक्ट्स के लिए हमारे पास कॉन्ट्रैक्ट्स बनाने के लिए एक जेनेरिक `Makefile` है: `sol.Makefile`. आप चाहें तो इसे पुनः उपयोग कर सकते हैं, उदाहरण के लिए `./data/tests/Makefile` देखें।
2. बिल्ड आर्टिफैक्ट्स बनाने के लिए एक स्क्रिप्ट बनाएं, जिसमें कोई भी आवश्यक प्री-प्रोसेसिंग/स्क्रैपिंग चरण शामिल हो। उदाहरण के लिए `tests` डेटासेट के लिए हमारे पास `./scripts/build-tests.sh` स्क्रिप्ट है। बिल्ड आर्टिफैक्ट्स को `./builds/tests/${contract}.build.tar.xz` में संग्रहीत किया जाना चाहिए।
3. फ़ज़िंग अभियान शुरू करने के लिए एक स्क्रिप्ट बनाएं, उदा. `tests` डेटासेट के लिए `./scripts/fuzz-tests.sh` नामक स्क्रिप्ट बनाएं। आम तौर पर आप `./scripts/common.sh` से सामान्य फ़ज़िंग अभियान फ़ंक्शन का उपयोग कर सकते हैं। टेम्पलेट के लिए `fuzz-tests.sh` देखें।
4. `fuzz-tests.sh` के परिणाम `./results/run-fuzz-tests/` में संग्रहीत किए जाएंगे।
5. परिणामों को सारांशित करने के लिए हम bash-आधारित लॉन्चर स्क्रिप्ट्स के लिए `./scripts/summarize.py` और python लॉन्चर स्क्रिप्ट्स (जो `efcfuzz` टूल है) के लिए `./scripts/summarize_l.py` प्रदान करते हैं। आपको अपने चरण 3 के आधार पर इन स्क्रिप्ट्स को अनुकूलित करने की आवश्यकता हो सकती है।
### मौजूदा फ़ज़िंग प्रयोग
#### बेंचमार्क
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/multi">`./data/multi`</a> में स्केलेबिलिटी बेंचमार्क शामिल है जिसका उपयोग हमने यह आकलन करने के लिए किया कि एक विश्लेषण उपकरण लंबे ट्रांज़ैक्शन अनुक्रमों में कितनी अच्छी तरह स्केल करता है। इसमें तीन प्रकार के कॉन्ट्रैक्ट्स शामिल हैं:
* `multi_gen_*.sol` - स्वचालित रूप से संश्लेषित कॉन्ट्रैक्ट्स, जो बहुत सारे `require(input <= MAGIC)` करते हैं और फिर एक आंतरिक स्टेट वेरिएबल सेट करते हैं। यदि सभी स्टेट वेरिएबल्स सेट हो जाते हैं, तो `selfdestruct` (या echidna oracle) ट्रिगर किया जा सकता है।
* `multi_man_complex_*.sol` - मैन्युअल रूप से निर्मित वेरिएंट जो `multi_gen` प्रकार के कॉन्ट्रैक्ट्स के समान काम करते हैं, लेकिन थोड़ी अधिक पेचीदा बाधाओं वाले होते हैं (जैसे, जादुई मान के साथ समानता और असमानता के अलावा अन्य चीज़ें)
* `justlen_*.sol` - ये [echidna-parade example](https://github.com/crytic/echidna-parade/blob/main/examples/justlen.sol) से लिए गए हैं
* `multi_simple_*.sol` - सैनिटी जाँचें जो सत्यापित करती हैं कि कोई फ़ज़र/टूल सैद्धांतिक रूप से ऐसी बग ढूंढ सकता है जिनके लिए 9 या 10 ट्रांज़ैक्शन की आवश्यकता होती है। यहाँ विश्लेषक को बिना किसी आर्गुमेंट के केवल सही क्रम में 10 फ़ंक्शन कॉल करने की आवश्यकता होती है। यह अधिकांश विश्लेषण टूल्स के लिए काफी आसान है।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/throughput">`./data/throughput`</a> में वे कॉन्ट्रैक्ट्स हैं जिनका उपयोग हमने थ्रूपुट का आकलन करने के लिए किया। यह अलग-अलग आकार के कॉन्ट्रैक्ट्स का चयन है। ध्यान दें कि हमने इन कॉन्ट्रैक्ट्स में सभी कमजोरियों को पैच कर दिया है, ताकि पाई गई कमजोरियाँ थ्रूपुट मापन को प्रभावित न करें।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/cov-max-testset">`./data/cov-max-testset`</a> में वे कॉन्ट्रैक्ट्स हैं जिनका उपयोग हमने कोड कवरेज के आधार पर फ़ज़र्स की तुलना के लिए किया।
#### बग का पता लगाना
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/ethbmc-vuln">`./data/ethbmc-vuln`</a> उन कॉन्ट्रैक्ट्स की सूची जिन्हें EthBMC ने कमजोर के रूप में पहचाना।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/ethbmc-timeouts">`./data/ethbmc-timeouts`</a> उन कॉन्ट्रैक्ट्स की सूची, जहाँ EthBMC ने टाइमआउट के कारण विश्लेषण रोक दिया।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/reentrancy">`./data/reentrancy`</a> रीएंट्रेंसी हमलों की चपेट में आने वाले कॉन्ट्रैक्ट्स का एक सेट।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/sailfish-dao-tp">`./data/sailfish-dao-tp`</a> कॉन्ट्रैक्ट्स का एक सेट जिनमें [sailfish study](https://github.com/ucsb-seclab/sailfish/tree/master/data/ground-truth) के भाग के रूप में रीएंट्रेंसी बग होने की पुष्टि की गई है।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/sailfish-dao">`./data/sailfish-dao`</a> उन सभी कॉन्ट्रैक्ट्स की सूची, जहाँ [sailfish](https://github.com/ucsb-seclab/sailfish/tree/master/data/bugs) ने रीएंट्रेंसी बग पाया।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/sereum">`./data/sereum`</a> [Sereum](https://github.com/uni-due-syssec/sereum-results) के अनुसार रीएंट्रेंसी हमलों की चपेट में आने वाले कॉन्ट्रैक्ट्स की एक सूची।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/smartbugs-curated-accesscontrol">`./data/smartbugs-curated-accesscontrol`</a> क्यूरेटेड स्मार्टबग्स के कॉन्ट्रैक्ट्स, जिन्हें "access control" बग के रूप में वर्गीकृत किया गया है ([smartbugs github](https://github.com/smartbugs/smartbugs/tree/master/dataset/access_control))
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/smartbugs-curated-reentrancy">`./data/smartbugs-curated-reentrancy`</a> क्यूरेटेड स्मार्टबग्स के कॉन्ट्रैक्ट्स, जिन्हें "reentrancy" बग के रूप में वर्गीकृत किया गया है ([smartbugs github](https://github.com/smartbugs/smartbugs/tree/master/dataset/reentrancy))
#### परीक्षण
निम्नलिखित डेटासेट में फ़ज़र की क्षमताओं का परीक्षण करने के लिए बुनियादी सिंथेटिक टेस्ट कॉन्ट्रैक्ट्स हैं:
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/tests">`./data/tests`</a> कई स्रोतों से एकत्रित बुनियादी परीक्षण जो एक फ़ज़र की बुनियादी क्षमताओं की जाँच करते हैं। सभी selfdestruct ओरेकल का उपयोग करते हैं।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/tests-not-vuln">`./data/tests-not-vuln`</a> tests के समान, लेकिन इन्हें कमजोर के रूप में पहचाना नहीं जाना चाहिए।
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/properties-tests">`./data/properties-tests`</a> प्रॉपर्टी-आधारित फ़ज़िंग के लिए परीक्षण
* <a href="https://github.com/uni-due-syssec/efcf-framework/blob/main/data/assertions-tests">`./data/assertions-tests`</a> एसर्शन के लिए फ़ज़िंग के परीक्षण।
## फ़ज़िंग और अधिक विवरण में
हम वास्तविक फ़ज़र (हमारे मामले में AFL++) को लॉन्च करने के लिए रैपर स्क्रिप्ट्स का उपयोग करते हैं। यह `efcfuzz` लॉन्चर का उपयोग करते समय स्वचालित रूप से किया जाता है।```bash
$ cd data/tests
$ make SimpleDAO.evm2cpp
$ cd ../../src/eEVM/
$ env AFL_BENCH_UNTIL_CRASH=1 ./fuzz/launch-aflfuzz.sh SimpleDAO
यदि आपके पास tmux और tmuxp स्थापित हैं तो विकास और निरीक्षण के लिए स्क्रिप्ट का इंटरैक्टिव संस्करण उपयोगी हो सकता है:```bash $ ./fuzz/interactive-aflfuzz.sh -b SimpleDAO
यह फिर कुछ समय के लिए कंपाइल और फज़ करेगा। फिर आप
`cd ./fuzz/out/SimpleDAO*` करके फज़िंग परिणाम देख सकते हैं। हमारे रैपर स्क्रिप्ट
`afl-fuzz` प्रोग्राम को लॉन्च करने के अलावा कुछ अतिरिक्त काम करते हैं, यानी मुख्यतः
परिणामों का पोस्ट-प्रोसेसिंग। इसके अलावा यह उत्पन्न टेस्ट केसों के विश्लेषण के लिए कई सुविधाजनक स्क्रिप्ट भी बनाएगा।
* `./a.sh` - किसी टेस्ट केस का मानव-पठनीय रूप प्रिंट करें, जो `efuzzcaseanalyzer` के चारों ओर एक रैपर है।
* `./r.sh` - किसी टेस्ट केस को उन्हीं सेटिंग्स के साथ चलाएं जो फज़र चलाते समय थीं।
* `./m.sh` - किसी टेस्ट केस को उन्हीं सेटिंग्स के साथ मिनिमाइज़ करें जो फज़र चलाते समय थीं।
* `./c.sh` - दिए गए टेस्ट केस तक पहुँचाने वाली टेस्ट केसों की "श्रृंखला" का विश्लेषण करें। फज़र का विश्लेषण/अनुकूलन करने के लिए उपयोगी। आप जल्दी देख सकते हैं कि कौन सा टेस्ट केस किस क्यू एंट्री पर किस उत्परिवर्तन श्रृंखला द्वारा उत्पन्न हुआ था। `fzf` आवश्यक है।
कुछ अन्य सुविधाजनक रिपोर्ट भी हैं, जैसे
* `./bugs` और `./bugtypes` जो पहचाने गए किसी भी बग का सारांश देते हैं।
* `./crashes_min`, जिसमें सभी `afl-fuzz` इंस्टेंसों के मिनिमाइज़ किए गए क्रैश शामिल हैं।
**EVM बेसिक ब्लॉक कोड कवरेज देखें**```bash
$ cat coverage-percent-all.evmcov
70.73170731707317
स्क्रिप्ट fuzz/evm-bb-coverage.sh किसी AFL आउटपुट निर्देशिका के आधार पर बेसिक ब्लॉक कवरेज की गणना करेगी। हार्नेस वैकल्पिक रूप से बेसिक ब्लॉक्स का एक ट्रेस डंप कर सकता है, जिसकी तुलना तब बेसिक ब्लॉक्स की उस सूची से की जाती है जो evm2cpp द्वारा आउटपुट की जाती है (अर्थात eEVM/contracts/ में .bb_list फ़ाइलें)।
डिफ़ॉल्ट रूप से हम उस कवरेज की भी गणना करते हैं जो हमारे डिफ़ॉल्ट जेनेरिक सीड्स (देखें
eEVM/fuzz/generic_seeds उत्पन्न करते हैं:```bash
$ cat coverage-percent-seeds.evmcov
10.5890
कवर किए गए बेसिक ब्लॉकों की सूची `all.evmcov` फ़ाइल में संग्रहीत है।
**जनरेट किए गए टेस्टकेस का सारांश देखें**
`efuzzcaseanalyzer` का उपयोग जनरेट किए गए टेस्टकेस को देखने/सारांशित करने के लिए किया जा सकता है, उदा.,```
$ efuzzcaseanalyzer -a ./contract.abi -s ./crashes_min/
Transactions Sequences:
--------------------------------------------------------------
TX [🪙]
deposit()[🪙];
withdraw(uint256)[↕️ ↩️ ];
withdraw(uint256)[];
--------------------------------------------------------------
Number of fuzzcases: 1
Average number of TXs: 3
Number of unique TX sequences: 1
Number of unique TX sequences (consecutive deduplicated): 1
सारांश आमतौर पर फ़ाइलों crashes_tx_summary और
queue_tx_summary में संग्रहीत होते हैं, लेकिन यह अंतिम वाला थोड़ा विस्तृत हो सकता है।
एकल क्रैशिंग टेस्टकेस का विश्लेषण करें``` $ ./a.sh default/crashes/id:000000,...
$ efuzzcaseanalyzer -a ./contract.abi default/crashes/id:000000,... Block header: number: 0 difficulty: 0 gas_limit: 0 timestamp: 0 initial_ether: 0
TX with tx_sender: 54 (selector); call_value: 0x0; length: 36; block+=1; #returns=0 func: withdraw(uint256) input: { Uint(80), } TX with tx_sender: 238 (selector); call_value: 0x246ddf979; length: 4; block+=1; #returns=0 func: deposit() input: { } TX with tx_sender: 153 (selector); call_value: 0x3860e6373; length: 4; block+=1; #returns=0 func: deposit() input: { } TX with tx_sender: 166 (selector); call_value: 0x0; length: 36; block+=1; #returns=1 func: withdraw(uint256) input: { Uint(37000000000000000000), } returns: return val: 1; allows reenter: 2; data: 0x0000000000000000000000000000000000000000000000000000000000000001 TX with tx_sender: 166 (selector); call_value: 0x0; length: 36; block+=1; #returns=0 func: withdraw(uint256) input: { Uint(37000000000000000000), }
और फ़ज़ टार्गेट का वास्तविक परिणाम प्राप्त करने के लिए, आप निष्पादित कर सकते हैं:```
$ ./r.sh default/crashes/id:000000,sig:06,src:000000+000010,time:1584,EM-________SAO_______AD
# roughly equivalent to running
$ env EVM_DEBUG_PRINT=1 ./build/fuzz_multitx default/crashes/id:000000,sig:06,src:000000+000010,time:1584,EM-________SAO_______AD
[...]
account 0xc4b803ea8bc30894cc4672a9159ca000d377d9a3 has balance 0x100000000000000000000000000000001bc16d67562e80000( > 0x1000000000000000000000000000000000000000000000000)
Aborted (core dumped)
यह आपको बहुत सारा विस्तृत आउटपुट देता है, जिसमें कॉन्ट्रैक्ट्स के एक्ज़ीक्यूशन ट्रेस के कुछ हिस्से और बैलेंस चेक का परिणाम शामिल हैं जो हार्नेस करता है।
क्रैशिंग इनपुट्स को मिनिमाइज़ करना
क्रैशिंग इनपुट में अक्सर असंबंधित ट्रांज़ैक्शन होते हैं, क्योंकि रैंडमाइज़्ड
टेस्टिंग दृष्टिकोण की वजह से। इसे क्रैशिंग इनपुट पर मिनिमाइज़ेशन करके
कम किया जा सकता है (यानी, इनपुट को तब तक कम करें जब तक वह अभी भी क्रैश का कारण बनता है)।
यदि आप गैर-क्रैशिंग इनपुट को मिनिमाइज़ करना चाहते हैं, तो आप -M फ़्लैग का उपयोग कर सकते हैं
ताकि मिनिमाइज़ेशन, कवरेज को मिनिमाइज़ेशन मानदंड के रूप में उपयोग करते हुए सक्षम हो।
निम्नलिखित कमांड टेस्टकेस को कम करेगा और फ़ाइल को अधिलेखित कर देगा:``` $ efuzzcaseminimizer -oa ./contract.abi ./build/fuzz_multitx ./default/crashes/id:000000,sig:06,src:000000+000010,time:1584,EM-________SAO_______AD
[..]
=== Before minimizing: === Block header: number: 0 difficulty: 0 gas_limit: 0 timestamp: 0 initial_ether: 0
TX with tx_sender: 54 (selector); call_value: 0x0; length: 36; block+=1; #returns=0 func: withdraw(uint256) input: { Uint(80), } TX with tx_sender: 238 (selector); call_value: 0x246ddf979; length: 4; block+=1; #returns=0 func: deposit() input: { } TX with tx_sender: 153 (selector); call_value: 0x3860e6373; length: 4; block+=1; #returns=0 func: deposit() input: { } TX with tx_sender: 166 (selector); call_value: 0x0; length: 36; block+=1; #returns=1 func: withdraw(uint256) input: { Uint(37000000000000000000), } returns: return val: 1; allows reenter: 2; data: 0x0000000000000000000000000000000000000000000000000000000000000001 TX with tx_sender: 166 (selector); call_value: 0x0; length: 36; block+=1; #returns=0 func: withdraw(uint256) input: { Uint(37000000000000000000), }
=== After minimizing: === Block header: number: 0 difficulty: 0 gas_limit: 0 timestamp: 0 initial_ether: 15133991795
TX with tx_sender: 4 (selector); call_value: 0x246ddf979; length: 4; block+=0; #returns=0 func: deposit() input: { } TX with tx_sender: 4 (selector); call_value: 0x0; length: 36; block+=1; #returns=1 func: withdraw(uint256) input: { Uint(37000000000000000000), } returns: return val: 1; allows reenter: 2; data: 0x TX with tx_sender: 0 (selector); call_value: 0x0; length: 36; block+=1; #returns=0 func: withdraw(uint256) input: { Uint(37000000000000000000), }
## टेस्ट-केस प्रारूप को पढ़ना
टेस्ट केस प्रारूप फ़ज़िंग के लिए बनाया गया है और इसे पढ़ना उतना सीधा नहीं है। कई बारीकियाँ हैं जिनके बारे में आपको पता होना चाहिए।
* टेस्ट केस प्रारूप को निष्पादित की जा सकने वाली ट्रांज़ैक्शनों की "कतार" माना जाता है। जैसे ही कोई समस्या आती है, टेस्ट केस की प्रोसेसिंग रुक जाती है। इसमें शामिल हैं:
* जब कोई ट्रांज़ैक्शन revert होती है।
* जब harnessing कोड को कोई त्रुटि मिलती है।
* जब कोई बग ट्रिगर होकर डिटेक्ट होता है।
इसके परिणामस्वरूप, प्रिंट किया गया टेस्ट केस जरूरी नहीं कि वही हो जो निष्पादित किया गया है - अंत में कुछ ऐसी ट्रांज़ैक्शनें हो सकती हैं जो निष्पादित नहीं हुईं। verbose आउटपुट देखें और उन्हें हटाने के लिए minimizer का उपयोग करें!
* इसी तरह, बहुत सारे `returns` या नकली `reenter` फ़्लैग हो सकते हैं। उन्हें हटाने के लिए टेस्ट केस minimizer का उपयोग करें।
* किसी कॉन्ट्रैक्ट को केवल तब reenter किया जाता है जब सूची में उस ट्रांज़ैक्शन के बाद कोई और ट्रांज़ैक्शन हो जो reentrancy करने वाली हो (यानी कतार में एक और अनुवर्ती प्रविष्टि हो)।
* भले ही `reenter` फ़्लैग कुछ भी सेट हो, इसका यह मतलब जरूरी नहीं कि कॉन्ट्रैक्ट reenter किया गया है; इसका सीधा सा अर्थ है कि harnessing कोड संभव होने पर ऐसा करने की कोशिश करेगा। उदाहरण के लिए, यदि कॉन्ट्रैक्ट कोई कॉल नहीं करता है, तो `reenter` फ़्लैग को अनदेखा कर दिया जाता है क्योंकि reenter करने की कोई संभावना नहीं होती। सामान्यतः minimizer किसी भी नकली reenter फ़्लैग को हटा देगा।
सामान्य तौर पर, टेस्ट केस minimizer का उपयोग करने पर इनमें से कई समस्याएँ दूर हो जाती हैं, इसलिए जनरेट किए गए टेस्ट केसों का विश्लेषण करने से पहले इसका उपयोग करना हमेशा एक अच्छा विचार है।
## ज्ञात गलत अलार्म
हमने कई प्रकार के गलत अलार्म देखे हैं जो EF/CF के साथ कॉन्ट्रैक्ट्स को फ़ज़ करते समय बार-बार सामने आते हैं।
* जो कॉन्ट्रैक्ट डिज़ाइन के अनुसार Ether का भुगतान करते हैं। EF/CF का Ether-gains बग ओरेकल इन कॉन्ट्रैक्ट्स को कमजोर मान लेगा, हालाँकि वे डिज़ाइन के अनुसार ही काम कर रहे हैं:
* जुआ कॉन्ट्रैक्ट्स: कई जुआ कॉन्ट्रैक्ट्स में किसी न किसी रूप में randomness होती है, जो पहले से ही Ethereum में एक बुरी प्रथा है। हालाँकि, कुछ जुआ कॉन्ट्रैक्ट्स को इस तरह लागू किया जाता है कि आपको अनुमान लगाने के लिए मजबूर किया जाए, जैसे अगले blockhash के अंतिम दो अंक या ऐसा ही कुछ। इसे commitment scheme की मदद से सक्षम किया जा सकता है, यानी पहली ट्रांज़ैक्शन उपयोगकर्ता को एक निश्चित मान के लिए प्रतिबद्ध करती है और दूसरी ट्रांज़ैक्शन अनुमान और जीतने पर भुगतान को ट्रिगर करती है। ये कॉन्ट्रैक्ट आम तौर पर वास्तविक blockchain में exploitable नहीं होते। हालाँकि, EF/CF के सिम्युलेटेड blockchain में, fuzzer दूसरी ट्रांज़ैक्शन में मान देखे जाने के बाद commitment को अनुकूलित कर सकता है। यह तथ्य EF/CF के लिए बेहतर कोड कवरेज प्राप्त करने के लिए महत्वपूर्ण है। लेकिन इससे EF/CF के लिए एक TX अनुक्रम की पहचान करना भी आसान हो जाता है जो fuzzer को जुआ कॉन्ट्रैक्ट में निर्धारित रूप से जीतने देता है।
* ब्याज देने वाले कॉन्ट्रैक्ट्स: कई छोटे कॉन्ट्रैक्ट होते हैं जो आपको Ether निवेश करने की अनुमति देते हैं और फिर हर `N` ब्लॉक में एक निश्चित प्रतिशत ब्याज का भुगतान करते हैं। EF/CF का सिम्युलेटेड हमलावर `N` ब्लॉकों तक इंतजार कर सकता है और फिर ब्याज का भुगतान प्राप्त करता है, जिसे फिर से Ether-gains बग ओरेकल उठा लेता है।
* Airdrops: कुछ टोकन कॉन्ट्रैक्ट airdrop सक्षम करते हैं, यानी किसी भी व्यक्ति को टोकन दे देना जो उन्हें मांगता है, जब तक कि एक निश्चित सीमा तक नहीं पहुँच जाती। उदाहरण के लिए, airdrop अक्सर केवल थोड़े समय के लिए सक्षम होते हैं। यदि ऐसा कोई कॉन्ट्रैक्ट EF/CF में डिप्लॉय किया जाता है, तो संभावना अधिक है कि समय सीमा ऐसी सेट हो कि airdrop अभी भी सक्षम हों। फिर EF/CF एक Ether-gains उठा लेता है यदि airdrop किए गए टोकन दोबारा बेचे जा सकते हैं।
* नियंत्रणीय `DELEGATECALL` की तुरंत रिपोर्टिंग: वर्तमान में हम किसी controllable delegatecall को आह्वान होते ही रिपोर्ट कर देते हैं। हालाँकि, ऐसे कई कॉन्ट्रैक्ट हैं जिनमें ऐसे फ़ंक्शन मौजूद होते हैं जो जानबूझकर कॉलर को किसी मनमाने पते पर delegatecall करने की अनुमति देते हैं। परंतु ये फ़ंक्शन delegatecall के तुरंत बाद बिना किसी शर्त के ट्रांज़ैक्शन को revert कर देते हैं। यह किसी भी state अपडेट या ether ट्रांसफर को स्थायी होने से रोकता है। आमतौर पर ऐसे फ़ंक्शनों के नाम में "simulate" जैसे शब्द होते हैं और इसलिए उन्हें पहचानना आसान होता है।
* इसे EF/CF में रिपोर्टिंग को निष्पादन के अंत तक टालकर ठीक किया जा सकता है। हालाँकि, यह बग ओरेकल को काफी जटिल बना देता है।
* वर्तमान में इसे ठीक करने की कोई योजना नहीं है।
* Initializer कॉल किया जा सकता है: हमने देखा कि blockchain से निर्यात किए गए कॉन्ट्रैक्ट्स को फ़ज़ करते समय, EF/CF कभी-कभी initializer फ़ंक्शनों को कॉल करने में सक्षम होता है, भले ही कॉन्ट्रैक्ट पहले ही initialized हो चुका हो। सामान्यतः, इससे revert होना चाहिए, लेकिन EF/CF के EVM वातावरण में ऐसा नहीं होता। Initializer को दोबारा कॉल करने से अक्सर मामूली Ether gains की स्थिति बनती है, क्योंकि उदाहरण के लिए, initializer एक *owner* वेरिएबल या ऐसा ही कुछ सेट करता है।
* हमें अभी तक इस समस्या का मूल कारण पक्का नहीं पता है। हालाँकि, इसे पहचानना आमतौर पर आसान होता है, क्योंकि initializer फ़ंक्शन को प्रायः `initializer`, `init`, या इसी तरह के नाम से बुलाया जाता है।
## सामान्य समस्याएँ
हमने इसे कुछ हद तक उपयोग योग्य बनाने की पूरी कोशिश की है, लेकिन यह अभी भी एक research prototype है। कुछ चीज़ों के टूटने की उम्मीद रखें। यहाँ कुछ सामान्य समस्याएँ दी गई हैं जो हमने देखीं:
* *Q: मुझे `TOKENPASTE` मैक्रो के कारण अजीब compile error आ रहा है।*
A: यह अक्सर तब होता है जब `efcfuzz` गलत कॉन्ट्रैक्ट नाम का अनुमान लगाता है (यानी वह किसी abstract कॉन्ट्रैक्ट का अनुमान लगाता है), टारगेट कॉन्ट्रैक्ट निर्दिष्ट करने के लिए `--name YourContract` पास करने की कोशिश करें।