kihlh / hmc-win32

HMC Easier Access to System APIs 简化连接winapi的过程的node c++模块
https://kihlh.gitbook.io/hmc/
MIT License
85 stars 11 forks source link

getProcessName getProcessPath 方法太多,有的连普通的进程都获取不了信息 #42

Closed xianyunleo closed 11 months ago

xianyunleo commented 11 months ago

方法太多,学习成本太大,用户只想用一个简单可靠的,不会在意那几毫秒

如下代码不能得到预期结果

    static async getListForWindows() {
        try {
            const hmc = require('hmc-win32')
            const hmn = require('net-win32')
            let list = await hmn.getConnectNetListAsync(true,false,false,false)
            list = list.filter(item=>item.state==='LISTEN')
            console.log('list',list)
            list =  await Promise.all(
                list.map(async item => {
                    const { pid, ip, port } = item
                    console.log('pid',pid)
                    const name = await hmc.getProcessName2(pid)
                    console.log('name',name)
                    const path = await hmc.getProcessFilePath2(pid)
                    return { pid, ip, port, name, path, status: 'Listen'}
                })
            );
            return list
        } catch (e) {
            console.log('e',e)
            return [];
        }
    }

建议参考c# api,getProcessName和getProcessPath 同步异步只留一个方法。如下是c#写的软件获取的进程信息 image image

kihlh commented 11 months ago

c++的世界确实有点复杂

getProcessName2 我加个补丁 getProcessName已经不可能改了 一改倒一片

xianyunleo commented 11 months ago

想要和c#差不多的结果。

管理员权限调用api时。 getProcessName2,能获取99.99%的进程名。 getProcessPath2,除了一些系统进程,service,console程序的Path也能获取。

非管理员权限时,尽量获取。

@kihlh 🙏

kihlh commented 11 months ago

想要和c#差不多的结果。

管理员权限调用api时。 getProcessName2,能获取99.99%的进程名。 getProcessPath2,除了一些系统进程,service,console程序的Path也能获取。

非管理员权限时,尽量获取。

@kihlh 🙏

高权限应用 文件路径我再想想办法 名称在没有管理权限情况下 确实能够获取99%左右

image

kihlh commented 11 months ago

此问题在 1.4.6 中已经解决并发布

xianyunleo commented 11 months ago

014db39a1d46047801afd8751c38bd8 8bf2c5989f3f56201fc67ee280a5b5b ef607a5d6b89befe8ee159d6a43b17c

@kihlh 还是有一些进程获取到的name和path有问题

kihlh commented 11 months ago

进程权限是 SYSTEM 的获取的是快照名称 或者内核名称 如果信息有误就是下方的解释:

这个进程是无解的,这个权限被提权到系统了,是软件最高权限,如果不提权到一样的权限是无法打开的,提权到sys进程将被win直接禁用网络而且并不是想提权就能提的,主流的方案都是依靠签名的驱动进行提权获取的

其他的我研究下他整了啥操作

kihlh commented 11 months ago

无法复现 可以使用火绒剑或者openark或者SystemInformer 打开下进程信息截图下嘛

xianyunleo commented 11 months ago

image 这是1212进程。 getProcessName2和getProcessPath2同一个pid,path和name根本对不上。你测试的时候,循环array测试呢?是不是有缓存啥的?

kihlh commented 11 months ago

getProcessName2

image 这是1212进程。 getProcessName2和getProcessPath2同一个pid,path和name根本对不上。你测试的时候,循环array测试呢?是不是有缓存啥的?

是异步并发嘛? 没有await 有缓存机制但是没启用

kihlh commented 11 months ago

image

我这边测试只有内核 是不对的

kihlh commented 11 months ago

我好像知道问题在哪了,

可以发下你调用时候的代码

xianyunleo commented 11 months ago

@kihlh

async getListForWindows() {
        try {
            const hmc = require('hmc-win32')
            const hmn = require('net-win32')
            console.log('isAdmin ',hmc.isAdmin() )
            let list = await hmn.getConnectNetListAsync(true,false,false,false)
            list = list.filter(item=>item.state==='LISTEN')
            list =  await Promise.all(
                list.map(async item => {
                    const { pid, ip, port } = item
                    const name = await hmc.getProcessName2(pid)
                    const path = await hmc.getProcessFilePath2(pid)

                    return { pid, ip, port, name, path}
                })
            )
            console.log('hmc list',list)
            return list
        } catch (e) {
            console.log('e',e)
            return [];
        }
    }
kihlh commented 11 months ago
async getListForWindows() {
        try {
            const hmc = require('hmc-win32')
            const hmn = require('net-win32')
            console.log('isAdmin ',hmc.isAdmin() )
            let list = await hmn.getConnectNetListAsync(true,false,false,false)
            list = list.filter(item=>item.state==='LISTEN')
            list =  await Promise.all(
                list.map(async item => {
                    const { pid, ip, port } = item
                    const name = await hmc.getProcessName2(pid)
                    const path = await hmc.getProcessFilePath2(pid)

                    return { pid, ip, port, name, path}
                })
            )
            console.log('hmc list',list)
            return list
        } catch (e) {
            console.log('e',e)
            return [];
        }
    }

异步空间竞态冲突了 这边异步并发了 多线程冲突, 我再研究下 你转为同步并发 异步函数估计就不会有这个问题了 获取300个信息大概是1秒 await Promise.all(Array(50).map(async item => {});

你试下这样的: `async getListForWindows() { try { const hmc = require('hmc-win32') const hmn = require('net-win32') console.log('isAdmin ',hmc.isAdmin() ) let list = await hmn.getConnectNetListAsync(true,false,false,false) list = list.filter(item=>item.state==='LISTEN');

        for (let index = 0; index < list.length; index++) {
            const { pid, ip, port }= list[index];
            const name = await hmc.getProcessName2(pid).catch(_=>null);
            const path = await hmc.getProcessFilePath2(pid).catch(_=>null)
            list[index]= { pid, ip, port, name, path};
        }

        console.log('hmc list',list)
        return list
    } catch (e) {
        console.log('e',e)
        return [];
    }
}`
xianyunleo commented 11 months ago

@kihlh “你试下这样的“代码乱了,整理一下

kihlh commented 11 months ago
async getListForWindows() {
    try {
        const hmc = require('hmc-win32')
        const hmn = require('net-win32')
        console.log('isAdmin ', hmc.isAdmin())
        let list = await hmn.getConnectNetListAsync(true, false, false, false)
        list = list.filter(item => item.state === 'LISTEN');
        for (let index = 0; index < list.length; index++) {
            const { pid, ip, port } = list[index];
            const name = await hmc.getProcessName2(pid).catch(_ => null);
            const path = await hmc.getProcessFilePath2(pid).catch(_ => null)
            list[index] = { pid, ip, port, name, path };
        }
        console.log('hmc list', list)
        return list
    } catch (e) {
        console.log('e', e)
        return [];
    }
}
xianyunleo commented 11 months ago

改用你的for,数据基本上可以。这里有点问题。 image 还有就是非管理员权限的时候,管理员权限的进程path就是name。由于隐私不方便截图了。 建议非管理员权限下,获取管理员权限进程的path和系统进程的path,返回null

kihlh commented 11 months ago

改用你的for,数据基本上可以。这里有点问题。 image 还有就是非管理员权限的时候,管理员权限的进程path变成name了。由于隐私不方便截图了。 建议非管理员权限下,获取管理员权限进程的path和系统进程的path,返回null

这个好解决

function formatVolumePath(path){
    if(path&&path?.match(/^\\/)){
        for (let Volume of hmc.getVolumeList()) {
            if(path.indexOf(Volume.device)==0){
                return path.replace(Volume.device,Volume.path).replace(/[\\/]+/,"\\");
            }
        }
    }else return path;
}

image

xianyunleo commented 11 months ago

没事我不急,formatVolumePath交给api提供方处理好点。