Skip to content

Commit 7e184bc

Browse files
committed
feat: process scan
1 parent 82d4672 commit 7e184bc

File tree

9 files changed

+887
-5
lines changed

9 files changed

+887
-5
lines changed

chunkupload/filter.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package chunkupload
22

33
import (
4+
"encoding/binary"
5+
"io"
46
"io/fs"
7+
"os"
58
"strings"
69
)
710

@@ -27,4 +30,51 @@ var DiscardDot Filter = func(path string, entry fs.DirEntry) (FilterVote, error)
2730
}
2831
return FilterAdd, nil
2932
}
33+
34+
var BinaryOnly Filter = func(path string, entry fs.DirEntry) (FilterVote, error) {
35+
if entry.IsDir() {
36+
return FilterAdd, nil
37+
}
38+
eFormat, _ := detectFileFormat(path)
39+
if eFormat != "" {
40+
return FilterAdd, nil
41+
}
42+
return FilterSkip, nil
43+
}
44+
3045
var uploadAll Filter = func(path string, entry fs.DirEntry) (FilterVote, error) { return FilterAdd, nil }
46+
47+
func detectFileFormat(path string) (string, error) {
48+
file, err := os.Open(path)
49+
if err != nil {
50+
return "", err
51+
}
52+
defer func() { _ = file.Close() }()
53+
54+
magic := make([]byte, 4)
55+
_, err = io.ReadFull(file, magic)
56+
if err != nil {
57+
return "", err
58+
}
59+
60+
// Check ELF (0x7f 'E' 'L' 'F')
61+
if magic[0] == 0x7f && magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F' {
62+
return "ELF", nil
63+
}
64+
65+
// Check Mach-O (32-bit or 64-bit, big or little endian)
66+
magicNum := binary.BigEndian.Uint32(magic)
67+
switch magicNum {
68+
case 0xfeedface, 0xcefaedfe, // 32-bit Mach-O
69+
0xfeedfacf, 0xcffaedfe, // 64-bit Mach-O
70+
0xcafebabe, 0xbebafeca: // FAT binary
71+
return "Mach-O", nil
72+
}
73+
74+
// Check PE (first two bytes 'M' 'Z')
75+
if magic[0] == 'M' && magic[1] == 'Z' {
76+
return "PE", nil
77+
}
78+
79+
return "", nil
80+
}

cmd/murphy/internal/scan/cmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ var scanCodeHash bool
4545
var gradleProjectFilter gradle.ProjectFilter
4646
var branch string
4747
var mavenModuleName []string
48+
var binaryOnly bool
4849

4950
func Cmd() *cobra.Command {
5051
var c cobra.Command
@@ -67,6 +68,7 @@ func Cmd() *cobra.Command {
6768
c.Flags().Var(&webhookMode, "webhook-mode", "specify the webhook mode, currently supports: simple, full")
6869
c.Flags().StringVar(&extraData, "extra-data", "", "specify the extra data")
6970
c.Flags().BoolVar(&scanCodeHash, "scan-snippets", false, "Enable scanning of code snippets to detect SBOM and vulnerabilities. Disabled by default")
71+
c.Flags().BoolVar(&binaryOnly, "binary-only", false, "only scan binary files, skip source code scanning")
7072
return &c
7173
}
7274

cmd/murphy/internal/scan/scan.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,11 @@ func scan(ctx context.Context, dir string, accessType model.AccessType, mode mod
238238
}
239239
if task.Mode != model.ScanModeSource || isDeep {
240240
cv.DisplayUploading(ctx)
241-
e = chunkupload.UploadDirectory(ctx, task.ProjectPath, chunkupload.DiscardDot, chunkupload.Params{
241+
var filter = chunkupload.DiscardDot
242+
if binaryOnly {
243+
filter = chunkupload.BinaryOnly
244+
}
245+
e = chunkupload.UploadDirectory(ctx, task.ProjectPath, filter, chunkupload.Params{
242246
SubtaskId: task.SubtaskId,
243247
}, concurrentNumber)
244248
if e != nil {

envinspection/inspection.go

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
)
1616

1717
func InspectEnv(ctx context.Context) error {
18-
var LOG = logctx.Use(ctx).Sugar()
1918
task := model.UseScanTask(ctx)
2019
if task == nil {
2120
panic("task == nil")
@@ -36,6 +35,20 @@ func InspectEnv(ctx context.Context) error {
3635
ModulePath: "/InstalledSoftware", // never be empty, workaround for the platform issue
3736
}
3837

38+
// 获取软件包列表
39+
inspectInstalledSoftware(ctx, &module)
40+
41+
// 获取进程文件列表
42+
inspectProcessFiles(ctx)
43+
44+
return nil
45+
}
46+
47+
// 检查已安装的软件
48+
func inspectInstalledSoftware(ctx context.Context, module *model.Module) {
49+
LOG := logctx.Use(ctx).Sugar()
50+
task := model.UseScanTask(ctx)
51+
3952
var scanFunc []func(ctx context.Context) ([]model.DependencyItem, error)
4053
if runtime.GOOS == "windows" {
4154
scanFunc = append(scanFunc, listInstalledSoftwareWindows /*listRunningProcessExecutableFileWindows*/)
@@ -77,9 +90,38 @@ func InspectEnv(ctx context.Context) error {
7790
for i := range module.Dependencies {
7891
module.Dependencies[i].IsOnline.SetOnline(false)
7992
module.Dependencies[i].IsDirectDependency = true
80-
module.Dependencies[i].EcoRepo.Repository = packageManager
93+
module.Dependencies[i].EcoRepo.Repository = module.PackageManager
8194
}
82-
task.Modules = append(task.Modules, module)
95+
task.Modules = append(task.Modules, *module)
96+
}
8397

84-
return nil
98+
// 检查进程文件
99+
func inspectProcessFiles(ctx context.Context) {
100+
LOG := logctx.Use(ctx).Sugar()
101+
task := model.UseScanTask(ctx)
102+
103+
// 仅在Linux系统上执行进程文件检查
104+
if runtime.GOOS != "linux" {
105+
LOG.Info("Process file inspection is only supported on Linux, skipping...")
106+
return
107+
}
108+
109+
// 获取进程相关的模块列表
110+
processModules, err := listProcessFiles(ctx)
111+
if err != nil {
112+
LOG.Warnf("Process file inspection error: %s", err)
113+
scanerr.Add(ctx, scanerr.Param{
114+
Kind: "process_file_inspection_error",
115+
Content: err.Error(),
116+
})
117+
return
118+
}
119+
120+
// 添加进程模块到任务中
121+
if len(processModules) > 0 {
122+
task.Modules = append(task.Modules, processModules...)
123+
LOG.Infof("Process file inspection succeeded, found %d processes", len(processModules))
124+
} else {
125+
LOG.Info("No process files found")
126+
}
85127
}

0 commit comments

Comments
 (0)