(t *testing.T)
| 30 | ) |
| 31 | |
| 32 | func TestIsHeaderModified(t *testing.T) { |
| 33 | var tests = []struct { |
| 34 | executable string |
| 35 | modified bool |
| 36 | }{ |
| 37 | {filepath.Join(os.Getenv("windir"), "explorer.exe"), false}, |
| 38 | {filepath.Join(os.Getenv("windir"), "system32", "calc.exe"), true}, |
| 39 | } |
| 40 | |
| 41 | // perform PE injection on the calc.exe executable with |
| 42 | // process overwriting technique as explained in the repo |
| 43 | // https://github.com/hasherezade/process_overwriting |
| 44 | cmd := exec.Command("_fixtures/process_overwriting.exe", "_fixtures/shellcode.bin") |
| 45 | require.NoError(t, cmd.Run()) |
| 46 | |
| 47 | for _, tt := range tests { |
| 48 | pid, err := findProcessID(tt.executable) |
| 49 | require.NoError(t, err) |
| 50 | addr, err := getModuleBaseAddress(pid) |
| 51 | if err != nil { |
| 52 | t.Fatalf("%s: unable to get the base address: %v", tt.executable, err) |
| 53 | } |
| 54 | file, err := ParseFile(tt.executable, WithSections()) |
| 55 | if err != nil { |
| 56 | t.Fatalf("%s: %v", tt.executable, err) |
| 57 | } |
| 58 | mem, err := ParseMem(pid, addr, false, WithSections()) |
| 59 | if err != nil { |
| 60 | t.Fatalf("%s: %v", tt.executable, err) |
| 61 | } |
| 62 | if mem == nil { |
| 63 | t.Fatalf("%s: PE mem data is nil", tt.executable) |
| 64 | } |
| 65 | isHdrModified := file.IsHeaderModified(mem) |
| 66 | if isHdrModified != tt.modified { |
| 67 | t.Errorf("%s: expected %t, but got: %t", tt.executable, tt.modified, isHdrModified) |
| 68 | } |
| 69 | // terminate injected process |
| 70 | if filepath.Base(tt.executable) == "calc.exe" { |
| 71 | proc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, pid) |
| 72 | if err != nil { |
| 73 | continue |
| 74 | } |
| 75 | windows.TerminateProcess(proc, 1) |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | func findProcessID(image string) (uint32, error) { |
| 81 | const processEntrySize = 568 |
nothing calls this directly
no test coverage detected