Skip to content

3.3. JSON reports

hasherezade edited this page May 14, 2023 · 46 revisions

PE-sieve creates 2 JSON reports:

JSON output

By default, the reports are saved into the output directory, in the files appropriately named scan_report.json and dump_report.json.

If PE-sieve is run with the option /json, then additionally both reports are displayed on stdout after the scan is finished (instead of the brief summary). Format:

{
 "scan_report" :
 {
// scan report content
 },
 "dump_report" :
 {
// dump report content
 }
}

Scan report

The scan report is divided into segments. First comes the general summary from all scans. Example:

{
 "pid" : 684, // PID of the process that was scanned
 "is_64_bit" : 1, // Flag indicating if the process was 64 bit: 1 if true, 0 if false
 "is_managed" : 0, // Flag indicating if the process was managed (.NET) : 1 if true (.NET process) , 0 if false (native process)
 "main_image_path" : "", // The path of the main image (from PEB). If empty, it often indicates process Doppelgänging.
 "used_reflection" : 0, // Flag indicating if the scan was performed on the raw process, or on process reflection
 "scanned" : 
 {
  "total" : 48,  // total count of scanned modules
  "skipped" : 0, // count of modules excluded from the scan, for example:
                 // excluded on demand by the parameter: /mignore <module>
  "modified" : // list of all the modules in which any of the suspicious indicators were detected
  {
   "total" : 2, // total count of modules detected as suspicious
   "patched" : 0, // count of modules detected as patched (possible inline hooks or other code modifications)
   "iat_hooked" : 0, // count of modules where IAT hooks were detected
   "replaced" : 1, // count of hollowed/replaced modules
   "hdr_modified" : 0, //count of modules with PE headers modified (but without modifications typical for replaced modules)
   "implanted_pe" : 0, // count of manually mapped PEs (not associated with any PE file on the disk)
   "implanted_shc" : 0, // count of sections with code mapped outside of any PE (shellcodes, JITs)
   "unreachable_file" : 0, // count of modules that were associated with a PE file on the disk, but
                           // this file was deleted or inaccessible
   "other" : 1 // any additional indicators - such as
               // inconsistency between the path of mapped module and corresponding path set in the PEB
  },
  "errors" : 0 // count of inconclusive scans, interrupted by some errors
 },
[...]

After the general summary, we have a list of reports for particular scans that gave the suspicious indicators. Example:

 "scans" : [ // list of the reports from particular scans
  {
   "mapping_scan" : {
    "module" : "7ff6bc950000",
    "module_file" : "C:\\Windows\\notepad.exe",
    "mapped_file" : "",
    "status" : 1
   }
  },
  {
   "headers_scan" : {
    "module" : "7ff6bc950000",
    "module_file" : "C:\\Windows\\notepad.exe",
    "status" : 1,
    "is_pe_replaced" : 1,
    "dos_hdr_modified" : 1,
    "file_hdr_modified" : 1,
    "nt_hdr_modified" : 1,
    "ep_modified" : 1,
    "sec_hdr_modified" : 1
   }
  }
 ]

Mapping scan

Scan checking consistency between the path that was mapped, and the path set in PEB. In a normal situation they both should point to the same file.

   "mapping_scan" : { // report from the mapping scan
    "module" : "7ff6bc950000", // the base address at which the module was mapped in the memory
    "module_file" : "C:\\Windows\\notepad.exe", // The path set in the PEB
    "mapped_file" : "", // The path from which the module was mapped. If empty, it often indicates process Doppelgänging.
    "status" : 1 // status 1 - means positive result (suspicious)
   }

Headers scan

Scan checking consistency between the PE header mapped in memory, and header from a corresponding file on the disk.

   "headers_scan" : { // report from the headers scan
    "module" : "7ff6bc950000", // the base address at which the module was mapped in the memory
    "module_file" : "C:\\Windows\\notepad.exe", // The path corresponding to the module (for informational purposes)
    "status" : 1, // status 1 - means positive result (suspicious)
    "is_pe_replaced" : 1, // Flag indicating if the PE was detected as replaced - completely different than corresponding file on the disk
    "dos_hdr_modified" : 1, // Flag indicating if the differences were detected in DOS headers of both PEs:  
                            // 1 if true (different) , 0 if false (same)
    "file_hdr_modified" : 1, // Flag indicating if the differences were detected in File headers of both PEs 
    "nt_hdr_modified" : 1, // Flag indicating if the differences were detected in NT headers of both PEs 
    "ep_modified" : 1, // Flag indicating if the Entry Point differs in both PEs
    "sec_hdr_modified" : 1 // Flag indicating if the differences were detected in Section Headers of both PEs
   }

Sometimes the modifications in the headers are subtle, and they do not indicate a replacement of the full PE. That's why the flag is_pe_replaced helps to easily filter out when the PE was really replaced/hollowed.

Code scan

Scan checking consistency between the code section(s) of the PE mapped in memory, and corresponding sections from a file on the disk.

   "code_scan" : { // report from the code scan
    "module" : "75660000", // the base address at which the module was mapped in the memory
    "module_file" : "C:\\Windows\\SysWoW64\\user32.dll",  // The path corresponding to the module (for informational purposes)
    "status" : 1,  // status 1 - means positive result (suspicious)
    "patches" : 2, // how many patches are detected
    "scanned_sections" : 1 // how many sections in the PE were detected as code sections, and scanned for patches
   }

If this scan detected some patches, the full list of them will be dumped as a file with .tag extension. This file can be loaded to other analysis tools, and used for investigating of hooks and patches.

IAT scan

This scan is optional, performed only with the parameter /iat

Scan checking consistency between the addresses filled with IATs and the addresses of the imported functions. It detects IAT hooks, as well as imports shimming.

   "iat_scan" : { // report from the IAT scan
    "module" : "400000", // the base address at which the module was mapped in the memory
    "module_file" : "C:\\Users\\tester\\Desktop\\cm_hooked\\hooked2.exe", // The path corresponding to the module (for informational purposes)
    "status" : 1, // status 1 - means positive result (suspicious)
    "hooks" : 1 // how many IAT records have been replaces
   }

If this scan detected some modifications, the full list of them will be dumped to a separate report, helpful in investigating the details of the hook.

Workingset scan

Scan checking workingset against manually mapped (potentially implanted) PE files and related artifacts.

If the parameter /shellc was used, it additionally detects sections with code mapped outside of any PE (shellcodes, JITs).

Example of a workingset scan report, where a complete PE file was detected:

   "workingset_scan" : { // report from the workinset scan
    "module" : "6f66740000", // the base address at which the module was mapped in the memory
    "status" : 1, // status 1 - means positive result (suspicious)
    "has_pe" : 1, // Flag indicating if PE was detected
    "has_shellcode" : 0, // Flag indicating if shellcode was detected
    "is_listed_module" : 0,
    "protection" : "40", // a value of the memory protection constant* (hexadecimal)
    "mapping_type" : "MEM_PRIVATE", // what type of memory region is it? 
                                    // possible options: MEM_IMAGE, MEM_MAPPED, MEM_PRIVATE
    "pe_artefacts" : { // if PE artifacts were detected, what are the offsets of particular elements 
                        // (the offsets are relative to the "module" base address)
     "pe_base_offset" : "0",
     "nt_file_hdr" : "fc",
     "sections_hdrs" : "200",
     "sections_count" : 7,
     "is_dll" : 0,
     "is_64_bit" : 1
    }
   }

*memory protection constants

The report may be smaller if only a shellcode was detected, and no PE artifacts:

   "workingset_scan" : { // report from the workinset scan
    "module" : "7ff7d9fe1000", // the base address at which the module was mapped in the memory
    "status" : 1, // status 1 - means positive result (suspicious)
    "has_pe" : 0,  // Flag indicating if PE was detected
    "has_shellcode" : 1, // Flag indicating if shellcode was detected
    "is_listed_module" : 0,
    "protection" : "20",
    "mapping_type" : "MEM_PRIVATE" // what type of memory region is it? 
                                    // possible options: MEM_IMAGE, MEM_MAPPED, MEM_PRIVATE
   }

Dump report

While the scan report gives details about the results of the scans, dump report describes the material that was dumped.

See also: dump modes /dmode ?

Example:

{
 "pid" : 684, // PID of the process that was scanned
 "output_dir" : "process_684", // The directory where the output from the process was saved
 "dumped" :  // summary of the dumped modules
 {
  "total" : 2, // total count of the modules supposed to be dumped
  "dumped" : 2 // count of the module that were dumped successfully
 },
 "dumps" : [ // reports about each dumped module
  {
   "module" : "7ff6bc950000", // the base address at which the module was mapped in the memory
   "module_size" : "e4000", // the size of the module
   "dump_file" : "7ff6bc950000.notepad.exe", // the file under which the dumped module was saved
   "dump_mode" : "UNMAPPED", // Mode in which the module was dumped.
                             // Possible modes can be listed by a parameter: /dmode ?
   "is_shellcode" : 0, // Flag indicating if the dumped component was a shellcode : 
                       // 1 if true (shellcode) , 0 if false (PE)
   "status" : 1 //  Flag indicating if the module  was dumped successfully
  },
[...]
 ]
}

If some additional material was dumped, the dump report may contain more fields. See the examples given below.

Tag file

 "dumps" : [
  {
   "module" : "75660000",
   "module_size" : "153000",
   "dump_file" : "75660000.user32.dll",
   "tags_file" : "75660000.user32.dll.tag", // the tag file where the details about patches have been saved
   "dump_mode" : "UNMAPPED",
   "is_shellcode" : 0,
   "status" : 1
  }

More about the TAG files.

IAT hooks file

  {
   "module" : "400000",
   "module_size" : "6336",
   "dump_file" : "400000.hooked2.exe",
   "iat_hooks_file" : "400000.hooked2.exe.iat_hooks.txt",  // the tag file where the details about IAT hooks have been saved
   "dump_mode" : "UNMAPPED",
   "is_shellcode" : 0,
   "status" : 1
  }

More about the IAT hooks report.

Import reconstruction status

Related option: /imp

If the import reconstruction was requested, the dump report will contain details about in which mode was it performed, and if it was successful. Additional reports are created, listing all the found imports, or the thunks that were not resolved.

  {
   "module" : "400000",
   "module_size" : "723000",
   "dump_file" : "400000.HxD.exe",
   "tags_file" : "400000.HxD.exe.tag",
   "imports_file" : "400000.HxD.exe.imports.txt", // The report of all the imports that were found by PE-sieve.
   "imp_rec_result" : "IMP_ALREADY_OK", // The import table was left as is - not overwritten. 
                                        // This may happen depending on the mode in which the import reconstruction was requested.
                                        // If the autodetect mode was selected, PE-sieve will not overwrite the import table if a valid one was detected
   "imp_not_recovered_file" : "400000.HxD.exe.not_fixed_imports.txt", // There were some thunks that could not be resolved, and they have been stored in additional report. 
   "dump_mode" : "UNMAPPED",
   "is_shellcode" : 0,
   "status" : 1
  }