调用EnumProcessModules时出现“意外故障地址”

I am writing a function that enumerates the base address of a process. This is done through a few Windows API calls, however, I believe it's my call to EnumProcessModules that is creating the error.

It should also be noted that this error does not occur for every process.

I have already tried changing around some of the uint32 to uint64 and vice versa, and different ways of creating the moduleHandles array, but I can't get anything working.

This is just one function in an application I'm creating to retrieve and scan another process's memory.

This is the source code of my function:

func getBaseAddress(handle uintptr) int64 {
    // GetProcessImageFileNameA
    var imageFileName [200]byte
    var fileSize uint32 = 200
    var fileName string

    ret, _, _ := procGetProcessImageFileNameA.Call(handle, uintptr(unsafe.Pointer(&imageFileName)), uintptr(fileSize))

    for _, char := range imageFileName {
        if char == 0 {
            break
        }

        fileName += string(char)
    }

    fileName = fileName[24:]

    // EnumProcessModules
    var n uint32
    var needed uint64

    ret, _, _ = procEnumProcessModules.Call(handle, 0, uintptr(n), uintptr(unsafe.Pointer(&needed)))

    moduleHandles := make([]syscall.Handle, int(needed))

    if ret == 1 && needed > 0 {
        ret, _, _ = procEnumProcessModules.Call(handle, uintptr(unsafe.Pointer(&moduleHandles)), uintptr(needed), uintptr(unsafe.Pointer(&needed)))
    }

    // GetModuleFileNameExA
    var finalModuleHandle uintptr

    for _, moduleHandle := range moduleHandles {
        if moduleHandle > 0 {
            var moduleFileName [200]byte
            var moduleSize uint32 = 200
            var moduleName string

            ret, _, _ = procGetModuleFileNameExA.Call(handle, uintptr(moduleHandle), uintptr(unsafe.Pointer(&moduleFileName)), uintptr(moduleSize))

            if ret != 0 {
                for _, char := range moduleFileName {
                    if char == 0 {
                        break
                    }

                    moduleName += string(char)
                }

                moduleName = moduleName[3:]

                if moduleName == fileName {
                    finalModuleHandle = uintptr(moduleHandle)
                    break
                }
            }
        }
    }

    return int64(finalModuleHandle)
}

I figured out the issue. I was interacting with the EnumProcessModules incorrectly. Here's a working function:

func getBaseAddress(handle uintptr) int64 {
    // GetProcessImageFileNameA
    var imageFileName [200]byte
    var fileSize uint32 = 200
    var fileName string

    ret, _, _ := procGetProcessImageFileNameA.Call(handle, uintptr(unsafe.Pointer(&imageFileName)), uintptr(fileSize))

    for _, char := range imageFileName {
        if char == 0 {
            break
        }

        fileName += string(char)
    }

    fileName = fileName[24:]

    // EnumProcessModules
    moduleHandles := make([]uintptr, 1024)
    var needed int32
    const handleSize = unsafe.Sizeof(moduleHandles[0])

    ret, _, _ = procEnumProcessModules.Call(uintptr(handle), uintptr(unsafe.Pointer(&moduleHandles[0])), handleSize*uintptr(len(moduleHandles)), uintptr(unsafe.Pointer(&needed)))

    // GetModuleFileNameExA
    var finalModuleHandle uintptr

    for _, moduleHandle := range moduleHandles {
        if moduleHandle > 0 {
            var moduleFileName [200]byte
            var moduleSize uint32 = 200
            var moduleName string

            ret, _, _ = procGetModuleFileNameExA.Call(handle, uintptr(moduleHandle), uintptr(unsafe.Pointer(&moduleFileName)), uintptr(moduleSize))

            if ret != 0 {
                for _, char := range moduleFileName {
                    if char == 0 {
                        break
                    }

                    moduleName += string(char)
                }

                moduleName = moduleName[3:]

                if moduleName == fileName {
                    finalModuleHandle = uintptr(moduleHandle)
                    break
                }
            }
        }
    }

    return int64(finalModuleHandle)
}

I hope this can help someone, I spent a lot of time working on this function.

The 2nd parameter to EnumProcessModules cannot be a null pointer (0) even if you are just trying to determine the number of entries needed.