Winapi EnumProcessModules返回0,错误为299

Winapi EnumProcessModules返回0,错误为299,winapi,rust,Winapi,Rust,我目前正在尝试枚举我以前用32位程序创建的SupSend 32位进程的所有模块,我的Windows是64位的。 (我已经阅读了关于这个问题的所有其他主题) 代码如下: let a = CreateProcessA( "C:\\Program Files (x86)\\GlassWire\\GlassWire.exe\0".as_ptr(), null_mut(), null_mut(), null_mut(), false, 0x00000004, nul

我目前正在尝试枚举我以前用32位程序创建的SupSend 32位进程的所有模块,我的Windows是64位的。 (我已经阅读了关于这个问题的所有其他主题)

代码如下:

let a = CreateProcessA(
    "C:\\Program Files (x86)\\GlassWire\\GlassWire.exe\0".as_ptr(),
    null_mut(), null_mut(), null_mut(),
    false,
    0x00000004,
    null_mut(), null_mut(), SI, PI);
println!("{}", GetLastError());

let mut buffer: [*mut c_void;10] = [0 as *mut c_void;10];
WaitForInputIdle((*PI).hProcess as *mut c_void, -1);
let result = EnumProcessModules(
    (*PI).hProcess as *mut c_void,
    buffer.as_ptr() as *mut c_void,
    10, null_mut());

println!("EnumProcessModules([...]) = {} - {}", result, GetLastError());

let mut index: usize = 0x0; 
let mut modname: [u8;1024] = [0;1024];
while(transmute::<*mut c_void, u32>(buffer[index]) != 0x0){
    GetModuleFileNameExA((*PI).hProcess as *mut c_void, buffer[index], modname.as_ptr() as *mut c_void, 1024);
    println!("module: {}", std::str::from_utf8_unchecked(&modname));
    modname = [0;1024];
    index += 1;
}
println!("Dump: {:?}", buffer.to_vec());
如果我在
CreateProcessA()
中指定正在运行的程序的路径,它还将返回0和299作为windows错误代码


我真的很困惑…感谢阅读,我希望我已经足够清楚了。

首先,使用
CREATE\u NEW\u控制台
CREATE\u NO\u窗口
而不是
CREATE\u SUSPENDED(0x00000004)
,因为@Jonathan Potter,挂起状态将阻止函数
WaitForInputIdle

其次,确保进程不是控制台应用程序或具有消息队列,否则
WaitForInputIdle
会立即返回

然后,您可以尝试在
waitforinputile
之后调用
SuspendThread
,以挂起进程以防止其结束

编辑:

注意以下的最后两个参数:

cb

lphModule数组的大小,以字节为单位

lpcbNeeded

在中存储所有模块句柄所需的字节数 lphModule阵列


以下是msdn上的一个很好的示例:。只需替换
hProcess

首先,使用
CREATE\u NEW\u控制台
CREATE\u NO\u窗口
而不是
CREATE\u SUSPENDED(0x00000004)
,因为@Jonathan Potter,挂起状态将阻止函数
WaitForInputIdle

其次,确保进程不是控制台应用程序或具有消息队列,否则
WaitForInputIdle
会立即返回

然后,您可以尝试在
waitforinputile
之后调用
SuspendThread
,以挂起进程以防止其结束

编辑:

注意以下的最后两个参数:

cb

lphModule数组的大小,以字节为单位

lpcbNeeded

在中存储所有模块句柄所需的字节数 lphModule阵列


以下是msdn上的一个很好的示例:。只需替换
hProcess

0x00000004
意味着
CREATE\u SUSPENDED
,创建新进程时线程处于挂起状态,然后您将永远等待新进程空闲。挂起时它不会空闲。同样,如果目标进程中的模块列表已损坏或尚未初始化,
EnumProcessModules
可能会因299而失败。
0x00000004
表示
CREATE\u suspended
,则新进程的线程处于挂起状态,然后,您将永远等待新进程空闲。它不会在挂起时空闲。同样,如果目标进程中的模块列表已损坏或尚未初始化,
EnumProcessModules
可能会因299而失败。感谢它的工作,但它与我设置
GetCurrentProcess()
时所做的相同,主进程和ntdll模块句柄写入缓冲区,但
EnumProcessModules()
仍返回0,而
GetLastError()
返回998(错误\u NOACCESS->对内存位置的访问无效)。我能做些什么来解决这个问题呢?请注意,
cb
的最后两个参数:lphModule数组的大小,**以字节为单位。**(不是数组大小)
lpcbNeeded
:在lphModule数组中存储所有模块句柄所需的字节数。(不能为NULL,这将导致C/C++代码中出现NULL指针访问冲突异常)这可能是因为在32位中,
HMODULE
占用4个字节,而10个字节最多只能得到两个
HMODULE
s(您已经得到)。感谢它的工作,但它的作用与我设置
GetCurrentProcess()
时相同,主进程和ntdll模块句柄写在缓冲区中,但
EnumProcessModules()
仍然返回0,
GetLastError()
返回998(错误\u NOACCESS->对内存位置的访问无效)。我能做些什么来解决这个问题呢?请注意,
cb
的最后两个参数:lphModule数组的大小,**以字节为单位。**(不是数组大小)
lpcbNeeded
:在lphModule数组中存储所有模块句柄所需的字节数。(不能为NULL,这将导致C/C++代码中出现NULL指针访问冲突异常)这可能是因为在32位中,
HMODULE
占用4个字节,而10个字节最多只能得到两个
HMODULE
s(您已经得到)。
A:\Encrypted\Temp\injector\target\i686-pc-windows-msvc\debug\main.exe // (the program)
C:\WINDOWS\SYSTEM32\ntdll.dll

Dump: [0x920000, 0x77180000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]