Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
Someone asked for Task Manager style information, without parsing pslist (a MS command line tool similar to Task Manager and Process Explorer), or using WMI (the "official way" according to Win32::Process::Info). So here is the answer in Perl. The author of Win32::Process::Info decided to not use Native API Win32::Process::Info::NT leaving only WMI as the alternative according to what I've been told. Anyway, here is calling NtQuerySystemInformation for Task Manager like info using Win32::API. Tested on Windows XP 64 bit and 32 bit corresponding bit Perls on each OS. It is rough (uninformative errors, assumptions about buffer sizes, etc), and the last 1/3rd of the struct is never processed. I dont plan to finish it, but more than half the work was done. Comparing the Dumper outputs with Task Manager processes tab shows this is the same info.
#!/usr/bin/perl -w use Win32::API; use Math::Int64 qw ( native_to_int64 int64_to_string); use Data::Dumper; use warnings; use strict; BEGIN { use Config; eval ' sub PTR_LET () { "' .($Config{ptrsize} == 8 ? 'Q' : 'L'). '" }'; } #Win32::API doesnt do enums Win32::API::Type->typedef( 'SYSTEM_INFORMATION_CLASS', 'ULONG' ); my $api = Win32::API::More->new('ntdll.dll', ' NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength );'); #uninfomative error, GetLastError should be fetched die "Win32::API failure" if !$api; #this should really be a loop, a fixed 65KB is wrong, #NtQuerySystemInformation will fail with STATUS_INFO_LENGTH_MISMATCH i +f the buffer #is not long enough #changing \x00 to \xff and comparing the before and after will show wh +at #reserved fields are never filled and truly have no meaning my $buf = "\x00" x 65000; my $retlen = 0; # 5 == SystemProcessInformation my $ret = $api->Call(5, $buf, length($buf), $retlen ); #todo print NTSTATUS code die "failed " if $ret; #ImageName.Buffer is a pointer to inside $buf, if $buf is realloced #there is a problem, so save the PV, then use that to convert Buffer t +o #offset not a ptr later my $bufptr = unpack(PTR_LET, pack('p', $buf)); #how far are we into the buffer, part of extracting ImageName.Buffer my $bufoffset = 0; print "retlen $retlen ret $ret\n"; #cut off uninit data at the end $buf = substr($buf, 0, $retlen); my %h; do { ($h{NextEntryOffset}, $h{NumberOfThreads}, $h{Reserved1}, $h{Reserved2}, $h{Reserved3}, $h{CreateTime}, $h{UserTime}, $h{KernelTime}, $h{ImageName}, $h{BasePriority}, $h{ProcessId}, $h{InheritedFromProcessId}, $h{HandleCount}, $h{Reserved4}, $h{Reserved5}, $h{PrivatePageCount} ) = unpack('LL(a[8])[6]a[SS'.(PTR_LET eq 'Q' ? 'x!['.PTR_LET.']' : + '').PTR_LET.']lx!['.PTR_LET.']' #pid .PTR_LET.'' #parent pid .PTR_LET. #handle count, 2 reserveds, private page count 'LLLL' #VM_COUNTERS VirtualMemoryCounters; #IO_COUNTERS IoCounters; #SYSTEM_THREAD Threads[0]; #not done/todo , $buf); #portable 64 bit int conversion, these are strings now $h{Reserved1} = int64_to_string(native_to_int64($h{Reserved1})); $h{Reserved2} = int64_to_string(native_to_int64($h{Reserved2})); $h{Reserved3} = int64_to_string(native_to_int64($h{Reserved3})); $h{CreateTime} = int64_to_string(native_to_int64($h{CreateTime})); $h{UserTime} = int64_to_string(native_to_int64($h{UserTime})); $h{KernelTime} = int64_to_string(native_to_int64($h{KernelTime})); { #this is still packed, make a copy my $in = $h{ImageName}; $h{ImageName} = {}; ($h{ImageName}->{Length}, $h{ImageName}->{MaximumLength}, $h{ImageName}->{Buffer} ) = unpack('SS'.(PTR_LET eq 'Q' ? 'x!['.PTR_LET.']' : '').PTR_ +LET, $in); #Buffer is still packed, but convert the pointer to the offset + into the #$buf $h{ImageName}->{Buffer} = substr($buf, $h{ImageName}->{Buffer} +-$bufptr-$bufoffset, $h{ImageName}->{Length}); #$h{ImageName}->{Buffer} is in UTF16 wont print nicely to cons +ole } #slice off the processed SYSTEM_PROCESS_INFORMATION struct and tra +iling #VLA/unprocesed data $buf = substr($buf, $h{NextEntryOffset}); $bufoffset += $h{NextEntryOffset}; print Dumper(\%h); } while ($h{NextEntryOffset});
This is the struct that the above script decodes. Debate exists about what is the correct struct for SystemProcessInformation . This is correct for Windows XP I guess. Vista/7 IDK.
typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER Reserved[3]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE ProcessId; HANDLE InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; ULONG PrivatePageCount; VM_COUNTERS VirtualMemoryCounters; IO_COUNTERS IoCounters; SYSTEM_THREAD Threads[0]; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
The h in %h means hash.

In reply to NtQuerySystemInformation/Task Manger processes tab with Win32::API by bulk88

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others romping around the Monastery: (4)
    As of 2014-09-02 06:00 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      My favorite cookbook is:










      Results (20 votes), past polls