winapi-rs icon indicating copy to clipboard operation
winapi-rs copied to clipboard

processsnapshot is missing several types

Open brennie opened this issue 3 years ago • 2 comments

Any chance these are gonna be added?

I was exploring this api. I am gonna try to translate the PSS_PROCESS_INFORMATION to a rust struct and go from there until this issue gets more momentum.

dfirence avatar Apr 06 '21 03:04 dfirence

@brennie and @retep998

I created the first struct, but I am not knowledgable on how to add these to the WIN API project, is there a tutorial?

I created the rust struct manually



/// Struct PSS_PROCESS_FLAGS
///
/// ```c++
///typedef struct {
///    DWORD             ExitStatus;
///    void              *PebBaseAddress;
///    ULONG_PTR         AffinityMask;
///    LONG              BasePriority;
///    DWORD             ProcessId;
///    DWORD             ParentProcessId;
///    PSS_PROCESS_FLAGS Flags;
///    FILETIME          CreateTime;
///    FILETIME          ExitTime;
///    FILETIME          KernelTime;
///    FILETIME          UserTime;
///    DWORD             PriorityClass;
///    ULONG_PTR         PeakVirtualSize;
///    ULONG_PTR         VirtualSize;
///    DWORD             PageFaultCount;
///    ULONG_PTR         PeakWorkingSetSize;
///    ULONG_PTR         WorkingSetSize;
///    ULONG_PTR         QuotaPeakPagedPoolUsage;
///    ULONG_PTR         QuotaPagedPoolUsage;
///    ULONG_PTR         QuotaPeakNonPagedPoolUsage;
///    ULONG_PTR         QuotaNonPagedPoolUsage;
///    ULONG_PTR         PagefileUsage;
///    ULONG_PTR         PeakPagefileUsage;
///    ULONG_PTR         PrivateUsage;
///    DWORD             ExecuteFlags;
///    wchar_t           ImageFileName[MAX_PATH];
///  } PSS_PROCESS_INFORMATION;
/// ```
#[repr(C)]
pub struct PSS_PROCESS_INFORMATION {
    pub ExitStatus:                  DWORD,
    pub PebBaseAddress:              *mut c_void,
    pub AffinityMask:                ULONG_PTR,
    pub BasePriority:                LONG,
    pub ProcessId:                   DWORD,
    pub ParentProcessId:             DWORD,
    pub Flags:                       PSS_PROCESS_FLAGS,
    pub CreateTime:                  FILETIME,
    pub ExitTime:                    FILETIME,
    pub KernelTime:                  FILETIME,
    pub UserTime:                    FILETIME,
    pub PriorityClass:               DWORD,
    pub PeakVirtualSize:             ULONG_PTR,
    pub VirtualSize:                 ULONG_PTR,
    pub PageFaultCount:              DWORD,
    pub PageWorkingSetSize:          ULONG_PTR,
    pub WorkingSetSize:              ULONG_PTR,
    pub QuotaPeakPagedPoolUsage:     ULONG_PTR,
    pub QuotaPagedPoolUsage:         ULONG_PTR,
    pub QuotaPeakNonPagePoolUsage:   ULONG_PTR,
    pub QuotaNonPagedPoolUsage:      ULONG_PTR,
    pub PagefileUsage:               ULONG_PTR,
    pub PeakPagefileUsage:           ULONG_PTR,
    pub PrivateUsage:                ULONG_PTR,
    pub ExecuteFlags:                DWORD,
    pub ImageFileName:               [u16; 260]
}
impl PSS_PROCESS_INFORMATION {
    pub fn new() -> Self
    {
        PSS_PROCESS_INFORMATION {
            ExitStatus:                   DWORD::default(),
            PebBaseAddress:               std::ptr::null_mut(),
             AffinityMask:                ULONG_PTR::default(),
             BasePriority:                LONG::default(),
             ProcessId:                   DWORD::default(),
             ParentProcessId:             DWORD::default(),
             Flags:                       PSS_PROCESS_FLAGS::PSS_PROCESS_FLAGS,
             CreateTime:                  FILETIME {dwLowDateTime: 0, dwHighDateTime: 0},
             ExitTime:                    FILETIME {dwLowDateTime: 0, dwHighDateTime: 0},
             KernelTime:                  FILETIME {dwLowDateTime: 0, dwHighDateTime: 0},
             UserTime:                    FILETIME {dwLowDateTime: 0, dwHighDateTime: 0},
             PriorityClass:               DWORD::default(),
             PeakVirtualSize:             ULONG_PTR::default(),
             VirtualSize:                 ULONG_PTR::default(),
             PageFaultCount:              DWORD::default(),
             PageWorkingSetSize:          ULONG_PTR::default(),
             WorkingSetSize:              ULONG_PTR::default(),
             QuotaPeakPagedPoolUsage:     ULONG_PTR::default(),
             QuotaPagedPoolUsage:         ULONG_PTR::default(),
             QuotaPeakNonPagePoolUsage:   ULONG_PTR::default(),
             QuotaNonPagedPoolUsage:      ULONG_PTR::default(),
             PagefileUsage:               ULONG_PTR::default(),
             PeakPagefileUsage:           ULONG_PTR::default(),
             PrivateUsage:                ULONG_PTR::default(),
             ExecuteFlags:                0,
             ImageFileName:               [0; 260]   
        }
    }
}


Implementation Code Snippert

Then in my code, I implemented it like this: note for simplicity only adding relevant portion

.... code

     let _dw_result = PssCaptureSnapshot(_h_process, _dw_capture_flags, CONTEXT_ALL, &mut _h_snapshot);
        
        if _dw_result != ERROR_SUCCESS {
            eprintln!("PssCaptureSnapshot() | Error: {:<7}", GetLastError());
            CloseHandle(_h_process);
            std::process::exit(1);
        }
        // Success - prep for snapshot queries
        //      Start with Process Data: PSS_QUERY_PROCESS_INFORMATION
        let mut _p_data: PSS_PROCESS_INFORMATION = PSS_PROCESS_INFORMATION::new();
        let _ptr_pdata: *mut c_void = &mut _p_data as *mut _ as *mut c_void;

        let mut _p_size: DWORD = mem::size_of::<PSS_PROCESS_INFORMATION>() as DWORD;

        let _p_query = PssQuerySnapshot(_h_snapshot,
                                        PSS_QUERY_PROCESS_INFORMATION,
                                        _ptr_pdata,
                                        _p_size);
        
        
        
        if _p_query != ERROR_SUCCESS {
            println!("PssQueryInformation(): Error Code: {}", GetLastError());
            CloseHandle(_h_process);
            std::process::exit(1);
        }


Testing it

Lastly, the usage of my test binary

$> apss-snapshot.exe -pid 6012

    Snapshot Handle         : 0x5973f5f698
    Process  Handle         : 0x5973f5f6d0
    Proccess Query          : 0
    DwResult                : 0
    ----------------------------------------------------------------------
    ExitStatus              : 259
    ParentProcessId         : 5124
    ProcessId               : 6012
    Process Name            : C:\Windows\System32\conhost.exe
    Process PEB Pointer     : 0x4e37917000
    Process Affinity Mask   : 15
    Process Flags           : PSS_PROCESS_FLAGS
    Process Execute Flags   : 0
    Process Page File Use   : 7753728
    ----------------------------------------------------------------------
    Process Created Time    : 132622303070306080
    Process Exited Time     : 0
    Process Kernel Time     : 6562500
    Process User Time       : 1718750
    ----------------------------------------------------------------------
    Process Priority Class  : 32
    Process Peak Virtual Sz : 2199141650432
    Process Page Fault Count: 10064
    Process WorkingSetSize  : 17256448
    ----------------------------------------------------------------------

dfirence avatar Apr 08 '21 02:04 dfirence