Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A powerful and easy-to-use fuzzing framework in Nim for C/C++/Obj-C targets

License

NotificationsYou must be signed in to change notification settings

status-im/nim-drchaos

Repository files navigation

Fuzzing is a technique for automated bug detection that involves providing random inputsto a target program to induce crashes. This approach can increase test coverage, enablingthe identification of edge cases and more efficient triggering of bugs.

Drchaos extends the Nim interface to LLVM/Clang libFuzzer, an in-process, coverage-guided,and evolutionary fuzzing engine, while also introducing support forstructured fuzzing.To utilize this functionality, users must specify the input type as a parameter for thetarget function, and the fuzzer generates valid inputs. This process employs valueprofiling to direct the fuzzer beyond these comparisons more efficiently than relying onthe probability of finding the exact sequence of bytes by chance.

Usage

Creating a fuzz target by defining a data type and a target function that performsoperations and verifies if the invariants are maintained via assert conditions is usuallyan uncomplicated task for most scenarios. For more information on creating effective fuzztargets, please refer toWhat makes a good fuzz targetOnce the target function is defined, thedefaultMutator can be called with that functionas argument.

A basic fuzz target, such as verifying that the software under test remains stable withoutcrashing by defining a fixed-size type, can suffice:

import drchaosprocfuzzMe(s:string, a, b, c:int32)=# The function being tested.if a==0xdeadc0de'i32and b==0x11111111'i32and c==0x22222222'i32:if s.len==100:doAssertfalseprocfuzzTarget(data: (string,int32,int32,int32))=let (s, a, b, c)= datafuzzMe(s, a, b, c)defaultMutator(fuzzTarget)

WARNING: Modifying the input variable within fuzz targets is not allowed.If you are using ref types, you can prevent modifications by utilizing thefunc keywordand{.experimental: "strictFuncs".} in your code.

It is also possible to create more complex fuzz targets, such as the one shown below:

import drchaostypeContentNodeKind=enum    P,Br,TextContentNode=objectcase kind:ContentNodeKind    of P: pChildren:seq[ContentNode]    ofBr:discard    ofText: textStr:stringproc`==`(a, b:ContentNode):bool=if a.kind!= b.kind:returnfalsecase a.kind  of P:return a.pChildren== b.pChildren  ofBr:returntrue  ofText:return a.textStr== b.textStrprocfuzzTarget(x:ContentNode)=# Convert or translate `x` to any desired format (JSON, HMTL, binary, etc.),# and then feed it into the API being tested.defaultMutator(fuzzTarget)

Using drchaos, it is possible to generate millions of inputs and execute fuzzTarget withinjust a few seconds. More elaborate examples, such as fuzzing a graph library, can belocated in theexamples directory.

It is critical to define a== proc for the input type. Overloadingproc default(_: typedesc[T]): T can also be advantageous, especially whennil is not avalid value forref.

Needed config

To compile the fuzz target, it is recommended to use at least the following flags:--cc:clang -d:useMalloc -t:"-fsanitize=fuzzer,address,undefined" -l:"-fsanitize=fuzzer,address,undefined" -d:nosignalhandler --nomain:on -g.Additionally, it is recommended to use--mm:arc|orc when possible.

Sample nim.cfg and .nimble files can be found in thetests/ directory andthis repository, respectively.

Alternatively, drchaos offers structured input for fuzzing usingnim-testutils. This includes a convenienttestrunner.

Post-processors

In some cases, it may be necessary to modify the randomized input to include specificvalues or create dependencies between certain fields. To support this functionality,drchaos offers a post-processing step that runs on compound types like object, tuple, ref,seq, string, array, and set. This step is only executed on these types for performance andclarity purposes, with distinct types being the exception.

procpostProcess(x:varContentNode; r:varRand)=if x.kind==Text:    x.textStr="The man the professor the student has studies Rome."

Custom mutator

ThedefaultMutator is a convenient way to generate and mutate inputs for a givenfuzz target. However, if more fine-grained control is needed, thecustomMutatorcan be used. WithcustomMutator, the mutation procedure can be customized toperform specific actions, such as uncompressing aseq[byte] before callingrunMutator on the raw data, and then compressing the output again.

procmyTarget(x:seq[byte])=var data=uncompress(x)# ...procmyMutator(x:varseq[byte]; sizeIncreaseHint:Natural; r:varRand)=var data=uncompress(x)runMutator(data, sizeIncreaseHint, r)  x=compress(data)customMutator(myTarget, myMutator)

User-defined mutate procs

Distinct types can be used to provide a mutate overload for fields with unique values orto restrict the search space. For example, it is possible to define a distinct type forfile signatures or other specific values that may be of interest.

# Inside the library being fuzzedwhendefined(runFuzzTests):typeClientId=distinctintproc`==`(a, b:ClientId):bool {.borrow.}else:typeClientId=int# Inside a test fileimport drchaos/mutatorconst  idA=0.ClientId  idB=2.ClientId  idC=4.ClientIdprocmutate(value:varClientId; sizeIncreaseHint:int; enforceChanges:bool; r:varRand)=# Call `random.rand()` to return a new value.repeatMutate(r.sample([idA, idB, idC]))

Thedrchaos/mutator module exports mutators for every supported type to aid in thecreation of mutate functions.

User-defined serializers

User overloads should follow the followingproc signatures:

procfromData(data:openArray[byte]; pos:varint; output:var T)proctoData(data:varopenArray[byte]; pos:varint; input: T)procbyteSize(x: T):int {.inline.}# The amount of memory that the serialized type will occupy, measured in bytes.

The need for this arises only in the case of objects that include raw pointers. To addressthis,drchaos/common offers read/write procedures to simplify the process.

It is necessary to define themutate,default and== procedures. For containertypes, it is also necessary to definemitems ormpairs iterators.

Best practices and considerations

  • Avoid usingecho in a fuzz target as it can significantly slow down the execution speed.

  • Prefer using-d:danger for maximum performance, but ensure that your code is free fromundefined behavior and does not rely on any assumptions that may break in unexpected ways.

  • Once you have identified a crash, you can recompile the program with-d:debug and pass thecrashing test case as a parameter to further investigate the cause of the crash.

  • UsedebugEcho(x) in a target to print the input that caused the crash, which can behelpful in debugging and reproducing the issue.

  • Although disabling sanitizers may improve performance, it is not recommended asAddressSanitizer can help catch memory errors and undefined behavior that may lead tocrashes or other bugs.

What's not supported

  • Polymorphic types do not have serialization support.
  • References with cycles are not supported. However, a .noFuzz custom pragma will be added soon for cursors.
  • Object variants only work with the latest memory management model, which is--mm:arc|orc.

Advantages of using drchaos for fuzzing

drchaos offers a number of advantages over frameworks based onFuzzDataProvider,which often have difficulty handling nested dynamic types. For a more detailedexplanation of these issues, you can read an article by the author of Fuzzcheck, availableat the following link:https://github.com/loiclec/fuzzcheck-rs/blob/main/articles/why_not_bytes.md

Bugs discovered with the assistance of drchaos

The drchaos framework has helped discover various bugs in software projects. Here are someexamples of bugs that were found in the Nim reference implementation with the help ofdrchaos:

License

Licensed and distributed under either of

or

at your option. These files may not be copied, modified, or distributed except according to those terms.

About

A powerful and easy-to-use fuzzing framework in Nim for C/C++/Obj-C targets

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp