http://qs321.pair.com?node_id=959320

dt667 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use the Win32::API module to determine if a particular Windows process has DEP enabled or not. I believe my confusion is in how to pass the appropriate type of information into GetProcessDEPPolicy(). Any help would be greatly appreciated!!!!

#!/usr/bin/perl -w use strict; use Win32::OLE; use Win32::API; my $PROCESS_QUERY_INFORMATION = 0x0400; my $TOKEN_QUERY = 0x0008; my $TOKEN_ADJUST_PRIVILEGES = 0x0020; my $SE_PRIVILEGE_ENABLED = 0x02; my $SE_DEBUG_NAME = "SeDebugPrivilege"; my $objWMIService; my $colItems; my $iResult; unless ($objWMIService = Win32::OLE->GetObject("winmgmts:{impersonatio +nLevel=impersonate}!\\\\localhost\\root\\cimv2")) { throw Error::Simple("Could not connect to WMI Service on 'localhos +t'while attempting to collect a remote item. The error returned was: + " . Win32::OLE->LastError() . "."); } unless($colItems= $objWMIService->ExecQuery("SELECT * FROM Win32_Proce +ss", "WQL",0x10 | 0x20)) { throw Error::Simple("Could not extract notification query from WMI + Service on 'localhost'. The error returned was: " . Win32::OLE->Last +Error() . "."); } my $OpenProcess = Win32::API->new('kernel32.dll', 'OpenProcess', 'NIN' +, 'N') or die $^E; my $CloseHandle = new Win32::API( 'kernel32.dll', 'CloseHandle', 'N', +'I' ) || die "Can not link to CloseHandle()"; my $GetProcessDEPPolicy = Win32::API->new('kernel32.dll', 'GetProcessD +EPPolicy', 'NPP', 'I' ) or die $^E; my $GetCurrentProcess = new Win32::API( 'Kernel32.dll', 'GetCurrentPro +cess', [], 'N' ) || die; my $OpenProcessToken = new Win32::API( 'AdvApi32.dll', 'OpenProcessTok +en', 'NNP', 'I' ) || die; my $AdjustTokenPrivileges = new Win32::API( 'AdvApi32.dll', 'AdjustTok +enPrivileges', 'NIPNPP', 'I' ) || die; my $LookupPrivilegeValue = new Win32::API( 'AdvApi32.dll', 'LookupPriv +ilegeValue', 'PPP', 'I' ) || die; foreach my $objItem (in $colItems) { if(defined($objItem->{CommandLine})) { if($objItem->{CommandLine} ne '') { print "pid: " . $objItem->{'ProcessId'} ."\n"; my $pid = sprintf("%d", $objItem->{'ProcessId'}); my $phToken = pack( "L", 0 ); my $dep = pack( "L", 0 ); if( $OpenProcessToken->Call( $GetCurrentProcess->Call(), $ +TOKEN_ADJUST_PRIVILEGES | $TOKEN_QUERY, $phToken ) ) { my $hToken = unpack( "L", $phToken ); if( SetPrivilege( $hToken, $SE_DEBUG_NAME, 1 ) ) { my $hProcess = $OpenProcess->Call( $PROCESS_QUERY_ +INFORMATION, 0, $pid ); if( $hProcess ) { print "handle: " . $hProcess ."\n"; my $return = $GetProcessDEPPolicy->Call($hProc +ess, $dep, 0); if ($return == 0) #return always equals 0, Get +LastError: The parameter is incorrect. { print "GetProcessDEPPolicy failed with err +or: " . Win32::FormatMessage(Win32::GetLastError()); } SetPrivilege( $hToken, $SE_DEBUG_NAME, 0 ); $CloseHandle->Call( $hProcess ); } else { print "OpenProcess failed with error: " . Win3 +2::FormatMessage(Win32::GetLastError()); } } $CloseHandle->Call( $hToken ); } else { print "OpenProcessToken failed with error: " . Win32:: +FormatMessage(Win32::GetLastError()); } print "System_Functions->getProcessInfo collected dep: " . + $dep ."\n"; print "System_Functions->getProcessInfo collected primary_ +window_text: " . $objItem->{'Caption'} ."\n"; } } } sub SetPrivilege { my( $hToken, $pszPriv, $bSetFlag ) = @_; my $pLuid = pack( "Ll", 0, 0 ); if( $LookupPrivilegeValue->Call( "\x00\x00", $pszPriv, $pLuid ) ) { my $pPrivStruct = pack( "LLlL", 1, unpack( "Ll", $pLuid ), ( ( + $bSetFlag )? $SE_PRIVILEGE_ENABLED : 0 ) ); $iResult = ( 0 != $AdjustTokenPrivileges->Call( $hToken, 0,$pP +rivStruct, length( $pPrivStruct ), 0, 0 ) ); } print "iResult: $iResult\n"; return( $iResult ); }

my $return = $GetProcessDEPPolicy->Call($hProcess, $dep, 0); always equals zero and the Win32::GetLastError() is "The parameter is incorrect." I cannot figure out which parameter is incorrect. Is there more verbose logging I can enable somehow?

Replies are listed 'Best First'.
Re: Win32::API GetProcessDEPPolicy usage
by dt667 (Acolyte) on Mar 13, 2012 at 13:41 UTC

    Figured it out. The third input to GetProcessDEPPolicy needed to be $perm = pack("L",0); and then the $dep value is read by unpack("L",$dep); As this is only available for 32-bit processes and I am running the code on a 64-bit OS, I am assuming the "Parameter is incorrect" errors are from the 64-bit process running on my system.