Skip to content

Commit

Permalink
feat(dumper): walk dir in async mode + print rsrc version info (#92)
Browse files Browse the repository at this point in the history
* feat(dumper): walk dir in async mode

* print version info

* comment update
  • Loading branch information
LordNoteworthy authored Feb 10, 2024
1 parent ad42489 commit 8980c0f
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 25 deletions.
97 changes: 73 additions & 24 deletions cmd/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"path/filepath"
"reflect"
"strings"
"sync"
"text/tabwriter"
"time"
"unicode"
Expand All @@ -23,11 +24,54 @@ import (
"github.com/saferwall/pe/log"
)

func prettyPrint(buff []byte) string {
var (
wg sync.WaitGroup
jobs chan string = make(chan string)
)

func loopFilesWorker(cfg config) error {
for path := range jobs {
files, err := os.ReadDir(path)
if err != nil {
wg.Done()
return err
}

for _, file := range files {
if !file.IsDir() {
fullpath := filepath.Join(path, file.Name())
parsePE(fullpath, cfg)
}
}
wg.Done()
}
return nil
}

func LoopDirsFiles(path string) error {
files, err := os.ReadDir(path)
if err != nil {
return err
}

go func() {
wg.Add(1)

Check failure on line 58 in cmd/dump.go

View workflow job for this annotation

GitHub Actions / Build & Test (1.19.x, windows-latest)

should call wg.Add(1) before starting the goroutine to avoid a race (SA2000)

Check failure on line 58 in cmd/dump.go

View workflow job for this annotation

GitHub Actions / Build & Test (1.19.x, windows-latest)

should call wg.Add(1) before starting the goroutine to avoid a race (SA2000)
jobs <- path
}()
for _, file := range files {
if file.IsDir() {
LoopDirsFiles(filepath.Join(path, file.Name()))
}
}
return nil
}

func prettyPrint(iface interface{}) string {
var prettyJSON bytes.Buffer
error := json.Indent(&prettyJSON, buff, "", "\t")
if error != nil {
log.Info("JSON parse error: ", error)
buff, _ := json.Marshal(iface)
err := json.Indent(&prettyJSON, buff, "", "\t")
if err != nil {
log.Errorf("JSON parse error: %v", err)
return string(buff)
}

Expand Down Expand Up @@ -200,30 +244,12 @@ func parsePE(filename string, cfg config) {
}

// Dump all results to disk in JSON format.
// b, _ := json.Marshal(pe)
// f, err := os.Create("out.json")
// if err != nil {
// return
// }
// defer f.Close()
// f.WriteString(prettyPrint(b))

// Calculate the PE authentihash.
pe.Authentihash()

// Calculate the PE checksum.
pe.Checksum()

// Get file type.
if pe.IsEXE() {
log.Debug("File is Exe")
}
if pe.IsDLL() {
log.Debug("File is DLL")
}
if pe.IsDriver() {
log.Debug("File is Driver")
}
// f.WriteString(prettyPrint(pe))

if cfg.wantDOSHeader {
DOSHeader := pe.DOSHeader
Expand Down Expand Up @@ -500,6 +526,13 @@ func parsePE(filename string, cfg config) {

fmt.Printf("\nRESOURCES\n**********\n")
printRsrcDir(pe.Resources)

versionInfo, err := pe.ParseVersionResources()
if err != nil {
log.Errorf("failed to parse version resources: %v", err)
} else {
fmt.Printf("\nVersion Info: %v", prettyPrint(versionInfo))
}
}

if cfg.wantException && pe.FileInfo.HasException {
Expand Down Expand Up @@ -550,6 +583,9 @@ func parsePE(filename string, cfg config) {
fmt.Fprintf(w, "Signature Algorithm:\t %s\n", cert.Info.SignatureAlgorithm.String())
fmt.Fprintf(w, "PublicKey Algorithm:\t %s\n", cert.Info.PublicKeyAlgorithm.String())
w.Flush()

// Calculate the PE authentihash.
pe.Authentihash()
}

if cfg.wantReloc && pe.FileInfo.HasReloc {
Expand Down Expand Up @@ -647,7 +683,6 @@ func parsePE(filename string, cfg config) {
fpoData.Reserved, fpoData.FrameType, fpoData.FrameType.String())
}
}

}
}

Expand Down Expand Up @@ -830,5 +865,19 @@ func parsePE(filename string, cfg config) {
}
}

// Get file type.
if pe.IsEXE() {
log.Debug("File is Exe")
}
if pe.IsDLL() {
log.Debug("File is DLL")
}
if pe.IsDriver() {
log.Debug("File is Driver")
}

// Calculate the PE checksum.
pe.Checksum()

fmt.Print("\n")
}
17 changes: 16 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"flag"
"fmt"
"os"
"runtime"
)

type config struct {
Expand Down Expand Up @@ -88,7 +89,20 @@ func main() {
wantCLR: *dumpCLR,
}

parse(os.Args[2], cfg)
// Start as many workers you want, default to cpu count -1.
numWorkers := runtime.GOMAXPROCS(runtime.NumCPU() - 1)
for w := 1; w <= numWorkers; w++ {
go loopFilesWorker(cfg)
}

if !isDirectory(os.Args[2]) {
// Input path in a single file.
parsePE(os.Args[2], cfg)
} else {
// Input path in a directory.
LoopDirsFiles(os.Args[2])
wg.Wait()
}

case "version":
verCmd.Parse(os.Args[2:])
Expand All @@ -109,5 +123,6 @@ func showHelp() {
Brought to you by Saferwall (c) 2018 MIT
`)
fmt.Println("\nAvailable sub-commands 'dump' or 'version' subcommands")

os.Exit(1)
}

0 comments on commit 8980c0f

Please sign in to comment.