Using golang to call the api in pe-sieve64.dll #112
-
Hi, recently I want to use golang to call the api in pe-sieve64.dll, I tried to convert this demo to golang code(https://github.com/hasherezade/pe-sieve/wiki/5.-API package main
import (
"fmt"
"syscall"
"unsafe"
)
var (
peSieveDll = syscall.NewLazyDLL("pe-sieve64.dll")
peSieveScan = peSieveDll.NewProc("PESieve_scan_ex")
)
const (
ERROR_SCAN_FAILURE = ^uint32(0)
MAX_PATH = 260
)
type PEsieveRtype int
const (
ReportNone PEsieveRtype = iota
ReportScanned
ReportDumped
ReportAll
)
type ParamString struct {
Length uint32
Buffer *byte
}
type DotnetPolicy int
const (
PeDnetNone DotnetPolicy = iota
PeDnetSkipMapping
PeDnetSkipShc
PeDnetSkipHooks
PeDnetSkipAll
PeDnetCount
)
type ImprecMode int
const (
PeImprecNone ImprecMode = iota
PeImprecAuto
PeImprecUnerase
PeImprecRebuild0
PeImprecRebuild1
PeImprecRebuild2
PeImprecModesCount
)
type OutputFilter int
const (
OutFull OutputFilter = iota
OutNoDumps
OutNoDir
OutFiltersCount
)
type IatScanMode int
const (
PeIatsNone IatScanMode = iota
PeIatsCleanSysFiltered
PeIatsAllSysFiltered
PeIatsUnfiltered
PeIatsModesCount
)
type DataScanMode int
const (
PeDataNoScan DataScanMode = iota
PeDataScanDotnet
PeDataScanNoDep
PeDataScanAlways
PeDataScanInaccessible
PeDataScanInaccessibleOnly
PeDataCount
)
type DumpMode int
const (
PeDumpAuto DumpMode = iota
PeDumpVirtual
PeDumpUnmap
PeDumpRealign
PeDumpModesCount
)
type JsonLevel int
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,
}
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, _, _ := peSieveScan.Call(
uintptr(unsafe.Pointer(&pp)),
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:
fmt.Println(string(jsonBuf))
fmt.Println(ret)
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
hi @wh0im1 ! thank you for reporting! I will check it and get back to you soon! |
Beta Was this translation helpful? Give feedback.
-
@wh0im1 - I made some fixes in your code. It should work now. 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 // always use explicit integer types
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)
} |
Beta Was this translation helpful? Give feedback.
@wh0im1 - I made some fixes in your code. It should work now.
Please check it out: https://gist.github.com/hasherezade/f6fafac2b7e452a36410c2c5583f9790