Go1.10获取进程打开的动态库

type ListMode uintptr

const (
    LIST_MODULES_DEFAULT ListMode = 0x0  //查看默认的模块
    LIST_MODULES_32BIT            = 0x01 //查看32-bit的模块
    LIST_MODULES_64BIT            = 0x02 //查看64-bit的模块
    LIST_MODULES_ALL              = 0x03 //查看所有的模块
)


//Windows上实现
psapi                = syscall.NewLazyDLL("Psapi.dll")
enumProcessModulesEx = psapi.NewProc("EnumProcessModulesEx")
getModuleFileNameExW = psapi.NewProc("GetModuleFileNameExW")

func ListDynamicModule(pid uint32, mode ListMode) ([]string, error) {
    //获取进程句柄
    var hProcess, err = syscall.OpenProcess(0x0400|0x0010, false, pid)
    if err != nil {
        return nil, err
    }

    //注意关闭句柄
    defer syscall.CloseHandle(hProcess)

    var (
        cbNeeded uint32
        hMods    [1024]uintptr
    )

    //获取进程打开的模块数
    r, _, err := enumProcessModulesEx.Call(uintptr(hProcess), uintptr(unsafe.Pointer(&hMods[0])), unsafe.Sizeof(hMods), uintptr(unsafe.Pointer(&cbNeeded)), uintptr(mode))
    if r == 0 {
        return nil, err
    }

    //计算模块数量
    var modelength = int(cbNeeded) / int(unsafe.Sizeof(hMods[0]))
    var szModName [260]uint16
    var list = make([]string, 0, modelength)

    for i := 0; i < modelength; i++ {
        r, _, err = getModuleFileNameExW.Call(uintptr(hProcess), hMods[i], uintptr(unsafe.Pointer(&szModName)), unsafe.Sizeof(szModName))
        if r == 0 {
            return list, err
        }
        list = append(list, syscall.UTF16ToString(szModName[:]))
    }
    return list, nil
}

//Linux实现
//Linux下mode不生效
func ListDynamicModule(pid uint32, mode ListMode) ([]string, error) {
    exe, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid))
    if err != nil {
        if os.IsNotExist(err) {
            return nil, fmt.Errorf("Pid %d 不存在", pid)
        }
        return nil, err
    }

    File, err := os.Open(fmt.Sprintf("/proc/%d/maps", pid))
    if err != nil {
        if os.IsNotExist(err) {
            return nil, fmt.Errorf("Pid %d 不存在", pid)
        }
        return nil, err
    }
    defer File.Close()

    var maps = make(map[string]struct{})
    buf := bufio.NewReader(File)
    for {
        line, _, err := buf.ReadLine()
        if err != nil {
            break
        }
        if !bytes.Contains(line, []byte(".so")) {
            continue
        }

        lines := bytes.Fields(line)
        if len(lines) < 6 {
            continue
        }
        maps[string(lines[5])] = struct{}{}
    }
    var list = make([]string, 0, len(maps))
    list = append(list, exe)
    for k, _ := range maps {
        list = append(list, k)
    }
    return list, nil
}

你可能感兴趣的:(Golang)