Last active
January 6, 2023 02:11
-
-
Save hasherezade/f6fafac2b7e452a36410c2c5583f9790 to your computer and use it in GitHub Desktop.
PE-sieve scan in Golang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"syscall" | |
"unsafe" | |
) | |
var ( | |
peSieveDll = syscall.NewLazyDLL("pe-sieve64.dll") | |
peSieveScanEx = peSieveDll.NewProc("PESieve_scan_ex") | |
) | |
const ( | |
ERROR_SCAN_FAILURE = ^uint32(0) | |
MAX_PATH = 260 | |
) | |
type PEsieveRtype int32 | |
const ( | |
ReportNone PEsieveRtype = iota | |
ReportScanned | |
ReportDumped | |
ReportAll | |
) | |
type ParamString struct { | |
Length uint32 | |
Buffer *byte | |
} | |
type DotnetPolicy int32 | |
const ( | |
PeDnetNone DotnetPolicy = iota | |
PeDnetSkipMapping | |
PeDnetSkipShc | |
PeDnetSkipHooks | |
PeDnetSkipAll | |
PeDnetCount | |
) | |
type ImprecMode int32 | |
const ( | |
PeImprecNone ImprecMode = iota | |
PeImprecAuto | |
PeImprecUnerase | |
PeImprecRebuild0 | |
PeImprecRebuild1 | |
PeImprecRebuild2 | |
PeImprecModesCount | |
) | |
type OutputFilter int32 | |
const ( | |
OutFull OutputFilter = iota | |
OutNoDumps | |
OutNoDir | |
OutFiltersCount | |
) | |
type IatScanMode int32 | |
const ( | |
PeIatsNone IatScanMode = iota | |
PeIatsCleanSysFiltered | |
PeIatsAllSysFiltered | |
PeIatsUnfiltered | |
PeIatsModesCount | |
) | |
type DataScanMode int32 | |
const ( | |
PeDataNoScan DataScanMode = iota | |
PeDataScanDotnet | |
PeDataScanNoDep | |
PeDataScanAlways | |
PeDataScanInaccessible | |
PeDataScanInaccessibleOnly | |
PeDataCount | |
) | |
type DumpMode int32 | |
const ( | |
PeDumpAuto DumpMode = iota | |
PeDumpVirtual | |
PeDumpUnmap | |
PeDumpRealign | |
PeDumpModesCount | |
) | |
type JsonLevel int32 | |
const ( | |
JsonBasic JsonLevel = iota | |
JsonDetails | |
JsonDetails2 | |
JsonLvlCount | |
) | |
type PEsieveParams struct { | |
Pid uint32 | |
TDotnetPolicy DotnetPolicy | |
TImprecMode ImprecMode | |
Quiet bool | |
TOutputFilter OutputFilter | |
Nohooks bool | |
Shellcode bool | |
Threads bool | |
Iat IatScanMode | |
Data DataScanMode | |
Minidump bool | |
TDumpMode DumpMode | |
JsonOutput bool | |
MakeReflection bool | |
UseCache bool | |
TJsonLevel JsonLevel | |
OutputDir [MAX_PATH + 1]byte | |
ModulesIgnored ParamString | |
} | |
type PEsieveReport struct { | |
Pid uint32 | |
IsManaged bool | |
Is64bit bool | |
IsReflection bool | |
Scanned uint32 | |
Suspicious uint32 | |
Replaced uint32 | |
HdrMod uint32 | |
UnreachableFile uint32 | |
Patched uint32 | |
IatHooked uint32 | |
Implanted uint32 | |
ImplantedPe uint32 | |
ImplantedShc uint32 | |
Other uint32 | |
Skipped uint32 | |
Errors uint32 | |
} | |
func main() { | |
// Set up the scan parameters | |
pp := PEsieveParams{ | |
Pid: uint32(syscall.Getpid()), // scan current process | |
Threads: true, | |
Shellcode: true, | |
Quiet: true, | |
} | |
pr := PEsieveReport{} | |
const rtype = ReportAll | |
// Prepare the buffer for the output report | |
const bufSize uint = 0x1000 | |
jsonBuf := make([]byte, bufSize) | |
neededSize := uint32(0) | |
// Perform the scan: | |
ret, _, out2 := peSieveScanEx.Call( | |
uintptr(unsafe.Pointer(&pr)), // first pass the return variable | |
uintptr(unsafe.Pointer(&pp)), // then pass the typical arguments of the function | |
uintptr(rtype), | |
uintptr(unsafe.Pointer(&jsonBuf[0])), | |
uintptr(bufSize), | |
uintptr(unsafe.Pointer(&neededSize)), | |
) | |
if neededSize > uint32(bufSize) { | |
// The supplied buffer was too small to fit in the whole JSON report | |
fmt.Printf("Couldn't retrieve the full buffer. Needed size: %x\n", neededSize) | |
} | |
// Print the obtained report: | |
var reportStr = string(jsonBuf[:neededSize]) | |
fmt.Println(reportStr) | |
// Some additional returned stuff: | |
if (uintptr(unsafe.Pointer(&pr)) == ret) { | |
fmt.Println("Returned val OK") | |
} else { | |
fmt.Printf("Returned val invalid: %x vs %x\n", unsafe.Pointer(&pr) , ret) | |
} | |
fmt.Println("Info:", out2) | |
fmt.Printf("Summary for PID %d:\n", pr.Pid) | |
fmt.Printf("Scanned: %d\n", pr.Scanned) | |
fmt.Printf("Detected: %d\n", pr.Suspicious) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment