Skip to content

Latest commit

 

History

History
164 lines (147 loc) · 8.3 KB

File metadata and controls

164 lines (147 loc) · 8.3 KB

Structure of traces

This document explains the structure and format of trace output files generated by PFuzzer. Each trace is divided into phases (Phase 1 and Phase 2), each with start and termination markers, followed by labeled lines describing specific events.

Mutation type codes:

Code Description
0 Nothing
1 Retarget
2 Succeed
3 Fail
4 Selective retargeting (Process32Next/FindNextFile only)
5 Scaling (timing delay scaled by 0.3)
6 Zero (timing delay zeroed out)
7 Adjust (timing query adjusted if delay mutation applied)

Trace starting line

The trace of a run begins with a line describing the current execution type and iteration: [*] <P1/P2>-iteration: <iteration-number> - Start-KUserTickCount: <tick count>

In the implementation, by Phase 1 and Phase 2 we refer, respectively, to a new epoch when fuzzing a configuration and the runs within the epoch with new mutations.

For Phase 2, and for every Phase 1 except the first, the starting line is followed by the current configuration.

The configuration lists the APIs involved, along with their properties: <api-name> - <delta> - <return-address> - <mutation-type> - <retarget-index>

Note that for APIs that iterate over a list of items (e.g., Process32Next and FindNextFile), for the retargeting mutation multiple sets of mappings are maintained between each returned item and the retarget value applied to it. Each set is indexed to allow tracking, and the mappings are saved in the file mappings_.

For Phase 1 traces (except the first, which represent the baseline run), a line is printed before the configuration to indicate which configuration is being fuzzed: [+] Now fuzzing configuration 14.

Note that if the sample tries to self-delete and PFuzzer is able to recover from this situation, in the next execution it will print [X] Self-Deleting Sample.

Phase 1 - Trace ending

The trace for a Phase 1 run ends with the following sequence of lines:

  • APIs to fuzz: Lists the environmental information-accessing APIs gathered during execution. Example: [*] To fuzz: GetModuleFileNameA 25754 40649A GetComputerNameA 9523 402533 GetFileAttributesA 10675 4029B3 Each API is followed by:
    • The offset for its return address from the PE base address
    • Its return address
  • IoC APIs: Lists all IoC-related (Indicator of Compromise) APIs and their return addresses. If present, relevant arguments are printed in the subsequent line. Example:
    IoC APIs: LoadLibraryA @ 401571
    ~>  Loading module: KERNEL32.DLL
    
  • Execution Statistics: Provides run-related metrics. Example: [+] NZB [668] HASH [23EA8411] SCORE: [77800] EVASIVE-API [14] POST-EVASIVE-API [4] Where:
    • NZB: Number of basic blocks with non-zero coverage.
    • HASH: 32-bit hash of the coverage map.
    • SCORE: Score obtained for the current run.
    • EVASIVE-API: Number of environment information-accessing APIs.
    • POST-EVASIVE-API: Number of IoC-related APIs logged.
  • Termination Line: Marks the end of the trace, along with the current tick count. Example: [*] Run terminated at KUserTickCount: 19457

Complete example:

[*] To fuzz: GetModuleFileNameA 25754 40649A GetModuleFileNameA 6725 401A45 GetComputerNameA 9523 402533 GetFileAttributesA 10675 4029B3 GetFileAttributesA 12726 4031B6 GetComputerNameA 22242 4056E2 CreateMutexA 22563 405823 Process32First 19359 404B9F Process32Next 20842 40516A GetComputerNameA 15611 403CFB GetFileAttributesA 16185 403F39 CreateFileA 17797 404585 TimeQueryAPIs 17890 4045E2 TimeDelayAPIs 17540 404484 
	IoC APIs: LoadLibraryA @ 401571
	IoC APIs: CreateFileA @ 404585
	IoC APIs: WriteFile @ 40478B
	IoC APIs: ShellExecuteA @ 4043DF
[+] NZB [668] HASH [23EA8411] SCORE: [77800] EVASIVE-API [14] POST-EVASIVE-API [4]
[*] Run terminated at KUserTickCount: 19457

Phase 2 - Trace ending

The trace for a Phase 2 run ends with a similar termination structure, with some fields being optional or reduced:

  • (Optional) IoC APIs: IoC APIs: LoadLibraryA @ 401571
  • Execution Statistics (subset of the information described for Phase1): [-] NZB [562] HASH [3EBC6B47]
  • Termination line: [*] Run terminated at KUserTickCount: 19556
  • Configuration Details (if coverage novelty was found): Printed only when the current configuration yields new coverage: [CONFIG] Score: 57200 - ID: 1 - Parent ID: 0 - Num API: 14 - Num post-evasive API: 1 - Born in run: 2 - Epoch: 1, Fuzzed in epoch: 0 This block contains:
    • Score: Score for the configuration.
    • ID: Configuration identifier in the queue.
    • Parent ID: Parent configuration's ID (0 if born in the first epoch, otherwise the ID of the configuration from which this was derived).
    • Num API: Number of environment information-accessing APIs.
    • Num post-evasive API: Number of IoC-related APIs.
    • Born in run: Run in which the configuration was created.
    • Epoch: Epoch of creation.
    • Fuzzed in epoch: Epoch during which the configuration was fuzzed.
    • List of mutated APIs, each line formatted as: `

Complete example:

	IoC APIs: LoadLibraryA @ 401571
	IoC APIs: ShellExecuteA @ 402A8F
	IoC APIs: CreateFileA @ 404585
	IoC APIs: ShellExecuteA @ 4043DF
[-] NZB [661] HASH [BA690E91]
[*] Run terminated at KUserTickCount: 23169
 |  
[CONFIG] Score: 70100 - ID: 2 - Parent ID: 0 - Num API: 14 - Num post-evasive API: 4 - Born in run: 3 - Epoch: 1, Fuzzed in epoch: 0
 ↪   GetModuleFileNameA 25754 40649A 1 1
 ↪   GetModuleFileNameA 6725 401A45 0 0
 ↪   GetComputerNameA 9523 402533 0 0
 ↪   GetFileAttributesA 10675 4029B3 2 0
 ↪   GetFileAttributesA 12726 4031B6 1 2
 ↪   GetComputerNameA 22242 4056E2 1 24
 ↪   CreateMutexA 22563 405823 1 35
 ↪   Process32First 19359 404B9F 0 0
 ↪   Process32Next 20842 40516A 4 2
 ↪   GetComputerNameA 15611 403CFB 1 26
 ↪   GetFileAttributesA 16185 403F39 1 6
 ↪   CreateFileA 17797 404585 1 2
 ↪   TimeQueryAPIs 17890 4045E2 7 0
 ↪   TimeDelayAPIs 17540 404484 6 0

Trace Labels

Throughout a trace, individual lines begin with specific labels indicating their type or context.

  • [*] Phase1 for Api: Environmental‑info API lines recorded during Phase 1. Example: [*] Phase1 for Api: GetModuleFileNameA @ 40649A => SUCCEED Format: <api-name> @ <return-address> => <result> (SUCCEED for successful calls, FAIL for negative outcomes).
  • [*] New IoC Api: IoC‑related API call, optionally followed by argument information. Example:
    [*] New IoC Api: LoadLibraryA @ 401571
    ~>  Loading module: KERNEL32.DLL
    
  • [*] Phase1 for time-delay API: Environmental-info API used to delay time. Example: [*] Phase1 for time-delay API (Sleep@41E83A)
  • [*] Phase1 for time-query API: Environmental-info API used to query time. Example: [*] Phase1 for time-query API (QueryPerformanceCounter@402E0D)

In Phase 2, the lines are prefixed by the following labels:

  • [*] Now Fuzzing Api: APIs currently in the configuration, printed at the hook location when applying the current mutation. Example: [*] Now Fuzzing Api: GetModuleFileNameA @ 40649A => RETARGET Format: <api-name> @ <retaddr> => <mutation-applied>
  • [*] New Evasive API: For new environment information-accessing APIs.
  • [*] Confirmed mutation: For certain APIs like file and registry accessing operations, this line is prefixed to APIs that required that mutation to be applied, for example: [*] Confirmed mutation (FAIL) for CreateFileW @ 4535cf indicates that such API, untouched would not fail and such mutation is actually applied, otherwise no changes to the API are made for this mutation.

When the current API has the same return address as the last logged API (for whichever label), its line is subfixed by the label (SUPPRESSED), indicating that if the next line has the same return address no trace will be seen in the output, suppressing looping prints.