windows: Add tests for process modules

This commit is contained in:
Weilu Jia
2021-09-19 19:11:32 -07:00
parent f6f5f146cd
commit cf298734ae

View File

@@ -701,3 +701,87 @@ func TestWinVerifyTrust(t *testing.T) {
}
}
func TestProcessModules(t *testing.T) {
process, err := windows.GetCurrentProcess()
if err != nil {
t.Fatalf("unable to get current process: %v", err)
}
// NB: Assume that we're always the first module. This technically isn't documented anywhere (that I could find), but seems to always hold.
var module windows.Handle
var cbNeeded uint32
err = windows.EnumProcessModules(process, &module, uint32(unsafe.Sizeof(module)), &cbNeeded)
if err != nil {
t.Errorf("unable to call EnumProcessModules: %v", err)
}
var moduleEx windows.Handle
err = windows.EnumProcessModulesEx(process, &moduleEx, uint32(unsafe.Sizeof(moduleEx)), &cbNeeded, windows.LIST_MODULES_DEFAULT)
if err != nil {
t.Errorf("unable to call EnumProcessModulesEx: %v", err)
}
if module != moduleEx {
t.Errorf("module from EnumProcessModules does not match EnumProcessModulesEx: %v != %v", module, moduleEx)
}
exePath, err := os.Executable()
if err != nil {
t.Errorf("unable to get current executable path: %v", err)
}
modulePathUTF := make([]uint16, len(exePath)+1)
err = windows.GetModuleFileNameEx(process, module, &modulePathUTF[0], uint32(len(modulePathUTF)))
if err != nil {
t.Errorf("unable to call GetModuleFileNameEx: %v", err)
}
modulePath := windows.UTF16ToString(modulePathUTF)
if modulePath != exePath {
t.Errorf("module does not match executable for GetModuleFileNameEx: %s != %s", modulePath, exePath)
}
err = windows.GetModuleBaseName(process, module, &modulePathUTF[0], uint32(len(modulePathUTF)))
if err != nil {
t.Errorf("unable to call GetModuleBaseName: %v", err)
}
modulePath = windows.UTF16ToString(modulePathUTF)
baseExePath := filepath.Base(exePath)
if modulePath != baseExePath {
t.Errorf("module does not match executable for GetModuleBaseName: %s != %s", modulePath, baseExePath)
}
var moduleInfo windows.ModuleInfo
err = windows.GetModuleInformation(process, module, &moduleInfo, uint32(unsafe.Sizeof(moduleInfo)))
if err != nil {
t.Errorf("unable to call GetModuleInformation: %v", err)
}
var arch int
var size uint32
peFile, err := pe.Open(exePath)
if err != nil {
t.Errorf("unable to open current executable: %v", err)
} else {
switch runtime.GOARCH {
case "amd64":
case "arm64":
arch = 64
case "386":
case "arm":
arch = 32
}
if arch == 32 {
size = peFile.OptionalHeader.(pe.OptionalHeader32).SizeOfImage
} else if arch == 64 {
size = peFile.OptionalHeader.(pe.OptionalHeader64).SizeOfImage
} else {
t.Logf("unable to test GetModuleInformation on arch %v", runtime.GOARCH)
}
}
if arch != 0 && moduleInfo.SizeOfImage != size {
t.Errorf("module size does not match executable: %v != %v", moduleInfo.SizeOfImage, size)
}
}