>This thread is old but still of value
The value is diminished by advances in operating systems. Information about a process is much more readily available starting with Windows/XP and later; you don't have to use some of the tools you had to use with 9x/ME/2000.
It's diminished even more by advances in the PowerBASIC compiler, which now supports simplified access to portions of the Windows' API which offer only a COM interface.
MCM
Announcement
Collapse
No announcement yet.
Process Handles? via NtDll or PsApi?
Collapse
X
-
see also...
And a little bit offtopic but icing on the related cake http://www.powerbasic.com/support/pb...d.php?t=055164Last edited by Wayne Diamond; 29 Oct 2014, 01:41 AM.
Leave a comment:
-
-
This thread is old but still of value.
During my testing of the various code from this thread and the source code section it points to, many of the handles do not close in the thread that includes the DuplicateHandle function.
I am not a threads expert, but I have used another approach to closing threads by using global variables as flags. I will have to post that code later.
This code show in this thread up to this point will also possibly hang. I am simply a newbie in this area.
I used Nirsoft's openedfilesview.exe program to compare their results from what result I was seeing from this program.
Basically, from what I am seeing, is that if the granted access is of certain values on object types. This program will hang on the call to the DuplicateHandle function.
I am not a computer guy that knows much if any about granted access and security to files and certainly not keen on HEX.
In the above thread, you can see coding and some definitions on the granted access byte.
See the function "SortAccessGranted" in the above posting.
I believe if this program is run from a service(with no display), then there is the high possibility that this program will not hang on any or all of the granted access codes.
From viewing the Nirsoft sotware, the files listed never go above 0x001??????.
See for yourself with the Nirsoft openedfilesview.exe program from their website, and sort the "Granted Access" column.
I have not tried any of the Sysinternal's programs.
Please see this website on this as well.
In the DuplicateHandle MSDN documentation there is not a lot of information about the Access Mask that can be passed to DuplicateHandle. Wh...
I had this program hang on mbam.exe(Malwarebytes) until the mbam.exe process was killed.
During testing, it is good to display every processid, filename, and granted access before making the call the DuplicateHandle function to see what program and object type with granted access code is causing the hang.
As from my memory, I do not think the granted access setting does not have any bearing on the handles not closing.
I will have to post more on this later. I just wanted to through out there some observations because much of this I do not understand. All I know to do is observe and compare(on the granted access) and try another approach on managing threads(be it unorthodox or not).Last edited by Paul Purvis; 29 Oct 2014, 01:17 AM.
Leave a comment:
-
-
<UPDATED 7 Sept 2007>
Thanx Aleksandr,
I figured out a bit tricky work-around shortly before your post, and got things down to no memory leaks (meaning I can completely close my program)
Your post helped confirm some ideas in my head (still threating those lil voices with the q-tip for getting me in this deep)
After much debate, I have now posted the code as I have it in the source-code forum (under the Enum Handles with NtQuerySystemInformation (improved) for others to see and use.
Some minor things still bug me (like Win2K not finding "\Device\Serial0" even though I know it is open) and I need to go back and clean up the code (change declares to loadlibrary and the like) and find my notes on which OS and servicepack is needed to use ntdll.dll (I think its all NT side of windows but not sure)Last edited by Cliff Nichols; 7 Sep 2007, 12:53 PM.
Leave a comment:
-
-
Cliff,
I don't want to disappoint you, but I'm afraid you don't have chance to enumerate all objects without jumping to ring 0. That mean you need a driver to do this job.
Check this Delphi example for method how to jump over sync. locked pipes.Last edited by Aleksandr Dobrev; 5 Sep 2007, 11:36 AM.
Leave a comment:
-
-
Like a dog with an old bone, I can NOT let go...
Below is my code mixed with Pierre's code for what I believe is close (but just not there yet)
Problems I am having:- Processes not being enumerated...(Somewhere near a value of 10,000 but PID is a dword and should be able to enumerate well beyond this range)
- What I believe are Named-Pipes, hanging up code (even in a thread) so a memory leak remains after closure
- Apparently Named pipes and other files have the same access flags, so I need to find another way to find out if a named pipe without asking the name (hence the catch-22) by asking I fall into the trap
Any help with pipes will be GREATLY appreciated.
Anyways here is my current version of the code (I think Pierre will like some of the routines I built in)
Code:#COMPILE EXE '#Win 8.03# #INCLUDE "win32api.inc" '#2005-01-27# #OPTION VERSION5 'Windows 2000 or higher '--------------------------------------------------------------------------- ' GLOBALS '--------------------------------------------------------------------------- GLOBAL hDlg AS DWORD 'Handle for the dialog GLOBAL hList AS DWORD 'Handle for the listbox to show results GLOBAL sObjName AS STRING 'Object name <-- Core Point of demo to find the correct results without lockup or memory leaks '--------------------------------------------------------------------------- ' APPLICATION TITLE '--------------------------------------------------------------------------- $Title = "Enum Processes, Get Handles, Get Object Names" '--------------------------------------------------------------------------- ' DIALOG CONSTANTS '--------------------------------------------------------------------------- %Grip = 101 %Listbox = 201 %Checkbox = 301 %Combobox = 401 %ButtonSearch = 501 %ButtonQuery = 502 %ButtonQuit = 503 '--------------------------------------------------------------------------- ' UN-DOCUMENTED CONSTANTS FOR NTDLL '--------------------------------------------------------------------------- %ObjectNameInformation = &h01 %SystemHandleInformation = &h10 '<--- Change to Unsigned once program is debugged %STATUS_SUCCESS = &h00000000 %STATUS_MORE_ENTRIES = &h00000105 %STATUS_INFO_LENGTH_MISMATCH = &hC0000004 '<--- Change to Unsigned once program is debugged %STATUS_BUFFER_OVERFLOW = &h80000005 '<--- Change to Unsigned once program is debugged %STATUS_SEVERITY_ERROR = &h00000003 '--------------------------------------------------------------------------- ' UN-DOCUMENTED USER DEFINED TYPES (UDT's) FOR NTDLL '--------------------------------------------------------------------------- TYPE SYSTEM_HANDLE_INFORMATION 'System Handle Information Class is &h10 <--- If my guess is right Object Information is &h01 ProcessID AS DWORD 'ID of the Process ObjectTypeNumber AS BYTE 'Number to indicate the type of Object Flags AS BYTE 'Flags (0x00 = None, 0x01 = Protect_from_close, 0x02 = Inherit) ' HANDLE AS WORD '<--- HANDLE is a PB reserved word (but not documented in WinHelp2000) use another variable ' OBJECT AS DWORD '<--- OBJECT is a PB reserved word (WinHelp2000 says for COM (activex) use), use another variable SysHandle AS WORD '<--- To replace HANDLE above SysObjectAddr AS DWORD '<--- To replace OBJECT above GrantedAccess AS DWORD 'User Permissions END TYPE TYPE SYSTEM_HANDLE_TABLE_ENTRY_INFO NumberOfHandles AS DWORD 'Number of Handles in the system (the WHOLE SYSTEM) ' HANDLES(0 TO 0) AS SYSTEM_HANDLE_INFORMATION 'HANDLES is a PB reserved word, use another (see PB Help-File for SHELL commands) SysHandles(0 TO 0) AS SYSTEM_HANDLE_INFORMATION 'To replace HANDLES above END TYPE TYPE UNICODE_STRING Length AS WORD 'Length in bytes of string in Buffer MaximumLength AS WORD 'Maximum length in bytes of Buffer pBuffer AS DWORD 'Pointer to unicode string END TYPE '--------------------------------------------------------------------------- ' UN-DOCUMENTED NTDLL FUNCTION CALLS '--------------------------------------------------------------------------- DECLARE FUNCTION NtQuerySystemInformation LIB "NtDLL.DLL" ALIAS "NtQuerySystemInformation"( _ BYVAL SystemInformationClass AS DWORD, _ BYVAL SystemInformation AS DWORD, _ BYVAL SystemInformationLength AS DWORD, _ BYREF ReturnLength AS DWORD) AS LONG DECLARE FUNCTION NtQueryObject LIB "NtDLL.DLL" ALIAS "NtQueryObject"( _ BYVAL hndl AS DWORD, _ BYVAL ObjectInformationClass AS DWORD, _ BYVAL ObjectInformation AS DWORD, _ BYVAL ObjectInformationLength AS DWORD, _ BYREF ReturnLength AS DWORD) AS LONG 'NtClose issuperseded by CloseHandle 'DECLARE FUNCTION NtClose LIB "NtDLL.DLL" ALIAS "NtClose"( _ ' BYVAL hndl AS DWORD) AS LONG 'STATUS_SUCCESS if handle was closed. '--------------------------------------------------------------------------- ' PSAPI FUNCTION CALLS '--------------------------------------------------------------------------- DECLARE FUNCTION EnumProcessModules LIB "PsApi.DLL" ALIAS "EnumProcessModules"( _ BYVAL hProcess AS DWORD, _ BYVAL lphModule AS DWORD, _ BYVAL cb AS DWORD, _ BYREF cbNeeded AS DWORD) AS LONG DECLARE FUNCTION GetModuleFileNameEx LIB "PsApi.DLL" ALIAS "GetModuleFileNameExA"( _ BYVAL hProcess AS DWORD, _ BYVAL hModule AS DWORD, _ lpFilename AS ASCIIZ, _ BYVAL nSize AS DWORD) AS LONG '--------------------------------------------------------------------------- ' WRAPPER FUNCTIONS '--------------------------------------------------------------------------- DECLARE FUNCTION CancelIo LIB "KERNEL32.DLL" ALIAS "CancelIo" (BYVAL hFile AS DWORD) AS LONG DECLARE FUNCTION pidEnum AS LONG 'Main function to get data DECLARE FUNCTION pidGetFileName(PID AS DWORD) AS STRING DECLARE FUNCTION pidGetObjectNameThread(hPort AS DWORD) AS LONG DECLARE FUNCTION pidGetObjectName(ProcessId AS DWORD, Hndl AS WORD) AS LONG '*** Re-Enable if needed later <--- Starting to get indications that this may be a mute point with VISTA 'DECLARE FUNCTION LoadPrivilege(BYVAL sPrivilege AS STRING) AS LONG DECLARE FUNCTION SetHorizontalListboxBar() AS LONG DECLARE FUNCTION ListAdd(AddToList AS STRING) AS LONG DECLARE CALLBACK FUNCTION DlgProc DECLARE FUNCTION PBMAIN AS LONG '--------------------------------------------------------------------------- ' EXTRA WRAPPER FUNCTIONS (MOSTLY FOR SORTING DATA) '--------------------------------------------------------------------------- DECLARE FUNCTION GetProcessID(ProcessId AS DWORD) AS STRING DECLARE FUNCTION GetProcessHandle(ProcessHandle AS WORD) AS STRING DECLARE FUNCTION GetProcessAccess(ProcessAccess AS DWORD) AS STRING DECLARE FUNCTION SortAccessGranted(GrantedAccessValue AS LONG) AS STRING DECLARE FUNCTION GetProcessObjAddress(ProcessObjAddress AS DWORD) AS STRING DECLARE FUNCTION GetProcessObjFlags(ProcessObjFlags AS BYTE) AS STRING DECLARE FUNCTION SortObjectFlags(ObjectFlags AS BYTE) AS STRING DECLARE FUNCTION GetProcessObjType(ProcessObjType AS BYTE) AS STRING DECLARE FUNCTION SortObjectTypeName(BYVAL ObjectType AS LONG) AS STRING FUNCTION pidEnum AS LONG 'Main function to get data LOCAL pInfoTable AS SYSTEM_HANDLE_TABLE_ENTRY_INFO POINTER 'System holds a table of each process and whats involved in that process LOCAL sBuffer AS STRING LOCAL sObjectType AS STRING LOCAL sFileName AS STRING LOCAL pBuffer AS DWORD PTR LOCAL LenBuffer AS DWORD LOCAL ByteNeeded AS DWORD LOCAL InfoCount AS DWORD LOCAL Looper AS DWORD LOCAL AllHandle AS LONG LOCAL Retval AS LONG LOCAL ProcNumber AS STRING LOCAL ProcId AS STRING LOCAL ProcHandle AS STRING LOCAL ProcAccess AS STRING LOCAL ProcObjAddress AS STRING LOCAL ProcObjFlags AS STRING LOCAL ProcObjTypeName AS STRING LOCAL ProcObjAttrib AS STRING LOCAL ProcObjName AS STRING LOCAL ShowPort AS LONG ByteNeeded = SIZEOF(SYSTEM_HANDLE_TABLE_ENTRY_INFO) 'Minimum buffer size for a valid ByteNeeded FOR Looper = 1 TO 2 'Call once to get the bytes needed, call again to get actual info LenBuffer = ByteNeeded sBuffer = NUL$(ByteNeeded) pBuffer = STRPTR(sBuffer) Retval = NtQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) NEXT '*** Get needed info pInfoTable = pBuffer 'Fill my table with the info in the pointer to the real table InfoCount = @pInfoTable.NumberOfHandles 'Get the Number of handles in the system '*** Display purposes Retval = SendMessage(hList, %LB_INITSTORAGE, InfoCount * 4, InfoCount * 200) 'Faster listbox filling DIM Info(1 TO InfoCount) AS SYSTEM_HANDLE_INFORMATION AT pInfoTable + 4 '+ 4 to start just after .NumberOfHandles <--- Not sure what the AT part means yet (unless a pointer offset?) FOR Looper = 1 TO InfoCount 'For each Handle found in the system sFileName = pidGetFileName(Info(Looper).ProcessID) 'Get the file name of what owns the handle ' IF Info(Looper).ProcessID = GetModuleHandle(BYVAL %NULL) THEN ITERATE 'Dont enum yourself IF INSTR(UCASE$(sFileName), UCASE$("Process")) THEN ITERATE '<--- Do NOT iterate any copies of this program (exponentially grows each copy) ' IF INSTR(UCASE$(sFileName), UCASE$("SYSTEM")) THEN ITERATE '<--- Nothing returns from System anyways when getting object name ' IF INSTR(UCASE$(sFileName), UCASE$("WINLOGON")) THEN ITERATE '<--- Nothing returns from WinLogon anyways when getting object name ' IF INSTR(UCASE$(sFileName), UCASE$("SERVICES")) THEN ITERATE '<--- Nothing returns from Services anyways when getting object name ' IF INSTR(UCASE$(sFileName), UCASE$("LSASS")) THEN ITERATE '<--- Nothing returns from Lsass anyways when getting object name ' IF INSTR(UCASE$(sFileName), UCASE$("SVCHOST")) THEN ITERATE '<--- Nothing returns from SvcHost anyways when getting object name '' ' IF INSTR(UCASE$(sFileName), UCASE$("TASKMGR")) THEN ITERATE '<--- Why get handles from Windows Task Manager? ' IF INSTR(UCASE$(sFileName), UCASE$("Cosmos")) THEN ' 'Do Nothing ' else ' ITERATE '<--- Do NOT iterate any copies of this program (exponentially grows each copy) ' end if '*** My Version '*** Process Info ProcNumber = "Number: " & FORMAT$(Looper) 'IF Info(Looper).ProcessID = 109996 THEN MSGBOX STR$(Info(Looper).ProcessID) ProcId = GetProcessId(Info(Looper).ProcessID) ProcHandle = GetProcessHandle(Info(Looper).SysHandle) ProcAccess = GetProcessAccess(Info(Looper).GrantedAccess) '*** Object Info ProcObjAddress = GetProcessObjAddress(Info(Looper).SysObjectAddr) ProcObjFlags = GetProcessObjFlags(Info(Looper).Flags) '0x00 = None, 0x01 = Protect_from_close, 0x02 = Inherit ProcObjTypeName = GetProcessObjType(Info(Looper).ObjectTypeNumber) '*** Originally I thought one of the below commented cases was causing the memory leak ' IF INSTR(UCASE$(ProcObjTypeName), UCASE$("Semaphore")) THEN ITERATE ' IF INSTR(UCASE$(ProcObjTypeName), UCASE$("Thread")) THEN ITERATE ' IF INSTR(UCASE$(ProcObjTypeName), UCASE$("IoCompletion")) THEN ITERATE ' IF INSTR(UCASE$(ProcObjTypeName), UCASE$("Timer")) THEN ITERATE ' IF INSTR(UCASE$(ProcObjTypeName), UCASE$("Event")) THEN ITERATE ' ' '*** In My case I am only after what Windows reports as "Files" but may really be a Serial Port or a USB port IF INSTR(UCASE$(ProcObjTypeName), UCASE$("File")) THEN IF INSTR(UCASE$(ProcAccess), UCASE$("%SYNCHRONIZE")) THEN IF INSTR(UCASE$(ProcAccess), UCASE$("%PROCESS_DUP_HANDLE")) THEN 'Do Nothing ELSE ITERATE END IF ELSEIF INSTR(UCASE$(ProcAccess), UCASE$("%PROCESS_ALL_ACCESS")) THEN ' IF INSTR(UCASE$(ProcAccess), UCASE$("%PROCESS_DUP_HANDLE")) THEN IF INSTR(UCASE$(ProcObjFlags), UCASE$("(Inherit)")) THEN 'Do Nothing ELSEIF INSTR(UCASE$(ProcAccess), UCASE$("%PROCESS_DUP_HANDLE")) THEN 'Do Nothing '*** No memory leak if commented out, so currently I believe that the following holds true '*** 1.) Named pipes that lock-up just asking what the object name is due to one (or more) of the access flags except %PROCESS_DUP_HANDLE '*** 2.) Files that are Inherited do not seem to lock-up, so for the time being I have to assume named-pipes are not inherited '*** 3.) Odd how my own program can be no flags on one computer and inherited on another <--- Need to research this '*** 4.) Whatever named pipe(s) that are locking have the same access flags as files that do not lock <--- Need to find a workaround for this ' ELSEIF INSTR(UCASE$(ProcAccess), UCASE$("%PROCESS_VM_READ")) THEN 'Do Nothing ELSE ITERATE 'If a possible lock-up file (like named-pipes) then skip gathering info on it END IF ELSE ITERATE 'If a combination of access flags that I have not run into yet, then skip asking for info END IF ELSE ITERATE 'If not a "File" (only after files at the moment), then skip asking for info END IF '*** Get the object name if passed the above checks if possibly a named-pipe that will lock just by asking if a named pipe pidGetObjectName(Info(Looper).ProcessID, Info(Looper).SysHandle) 'Get the object name of each handle contained in each process'*** Display Results '*** Since I am after Serial Ports, USB Ports, and USB-RS232 Adapters I added the below filters SELECT CASE INSTR(UCASE$(sObjName), UCASE$("SERIAL")) CASE 0 ShowPort = %False SELECT CASE INSTR(UCASE$(sObjName), UCASE$("edgeser")) CASE 0 ShowPort = %False SELECT CASE INSTR(UCASE$(sObjName), UCASE$("USBPDO")) CASE 0 ShowPort = %False CASE ELSE ShowPort = %True END SELECT CASE ELSE ShowPort = %True END SELECT CASE ELSE ShowPort = %True END SELECT '*** If it matches one of the above filters, then show the information SELECT CASE ShowPort CASE %False CASE %True '*** Display Process Info ListAdd ProcNumber & $TAB & _ ProcId & $TAB & _ ProcHandle & $TAB & _ UCASE$(MID$(sFileName , INSTR(-1, sFileName, ANY ":/\") + 1)) 'Process Name without path '*** Display Handle Object Info ListAdd $TAB & ProcAccess ListAdd $TAB & ProcObjAddress & $TAB & _ ProcObjFlags & $TAB & _ ProcObjTypeName IF LEN(sFileName) THEN ListAdd " " & sFileName IF LEN(sObjName) THEN ListAdd " " & sObjName ListAdd STRING$(255,"-") ListAdd "" END SELECT NEXT Looper DIALOG SET TEXT hDlg, $Title & " -" & STR$(InfoCount) & " handles found" END FUNCTION '______________________________________________________________________________ '______________________________________________________________________________ FUNCTION pidGetFileName(PID AS DWORD) AS STRING LOCAL ModuleName AS STRING LOCAL PidPath AS STRING LOCAL sBuffer AS STRING LOCAL pBuffer AS DWORD PTR LOCAL LenBuffer AS DWORD LOCAL hProcess AS DWORD LOCAL ByteNeeded AS DWORD LOCAL HandleCount AS DWORD LOCAL Looper AS LONG LOCAL Retval AS LONG hProcess = OpenProcess(%PROCESS_QUERY_INFORMATION OR %PROCESS_VM_READ, 0, Pid) IF hProcess THEN ByteNeeded = SIZEOF(ByteNeeded) 'SIZEOF(ByteNeeded) = 4 = SIZEOF(DWORD) FOR Looper = 1 TO 2 'Call once to get bytes needed, call again to get actual info LenBuffer = ByteNeeded sBuffer = NUL$(ByteNeeded) pBuffer = STRPTR(sBuffer) Retval = EnumProcessModules(hProcess, pBuffer, LenBuffer, ByteNeeded) 'Get number of modules contained in process NEXT Looper IF Retval THEN HandleCount = LenBuffer \ SIZEOF(ByteNeeded) 'LenBuffer \ SIZEOF(ByteNeeded) = LenBuffer \ 4 DIM ModulesHandles(1 TO HandleCount) AS DWORD AT pBuffer ModuleName = "Unknown" & NUL$(%MAX_PATH) Retval = GetModuleFileNameEx(hProcess, ModulesHandles(1), BYVAL STRPTR(ModuleName), %MAX_PATH) PidPath = "FileName: " & LEFT$(ModuleName, Retval) ELSE ' ListAdd "Bad EnumProcessModules" END IF CloseHandle hProcess END IF IF PidPath = "" THEN PidPath = "FileName: SYSTEM" FUNCTION = PidPath END FUNCTION '______________________________________________________________________________ FUNCTION pidGetObjectNameThread(hPort AS DWORD) AS LONG LOCAL puString AS UNICODE_STRING POINTER LOCAL sBuffer AS STRING LOCAL pzBuffer AS ASCIIZ POINTER LOCAL psBuffer AS DWORD POINTER LOCAL LenBuffer AS DWORD LOCAL ByteNeeded AS DWORD LOCAL ByteCount AS DWORD LOCAL Looper AS LONG LOCAL Retval AS LONG ByteNeeded = SIZEOF(UNICODE_STRING) ' CancelIo hPort FOR Looper = 1 TO 2 'Call once to get bytes needed, call again to get actual info LenBuffer = ByteNeeded sBuffer = NUL$(ByteNeeded) psBuffer = STRPTR(sBuffer) Retval = NtQueryObject(hPort, %ObjectNameInformation, psBuffer, LenBuffer, ByteNeeded) NEXT IF Retval = %STATUS_SUCCESS THEN puString = psBuffer IF @puString.Length > 0 THEN sObjName = NUL$(@puString.Length \ 2) WideCharToMultiByte %CP_ACP, %NULL, BYVAL @puString.pBuffer, @puString.Length, _ BYVAL STRPTR(sObjName), LEN(sObjName), BYVAL %NULL, BYVAL %NULL '<--- Learn what this does, and do I need it? (1 char = 2 bytes instead of 1 byte) sObjName = "ObjName: " & sObjName END IF END IF END FUNCTION '______________________________________________________________________________ FUNCTION pidGetObjectName(ProcessId AS DWORD, Hndl AS WORD) AS LONG LOCAL hPort AS DWORD LOCAL hProc AS DWORD LOCAL idThread AS DWORD LOCAL hThread AS DWORD LOCAL Retval AS LONG DIM lResult AS LONG DIM ErrorBuff AS ASCIIZ * %MAX_PATH sObjName = "" IF ProcessId THEN hProc = OpenProcess(%PROCESS_DUP_HANDLE, 0, ProcessId) ' hProc = OpenProcess(%PROCESS_CREATE_THREAD Or %PROCESS_VM_OPERATION Or %PROCESS_VM_WRITE Or %PROCESS_VM_READ, 0, ProcessId) IF (hProc <> %INVALID_HANDLE_VALUE) AND (hProc <> 0) THEN IF DuplicateHandle(hProc, BYVAL Hndl, -1, hPort, 0, %PROCESS_ALL_ACCESS, %DUPLICATE_SAME_ACCESS) THEN ' SetNamedPipeHandleState(Byval Hndl, %PIPE_NOWAIT, byval %NULL, byval %NULL) ' IF DuplicateHandle(hProc, BYVAL Hndl, -1, hPort, 0, %PROCESS_QUERY_INFORMATION XOR %SYNCHRONIZE, 0) THEN hThread = CreateThread(BYVAL %NULL, 0, CODEPTR(pidGetObjectNameThread), BYREF hPort, _ %THREAD_TERMINATE OR %THREAD_QUERY_INFORMATION, BYVAL VARPTR(idThread)) '*** Left here just as a thought I had, but did not work, but I may not have understood well enough to do correctly *** 'dim Security as SECURITY_ATTRIBUTES 'dim StackSize as dword 'StackSize = sizeof(hPort) ' hThread = CreateRemoteThread(hProc, Security, StackSize, CODEPTR(pidGetObjectNameThread), BYREF hPort, _ ' %THREAD_TERMINATE OR %THREAD_QUERY_INFORMATION, BYVAL VARPTR(idThread)) '********************************************************************************************************************** ' Retval = WaitForSingleObjectEx(hThread, 30, %TRUE) 'Wait 30 miliseconds maximum Retval = WaitForSingleObjectEx(hThread, 30, %TRUE) '<--- Adjust TimeOut Time due to thread may not be completed within the timeout time '*** Failure Checks SELECT CASE RetVal CASE %WAIT_FAILED, %WAIT_ABANDONED lResult = GetLastError() FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, lResult, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL MSGBOX ErrorBuff CASE %WAIT_OBJECT_0 'Success I think? CASE %WAIT_TIMEOUT 'Failure <--- Check into the other timeout values ' Retval = TerminateThread(hThread, 13) '<--- Native API shows that TerminateProcess and TerminateThread in turn call NtTerminateProcess, NtTerminateThread ??? (Exitcode 13 = Just a code chosen? CloseHandle hThread 'Close the thread sObjName = "ObjName: Error" 'Return an error for the Object name CASE ELSE lResult = GetLastError() FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, lResult, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL MSGBOX ErrorBuff END SELECT Retval = TerminateThread(hThread, 0) 'Terminate the thread now that I am done with it CloseHandle hPort 'Close the handle ELSE ' FUNCTION = "No DuplicateHandle" END IF CloseHandle hProc 'Close the process ELSE ' FUNCTION = "Bad OpenProcess" END IF END IF END FUNCTION '______________________________________________________________________________ '*** Re-Enable if needed later 'FUNCTION LoadPrivilege(BYVAL sPrivilege AS STRING) AS LONG ' LOCAL TokenPrivilege AS TOKEN_PRIVILEGES ' LOCAL SEDebugNameValue AS LUID ' LOCAL hToken AS DWORD ' LOCAL hProcessHandle AS DWORD ' ' hProcessHandle = GetCurrentProcess() ' IF hProcessHandle THEN ' OpenProcessToken hProcessHandle, (%TOKEN_ADJUST_PRIVILEGES OR %TOKEN_QUERY), hToken ' IF hToken THEN ' IF LookupPrivilegeValue("", BYCOPY sPrivilege, SEDebugNameValue) THEN ' TokenPrivilege.PrivilegeCount = 1 ' TokenPrivilege.Privileges(0).pLuid = SEDebugNameValue ' TokenPrivilege.Privileges(0).Attributes = %SE_PRIVILEGE_ENABLED ' IF AdjustTokenPrivileges(hToken, %False, TokenPrivilege, SIZEOF(TokenPrivilege), _ ' BYVAL 0, BYVAL 0) THEN ' FUNCTION = %TRUE ' ELSE ' MSGBOX "AdjustTokenPrivileges, Error: " & FORMAT$(GetLastError()) ' END IF ' ELSE ' MSGBOX "LookupPrivilegeValue, Error: " & FORMAT$(GetLastError()) ' END IF ' ELSE ' MSGBOX "OpenProcessToken, Error: " & FORMAT$(GetLastError()) ' END IF ' ELSE ' MSGBOX "GetCurrentProcess, Error: " & FORMAT$(GetLastError()) ' END IF ' 'END FUNCTION ''______________________________________________________________________________ CALLBACK FUNCTION DlgProc LOCAL MinMaxInfoPtr AS MINMAXINFO POINTER LOCAL sBuffer AS STRING LOCAL sTextbox AS STRING LOCAL ListTabStop() AS LONG LOCAL Counter AS LONG LOCAL Retval AS LONG LOCAL LastItem AS LONG LOCAL TextLen AS LONG LOCAL Looper AS LONG LOCAL Found AS LONG STATIC Index AS LONG SELECT CASE CBMSG CASE %WM_INITDIALOG CONTROL HANDLE hDlg, %Listbox TO hList CASE %WM_COMMAND SELECT CASE LOWRD(CBWPARAM) CASE %ButtonQuery IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN CONTROL DISABLE hDlg, %Checkbox CONTROL DISABLE hDlg, %Combobox CONTROL DISABLE hDlg, %ButtonQuit CONTROL DISABLE hDlg, %ButtonQuery CONTROL DISABLE hDlg, %ButtonSearch LISTBOX RESET CBHNDL, %Listbox DIALOG SET TEXT CBHNDL, $Title & " - Please wait..." CONTROL REDRAW CBHNDL, %Listbox SLEEP 300 pidEnum 'Start the process to enum all processes and handles SetHorizontalListboxBar 'Set the scrollbar when done CONTROL ENABLE hDlg, %ButtonSearch CONTROL ENABLE hDlg, %ButtonQuery CONTROL ENABLE hDlg, %ButtonQuit CONTROL ENABLE hDlg, %Combobox CONTROL ENABLE hDlg, %Checkbox END IF CASE %ButtonSearch, %IDOK IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN CONTROL GET TEXT CBHNDL, %Combobox TO sTextbox IF LEN(sTextbox) THEN sTextbox = UCASE$(sTextbox) LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 IF LastItem > 0 THEN IF Index = LastItem THEN Index = -1 INCR Index FOR Looper = Index TO LastItem TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) IF TextLen THEN sBuffer = NUL$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, STRPTR(sBuffer) sBuffer = UCASE$(sBuffer) IF INSTR(sBuffer, sTextbox) THEN Index = Looper Found = %TRUE SendMessage hList, %LB_SETCURSEL, Index, 0 EXIT FOR END IF END IF NEXT IF Found = %FALSE THEN FOR Looper = 0 TO Index TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) IF TextLen THEN sBuffer = NUL$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, STRPTR(sBuffer) sBuffer = UCASE$(sBuffer) IF INSTR(sBuffer, sTextbox) THEN Index = Looper Found = %TRUE SendMessage hList, %LB_SETCURSEL, Index, 0 EXIT FOR END IF END IF NEXT END IF IF Found = %FALSE THEN BEEP END IF END IF END IF CASE %ButtonQuit, %IDCANCEL IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN DIALOG END CBHNDL CASE %Listbox IF CBCTLMSG = %LBN_SELCHANGE THEN Retval = SendMessage(hList, %LB_GETCURSEL, 0, 0) IF Retval > -1 THEN Index = Retval END IF END IF END SELECT CASE %WM_SIZE 'Resize and repos controls if parent is resized MoveWindow hList, 10, 10, LOWRD(CBLPARAM) - 20, HIWRD(CBLPARAM) - 50, %TRUE MoveWindow GetDlgItem(CBHNDL, %Checkbox), LOWRD(CBLPARAM) - 490, _ 'Hor, HIWRD(CBLPARAM) - 34, 115, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %Combobox), LOWRD(CBLPARAM) - 365, _ 'Hor, HIWRD(CBLPARAM) - 33, 120, 225, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %ButtonSearch), LOWRD(CBLPARAM) - 230, _ 'Hor, HIWRD(CBLPARAM) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %ButtonQuery), LOWRD(CBLPARAM) - 155, _ 'Hor, HIWRD(CBLPARAM) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %ButtonQuit), LOWRD(CBLPARAM) - 80, _ 'Hor, HIWRD(CBLPARAM) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %Grip), LOWRD(CBLPARAM) - 15, _ 'Hor, HIWRD(CBLPARAM) - 15, 15, 15, %TRUE 'Vert, W, H SetHorizontalListboxBar DIALOG REDRAW hDlg FUNCTION = 0 EXIT FUNCTION CASE %WM_GETMINMAXINFO MinMaxInfoPtr = CBLPARAM @MinMaxInfoPtr.ptMinTrackSize.x = 402 @MinMaxInfoPtr.ptMinTrackSize.y = 180 ' case %WM_CLOSE ' TerminateProcess GetModuleHandle(byval %NULL), 0 'Force my own process closed END SELECT END FUNCTION '______________________________________________________________________________ FUNCTION PBMAIN AS LONG LOCAL PrivilegeOk AS LONG '*** Figure out what priviledges there are 'PrivilegeOk = LoadPrivilege($SE_DEBUG_NAME) 'Debug privileges 'PrivilegeOk = LoadPrivilege($SE_LOAD_DRIVER_NAME) 'Load driver privileges DIALOG NEW %HWND_DESKTOP, "QuerySystemInformation", , , 600, 300, _ %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN OR %WS_CAPTION OR _ %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MINIMIZEBOX OR _ %WS_MAXIMIZEBOX, %WS_EX_WINDOWEDGE TO hDlg CONTROL ADD LISTBOX, hdlg, %Listbox , , 10, 10, 580, 280, _ %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %WS_VSCROLL OR %WS_HSCROLL OR _ %LBS_NOTIFY OR %WS_TABSTOP OR %LBS_USETABSTOPS, %WS_EX_CLIENTEDGE CONTROL ADD CHECKBOX, hDlg, %Checkbox, "Only with ObjName", 270, 281, 75, 12, _ %BS_LEFT OR %BS_VCENTER OR %WS_TABSTOP, %WS_EX_RIGHT CONTROL SET CHECK hDlg, %Checkbox, %TRUE CONTROL ADD COMBOBOX, hDlg, %Combobox, , 338, 281, 100, 50,%CBS_DROPDOWN OR _ %WS_TABSTOP OR %CBS_HASSTRINGS OR %CBS_AUTOHSCROLL, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT COMBOBOX ADD hDlg, %Combobox, "Serial" COMBOBOX ADD hDlg, %Combobox, "Serial0" COMBOBOX ADD hDlg, %Combobox, "\Device\Tcp" COMBOBOX ADD hDlg, %Combobox, "\Device\Udp" COMBOBOX ADD hDlg, %Combobox, "COM" COMBOBOX ADD hDlg, %Combobox, "COM1" COMBOBOX ADD hDlg, %Combobox, "UltraEdit" COMBOBOX ADD hDlg, %Combobox, "PbEdit" COMBOBOX ADD hDlg, %Combobox, "Registry" COMBOBOX ADD hDlg, %Combobox, "Type 2:" COMBOBOX SELECT hDlg, %Combobox, 3 CONTROL ADD BUTTON, hDlg, %ButtonSearch, "&Search", 418, 280, 45, 15, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_TEXT OR %BS_PUSHBUTTON OR _ %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL DISABLE hDlg, %ButtonSearch CONTROL ADD BUTTON, hDlg, %ButtonQuery, "&Query", 478, 280, 45, 15, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_TEXT OR %BS_PUSHBUTTON OR _ %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %ButtonQuit, "Quit", 538, 280, 45, 15, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_TEXT OR %BS_PUSHBUTTON OR _ %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD SCROLLBAR, hDlg, %Grip, "", 590, 290, 10, 10, %WS_CHILD OR %WS_VISIBLE OR _ %SBS_SIZEGRIP OR %SBS_SIZEBOXBOTTOMRIGHTALIGN 'Class: ScrollBar SetClassLong hDlg, %GCL_HICON, LoadIcon(BYVAL %NULL, BYVAL %IDI_INFORMATION) DIALOG SHOW MODAL hDlg CALL DlgProc END FUNCTION '______________________________________________________________________________ FUNCTION GetProcessID(ProcessId AS DWORD) AS STRING FUNCTION = " - Pid: " & FORMAT$(ProcessId) ' FUNCTION = " - Pid: " & str$(ProcessId) END FUNCTION '______________________________________________________________________________ FUNCTION GetProcessHandle(ProcessHandle AS WORD) AS STRING FUNCTION = " - Handle: " & HEX$(ProcessHandle, 16) END FUNCTION '______________________________________________________________________________ FUNCTION GetProcessAccess(ProcessAccess AS DWORD) AS STRING FUNCTION = " - Access: " & SortAccessGranted(ProcessAccess) END FUNCTION '______________________________________________________________________________ FUNCTION GetProcessObjAddress(ProcessObjAddress AS DWORD) AS STRING FUNCTION = " - Object Address: " & HEX$(ProcessObjAddress, 8) END FUNCTION '______________________________________________________________________________ FUNCTION GetProcessObjFlags(ProcessObjFlags AS BYTE) AS STRING FUNCTION = " - Flags " & SortObjectFlags(ProcessObjFlags) END FUNCTION '______________________________________________________________________________ FUNCTION GetProcessObjType(ProcessObjType AS BYTE) AS STRING FUNCTION = " - Type: " & SortObjectTypeName(ProcessObjType) END FUNCTION '______________________________________________________________________________ FUNCTION SortAccessGranted(GrantedAccessValue AS DWORD) AS STRING LOCAL ProcessAccessVal AS DWORD LOCAL ProcessAccess AS STRING LOCAL TempProcessAccess AS STRING LOCAL i AS LONG '*** Below tables are a sample of the permissions in each Info(Looper).GrantedAccess '-------------------------------------------------- ' Lo-Byte Lo-Word '-------------------------------------------------- '*** Pos 8 7 6 5 4 3 2 1 '*** Bit 7 6 5 4 3 2 1 0 '*** Value 128 64 32 16 8 4 2 1 '*** ---------------------------------------------- ' 0 0 0 0 0 0 0 1 = &H01 = 1 = %PROCESS_TERMINATE ' 0 0 0 0 0 0 1 0 = &H02 = 2 = %PROCESS_CREATE_THREAD ' 0 0 0 0 0 1 0 0 = &H04 = 4 = %PROCESS_SET_SESSIONID ' 0 0 0 0 1 0 0 0 = &H08 = 8 = %PROCESS_VM_OPERATION ' 0 0 0 1 0 0 0 0 = &H010 = 16 = %PROCESS_VM_READ ' 0 0 1 0 0 0 0 0 = &H020 = 32 = %PROCESS_VM_WRITE ' 0 1 0 0 0 0 0 0 = &H040 = 64 = %PROCESS_DUP_HANDLE ' 1 0 0 0 0 0 0 0 = &H080 = 128 = %PROCESS_CREATE_PROCESS ' 0 0 0 0 0 0 1 1 = &H03 = 3 = %PROCESS_TERMINATE OR %PROCESS_CREATE_THREAD ' 0 0 0 0 0 1 1 1 = &H07 = 7 = %PROCESS_TERMINATE OR %PROCESS_CREATE_THREAD OR %PROCESS_SET_SESSIONID ' 0 0 0 0 1 1 1 1 = &H0F = 15 = %PROCESS_TERMINATE OR %PROCESS_CREATE_THREAD OR %PROCESS_SET_SESSIONID OR %PROCESS_VM_OPERATION ' 0 0 0 1 1 1 1 1 = &H1F = 31 = %PROCESS_TERMINATE OR %PROCESS_CREATE_THREAD OR %PROCESS_SET_SESSIONID OR %PROCESS_VM_OPERATION OR %PROCESS_VM_READ ' 0 0 1 1 1 1 1 1 = &H3F = 63 = %PROCESS_TERMINATE OR %PROCESS_CREATE_THREAD OR %PROCESS_SET_SESSIONID OR %PROCESS_VM_OPERATION OR %PROCESS_VM_READ ' OR %PROCESS_VM_WRITE ' 0 1 1 1 1 1 1 1 = &H7F = 127 = %PROCESS_TERMINATE OR %PROCESS_CREATE_THREAD OR %PROCESS_SET_SESSIONID OR %PROCESS_VM_OPERATION OR %PROCESS_VM_READ ' OR %PROCESS_VM_WRITE OR %PROCESS_DUP_HANDLE ' 1 1 1 1 1 1 1 1 = &HFF = 255 = %PROCESS_TERMINATE OR %PROCESS_CREATE_THREAD OR %PROCESS_SET_SESSIONID OR %PROCESS_VM_OPERATION OR %PROCESS_VM_READ ' OR %PROCESS_VM_WRITE OR %PROCESS_DUP_HANDLE OR %PROCESS_CREATE_PROCESS '---------------------------------------------------------------------------------------------------- ' Hi-Byte Lo-Word '---------------------------------------------------------------------------------------------------- '*** Pos 16 15 14 13 12 11 10 9 '*** Bit 15 14 13 12 11 10 9 8 '*** Value 32768 16384 8192 4096 2048 1024 512 256 '*** -------------------------------------------------------------------------------------------- ' 0 0 0 0 0 0 0 1 = &H0100 = 256 = %PROCESS_SET_QUOTA ' 0 0 0 0 0 0 1 0 = &H0200 = 512 = %PROCESS_SET_INFORMATION '*** MANY MORE COMBINATIONS TO FIGURE OUT ' ' '*** Default the variables used ProcessAccessVal = GrantedAccessValue ProcessAccess = "" TempProcessAccess = "" '*** Determine Granted Access ' ProcessAccess = BIN$(Info(Looper).GrantedAccess, 8) '<--Not 8 but 32 bits in DWORD ProcessAccess = BIN$(ProcessAccessVal, 32) '<--Not 8 but 32 bits in DWORD FOR i = 1 TO LEN(ProcessAccess) SELECT CASE VAL((MID$(ProcessAccess, i, 1))) ' CASE 0 'Bit Not Set CASE 1 'Bit Set SELECT CASE i '*** Hi Byte Hi Word CASE 1 'Bit 31 CASE 2 'Bit 30 CASE 3 'Bit 29 CASE 4 'Bit 28 CASE 5 'Bit 27 CASE 6 'Bit 26 CASE 7 'Bit 25 CASE 8 'Bit 24 '*** Lo Byte Hi Word CASE 9 'Bit 23 CASE 10 'Bit 22 CASE 11 'Bit 21 CASE 12 'Bit 20 = &H00100000 = 1048576 TempProcessAccess = TempProcessAccess + " %PROCESS_ALL_ACCESS, " '%PROCESS_ALL_ACCESS = %STANDARD_RIGHTS_REQUIRED OR %SYNCHRONIZE OR &H0FFF (4095) = 2035711 = &H01F0FFF CASE 13 'Bit 19 = &H000F0000 = 983040 TempProcessAccess = TempProcessAccess + " %SYNCHRONIZE, " '%SYNCHRONIZE CASE 14 'Bit 18 CASE 15 'Bit 17 = UNKNOWN CASE 16 'Bit 16 = UNKNOWN '*** Hi Byte Lo Word CASE 17 'Bit 15 = UNKNOWN CASE 18 'Bit 14 = UNKNOWN CASE 19 'Bit 13 = UNKNOWN CASE 20 'Bit 12 = UNKNOWN CASE 21 'Bit 11 = UNKNOWN '*** Do NOT look for whatever &H0FFF is because it could be a combo of below CASE 22 'Bit 10 = %PROCESS_QUERY_INFORMATION = &H0400 = 1024 TempProcessAccess = TempProcessAccess + " %PROCESS_QUERY_INFORMATION, " CASE 23 'Bit 9 = %PROCESS_SET_INFORMATION = &H0200 = 512 TempProcessAccess = TempProcessAccess + " %PROCESS_SET_INFORMATION, " CASE 24 'Bit 8 = %PROCESS_SET_QUOTA = &H0100 = 256 TempProcessAccess = TempProcessAccess + " %PROCESS_SET_QUOTA, " '*** Lo Byte Lo Word CASE 25 'Bit 7 = %PROCESS_CREATE_PROCESS = &H0080 = 128 TempProcessAccess = TempProcessAccess + " %PROCESS_CREATE_PROCESS, " CASE 26 'Bit 6 = %PROCESS_DUP_HANDLE = &H0040 = 64 TempProcessAccess = TempProcessAccess + " %PROCESS_DUP_HANDLE, " CASE 27 'Bit 5 = %PROCESS_VM_WRITE = &H0020 = 32 TempProcessAccess = TempProcessAccess + " %PROCESS_VM_WRITE, " CASE 28 'Bit 4 = %PROCESS_VM_READ = &H0010 = 16 TempProcessAccess = TempProcessAccess + " %PROCESS_VM_READ, " CASE 29 'Bit 3 = %PROCESS_VM_OPERATION = &H0008 = 8 TempProcessAccess = TempProcessAccess + " %PROCESS_VM_OPERATION, " CASE 30 'Bit 2 = %PROCESS_SET_SESSIONID = &H0004 = 4 TempProcessAccess = TempProcessAccess + " %PROCESS_SET_SESSIONID, " CASE 31 'Bit 1 = %PROCESS_CREATE_THREAD = &H0002 = 2 TempProcessAccess = TempProcessAccess + " %PROCESS_CREATE_THREAD, " CASE 32 'Bit 0 = %PROCESS_TERMINATE = &H0001 = 1 TempProcessAccess = TempProcessAccess + " %PROCESS_TERMINATE, " END SELECT END SELECT NEXT i FUNCTION = "0x" + HEX$(ProcessAccessVal, 32) + " =" + TempProcessAccess '<--- Cant remember what the signed symbol for hex is but 0x is unsigned END FUNCTION '______________________________________________________________________________ FUNCTION SortObjectFlags(ObjectFlags AS BYTE) AS STRING SELECT CASE HEX$(ObjectFlags, 1) CASE "0" 'None FUNCTION = HEX$(ObjectFlags, 1) & " (None)" CASE "1" 'Protect_from_close FUNCTION = HEX$(ObjectFlags, 1) & " (Protect_from_close)" CASE "2" 'Inherit FUNCTION = HEX$(ObjectFlags, 1) & " (Inherit)" END SELECT END FUNCTION '______________________________________________________________________________ FUNCTION SortObjectTypeName(BYVAL ObjectType AS LONG) AS STRING STATIC NtVer AS DWORD LOCAL os AS OSVERSIONINFO IF NtVer = 0 THEN os.dwOSVersionInfoSize = SIZEOF(os) GetVersionEx os IF os.dwPlatformId = %VER_PLATFORM_WIN32_NT THEN IF os.dwMajorVersion = 4 THEN NtVer = 4 'Window NT 4 ELSEIF (os.dwMajorVersion = 5) AND (os.dwMinorVersion = 0) THEN NtVer = 50 'Windows 2000 ELSE NtVer = 51 'Windows XP 5.1, probably 2003 5.2 and Vista 6.x END IF END IF END IF SELECT CASE NtVer CASE 4 'Window NT 4 SELECT CASE ObjectType CASE 01 : FUNCTION = "1: Type" CASE 02 : FUNCTION = "2: Directory" CASE 03 : FUNCTION = "3: SymbolicLink" CASE 04 : FUNCTION = "4: Token" CASE 05 : FUNCTION = "5: Process" CASE 06 : FUNCTION = "6: Thread" CASE 07 : FUNCTION = "7: Event" CASE 08 : FUNCTION = "8: EventPair" CASE 09 : FUNCTION = "9: Mutant" CASE 10 : FUNCTION = "10: Semaphore" CASE 11 : FUNCTION = "11: Timer" CASE 12 : FUNCTION = "12: Profile" CASE 13 : FUNCTION = "13: WindowStation" CASE 14 : FUNCTION = "14: Desktop" CASE 15 : FUNCTION = "15: Section" CASE 16 : FUNCTION = "16: Key" CASE 17 : FUNCTION = "17: Port" CASE 18 : FUNCTION = "18: Adapter" CASE 19 : FUNCTION = "19: Controller" CASE 20 : FUNCTION = "20: Device" CASE 21 : FUNCTION = "21: Driver" CASE 22 : FUNCTION = "22: IoCompletion" CASE 23 : FUNCTION = "23: File" CASE ELSE : FUNCTION = FORMAT$(ObjectType) & ": Not defined" END SELECT CASE 50 'Windows 2000 SELECT CASE ObjectType CASE 01 : FUNCTION = "1: Type" CASE 02 : FUNCTION = "2: Directory" CASE 03 : FUNCTION = "3: SymbolicLink" CASE 04 : FUNCTION = "4: Token" CASE 05 : FUNCTION = "5: Process" CASE 06 : FUNCTION = "6: Thread" CASE 07 : FUNCTION = "7: Job" CASE 08 : FUNCTION = "8: Event" CASE 09 : FUNCTION = "9: EventPair" CASE 10 : FUNCTION = "10: Mutant" CASE 11 : FUNCTION = "11: Callback" CASE 12 : FUNCTION = "12: Semaphore" CASE 13 : FUNCTION = "13: Timer" CASE 14 : FUNCTION = "14: Profile" CASE 15 : FUNCTION = "15: WindowStation" CASE 16 : FUNCTION = "16: Desktop" CASE 17 : FUNCTION = "17: Section" CASE 18 : FUNCTION = "18: Key" CASE 19 : FUNCTION = "19: Port" CASE 20 : FUNCTION = "20: WaitablePort" CASE 21 : FUNCTION = "21: Adapter" CASE 22 : FUNCTION = "22: Controller" CASE 23 : FUNCTION = "23: Device" CASE 24 : FUNCTION = "24: Driver" CASE 25 : FUNCTION = "25: IoCompletion" CASE 26 : FUNCTION = "26: File" CASE 27 : FUNCTION = "27: WmiGuid" CASE ELSE : FUNCTION = FORMAT$(ObjectType) & ": Not defined" END SELECT CASE 51 'Windows XP, probably 2003 and Vista SELECT CASE ObjectType CASE 01 : FUNCTION = "1: Type" CASE 02 : FUNCTION = "2: Directory" CASE 03 : FUNCTION = "3: SymbolicLink" CASE 04 : FUNCTION = "4: Token" CASE 05 : FUNCTION = "5: Process" CASE 06 : FUNCTION = "6: Thread" CASE 07 : FUNCTION = "7: Job" CASE 08 : FUNCTION = "8: DebugObject" CASE 09 : FUNCTION = "9: Event" CASE 10 : FUNCTION = "10: EventPair" CASE 11 : FUNCTION = "11: Mutant" CASE 12 : FUNCTION = "12: Callback" CASE 13 : FUNCTION = "13: Semaphore" CASE 14 : FUNCTION = "14: Timer" CASE 15 : FUNCTION = "15: Profile" CASE 16 : FUNCTION = "16: KeyedEvent" CASE 17 : FUNCTION = "17: WindowStation" CASE 18 : FUNCTION = "18: Desktop" CASE 19 : FUNCTION = "19: Section" CASE 20 : FUNCTION = "20: Key" CASE 21 : FUNCTION = "21: Port" CASE 22 : FUNCTION = "22: WaitablePort" CASE 23 : FUNCTION = "23: Adapter" CASE 24 : FUNCTION = "24: Controller" CASE 25 : FUNCTION = "25: Device" CASE 26 : FUNCTION = "26: Driver" CASE 27 : FUNCTION = "27: IoCompletion" CASE 28 : FUNCTION = "28: File" CASE 29 : FUNCTION = "29: WmiGuid" CASE ELSE : FUNCTION = FORMAT$(ObjectType) & ": Not defined" END SELECT END SELECT ' Windows NT 4 Window 2000 Window XP, probably 2003 and Vista ' ----------------- ------------------- ------------------- ' 1 - Type 1 - Type 1 - (Type) ' 2 - Directory 2 - Directory 2 - Directory ' 3 - SymbolicLink 3 - SymbolicLink 3 - SymbolicLink ' 4 - Token 4 - Token 4 - Token ' 5 - Process 5 - Process 5 - Process ' 6 - Thread 6 - Thread 6 - Thread ' 7 - Event 7 - Job 7 - Job ' 8 - EventPair 8 - Event 8 - ((DebugObject)) ' 9 - Mutant 9 - EventPair 9 - Event ' 10 - Semaphore 10 - Mutant 10 - (EventPair) ' 11 - Timer 11 - Callback 11 - Mutant ' 12 - Profile 12 - Semaphore 12 - (Callback) ' 13 - WindowStation 13 - Timer 13 - Semaphore ' 14 - Desktop 14 - Profile 14 - Timer ' 15 - Section 15 - WindowsStation 15 - (Profile) ' 16 - Key 16 - Desktop 16 - KeyedEvent ' 17 - Port 17 - Section 17 - WindowStation ' 18 - Adapter 18 - Key 18 - Desktop ' 19 - Controller 19 - Port 19 - Section ' 20 - Device 20 - WaitablePort 20 - Key ' 21 - Driver 21 - Adapter 21 - Port ' 22 - IoCompletion 22 - Controller 22 - WaitablePort ' 23 - File 23 - Device 23 - (Adapter) ' 24 - Driver 24 - (Controller) ' 25 - IoCompletion 25 - (Device) ' 26 - File 26 - (Driver) ' 27 - WmiGuid 27 - IoCompletion ' 28 - File ' 29 - WmiGuid END FUNCTION '______________________________________________________________________________ '------------------------------------------------------------------------------------------------------------------ ' DISPLAY FUNCTIONS SHOWN BELOW '------------------------------------------------------------------------------------------------------------------ FUNCTION SetHorizontalListboxBar() AS LONG LOCAL hFont AS DWORD LOCAL hDC AS DWORD LOCAL ListWidth AS LONG LOCAL LastItem AS LONG LOCAL Counter AS LONG LOCAL sBuffer AS STRING LOCAL TextLen AS LONG LOCAL Si AS apiSize LOCAL Looper AS LONG hFont = SendMessage(hList, %WM_GETFONT, 0, 0) hDC = GetDC(hList) IF hFont THEN hFont = SelectObject(hDC, hFont) LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 IF LastItem > 0 THEN FOR Looper = 0 TO LastItem TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) IF TextLen THEN sBuffer = NUL$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, STRPTR(sBuffer) GetTextExtentPoint32 hDC, BYCOPY sBuffer + "W", TextLen + 1, Si ListWidth = MAX& (ListWidth, Si.cx) END IF NEXT SendMessage hList, %LB_SETHORIZONTALEXTENT, ListWidth, 0 END IF IF hFont THEN SelectObject hDC, hFont ReleaseDC hList, hDC END FUNCTION '______________________________________________________________________________ FUNCTION ListAdd(AddToList AS STRING) AS LONG STATIC LastItem AS LONG LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 LastItem = SendMessage(hList, %LB_ADDSTRING, LastItem, BYVAL STRPTR(AddToList)) SELECT CASE LastItem MOD 4 CASE 0 SendMessage hList, %LB_SETCURSEL, LastItem, 0 DIALOG DOEVENTS CASE ELSE END SELECT END FUNCTION '______________________________________________________________________________
Leave a comment:
-
If I start the exe and walk away (don't kill or add any processes, it
seems to run fine for what it is worth).
I browsed Mr. Nichols' version on line, and when I saw the terminateprocess code in separate thread of execution, all the GLOBAL vars and the use of undocumented/subject-to-change-without-notice WinAPI calls, I decided that any detailed debugging would have to be a fee-for-service project, and a project in which I am not interested.
But.. for something which may actually help ....
Instead of enumerating processes and possibly encountering add/kill of same during the enumeration, you might look at the ToolHelp32xxxx functions - specifically CreateToolHelp32Snapshot - to grab a 'snapshot' of all the processes and do the detail queries versus that snapshot.
[This message has been edited by Michael Mattias (edited August 22, 2007).]
Leave a comment:
-
-
Well it seems that I am back to the drawing board of sorts.
What I think I need to do is go back to basics and verify that EVERY
variable declared matches the final API call? Because no matter what I do,
I can NOT get the program to totally end...(I start out with about 2,485K at start (before enum)
and build up from there, and when done, I drop to 3,048 or so...but never totally release and
can not kill from Task Manager, nor SysInternals, but can die out if I reboot)
The other problem is that it is accumulative, each new copy can and will enum alllll the handles
from the previous copy (I have to rename each new copy to compile again obviously)
An odd side effect (which I think has inadvertently been solved since, was that
earlier tries would crash if the app lost focus, but by checking if the PID was
less or greater than 32767 and compensate, would get rid of the error, so I think
somewhere along the lines must have something to do with a LoByte Vs HiByte value in a DWORD?)
Now if I can just figure out what is holding the program in memory, then I KNOWWWWWwwwww I can get a
working concept running. Unfortunately I can not find a way to log errors, when the error is that there is
no error, just the idea someone hasn't replied yet (with and without threads)
------------------
Leave a comment:
-
-
Thank you Ken and Pierre,
Ken's code runs into the same trap I found a while back of if the
app loses focus, then it will crash when it regains focus, but it
does resolve the issue of being stuck in memory when I close the program
(I think anyways, because I skipped the problem points just for testing purposes)
Pierre's code optimizes and fixes some key points of my code that I found troubling
I will try to blend the best points for a working example, and see how it goes.
Right now time is no problem, proof-of-concept is the sole point for the time being.
Hope to have something soon.
Thanx again guys.
------------------
Leave a comment:
-
-
This code should probably be re-written to not take so long to run
as I suspect it could be very possible that the processes being
searched are not valid by the time they are checked. Could be all
kinds of other problems as well which I don't really have the time
today to look into. Maybe someone else can help Cliff on this one.
Basically, I just saw that his ProcessEnum was hanging his GUI and
slapped that in a thread so that his GUI wouldn't be frozen. If I
start the exe and walk away (don't kill or add any processes, it
seems to run fine for what it is worth).
-Ken
------------------
Leave a comment:
-
-
Pierre,
The GPF has nothing to do with what I posted. It has to do with
something in the ProcessEnum function that Cliff still needs to
work on. I was just showing him how to exit out cleanly before it
is done.
-Ken
------------------
Leave a comment:
-
-
cliff,
i updated the code at http://www.powerbasic.com/support/pb...ad.php?t=25170
to add a thread with waitforsingleobject and terminatethread
in concern of ntqueryobject.
this version have no problem with explorer.exe
i did also created a objecttype function to return
names under nt4, 2000 and xp.
pierre
added later: ken, the code you posted gpf after a while on my pc
[this message has been edited by pierre bellisle (edited august 19, 2007).]
Leave a comment:
-
-
I think there is quite a bit of room for improvement/cleaning up
of the code, but I know I have several programs that could use some
tidying up as well. The main problem you are having is that you
are tying up the main thread of your dialog and it is causing the
application to be non-responsive (thus the hard kill, etc.). I
merged your includes together and made the code even a bit messier
adding some things that I currently don't think are necessary, but
the app behaves a little better and you will get the point and can
clean it up from there.
Code:#Compile Exe '#Win 8.03# #Option Version5 'Windows 2K and up only '---------------------------------------------------------------- ' DIALOG GLOBALS '---------------------------------------------------------------- Global hDlg As Dword 'Handle for Dialog Global hList As Dword 'Handle for Listbox Global killMe As Long Global idThread As Long Global stopMe As Long Global stopThread As Long '---------------------------------------------------------------- '---------------------------------------------------------------- ' DIALOG FUNCTIONS DECLARES '---------------------------------------------------------------- Declare CallBack Function DlgProc() As Long Declare Function PBMain As Long Declare Function ListAdd(AddToList As String) As Long Declare Function SetHorizontalListboxBar() As Long Declare Function KillThread (ByVal x As Long) As Long Declare Sub startKiller() Declare Function EnumThread (ByVal x As Long) As Long Declare Sub startSearching() Declare Sub stopSearching() '---------------------------------------------------------------- ' INCLUDES '---------------------------------------------------------------- #Include "WIN32API.INC" '#2005-01-27# '---------------------------------------------------------------- ' Supporting Includes Here '---------------------------------------------------------------- '---------------------------------------------------------------- ' SYSTEM HANDLE INFORMATION CONSTANTS '---------------------------------------------------------------- %SystemHandleInformation = &H10 %ObjectNameInformation = &H1 %STATUS_SUCCESS = &H0 %STATUS_MORE_ENTRIES = &H105 %STATUS_INFO_LENGTH_MISMATCH = &HC0000004 %STATUS_BUFFER_OVERFLOW = &H80000005 %STATUS_SEVERITY_ERROR = &H00000003 '---------------------------------------------------------------- ' SYSTEM HANDLE INFORMATION USER DEFINED TYPES '---------------------------------------------------------------- Type SYSTEM_HANDLE_INFORMATION 'Information Class is &h10 (I do not know why) ProcessID As Dword 'Process Id ObjectTypeNumber As Byte 'Object type number Flags As Byte 'Flags (I do not know what the possible values are) SysHandle As Word 'Original was HANDLE, but that is a keyword (undocumented why?) SysObject As Dword 'Original was OBJECT, but that is a keyword for COM interaction in PB GrantedAccess As Dword 'Access granted (I do not know what the possible values are) End Type Type SYSTEM_OBJECT_INFORMATION 'Added to patch into SYSTEM_HANDLE_INFORMATION sPidPath As Asciiz * %MAX_PATH 'Object path sObjectName As Asciiz * %MAX_PATH 'Object name End Type Type SYSTEM_HANDLE_TABLE_ENTRY_INFO 'Internal lookup table to system information NumberOfHandles As Dword 'Number of handles in the system Handles(0 To 0) As SYSTEM_HANDLE_INFORMATION 'Array of System Handle Information, (dimensions?) End Type Type UNICODE_STRING Length As Word 'Length in bytes of string in Buffer MaximumLength As Word 'Maximum length in bytes of Buffer pBuffer As Dword 'Pointer to unicode string End Type '---------------------------------------------------------------- ' SYSTEM PRIVILEGE GLOBALS '---------------------------------------------------------------- Global Privilege As Long $SE_DEBUG_NAME = "SeDebugPrivilege" '---------------------------------------------------------------- ' SYSTEM PRIVILEGE CONSTANTS '---------------------------------------------------------------- %TOKEN_ADJUST_PRIVILEGES = &H20 %TOKEN_QUERY = &H8 %SE_PRIVILEGE_ENABLED = &H2 %PROCESS_VM_READ = &H10 %PROCESS_DUP_HANDLE = &H40 %PROCESS_QUERY_INFORMATION = &H400 %STANDARD_RIGHTS_ALL = &H1F0000 %GENERIC_ALL = &H10000000 '---------------------------------------------------------------- ' NTDLL API FUNCTIONS '---------------------------------------------------------------- 'DECLARE FUNCTION NtQuerySystemInformation LIB "NtDLL.DLL" ALIAS "NtQuerySystemInformation"( _ ' BYVAL SystemInformationClass AS DWORD, _ ' BYVAL SystemInformation AS DWORD, _ ' BYVAL SystemInformationLength AS DWORD, _ ' BYREF ReturnLength AS DWORD) AS LONG ' 'DECLARE FUNCTION NtQueryObject LIB "NtDLL.DLL" ALIAS "NtQueryObject"( _ ' BYVAL hndl AS DWORD, _ ' BYVAL ObjectInformationClass AS DWORD, _ ' BYVAL ObjectInformation AS DWORD, _ ' BYVAL ObjectInformationLength AS DWORD, _ ' BYREF ReturnLength AS DWORD) AS LONG '---------------------------------------------------------------- ' NTDLL API FUNCTIONS CALLED VIA LOADLIBRARY '---------------------------------------------------------------- Declare Function PbQuerySystemInformation Alias "PbQuerySystemInformation"( _ ByVal SystemInformationClass As Dword, _ ByVal SystemInformation As Dword, _ ByVal SystemInformationLength As Dword, _ ByRef ReturnLength As Dword) As Long Declare Function PbQueryObject Alias "PbQueryObject"( _ ByVal hndl As Dword, _ ByVal ObjectInformationClass As Dword, _ ByVal ObjectInformation As Dword, _ ByVal ObjectInformationLength As Dword, _ ByRef ReturnLength As Dword) As Long '---------------------------------------------------------------- ' WRAPPER GLOBALS '---------------------------------------------------------------- 'GLOBAL ObjNameRet AS DWORD 'Object Name returned from NtQueryObject Global NtDllHandle As Dword 'NtDll Handle to process Global PbQuerySysInfoHandle As Dword 'Pb Handle to NtDll - NtQuerySysInfoHandle via loadlibrary Global PbQueryObjName As Dword 'Pb Handle to NtDll - NtQueryObjName via loadlibrary Global Info() As SYSTEM_HANDLE_INFORMATION 'Array of System Handles Info Global ObjectInfo() As SYSTEM_OBJECT_INFORMATION 'Array of System Objects Info Global ObjNameRet As Dword 'Return of threaded get object Global hProc As Dword Global hThread As Dword Global sBuffer As String Global puString As UNICODE_STRING Pointer Global pBuffer As Dword Ptr Global LenBuffer As Dword Global hPort As Dword Global ByteNeeded As Dword Global sObjName As String '---------------------------------------------------------------- ' WRAPPER FUNCTIONS '---------------------------------------------------------------- Declare Function ProcessEnum As Long Declare Function FindHandleInformation(ProcessId As Dword, InfoCount As Dword, ProcSysHandleInfo As SYSTEM_HANDLE_INFORMATION) As Long Declare Function ThreadGetObjectName(ByVal x As Long) As Long Declare Function GetObjectName(ProcessId As Dword, Hndl As Word) As String Declare Function GetPidPath(PID As Dword) As String '------------------------------------------------------------------------------------------------------------------ ' THE BELOW WILL BE MOVED TO PSAPI.H BUT LEFT IN NTDLL.H FOR DEMO PURPOSES (UNTIL PROBLEMS SOLVED) '------------------------------------------------------------------------------------------------------------------ '---------------------------------------------------------------- ' PSAPI API FUNCTIONS '---------------------------------------------------------------- Declare Function EnumProcessModules Lib "PsApi.DLL" Alias "EnumProcessModules"( _ ByVal hProcess As Dword, _ 'Handle to Process ByVal lphModule As Dword, _ 'Handle to Module in Process ByVal cb As Dword, _ 'Bytes to get ByRef cbNeeded As Dword) As Long 'Bytes really needed Declare Function GetModuleFileNameEx Lib "PsApi.DLL" Alias "GetModuleFileNameExA"( _ ByVal hProcess As Dword, _ 'Handle to Process ByVal hModule As Dword, _ 'Handle to Module in Process lpFilename As Asciiz, _ 'Name of Module returned from call ByVal nSize As Dword) As Long 'Size of Name of Module (I use %MAX_PATH to get full name) '---------------------------------------------------------------- ' PSAPI API WRAPPER FUNCTIONS '---------------------------------------------------------------- Declare Function ProcessEnum As Long Declare Function GetPidPath(PID As Dword) As String '*** MOVE TO PSAPI.INC AFTER DEMO (when Problems are fixed) Function ProcessEnum As Long On Error GoTo errtrap: Local pInfoTable As SYSTEM_HANDLE_TABLE_ENTRY_INFO Pointer Local sBuffer As String Local sObjectType As String Local sObjectName As String Local sPidPath As String Local pBuffer As Dword Ptr Local LenBuffer As Dword Local ByteNeeded As Dword Local InfoCount As Dword Local Looper As Dword Local Retval As Long Local ObjectFlags As String '*** Set Initial Parameters LenBuffer = SizeOf(SYSTEM_HANDLE_TABLE_ENTRY_INFO) 'Minimum buffer size for a valid ByteNeeded sBuffer = Nul$(LenBuffer) 'Fill buffer with nulls pBuffer = StrPtr(sBuffer) 'Set pointer to buffer '*** Get needed number of bytes ' Retval = NtQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) 'Hardcoded Call Dword PbQuerySysInfoHandle Using PbQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) To Retval 'via loadlibrary '*** Set to needed number of bytes If ByteNeeded > LenBuffer Then LenBuffer = ByteNeeded sBuffer = Nul$(LenBuffer) pBuffer = StrPtr(sBuffer) ' Retval = NtQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) 'Hardcoded Call Dword PbQuerySysInfoHandle Using PbQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) To Retval 'via loadlibrary End If '*** Get Number of Handles in the system pInfoTable = pBuffer InfoCount = @pInfoTable.NumberOfHandles '*** Listbox Display Only Retval = SendMessage(hList, %LB_INITSTORAGE, InfoCount * 4, InfoCount * 200) 'Faster listbox filling '*** Set Array to store Handle Information ' DIM Info(1 TO InfoCount) AS SYSTEM_HANDLE_INFORMATION AT pInfoTable + 4 '+ 4 to start just after .NumberOfHandles ReDim Info(1 To InfoCount) As SYSTEM_HANDLE_INFORMATION At pInfoTable + 4 '+ 4 to start just after .NumberOfHandles ReDim ObjectInfo(1 To InfoCount) 'Dimension Object Info to same size as System Info MsgBox "System Info Gathered with " + Str$(InfoCount) + " items to sort" '*** Sort the Object Type of each element For Looper = 1 To InfoCount 'For each handle in the system If killMe=1 Then Exit For ' Select Case WindowsOs 'Dependin on Operating System Object types are different (add into code later) ' case 0 'Win95 ' CASE 1 'Win98 ' CASE 2 'WinME ' CASE 3 'WinNT ' CASE 4 'Win2k ' CASE 5 'WinXP Select Case Info(Looper).ObjectTypeNumber Case 02 : sObjectType = " Directory" Case 03 : sObjectType = " SymbolicLink" Case 04 : sObjectType = " Token" 'Added from SysInternals Case 05 : sObjectType = " Process" Case 06 : sObjectType = " Thread" Case 07 : sObjectType = " Job" 'Added from SysInternals Case 09 : sObjectType = " Event" Case 11 : sObjectType = " Mutant" Case 13 : sObjectType = " Semaphore" Case 14 : sObjectType = " Timer" 'Added from SysInternals Case 16 : sObjectType = " KeyedEvent" Case 17 : sObjectType = " WindowStation" 'Added from SysInternals Case 18 : sObjectType = " Desktop" 'Added from SysInternals Case 19 : sObjectType = " Section" 'Added from SysInternals Case 20 : sObjectType = " Key" 'Added from SysInternals Case 21 : sObjectType = " Port" 'Added from SysInternals Case 22 : sObjectType = " WaitablePort" 'Added from SysInternals Case 27 : sObjectType = " IoCompletion" 'Added from SysInternals Case 28 : sObjectType = " File" 'Added from SysInternals Case 29 : sObjectType = " WmiGuid" 'Added from SysInternals Case Else : sObjectType = " UnKnown " + $Tab + $Tab + Str$(Info(Looper).ObjectTypeNumber) End Select ' CASE 6 'WinVista ' end select '*** Re-Enable if you want to see the list ObjectFlags = Hex$(Info(Looper).Flags, 1) Select Case ObjectFlags '0x00 = NONE, 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT Case "0" ObjectFlags = ObjectFlags + " - NONE" Case "1" ObjectFlags = ObjectFlags + " - PROTECT_FROM_CLOSE" Case "2" ObjectFlags = ObjectFlags + " - INHERIT" End Select ''*** Get path to the process ObjectInfo(Looper).sPidPath = GetPidPath(Info(Looper).ProcessID) '*** Get the Object Name '*** WARNING ... Named Pipes are known to hang the code but unable to know if ObjectType is a pipe '*** and not a file without asking the name ... so its a catch-22 Dim SkipFile As Long If InStr(ObjectInfo(Looper).sPidPath, "Explorer.exe") Then SkipFile = %True If InStr(ObjectInfo(Looper).sPidPath, "EnumProcessObjectHandles") Then SkipFile = %True If SkipFile = %False Then ObjectInfo(Looper).sObjectName = GetObjectName(Info(Looper).ProcessID, Info(Looper).SysHandle) ' ObjectInfo(Looper).sObjectName = GetObjectName(Info(Looper).ProcessID, Info(Looper).SysHandle) ' SELECT CASE ObjectInfo(Looper).sObjectName ' CASE "", "No DuplicateHandle" ' CASE ELSE ListAdd "Number " & Format$(Looper) & _ " - Pid " & Format$(Info(Looper).ProcessID) & _ " - HandleId " & Hex$(Info(Looper).SysHandle, 4) & _ " - Object " & Hex$(Info(Looper).SysObject, 8) & _ " - Access " & Hex$(Info(Looper).GrantedAccess, 8) & _ " - Flags " & ObjectFlags & _ " - HandleType" & Str$(Info(Looper).ObjectTypeNumber) & _ sObjectType ListAdd "Pid Path = " & ObjectInfo(Looper).sPidPath ListAdd "Object Name = " & ObjectInfo(Looper).sObjectName ListAdd "" ' end select '*** Block to check for certain device types open (demo purposes Only) If InStr(ObjectInfo(Looper).sObjectName, "\Device\Serial") _ Or InStr(ObjectInfo(Looper).sObjectName, "\Device\EdgeSer") _ Or InStr(ObjectInfo(Looper).sObjectName, "\Device\USBPDO") _ Then MsgBox ObjectInfo(Looper).sObjectName + " open in " + ObjectInfo(Looper).sPidPath '*** Just to refresh the dialog Next Looper 'MSGBOX "All Done with " + STR$(UBOUND(SortProcess)) + " and " + STR$(UBOUND(Info)) Exit Function errtrap: Exit Function End Function Function GetObjectName(ProcessId As Dword, Hndl As Word) As String Local Retval As Long Local hCurrent As Dword Local hResult As Dword Local hExitCode As Dword Local Arg As Long Local idThread As Dword hCurrent = GetCurrentProcess If ProcessId Then hProc = OpenProcess(%PROCESS_DUP_HANDLE, 0, ProcessId) ' hProc = OpenProcess(%PROCESS_ALL_ACCESS, %False, ProcessId) If hProc <> %INVALID_HANDLE_VALUE Then If DuplicateHandle(hProc, ByVal Hndl, -1, hPort, (%GENERIC_READ Or %KEY_READ), _ %PROCESS_ALL_ACCESS, %DUPLICATE_SAME_ACCESS) Then LenBuffer = SizeOf(UNICODE_STRING) sBuffer = Nul$(LenBuffer) pBuffer = StrPtr(sBuffer) '*** Thread the calls to check object name since named pipes are known to "Hang" rather than return hThread = CreateThread(ByVal %Null, 0, CodePtr(ThreadGetObjectName), ByRef Arg, _ %THREAD_TERMINATE Or %THREAD_QUERY_INFORMATION, _ ByVal VarPtr(idThread)) If hThread <> %INVALID_HANDLE_VALUE Then Do Select Case WaitForSingleObject(hThread, 50) 'Try with 3500 and 7500 Case %WAIT_ABANDONED 'Mutex Object not released ' ObjNameRet = %STATUS_SEVERITY_ERROR hThread = %INVALID_HANDLE_VALUE Case %WAIT_OBJECT_0 'The state of the specified object is signaled GetExitCodeThread(hThread, Retval) ' TerminateThread BYVAL hThread, Retval CloseHandle hThread ' ObjNameRet = %STATUS_SEVERITY_ERROR hThread = %INVALID_HANDLE_VALUE Exit Do Case %WAIT_TIMEOUT 'The time-out interval elapsed, and the object's state is nonsignaled. TerminateThread ByVal hThread, ByVal 0 CloseHandle hThread 'CloseHandle after TerminateThread ' ObjNameRet = %STATUS_SEVERITY_ERROR hThread = %INVALID_HANDLE_VALUE Exit Do End Select Loop 'MSGBOX STR$(hPort) + $TAB + STR$(@pbuffer) + $TAB + STR$(lenBuffer) + $TAB + STR$(ByteNeeded) + $TAB + STR$(ObjNameRet) ' IF ObjNameRet = %STATUS_SUCCESS THEN ' puString = pBuffer ' IF @puString.Length > 0 THEN ' sObjName = NUL$(@puString.Length \ 2) '' sObjName = @puString.pBuffer ' WideCharToMultiByte %CP_ACP, %NULL, BYVAL @puString.pBuffer, @puString.Length, _ ' BYVAL STRPTR(sObjName), LEN(sObjName), BYVAL %NULL, BYVAL %NULL ' FUNCTION = "ObjName: " & sObjName ' END IF ' ELSE ' FUNCTION = "Bad NtQueryObject" ' END IF Function = "ObjName: " & sObjName CloseHandle hPort End If Else Function = "No DuplicateHandle" End If CloseHandle hProc Else Function = "Bad OpenProcess" End If End If 'hProc = OpenProcess(BYVAL %PROCESS_TERMINATE, BYVAL 0, BYVAL hProc) End Function Function ThreadGetObjectName(ByVal x As Long) As Long ' ObjNameRet = NtQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) Call Dword PbQueryObjName Using PbQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) To ObjNameRet If ByteNeeded > LenBuffer Then LenBuffer = ByteNeeded ' ObjNameRet = NtQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) Call Dword PbQueryObjName Using PbQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) To ObjNameRet End If If ObjNameRet = %STATUS_SUCCESS Then puString = pBuffer If @puString.Length > 0 Then sObjName = Nul$(@puString.Length \ 2) ' sObjName = @puString.pBuffer WideCharToMultiByte %CP_ACP, %Null, ByVal @puString.pBuffer, @puString.Length, _ ByVal StrPtr(sObjName), Len(sObjName), ByVal %Null, ByVal %Null ' FUNCTION = "ObjName: " & sObjName End If Else ' FUNCTION = "Bad NtQueryObject" sObjName = "Bad NtQueryObject" End If End Function Function GetPidPath(PID As Dword) As String Local ModuleName As String Local PidPath As String Local sBuffer As String Local pBuffer As Dword Ptr Local LenBuffer As Dword Local hProcess As Dword Local ByteNeeded As Dword Local HandleCount As Dword Local Retval As Long Local HandleSize As Dword hProcess = OpenProcess(%PROCESS_QUERY_INFORMATION Or %PROCESS_VM_READ, 0, Pid) If hProcess Then LenBuffer = 4 'SIZEOF(DWORD) sBuffer = Nul$(LenBuffer) pBuffer = StrPtr(sBuffer) Retval = EnumProcessModules(hProcess, pBuffer, LenBuffer, ByteNeeded) If ByteNeeded > LenBuffer Then LenBuffer = ByteNeeded sBuffer = Nul$(LenBuffer) pBuffer = StrPtr(sBuffer) Retval = EnumProcessModules(hProcess, pBuffer, LenBuffer, ByteNeeded) End If If Retval Then ' HandleCount = LenBuffer \ 4 HandleCount = LenBuffer \ SizeOf(HandleSize) Dim ModulesHandles(1 To HandleCount) As Dword At pBuffer ModuleName = "Unknown" & Nul$(%MAX_PATH) Retval = GetModuleFileNameEx(hProcess, ModulesHandles(1), ByVal StrPtr(ModuleName), %MAX_PATH) PidPath = Left$(ModuleName, Retval) Else 'ListAdd "Bad EnumProcessModules" End If CloseHandle hProcess End If If PidPath = "" Then PidPath = "SYSTEM" Function = PidPath 'hProcess = OpenProcess(BYVAL %PROCESS_TERMINATE, BYVAL 0, BYVAL hProcess) End Function '---------------------------------------------------------------- '---------------------------------------------------------------- ' DIALOG OBJECTS '---------------------------------------------------------------- %ButtonQuery = 101 'Query Button %ButtonSearch = 102 'Search Button %ButtonQuit = 103 'Quit Button %ListBox = 201 'Listbox %ComboBox = 301 'Combobox %Grip = 401 'SizeGrip Sub startSearching() Thread Create EnumThread(0) To stopThread End Sub Sub stopSearching() Local stopper As Long Thread Close stopThread To stopper End Sub Function EnumThread (ByVal x As Long) As Long ProcessEnum SetHorizontalListboxBar Control Enable hDlg, %ButtonSearch Control Enable hDlg, %ButtonQuery Control Enable hDlg, %ButtonQuit End Function '---------------------------------------------------------------- ' DIALOG FUNCTIONS '---------------------------------------------------------------- CallBack Function DlgProc() As Long Local MinMaxInfoPtr As MINMAXINFO Pointer Local sBuffer As String Local sTextbox As String Local ListTabStop() As Long Local Counter As Long Local Retval As Long Local LastItem As Long Local TextLen As Long Local Looper As Long Local Found As Long Static Index As Long Select Case CbMsg Case %WM_INITDIALOG Control Handle hDlg, %ListBox To hList '*** LoadLibrary and get functions Case %WM_COMMAND Select Case LoWrd(CbWParam) Case %ButtonQuery If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then Control Disable hDlg, %ButtonQuit Control Disable hDlg, %ButtonQuery Control Disable hDlg, %ButtonSearch ListBox Reset CbHndl, %ListBox Control ReDraw CbHndl, %ListBox Sleep 200 startSearching End If Case %ButtonSearch If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then Control Get Text CbHndl, %ComboBox To sTextbox sTextbox = UCase$(sTextbox) LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 If LastItem > 0 Then If Index = LastItem Then Index = -1 Incr Index For Looper = Index To LastItem TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) If TextLen Then sBuffer = Nul$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, StrPtr(sBuffer) sBuffer = UCase$(sBuffer) If InStr(sBuffer, sTextbox) Then Index = Looper Found = %TRUE SendMessage hList, %LB_SETCURSEL, Index, 0 Exit For End If End If Next If Found = %FALSE Then For Looper = 0 To Index TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) If TextLen Then sBuffer = Nul$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, StrPtr(sBuffer) sBuffer = UCase$(sBuffer) If InStr(sBuffer, sTextbox) Then Index = Looper Found = %TRUE SendMessage hList, %LB_SETCURSEL, Index, 0 Exit For End If End If Next End If If Found = %FALSE Then Beep End If End If End If Case %ButtonQuit If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then Dialog End CbHndl killMe=1 End If Case %ListBox If CbCtlMsg = %LBN_SELCHANGE Then Retval = SendMessage(hList, %LB_GETCURSEL, 0, 0) If Retval > -1 Then Index = Retval End If End If End Select Case %WM_SIZE 'Resize and repos controls if parent is resized MoveWindow hList, 10, 10, LoWrd(CbLParam) - 20, HiWrd(CbLParam) - 50, %TRUE MoveWindow GetDlgItem(CbHndl, %ComboBox), LoWrd(CbLParam) - 365, _ 'Hor, HiWrd(CbLParam) - 33, 120, 225, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CbHndl, %ButtonSearch), LoWrd(CbLParam) - 230, _ 'Hor, HiWrd(CbLParam) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CbHndl, %ButtonQuery), LoWrd(CbLParam) - 155, _ 'Hor, HiWrd(CbLParam) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CbHndl, %ButtonQuit), LoWrd(CbLParam) - 80, _ 'Hor, HiWrd(CbLParam) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CbHndl, %Grip), LoWrd(CbLParam) - 15, _ 'Hor, HiWrd(CbLParam) - 15, 15, 15, %TRUE 'Vert, W, H SetHorizontalListboxBar Dialog ReDraw hDlg Function = 0 Exit Function Case %WM_GETMINMAXINFO MinMaxInfoPtr = CbLParam @MinMaxInfoPtr.ptMinTrackSize.x = 385 @MinMaxInfoPtr.ptMinTrackSize.y = 180 Case %WM_CLOSE ' CloseHandle hProc 'Added in case 1 open ' CloseHandle hThread 'Added in case 1 open ' PostQuitMessage 0 killMe=1 End Select End Function Function PBMain As Long killMe=0 startKiller Dialog New %HWND_DESKTOP, "QuerySystemInformation", , , 600, 300, _ %WS_VISIBLE Or %WS_CLIPSIBLINGS Or %WS_CLIPCHILDREN Or %WS_CAPTION Or _ %WS_SYSMENU Or %WS_THICKFRAME Or %WS_MINIMIZEBOX Or _ %WS_MAXIMIZEBOX, %WS_EX_WINDOWEDGE To hDlg Control Add ListBox, hdlg, %ListBox , , 10, 10, 580, 280, _ %WS_CHILD Or %WS_VISIBLE Or %WS_BORDER Or %WS_VSCROLL Or %WS_HSCROLL Or _ %LBS_NOTIFY Or %WS_TABSTOP Or %LBS_USETABSTOPS, %WS_EX_CLIENTEDGE Control Add ComboBox, hDlg, %ComboBox, , 338, 281, 100, 50, _ %CBS_DROPDOWN Or %CBS_HASSTRINGS Or %WS_TABSTOP, %WS_EX_CLIENTEDGE Or %WS_EX_LEFT ComboBox Add hDlg, %ComboBox, "Serial" ComboBox Add hDlg, %ComboBox, "Serial0" ComboBox Add hDlg, %ComboBox, "\Device\Tcp" ComboBox Add hDlg, %ComboBox, "\Device\Udp" ComboBox Add hDlg, %ComboBox, "COM" ComboBox Add hDlg, %ComboBox, "COM1" ComboBox Add hDlg, %ComboBox, "Registry" ComboBox Add hDlg, %ComboBox, "HandleType 4 Key" ComboBox Select hDlg, %ComboBox, 2 Control Add Button, hDlg, %ButtonSearch, "&Search", 418, 280, 45, 15, _ %WS_CHILD Or %WS_VISIBLE Or %WS_TABSTOP Or %BS_TEXT Or %BS_PUSHBUTTON Or _ %BS_CENTER Or %BS_VCENTER, %WS_EX_LEFT Or %WS_EX_LTRREADING Control Disable hDlg, %ButtonSearch Control Add Button, hDlg, %ButtonQuery, "&Query", 478, 280, 45, 15, _ %WS_CHILD Or %WS_VISIBLE Or %WS_TABSTOP Or %BS_TEXT Or %BS_PUSHBUTTON Or _ %BS_CENTER Or %BS_VCENTER, %WS_EX_LEFT Or %WS_EX_LTRREADING Control Add Button, hDlg, %ButtonQuit, "Quit", 538, 280, 45, 15, _ %WS_CHILD Or %WS_VISIBLE Or %WS_TABSTOP Or %BS_TEXT Or %BS_PUSHBUTTON Or _ %BS_CENTER Or %BS_VCENTER, %WS_EX_LEFT Or %WS_EX_LTRREADING Control Add ScrollBar, hDlg, %Grip, "", 590, 290, 10, 10, %WS_CHILD Or _ %WS_VISIBLE Or %SBS_SIZEGRIP Or %SBS_SIZEBOXBOTTOMRIGHTALIGN 'SetClassLong hDlg, %GCL_HICON, LoadIcon(ByVal %Null, ByVal %IDI_INFORMATION) Control Set Focus hDlg, %ButtonQuery NtDllHandle = LoadLibrary("ntdll.dll") 'If exists then map into this process PbQuerySysInfoHandle = GetProcAddress(NtDllHandle, "NtQuerySystemInformation") 'If exists then map into this process PbQueryObjName = GetProcAddress(NtDllHandle, "NtQueryObject") 'If exists then map into this process 'MSGBOX "LoadLibrary = " + STR$(NtDllHandle) + $CR + "Query System = " + STR$(PbQuerySysInfoHandle) + $CR + "Query Object = " + STR$(PbQueryObjName) Dialog Show Modal hDlg Call DlgProc If stopMe<>1 Then stopMe=1 stopSearching() End If FreeLibrary NtDllHandle 'Free the Library once the above is mapped into this process End Function Function ListAdd(AddToList As String) As Long Local LastItem As Long LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 LastItem = SendMessage(hList, %LB_ADDSTRING, LastItem, ByVal StrPtr(AddToList)) ' Retval = SendMessage(hList, %LB_GETCURSEL, 0, 0) SendMessage hList, %LB_SETCURSEL, LastItem, 0 End Function Function SetHorizontalListboxBar() As Long Local Si As apiSize Local sBuffer As String Local hFont As Dword Local hDC As Dword Local ListWidth As Long Local LastItem As Long Local Counter As Long Local TextLen As Long Local Looper As Long hFont = SendMessage(hList, %WM_GETFONT, 0, 0) hDC = GetDC(hList) If hFont Then hFont = SelectObject(hDC, hFont) LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 If LastItem > 0 Then For Looper = 0 To LastItem TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) If TextLen Then sBuffer = Nul$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, StrPtr(sBuffer) GetTextExtentPoint32 hDC, ByCopy sBuffer + "W", TextLen + 1, Si ListWidth = Max& (ListWidth, Si.cx) End If Next SendMessage hList, %LB_SETHORIZONTALEXTENT, ListWidth, 0 End If If hFont Then SelectObject hDC, hFont ReleaseDC hList, hDC End Function '------------------------------------------------------------------------------ ' ** Killer Thread Start This One Early In PBMAIN() ** '------------------------------------------------------------------------------ Sub startKiller() Thread Create KillThread(0) To idThread End Sub Function KillThread (ByVal x As Long) As Long On Error Resume Next Do Until killMe=1 Sleep 1000 Loop Local ProcID As Long Local hProc As Long ProcID=GetCurrentProcessId() hProc = OpenProcess(ByVal %PROCESS_TERMINATE, ByVal 0, ByVal ProcID) If hProc <> %Null Then TerminateProcess ByVal hProc, ByVal %Null CloseHandle hProc End Function '------------------------------------------------------------------------------
Leave a comment:
-
-
Cliff,
Next stuff is probably right, names in parentesis are deduction
and have to be confirmed, DebugObject was the one hard to find...
Pierre
Code:' Windows NT 4 Window 2000 Window XP ' ----------------- ------------------- ------------------- ' 1 - Type 1 - Type 1 - (Type) ' 2 - Directory 2 - Directory 2 - Directory ' 3 - SymbolicLink 3 - SymbolicLink 3 - SymbolicLink ' 4 - Token 4 - Token 4 - Token ' 5 - Process 5 - Process 5 - Process ' 6 - Thread 6 - Thread 6 - Thread ' 7 - Event 7 - Job 7 - Job ' 8 - EventPair 8 - Event 8 - ((DebugObject)) ' 9 - Mutant 9 - EventPair 9 - Event ' 10 - Semaphore 10 - Mutant 10 - (EventPair) ' 11 - Timer 11 - Callback 11 - Mutant ' 12 - Profile 12 - Semaphore 12 - (Callback) ' 13 - WindowStation 13 - Timer 13 - Semaphore ' 14 - Desktop 14 - Profile 14 - Timer ' 15 - Section 15 - WindowsStation 15 - (Profile) ' 16 - Key 16 - Desktop 16 - KeyedEvent ' 17 - Port 17 - Section 17 - WindowStation ' 18 - Adapter 18 - Key 18 - Desktop ' 19 - Controller 19 - Port 19 - Section ' 20 - Device 20 - WaitablePort 20 - Key ' 21 - Driver 21 - Adapter 21 - Port ' 22 - IoCompletion 22 - Controller 22 - WaitablePort ' 23 - File 23 - Device 23 - (Adapter) ' 24 - Driver 24 - (Controller) ' 25 - IoCompletion 25 - (Device) ' 26 - File 26 - (Driver) ' 27 - WmiGuid 27 - IoCompletion ' 28 - File ' 29 - WmiGuid
defendion.com
vchelp.net
book. itzero.com
[This message has been edited by Pierre Bellisle (edited August 18, 2007).]
Leave a comment:
-
-
A little hard to find because you use GLOBALs which are defined in the #INCLUDE but...
Code:[b] NtDllHandle = LoadLibrary("ntdll.dll") 'If exists then map into this process[/b] PbQuerySysInfoHandle = GetProcAddress(NtDllHandle, "NtQuerySystemInformation") 'If exists then map into this process [b]PbQueryObjName[/b] = GetProcAddress(NtDllHandle, "NtQueryObject") 'If exists then map into this process 'MSGBOX "LoadLibrary = " + STR$(NtDllHandle) + $CR + "Query System = " + STR$(PbQuerySysInfoHandle) + $CR + "Query Object = " + STR$(PbQueryObjName) [b] FreeLibrary NtDllHandle 'Free the Library once the above is mapped into this process[/b] .... [b]CALL DWORD PbQueryObjName [/b]
Better still, eschew the GLOBAL, just reload the library, get the proc address, make the call and free the library each time you need to call a function in that library.
*This is an ADDRESS , not an object name; so a variable name something like "PbQueryAddress" would be more appropos.
Leave a comment:
-
-
I have things partially working. I say partially because still some bugs to fix
that I just can not live with.
Bugs I have:[list=1][*] I can not enum explorer.exe (this may be due to some security issue?)[*] On closing the program I either get a JIT error, or a error about reading a memory location, or closes fine, but Windows Task Manager (and SysInternals) shows my program still in use, and I can not end the process?[*] I still have to rely on my best guess as to what is happening since then concept is mostly "Undocumented"[/list=a]
Below I am going to show my code as it stands (in 3 files) as cleanly as I could get them, and based from
Pierre's assistance on different troublesome concepts (Thank you Pierre)
The rest is what I could piece together from snippets, and what I "THINK" a line of code is supposed to be doing.
Maybe this will help someone, or someone can help point out mistakes I have made.
Anyways, let me know anything good bad or otherwise....
(I commented as much as possible up to this point of key things I do not understand yet)
Cliff
The Demo.exe to show results
Code:#COMPILE EXE '#Win 8.03# #OPTION VERSION5 'Windows 2K and up only '---------------------------------------------------------------- ' DIALOG GLOBALS '---------------------------------------------------------------- GLOBAL hDlg AS DWORD 'Handle for Dialog GLOBAL hList AS DWORD 'Handle for Listbox '---------------------------------------------------------------- '---------------------------------------------------------------- ' DIALOG FUNCTIONS DECLARES '---------------------------------------------------------------- DECLARE CALLBACK FUNCTION DlgProc() AS LONG DECLARE FUNCTION PBMAIN AS LONG DECLARE FUNCTION ListAdd(AddToList AS STRING) AS LONG DECLARE FUNCTION SetHorizontalListboxBar() AS LONG '---------------------------------------------------------------- ' INCLUDES '---------------------------------------------------------------- #INCLUDE "WIN32API.INC" '#2005-01-27# #INCLUDE "NTDLL.h" #INCLUDE "NTDLL.INC" '---------------------------------------------------------------- ' DIALOG OBJECTS '---------------------------------------------------------------- %ButtonQuery = 101 'Query Button %ButtonSearch = 102 'Search Button %ButtonQuit = 103 'Quit Button %Listbox = 201 'Listbox %Combobox = 301 'Combobox %Grip = 401 'SizeGrip '---------------------------------------------------------------- ' DIALOG FUNCTIONS '---------------------------------------------------------------- CALLBACK FUNCTION DlgProc() AS LONG LOCAL MinMaxInfoPtr AS MINMAXINFO POINTER LOCAL sBuffer AS STRING LOCAL sTextbox AS STRING LOCAL ListTabStop() AS LONG LOCAL Counter AS LONG LOCAL Retval AS LONG LOCAL LastItem AS LONG LOCAL TextLen AS LONG LOCAL Looper AS LONG LOCAL Found AS LONG STATIC Index AS LONG SELECT CASE CBMSG CASE %WM_INITDIALOG CONTROL HANDLE hDlg, %Listbox TO hList '*** LoadLibrary and get functions NtDllHandle = LoadLibrary("ntdll.dll") 'If exists then map into this process PbQuerySysInfoHandle = GetProcAddress(NtDllHandle, "NtQuerySystemInformation") 'If exists then map into this process PbQueryObjName = GetProcAddress(NtDllHandle, "NtQueryObject") 'If exists then map into this process 'MSGBOX "LoadLibrary = " + STR$(NtDllHandle) + $CR + "Query System = " + STR$(PbQuerySysInfoHandle) + $CR + "Query Object = " + STR$(PbQueryObjName) FreeLibrary NtDllHandle 'Free the Library once the above is mapped into this process CASE %WM_COMMAND SELECT CASE LOWRD(CBWPARAM) CASE %ButtonQuery IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN CONTROL DISABLE hDlg, %ButtonQuit CONTROL DISABLE hDlg, %ButtonQuery CONTROL DISABLE hDlg, %ButtonSearch LISTBOX RESET CBHNDL, %Listbox CONTROL REDRAW CBHNDL, %Listbox SLEEP 200 ProcessEnum SetHorizontalListboxBar CONTROL ENABLE hDlg, %ButtonSearch CONTROL ENABLE hDlg, %ButtonQuery CONTROL ENABLE hDlg, %ButtonQuit END IF CASE %ButtonSearch IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN CONTROL GET TEXT CBHNDL, %Combobox TO sTextbox sTextbox = UCASE$(sTextbox) LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 IF LastItem > 0 THEN IF Index = LastItem THEN Index = -1 INCR Index FOR Looper = Index TO LastItem TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) IF TextLen THEN sBuffer = NUL$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, STRPTR(sBuffer) sBuffer = UCASE$(sBuffer) IF INSTR(sBuffer, sTextbox) THEN Index = Looper Found = %TRUE SendMessage hList, %LB_SETCURSEL, Index, 0 EXIT FOR END IF END IF NEXT IF Found = %FALSE THEN FOR Looper = 0 TO Index TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) IF TextLen THEN sBuffer = NUL$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, STRPTR(sBuffer) sBuffer = UCASE$(sBuffer) IF INSTR(sBuffer, sTextbox) THEN Index = Looper Found = %TRUE SendMessage hList, %LB_SETCURSEL, Index, 0 EXIT FOR END IF END IF NEXT END IF IF Found = %FALSE THEN BEEP END IF END IF END IF CASE %ButtonQuit IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN DIALOG END CBHNDL END IF CASE %Listbox IF CBCTLMSG = %LBN_SELCHANGE THEN Retval = SendMessage(hList, %LB_GETCURSEL, 0, 0) IF Retval > -1 THEN Index = Retval END IF END IF END SELECT CASE %WM_SIZE 'Resize and repos controls if parent is resized MoveWindow hList, 10, 10, LOWRD(CBLPARAM) - 20, HIWRD(CBLPARAM) - 50, %TRUE MoveWindow GetDlgItem(CBHNDL, %Combobox), LOWRD(CBLPARAM) - 365, _ 'Hor, HIWRD(CBLPARAM) - 33, 120, 225, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %ButtonSearch), LOWRD(CBLPARAM) - 230, _ 'Hor, HIWRD(CBLPARAM) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %ButtonQuery), LOWRD(CBLPARAM) - 155, _ 'Hor, HIWRD(CBLPARAM) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %ButtonQuit), LOWRD(CBLPARAM) - 80, _ 'Hor, HIWRD(CBLPARAM) - 33, 60, 24, %TRUE 'Vert, W, H MoveWindow GetDlgItem(CBHNDL, %Grip), LOWRD(CBLPARAM) - 15, _ 'Hor, HIWRD(CBLPARAM) - 15, 15, 15, %TRUE 'Vert, W, H SetHorizontalListboxBar DIALOG REDRAW hDlg FUNCTION = 0 EXIT FUNCTION CASE %WM_GETMINMAXINFO MinMaxInfoPtr = CBLPARAM @MinMaxInfoPtr.ptMinTrackSize.x = 385 @MinMaxInfoPtr.ptMinTrackSize.y = 180 CASE %WM_CLOSE ' CloseHandle hProc 'Added in case 1 open ' CloseHandle hThread 'Added in case 1 open ' PostQuitMessage 0 END SELECT END FUNCTION FUNCTION PBMAIN AS LONG DIALOG NEW %HWND_DESKTOP, "QuerySystemInformation", , , 600, 300, _ %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN OR %WS_CAPTION OR _ %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MINIMIZEBOX OR _ %WS_MAXIMIZEBOX, %WS_EX_WINDOWEDGE TO hDlg CONTROL ADD LISTBOX, hdlg, %Listbox , , 10, 10, 580, 280, _ %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %WS_VSCROLL OR %WS_HSCROLL OR _ %LBS_NOTIFY OR %WS_TABSTOP OR %LBS_USETABSTOPS, %WS_EX_CLIENTEDGE CONTROL ADD COMBOBOX, hDlg, %Combobox, , 338, 281, 100, 50, _ %CBS_DROPDOWN OR %CBS_HASSTRINGS OR %WS_TABSTOP, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT COMBOBOX ADD hDlg, %Combobox, "Serial" COMBOBOX ADD hDlg, %Combobox, "Serial0" COMBOBOX ADD hDlg, %Combobox, "\Device\Tcp" COMBOBOX ADD hDlg, %Combobox, "\Device\Udp" COMBOBOX ADD hDlg, %Combobox, "COM" COMBOBOX ADD hDlg, %Combobox, "COM1" COMBOBOX ADD hDlg, %Combobox, "Registry" COMBOBOX ADD hDlg, %Combobox, "HandleType 4 Key" COMBOBOX SELECT hDlg, %Combobox, 2 CONTROL ADD BUTTON, hDlg, %ButtonSearch, "&Search", 418, 280, 45, 15, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_TEXT OR %BS_PUSHBUTTON OR _ %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL DISABLE hDlg, %ButtonSearch CONTROL ADD BUTTON, hDlg, %ButtonQuery, "&Query", 478, 280, 45, 15, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_TEXT OR %BS_PUSHBUTTON OR _ %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %ButtonQuit, "Quit", 538, 280, 45, 15, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_TEXT OR %BS_PUSHBUTTON OR _ %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD SCROLLBAR, hDlg, %Grip, "", 590, 290, 10, 10, %WS_CHILD OR _ %WS_VISIBLE OR %SBS_SIZEGRIP OR %SBS_SIZEBOXBOTTOMRIGHTALIGN SetClassLong hDlg, %GCL_HICON, LoadIcon(BYVAL %NULL, BYVAL %IDI_INFORMATION) CONTROL SET FOCUS hDlg, %ButtonQuery DIALOG SHOW MODAL hDlg CALL DlgProc END FUNCTION FUNCTION ListAdd(AddToList AS STRING) AS LONG LOCAL LastItem AS LONG LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 LastItem = SendMessage(hList, %LB_ADDSTRING, LastItem, BYVAL STRPTR(AddToList)) ' Retval = SendMessage(hList, %LB_GETCURSEL, 0, 0) SendMessage hList, %LB_SETCURSEL, LastItem, 0 END FUNCTION FUNCTION SetHorizontalListboxBar() AS LONG LOCAL Si AS apiSize LOCAL sBuffer AS STRING LOCAL hFont AS DWORD LOCAL hDC AS DWORD LOCAL ListWidth AS LONG LOCAL LastItem AS LONG LOCAL Counter AS LONG LOCAL TextLen AS LONG LOCAL Looper AS LONG hFont = SendMessage(hList, %WM_GETFONT, 0, 0) hDC = GetDC(hList) IF hFont THEN hFont = SelectObject(hDC, hFont) LastItem = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1 IF LastItem > 0 THEN FOR Looper = 0 TO LastItem TextLen = SendMessage(hList, %LB_GETTEXTLEN, Looper, 0) IF TextLen THEN sBuffer = NUL$(TextLen) SendMessage hList, %LB_GETTEXT, Looper, STRPTR(sBuffer) GetTextExtentPoint32 hDC, BYCOPY sBuffer + "W", TextLen + 1, Si ListWidth = MAX& (ListWidth, Si.cx) END IF NEXT SendMessage hList, %LB_SETHORIZONTALEXTENT, ListWidth, 0 END IF IF hFont THEN SelectObject hDC, hFont ReleaseDC hList, hDC END FUNCTION
Code:'---------------------------------------------------------------- ' SYSTEM HANDLE INFORMATION CONSTANTS '---------------------------------------------------------------- %SystemHandleInformation = &H10 %ObjectNameInformation = &H1 %STATUS_SUCCESS = &H0 %STATUS_MORE_ENTRIES = &H105 %STATUS_INFO_LENGTH_MISMATCH = &HC0000004 %STATUS_BUFFER_OVERFLOW = &H80000005 %STATUS_SEVERITY_ERROR = &H00000003 '---------------------------------------------------------------- ' SYSTEM HANDLE INFORMATION USER DEFINED TYPES '---------------------------------------------------------------- TYPE SYSTEM_HANDLE_INFORMATION 'Information Class is &h10 (I do not know why) ProcessID AS DWORD 'Process Id ObjectTypeNumber AS BYTE 'Object type number Flags AS BYTE 'Flags (I do not know what the possible values are) SysHandle AS WORD 'Original was HANDLE, but that is a keyword (undocumented why?) SysObject AS DWORD 'Original was OBJECT, but that is a keyword for COM interaction in PB GrantedAccess AS DWORD 'Access granted (I do not know what the possible values are) END TYPE TYPE SYSTEM_OBJECT_INFORMATION 'Added to patch into SYSTEM_HANDLE_INFORMATION sPidPath AS ASCIIZ * %MAX_PATH 'Object path sObjectName AS ASCIIZ * %MAX_PATH 'Object name END TYPE TYPE SYSTEM_HANDLE_TABLE_ENTRY_INFO 'Internal lookup table to system information NumberOfHandles AS DWORD 'Number of handles in the system HANDLES(0 TO 0) AS SYSTEM_HANDLE_INFORMATION 'Array of System Handle Information, (dimensions?) END TYPE TYPE UNICODE_STRING Length AS WORD 'Length in bytes of string in Buffer MaximumLength AS WORD 'Maximum length in bytes of Buffer pBuffer AS DWORD 'Pointer to unicode string END TYPE '---------------------------------------------------------------- ' SYSTEM PRIVILEGE GLOBALS '---------------------------------------------------------------- GLOBAL Privilege AS LONG $SE_DEBUG_NAME = "SeDebugPrivilege" '---------------------------------------------------------------- ' SYSTEM PRIVILEGE CONSTANTS '---------------------------------------------------------------- %TOKEN_ADJUST_PRIVILEGES = &H20 %TOKEN_QUERY = &H8 %SE_PRIVILEGE_ENABLED = &H2 %PROCESS_VM_READ = &H10 %PROCESS_DUP_HANDLE = &H40 %PROCESS_QUERY_INFORMATION = &H400 %STANDARD_RIGHTS_ALL = &H1F0000 %GENERIC_ALL = &H10000000 '---------------------------------------------------------------- ' NTDLL API FUNCTIONS '---------------------------------------------------------------- 'DECLARE FUNCTION NtQuerySystemInformation LIB "NtDLL.DLL" ALIAS "NtQuerySystemInformation"( _ ' BYVAL SystemInformationClass AS DWORD, _ ' BYVAL SystemInformation AS DWORD, _ ' BYVAL SystemInformationLength AS DWORD, _ ' BYREF ReturnLength AS DWORD) AS LONG ' 'DECLARE FUNCTION NtQueryObject LIB "NtDLL.DLL" ALIAS "NtQueryObject"( _ ' BYVAL hndl AS DWORD, _ ' BYVAL ObjectInformationClass AS DWORD, _ ' BYVAL ObjectInformation AS DWORD, _ ' BYVAL ObjectInformationLength AS DWORD, _ ' BYREF ReturnLength AS DWORD) AS LONG '---------------------------------------------------------------- ' NTDLL API FUNCTIONS CALLED VIA LOADLIBRARY '---------------------------------------------------------------- DECLARE FUNCTION PbQuerySystemInformation ALIAS "PbQuerySystemInformation"( _ BYVAL SystemInformationClass AS DWORD, _ BYVAL SystemInformation AS DWORD, _ BYVAL SystemInformationLength AS DWORD, _ BYREF ReturnLength AS DWORD) AS LONG DECLARE FUNCTION PbQueryObject ALIAS "PbQueryObject"( _ BYVAL hndl AS DWORD, _ BYVAL ObjectInformationClass AS DWORD, _ BYVAL ObjectInformation AS DWORD, _ BYVAL ObjectInformationLength AS DWORD, _ BYREF ReturnLength AS DWORD) AS LONG '---------------------------------------------------------------- ' WRAPPER GLOBALS '---------------------------------------------------------------- 'GLOBAL ObjNameRet AS DWORD 'Object Name returned from NtQueryObject GLOBAL NtDllHandle AS DWORD 'NtDll Handle to process GLOBAL PbQuerySysInfoHandle AS DWORD 'Pb Handle to NtDll - NtQuerySysInfoHandle via loadlibrary GLOBAL PbQueryObjName AS DWORD 'Pb Handle to NtDll - NtQueryObjName via loadlibrary GLOBAL Info() AS SYSTEM_HANDLE_INFORMATION 'Array of System Handles Info GLOBAL ObjectInfo() AS SYSTEM_OBJECT_INFORMATION 'Array of System Objects Info GLOBAL ObjNameRet AS DWORD 'Return of threaded get object GLOBAL hProc AS DWORD GLOBAL hThread AS DWORD GLOBAL sBuffer AS STRING GLOBAL puString AS UNICODE_STRING POINTER GLOBAL pBuffer AS DWORD PTR GLOBAL LenBuffer AS DWORD GLOBAL hPort AS DWORD GLOBAL ByteNeeded AS DWORD GLOBAL sObjName AS STRING '---------------------------------------------------------------- ' WRAPPER FUNCTIONS '---------------------------------------------------------------- DECLARE FUNCTION ProcessEnum AS LONG DECLARE FUNCTION FindHandleInformation(ProcessId AS DWORD, InfoCount AS DWORD, ProcSysHandleInfo AS SYSTEM_HANDLE_INFORMATION) AS LONG DECLARE FUNCTION ThreadGetObjectName(BYVAL x AS LONG) AS LONG DECLARE FUNCTION GetObjectName(ProcessId AS DWORD, Hndl AS WORD) AS STRING DECLARE FUNCTION GetPidPath(PID AS DWORD) AS STRING '------------------------------------------------------------------------------------------------------------------ ' THE BELOW WILL BE MOVED TO PSAPI.H BUT LEFT IN NTDLL.H FOR DEMO PURPOSES (UNTIL PROBLEMS SOLVED) '------------------------------------------------------------------------------------------------------------------ '---------------------------------------------------------------- ' PSAPI API FUNCTIONS '---------------------------------------------------------------- DECLARE FUNCTION EnumProcessModules LIB "PsApi.DLL" ALIAS "EnumProcessModules"( _ BYVAL hProcess AS DWORD, _ 'Handle to Process BYVAL lphModule AS DWORD, _ 'Handle to Module in Process BYVAL cb AS DWORD, _ 'Bytes to get BYREF cbNeeded AS DWORD) AS LONG 'Bytes really needed DECLARE FUNCTION GetModuleFileNameEx LIB "PsApi.DLL" ALIAS "GetModuleFileNameExA"( _ BYVAL hProcess AS DWORD, _ 'Handle to Process BYVAL hModule AS DWORD, _ 'Handle to Module in Process lpFilename AS ASCIIZ, _ 'Name of Module returned from call BYVAL nSize AS DWORD) AS LONG 'Size of Name of Module (I use %MAX_PATH to get full name) '---------------------------------------------------------------- ' PSAPI API WRAPPER FUNCTIONS '---------------------------------------------------------------- DECLARE FUNCTION ProcessEnum AS LONG DECLARE FUNCTION GetPidPath(PID AS DWORD) AS STRING
Code:'*** MOVE TO PSAPI.INC AFTER DEMO (when Problems are fixed) FUNCTION ProcessEnum AS LONG LOCAL pInfoTable AS SYSTEM_HANDLE_TABLE_ENTRY_INFO POINTER LOCAL sBuffer AS STRING LOCAL sObjectType AS STRING LOCAL sObjectName AS STRING LOCAL sPidPath AS STRING LOCAL pBuffer AS DWORD PTR LOCAL LenBuffer AS DWORD LOCAL ByteNeeded AS DWORD LOCAL InfoCount AS DWORD LOCAL Looper AS DWORD LOCAL Retval AS LONG LOCAL ObjectFlags AS STRING '*** Set Initial Parameters LenBuffer = SIZEOF(SYSTEM_HANDLE_TABLE_ENTRY_INFO) 'Minimum buffer size for a valid ByteNeeded sBuffer = NUL$(LenBuffer) 'Fill buffer with nulls pBuffer = STRPTR(sBuffer) 'Set pointer to buffer '*** Get needed number of bytes ' Retval = NtQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) 'Hardcoded CALL DWORD PbQuerySysInfoHandle USING PbQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) TO Retval 'via loadlibrary '*** Set to needed number of bytes IF ByteNeeded > LenBuffer THEN LenBuffer = ByteNeeded sBuffer = NUL$(LenBuffer) pBuffer = STRPTR(sBuffer) ' Retval = NtQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) 'Hardcoded CALL DWORD PbQuerySysInfoHandle USING PbQuerySystemInformation(%SystemHandleInformation, pBuffer, LenBuffer, ByteNeeded) TO Retval 'via loadlibrary END IF '*** Get Number of Handles in the system pInfoTable = pBuffer InfoCount = @pInfoTable.NumberOfHandles '*** Listbox Display Only Retval = SendMessage(hList, %LB_INITSTORAGE, InfoCount * 4, InfoCount * 200) 'Faster listbox filling '*** Set Array to store Handle Information ' DIM Info(1 TO InfoCount) AS SYSTEM_HANDLE_INFORMATION AT pInfoTable + 4 '+ 4 to start just after .NumberOfHandles REDIM Info(1 TO InfoCount) AS SYSTEM_HANDLE_INFORMATION AT pInfoTable + 4 '+ 4 to start just after .NumberOfHandles REDIM ObjectInfo(1 TO InfoCount) 'Dimension Object Info to same size as System Info MSGBOX "System Info Gathered with " + STR$(InfoCount) + " items to sort" '*** Sort the Object Type of each element FOR Looper = 1 TO InfoCount 'For each handle in the system ' Select Case WindowsOs 'Dependin on Operating System Object types are different (add into code later) ' case 0 'Win95 ' CASE 1 'Win98 ' CASE 2 'WinME ' CASE 3 'WinNT ' CASE 4 'Win2k ' CASE 5 'WinXP SELECT CASE Info(Looper).ObjectTypeNumber CASE 02 : sObjectType = " Directory" CASE 03 : sObjectType = " SymbolicLink" CASE 04 : sObjectType = " Token" 'Added from SysInternals CASE 05 : sObjectType = " Process" CASE 06 : sObjectType = " Thread" CASE 07 : sObjectType = " Job" 'Added from SysInternals CASE 09 : sObjectType = " Event" CASE 11 : sObjectType = " Mutant" CASE 13 : sObjectType = " Semaphore" CASE 14 : sObjectType = " Timer" 'Added from SysInternals CASE 16 : sObjectType = " KeyedEvent" CASE 17 : sObjectType = " WindowStation" 'Added from SysInternals CASE 18 : sObjectType = " Desktop" 'Added from SysInternals CASE 19 : sObjectType = " Section" 'Added from SysInternals CASE 20 : sObjectType = " Key" 'Added from SysInternals CASE 21 : sObjectType = " Port" 'Added from SysInternals CASE 22 : sObjectType = " WaitablePort" 'Added from SysInternals CASE 27 : sObjectType = " IoCompletion" 'Added from SysInternals CASE 28 : sObjectType = " File" 'Added from SysInternals CASE 29 : sObjectType = " WmiGuid" 'Added from SysInternals CASE ELSE : sObjectType = " UnKnown " + $TAB + $TAB + STR$(Info(Looper).ObjectTypeNumber) END SELECT ' CASE 6 'WinVista ' end select '*** Re-Enable if you want to see the list ObjectFlags = HEX$(Info(Looper).Flags, 1) SELECT CASE ObjectFlags '0x00 = NONE, 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT CASE "0" ObjectFlags = ObjectFlags + " - NONE" CASE "1" ObjectFlags = ObjectFlags + " - PROTECT_FROM_CLOSE" CASE "2" ObjectFlags = ObjectFlags + " - INHERIT" END SELECT ''*** Get path to the process ObjectInfo(Looper).sPidPath = GetPidPath(Info(Looper).ProcessID) '*** Get the Object Name '*** WARNING ... Named Pipes are known to hang the code but unable to know if ObjectType is a pipe '*** and not a file without asking the name ... so its a catch-22 DIM SkipFile AS LONG IF INSTR(ObjectInfo(Looper).sPidPath, "Explorer.exe") THEN SkipFile = %True IF INSTR(ObjectInfo(Looper).sPidPath, "EnumProcessObjectHandles") THEN SkipFile = %True IF SkipFile = %False THEN ObjectInfo(Looper).sObjectName = GetObjectName(Info(Looper).ProcessID, Info(Looper).SysHandle) ' ObjectInfo(Looper).sObjectName = GetObjectName(Info(Looper).ProcessID, Info(Looper).SysHandle) ' SELECT CASE ObjectInfo(Looper).sObjectName ' CASE "", "No DuplicateHandle" ' CASE ELSE ListAdd "Number " & FORMAT$(Looper) & _ " - Pid " & FORMAT$(Info(Looper).ProcessID) & _ " - HandleId " & HEX$(Info(Looper).SysHandle, 4) & _ " - Object " & HEX$(Info(Looper).SysObject, 8) & _ " - Access " & HEX$(Info(Looper).GrantedAccess, 8) & _ " - Flags " & ObjectFlags & _ " - HandleType" & STR$(Info(Looper).ObjectTypeNumber) & _ sObjectType ListAdd "Pid Path = " & ObjectInfo(Looper).sPidPath ListAdd "Object Name = " & ObjectInfo(Looper).sObjectName ListAdd "" ' end select '*** Block to check for certain device types open (demo purposes Only) IF INSTR(ObjectInfo(Looper).sObjectName, "\Device\Serial") _ OR INSTR(ObjectInfo(Looper).sObjectName, "\Device\EdgeSer") _ OR INSTR(ObjectInfo(Looper).sObjectName, "\Device\USBPDO") _ THEN MSGBOX ObjectInfo(Looper).sObjectName + " open in " + ObjectInfo(Looper).sPidPath '*** Just to refresh the dialog NEXT Looper 'MSGBOX "All Done with " + STR$(UBOUND(SortProcess)) + " and " + STR$(UBOUND(Info)) END FUNCTION FUNCTION GetObjectName(ProcessId AS DWORD, Hndl AS WORD) AS STRING LOCAL Retval AS LONG LOCAL hCurrent AS DWORD LOCAL hResult AS DWORD LOCAL hExitCode AS DWORD LOCAL Arg AS LONG LOCAL idThread AS DWORD hCurrent = GetCurrentProcess IF ProcessId THEN hProc = OpenProcess(%PROCESS_DUP_HANDLE, 0, ProcessId) ' hProc = OpenProcess(%PROCESS_ALL_ACCESS, %False, ProcessId) IF hProc <> %INVALID_HANDLE_VALUE THEN IF DuplicateHandle(hProc, BYVAL Hndl, -1, hPort, (%GENERIC_READ OR %KEY_READ), _ %PROCESS_ALL_ACCESS, %DUPLICATE_SAME_ACCESS) THEN LenBuffer = SIZEOF(UNICODE_STRING) sBuffer = NUL$(LenBuffer) pBuffer = STRPTR(sBuffer) '*** Thread the calls to check object name since named pipes are known to "Hang" rather than return hThread = CreateThread(BYVAL %NULL, 0, CODEPTR(ThreadGetObjectName), BYREF Arg, _ %THREAD_TERMINATE OR %THREAD_QUERY_INFORMATION, _ BYVAL VARPTR(idThread)) IF hThread <> %INVALID_HANDLE_VALUE THEN DO SELECT CASE WaitForSingleObject(hThread, 50) 'Try with 3500 and 7500 CASE %WAIT_ABANDONED 'Mutex Object not released ' ObjNameRet = %STATUS_SEVERITY_ERROR hThread = %INVALID_HANDLE_VALUE CASE %WAIT_OBJECT_0 'The state of the specified object is signaled GetExitCodeThread(hThread, Retval) ' TerminateThread BYVAL hThread, Retval CloseHandle hThread ' ObjNameRet = %STATUS_SEVERITY_ERROR hThread = %INVALID_HANDLE_VALUE EXIT DO CASE %WAIT_TIMEOUT 'The time-out interval elapsed, and the object's state is nonsignaled. TerminateThread BYVAL hThread, BYVAL 0 CloseHandle hThread 'CloseHandle after TerminateThread ' ObjNameRet = %STATUS_SEVERITY_ERROR hThread = %INVALID_HANDLE_VALUE EXIT DO END SELECT LOOP 'MSGBOX STR$(hPort) + $TAB + STR$(@pbuffer) + $TAB + STR$(lenBuffer) + $TAB + STR$(ByteNeeded) + $TAB + STR$(ObjNameRet) ' IF ObjNameRet = %STATUS_SUCCESS THEN ' puString = pBuffer ' IF @puString.Length > 0 THEN ' sObjName = NUL$(@puString.Length \ 2) '' sObjName = @puString.pBuffer ' WideCharToMultiByte %CP_ACP, %NULL, BYVAL @puString.pBuffer, @puString.Length, _ ' BYVAL STRPTR(sObjName), LEN(sObjName), BYVAL %NULL, BYVAL %NULL ' FUNCTION = "ObjName: " & sObjName ' END IF ' ELSE ' FUNCTION = "Bad NtQueryObject" ' END IF FUNCTION = "ObjName: " & sObjName CloseHandle hPort END IF ELSE FUNCTION = "No DuplicateHandle" END IF CloseHandle hProc ELSE FUNCTION = "Bad OpenProcess" END IF END IF 'hProc = OpenProcess(BYVAL %PROCESS_TERMINATE, BYVAL 0, BYVAL hProc) END FUNCTION FUNCTION ThreadGetObjectName(BYVAL x AS LONG) AS LONG ' ObjNameRet = NtQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) CALL DWORD PbQueryObjName USING PbQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) TO ObjNameRet IF ByteNeeded > LenBuffer THEN LenBuffer = ByteNeeded ' ObjNameRet = NtQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) CALL DWORD PbQueryObjName USING PbQueryObject(hPort, %ObjectNameInformation, pBuffer, LenBuffer, ByteNeeded) TO ObjNameRet END IF IF ObjNameRet = %STATUS_SUCCESS THEN puString = pBuffer IF @puString.Length > 0 THEN sObjName = NUL$(@puString.Length \ 2) ' sObjName = @puString.pBuffer WideCharToMultiByte %CP_ACP, %NULL, BYVAL @puString.pBuffer, @puString.Length, _ BYVAL STRPTR(sObjName), LEN(sObjName), BYVAL %NULL, BYVAL %NULL ' FUNCTION = "ObjName: " & sObjName END IF ELSE ' FUNCTION = "Bad NtQueryObject" sObjName = "Bad NtQueryObject" END IF END FUNCTION FUNCTION GetPidPath(PID AS DWORD) AS STRING LOCAL ModuleName AS STRING LOCAL PidPath AS STRING LOCAL sBuffer AS STRING LOCAL pBuffer AS DWORD PTR LOCAL LenBuffer AS DWORD LOCAL hProcess AS DWORD LOCAL ByteNeeded AS DWORD LOCAL HandleCount AS DWORD LOCAL Retval AS LONG LOCAL HandleSize AS DWORD hProcess = OpenProcess(%PROCESS_QUERY_INFORMATION OR %PROCESS_VM_READ, 0, Pid) IF hProcess THEN LenBuffer = 4 'SIZEOF(DWORD) sBuffer = NUL$(LenBuffer) pBuffer = STRPTR(sBuffer) Retval = EnumProcessModules(hProcess, pBuffer, LenBuffer, ByteNeeded) IF ByteNeeded > LenBuffer THEN LenBuffer = ByteNeeded sBuffer = NUL$(LenBuffer) pBuffer = STRPTR(sBuffer) Retval = EnumProcessModules(hProcess, pBuffer, LenBuffer, ByteNeeded) END IF IF Retval THEN ' HandleCount = LenBuffer \ 4 HandleCount = LenBuffer \ SIZEOF(HandleSize) DIM ModulesHandles(1 TO HandleCount) AS DWORD AT pBuffer ModuleName = "Unknown" & NUL$(%MAX_PATH) Retval = GetModuleFileNameEx(hProcess, ModulesHandles(1), BYVAL STRPTR(ModuleName), %MAX_PATH) PidPath = LEFT$(ModuleName, Retval) ELSE 'ListAdd "Bad EnumProcessModules" END IF CloseHandle hProcess END IF IF PidPath = "" THEN PidPath = "SYSTEM" FUNCTION = PidPath 'hProcess = OpenProcess(BYVAL %PROCESS_TERMINATE, BYVAL 0, BYVAL hProcess) END FUNCTION
Leave a comment:
-
-
Forget what I said about the code revealing more than that found in
SysInternals Process Monitor. I found that the unknown Object types were
what is revealed if you show all un-named process handles.
Now I am back to figuring the lock-up which I believe is due to doing
a "GetObjectName" on a Pipe(or other handle) that is either synched, or locked somehow
so the code halts until a reply is found.
Thanx for the test Pierre, your test revealed what I 1st thought that if a reply does not
return from the query, then how would the code know to continue on to the WaitForSingleObject
and time itself out?
Since documentation says that you could use DuplicateHandle, I wonder how I would DuplicateHandle that is not synched or locked somehow?
Just some thoughts, but I know I am close to figuring things out
------------------
Leave a comment:
-
-
Note to self....One of the sites that mentions the difference between W2K and XP
SysInternals Forums
Pierre, I have been doing a ton of testing today and find the code reveals more that SysInternals.
(which is a clue to me of why it does not lock, but my code does)
Another clue is on the same page above (and others) is that GetObjectType will
hang on a process with an "Open-Named-Pipe"
------------------
Leave a comment:
-
-
As a test, I did encapsulate NtQueryObject in a thread
with %THREAD_TERMINATE OR %THREAD_QUERY_INFORMATION access
and used WaitForSingleObject and TerminateThread
to avoid program loosing control on non readable pid.
No success, still NtQueryObject refuse to quit.
Even if it is not the solution,
to cease freezing, I did update the code to bypass
the reading of SYSTEM's pid and those from
"SERVICES", "LSASS", "SVCHOST" and "ZONELABS\VSMON"
More digging have to be done...
Pierre
Leave a comment:
-
-
Heh....I should have read your post earlier today (would have saved some time)
I found the same problem in the same place.
My 1st initial thought for a work-around is to check for the GrantedAccess value?
Stuff I have already tried in the GetObjectName are
[list=1][*] Open the process, and immediately close after duplicating the ProcessHandle [*] Tried DuplicateHandle(hProc, BYVAL Hndl, -1, hPort, (%GENERIC_READ OR %KEY_READ), %PROCESS_ALL_ACCESS, %PROCESS_ALL_ACCESS) <---Do NOT!!!! do this one, it locked me out of the computer so hard I had to power off[/list=a]
I tried something else too but forgot what it was at the moment.
2 funny things I did notice were that each time at lock-up, you can not compile and run the same file name again (obvious because the 1st is still in use)
the other was that even if I can get the process killed (both by taskmanager, and sysinternals) it is only gone momentarily (at best) and seems to re-create itself?)
I am working on a few ideas, but think the granted access may be the key.
------------------
Leave a comment:
-
Leave a comment: