def tree_parent_process(grph, proc_obj, pids_seen_set): try: the_pid = proc_obj.pid if the_pid == 0 or the_pid == 1: return # A circular processes hierarchy can happen on Windows. if the_pid in pids_seen_set: WARNING("Circular pids tree:%d", the_pid) return pids_seen_set.add(the_pid) # Strange, but apparently it can happen. the_ppid = CIM_Process.PsutilProcToPPid(proc_obj) if the_ppid == 0: return if lib_common.is_useless_process(proc_obj): return node_process = lib_common.gUriGen.PidUri(the_pid) node_pprocess = lib_common.gUriGen.PidUri(the_ppid) grph.add((node_pprocess, pc.property_ppid, node_process)) CIM_Process.AddInfo(grph, node_pprocess, [str(the_ppid)]) AddExtraInformationtoProcess(grph, node_process, proc_obj) parent_proc_obj = CIM_Process.PsutilGetProcObjNoThrow(int(the_ppid)) tree_parent_process(grph, parent_proc_obj, pids_seen_set) # This exception depends on the version of psutil. except CIM_Process.NoSuchProcess: # Maybe a process has suddenly disappeared. It does not matter. return
def Main(): cgiEnv = lib_common.CgiEnv() try: the_pid = int(cgiEnv.GetId()) except KeyError: lib_common.ErrorMessageHtml("Process id should be provided") grph = cgiEnv.GetGraph() proc_obj = CIM_Process.PsutilGetProcObj(the_pid) procNode = lib_common.gUriGen.PidUri(the_pid) CIM_Process.AddInfo(grph, procNode, [str(the_pid)]) (execName, execErrMsg) = CIM_Process.PsutilProcToExe(proc_obj) if (execName == ""): lib_common.ErrorMessageHtml("Cannot gdb:" + execErrMsg) PassThreads(the_pid, execName, grph, procNode) # If the command did not return anything, it means that # there are no threads, so we fall back to the "classical" # gdb output format. if len(grph) == 0: PassNoThreads(the_pid, execName, grph, procNode) cgiEnv.OutCgiRdf()
def Main(): cgiEnv = lib_common.ScriptEnvironment() try: the_pid = int(cgiEnv.GetId()) except Exception: lib_common.ErrorMessageHtml("Must provide a pid") grph = cgiEnv.GetGraph() node_process = lib_uris.gUriGen.PidUri(the_pid) CIM_Process.AddInfo(grph, node_process, [str(the_pid)]) fil_cgroups = "/proc/%d/cgroup" % the_pid for lin_cg in open(fil_cgroups): split_cg = lin_cg.split(':') hierarchy = split_cg[0] subsys_name_list = split_cg[1] mount_path = split_cg[2] mount_path = mount_path[:-1] # Strip trailing backslash-N mount_path_node = lib_uris.gUriGen.DirectoryUri(mount_path) for subsys_name in subsys_name_list.split(","): if subsys_name: cgrp_node = survol_cgroup.MakeUri(subsys_name) grph.add( (node_process, lib_common.MakeProp("CGroup"), cgrp_node)) grph.add((cgrp_node, lib_common.MakeProp("Hierarchy"), lib_util.NodeLiteral(hierarchy))) grph.add((cgrp_node, lib_common.MakeProp("Control group path"), mount_path_node)) cgiEnv.OutCgiRdf()
def Main(): cgiEnv = lib_common.CgiEnv() try: thePid = int(cgiEnv.GetId()) except Exception: lib_common.ErrorMessageHtml("Must provide a pid") grph = cgiEnv.GetGraph() proc_obj = CIM_Process.PsutilGetProcObj(thePid) node_process = lib_common.gUriGen.PidUri(thePid) CIM_Process.AddInfo(grph, node_process, [str(thePid)]) filCGroups = "/proc/%d/cgroup" % thePid for lin_cg in open(filCGroups): split_cg = lin_cg.split(':') hierarchy = split_cg[0] subsys_name_list = split_cg[1] mount_path = split_cg[2] mount_path_node = lib_common.gUriGen.DirectoryUri(mount_path) for subsys_name in subsys_name_list.split(","): cgrpNode = survol_cgroup.MakeUri(subsys_name) grph.add((node_process, lib_common.MakeProp("CGroup"), cgrpNode)) grph.add((cgrpNode, lib_common.MakeProp("Hierarchy"), lib_common.NodeLiteral(hierarchy))) grph.add((cgrpNode, lib_common.MakeProp("Control group path"), mount_path_node)) cgiEnv.OutCgiRdf()
def Main(): cgiEnv = lib_common.CgiEnv() try: top_pid = int( cgiEnv.GetId() ) except Exception: lib_common.ErrorMessageHtml("Must provide a pid") grph = cgiEnv.GetGraph() proc_obj = CIM_Process.PsutilGetProcObj(top_pid) node_process = lib_common.gUriGen.PidUri(top_pid) CIM_Process.AddInfo( grph, node_process, [ str(top_pid) ] ) proc_cwd,proc_msg = CIM_Process.PsutilProcCwd(proc_obj) if proc_cwd: # proc_cwd = proc_cwd.replace("\\","/") # "Our" normalisation. node_cwd = lib_common.gUriGen.FileUri( proc_cwd ) grph.add( ( node_process, pc.property_cwd, node_cwd ) ) else: # The PID is added to the message such as "Access denied", so it is specific to the process # and prevents nodes with the same text to be merged in RDF or when displayed in Javascript. msgSpecific = "%s:Pid=%d" % (proc_msg,top_pid) grph.add( ( node_process, pc.property_information, lib_common.NodeLiteral(msgSpecific)) ) cgiEnv.OutCgiRdf()
def tree_parent_process(grph, proc_obj): try: the_pid = proc_obj.pid if the_pid == 0 or the_pid == 1: return # Strange, but apparently it can happen. the_ppid = CIM_Process.PsutilProcToPPid(proc_obj) if the_ppid == 0: return if lib_common.UselessProc(proc_obj): return node_process = lib_common.gUriGen.PidUri(the_pid) node_pprocess = lib_common.gUriGen.PidUri(the_ppid) grph.add((node_pprocess, pc.property_ppid, node_process)) CIM_Process.AddInfo(grph, node_pprocess, [str(the_ppid)]) AddExtraInformationtoProcess(grph, node_process, proc_obj) parent_proc_obj = CIM_Process.PsutilGetProcObjNoThrow(int(the_ppid)) tree_parent_process(grph, parent_proc_obj) # This exception depends on the version of psutil. except CIM_Process.NoSuchProcess: # Maybe a process has suddenly disappeared. It does not matter. return
def AddExtraInformationtoProcess(grph, node_process, proc_obj): CIM_Process.AddInfo(grph, node_process, [str(proc_obj.pid)]) usrNam = lib_common.format_username(CIM_Process.PsutilProcToUser(proc_obj)) userNode = lib_common.gUriGen.UserUri(usrNam) grph.add((userNode, pc.property_owner, node_process)) (execName, execErrMsg) = CIM_Process.PsutilProcToExe(proc_obj) if execName != "": execNod = lib_common.gUriGen.FileUri(execName) grph.add((node_process, pc.property_runs, execNod)) lib_entity_file.AddInfo(grph, execNod, [execName])
def Main(): cgiEnv = lib_common.CgiEnv() pid = int(cgiEnv.GetId()) # TODO: These are probably in win32com or a similar module. PROCESS_QUERY_INFORMATION = 0x0400 PROCESS_VM_READ = 0x0010 grph = cgiEnv.GetGraph() node_process = lib_common.gUriGen.PidUri(pid) exec_node = CIM_Process.AddInfo(grph, node_process, [pid]) #Get handle to the process based on PID hProcess = kernel.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, pid) if hProcess: ModuType = c_ulong * 512 hModuleArr = ModuType() rawCntModules = c_ulong() psapi.EnumProcessModules(hProcess, byref(hModuleArr), sizeof(hModuleArr), byref(rawCntModules)) nbModules = int(rawCntModules.value / sizeof(c_ulong())) if nbModules >= 512: raise Exception("Disaster overrun") modname = c_buffer(256) for idx in range(0, nbModules): retLen = psapi.GetModuleFileNameExA(hProcess, hModuleArr[idx], modname, sizeof(modname)) if retLen == 0: # Maybe the string is empty. continue raw_filename_bytes = modname[:retLen] raw_filename_as_str = raw_filename_bytes.decode() filnam = lib_util.standardized_file_path(raw_filename_as_str) #if lib_util.is_py3: # # Truncation because "b'C:/xxx/yyy.zzz'", on Python 3 # # Backslashes are duplicated. # filnam = str(tab).replace('\\','/')[2:-1].replace("//","/") #else: # # Windows "\\" must be replaced by "/", so the URLs are the same for all tools. # filnam = str(tab).replace('\\','/') # The same filename might appear several times. DEBUG("idx=%d retLen=%d filnam=%s", idx, retLen, filnam) libNode = lib_common.gUriGen.SharedLibUri(filnam) grph.add((node_process, pc.property_library_depends, libNode)) kernel.CloseHandle(hProcess) cgiEnv.OutCgiRdf()
def Main(): cgiEnv = lib_common.CgiEnv() pid = int(cgiEnv.GetId()) # TODO: These are probably in win32com or a similar module. PROCESS_QUERY_INFORMATION = 0x0400 PROCESS_VM_READ = 0x0010 grph = cgiEnv.GetGraph() node_process = lib_common.gUriGen.PidUri(pid) exec_node = CIM_Process.AddInfo(grph, node_process, [pid]) #Get handle to the process based on PID hProcess = kernel.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, pid) if hProcess: ModuType = c_ulong * 512 hModuleArr = ModuType() rawCntModules = c_ulong() psapi.EnumProcessModules(hProcess, byref(hModuleArr), sizeof(hModuleArr), byref(rawCntModules)) nbModules = int(rawCntModules.value / sizeof(c_ulong())) if nbModules >= 512: raise Exception("Disaster overrun") modname = c_buffer(256) for idx in range(0, nbModules): retLen = psapi.GetModuleFileNameExA(hProcess, hModuleArr[idx], modname, sizeof(modname)) tab = modname[:retLen] if sys.version_info >= (3, ): # Truncation because "b'C:/xxx/yyy.zzz'", on Python 3 filnam = str(tab).replace('\\', '/')[2:-1] else: filnam = tab # The same filename might appear several times. sys.stderr.write("idx=%d retLen=%d filnam=%s\n" % (idx, retLen, filnam)) if idx > 0: libNode = lib_common.gUriGen.SharedLibUri(filnam) grph.add((node_process, pc.property_library_depends, libNode)) kernel.CloseHandle(hProcess) cgiEnv.OutCgiRdf()
def Main(): paramkeyShowSharedLib = "Show shared libraries" paramkeyShowFontFiles = "Show font files" cgiEnv = lib_common.CgiEnv(parameters={ paramkeyShowSharedLib: False, paramkeyShowFontFiles: False }) top_pid = int(cgiEnv.GetId()) flagShowSharedLib = bool(cgiEnv.get_parameters(paramkeyShowSharedLib)) flagShowFontFiles = bool(cgiEnv.get_parameters(paramkeyShowFontFiles)) grph = cgiEnv.GetGraph() proc_obj = CIM_Process.PsutilGetProcObj(top_pid) # sys.stderr.write("top_pid=%d\n" % top_pid) node_process = lib_common.gUriGen.PidUri(top_pid) CIM_Process.AddInfo(grph, node_process, [str(top_pid)]) ################################################################################ try: fillist = CIM_Process.PsutilProcOpenFiles(proc_obj) except Exception: exc = sys.exc_info()[1] lib_common.ErrorMessageHtml("Caught:" + str(exc) + ":" + str(proc_obj)) for fil in fillist: # TODO: Resolve symbolic links. Do not do that if shared memory. # TODO: AVOIDS THESE TESTS FOR SHARED MEMORY !!!! if lib_common.is_meaningless_file(fil.path, not flagShowSharedLib, not flagShowFontFiles): continue fileNode = lib_common.gUriGen.FileUri(fil.path) grph.add((node_process, pc.property_open_file, fileNode)) # This works but not really necessary because there are not so many files. # cgiEnv.OutCgiRdf( "", [pc.property_open_file] ) cgiEnv.OutCgiRdf("LAYOUT_SPLINE")
def Main(): cgiEnv = lib_common.ScriptEnvironment() pid = int(cgiEnv.GetId()) # TODO: These are probably in win32com or a similar module. PROCESS_QUERY_INFORMATION = 0x0400 PROCESS_VM_READ = 0x0010 grph = cgiEnv.GetGraph() node_process = lib_uris.gUriGen.PidUri(pid) exec_node = CIM_Process.AddInfo(grph, node_process, [pid]) #Get handle to the process based on PID hProcess = kernel.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, pid) if hProcess: ModuType = c_ulong * 512 hModuleArr = ModuType() raw_cnt_modules = c_ulong() psapi.EnumProcessModules(hProcess, byref(hModuleArr), sizeof(hModuleArr), byref(raw_cnt_modules)) nb_modules = int(raw_cnt_modules.value/sizeof(c_ulong())) if nb_modules >= 512: raise Exception("Disaster overrun") modname = c_buffer(256) for idx in range(0, nb_modules): ret_len = psapi.GetModuleFileNameExA(hProcess, hModuleArr[idx], modname, sizeof(modname)) if ret_len == 0: # Maybe the string is empty. continue raw_filename_bytes = modname[:ret_len] raw_filename_as_str = raw_filename_bytes.decode() filnam = lib_util.standardized_file_path(raw_filename_as_str) lib_node = lib_uris.gUriGen.SharedLibUri(filnam) grph.add((node_process, pc.property_library_depends, lib_node)) kernel.CloseHandle(hProcess) cgiEnv.OutCgiRdf()
def Main(): cgiEnv = lib_common.ScriptEnvironment() try: the_pid = int(cgiEnv.GetId()) except Exception: lib_common.ErrorMessageHtml("Must provide a pid") # If cannot be the current pid, otherwise it will block. if the_pid == os.getpid(): lib_common.ErrorMessageHtml("Cannot debug current process") if not lib_util.isPlatformWindows: lib_common.ErrorMessageHtml("This works only on Windows platforms") grph = cgiEnv.GetGraph() # Starts a second session cdb_fil = lib_util.TmpFile("CdbCommand", "cdb") cdb_fd = open(cdb_fil.Name, "w") cdb_fd.write("lm\n") # List loaded modules cdb_fd.write("k\n") # Display stack backtrace. cdb_fd.write("qd\n") # Quit and detach. cdb_fd.close() cdb_cmd = "cdb -p " + str(the_pid) + " -cf " + cdb_fil.Name proc_node = lib_uris.gUriGen.PidUri(the_pid) call_node_prev = None modules_map = {} logging.debug("Starting cdb_cmd=%s", cdb_cmd) try: cdb_pipe = lib_common.SubProcPOpen(cdb_cmd) except WindowsError as exc: lib_common.ErrorMessageHtml("cdb not available: Caught:%s" % str(exc)) logging.debug("Started cdb_cmd=%s", cdb_cmd) cdb_output, cdb_err = cdb_pipe.communicate() # Without decode, "TypeError: Type str does not support the buffer API" cdb_str = cdb_output.decode("utf-8") call_depth = 0 for dot_line in cdb_str.split('\n'): err_match = re.match(".*parameter is incorrect.*", dot_line) if err_match: lib_common.ErrorMessageHtml("CDB:"+dot_line) # 76590000 766a0000 kernel32 (export symbols) C:\Windows\syswow64\kernel32.dll match_lm = re.match(r"[0-9a-fA-F]+ [0-9a-fA-F]+ +([^ ]*) +\(export symbols\) +(.*)", dot_line ) if match_lm: module_name = match_lm.group(1) dll_name_raw = match_lm.group(2).strip() dll_name = lib_util.standardized_file_path(dll_name_raw) logging.debug("module_name=%s dll_name=%s", module_name, dll_name) modules_map[module_name] = dll_name continue # 295cfb0c 00000000 ntdll!RtlInitializeExceptionChain+0x36 # Another format, maybe because of a 64 bits machine. # 00000000`02edff90 00000000`00000000 ntdll!RtlUserThreadStart+0x21 match_k = re.match("[`0-9a-fA-F]+ [`0-9a-fA-F]+ ([^!]*)!([^+]*)", dot_line) if match_k: module_name = match_k.group(1) try: dll_name = modules_map[module_name] except KeyError: dll_name = module_name func_name = match_k.group(2).strip() logging.debug("module_name=%s dll_name=%s func_name=%s", module_name, dll_name, func_name) dll_name = CDB.TestIfKnownDll(dll_name) call_node_prev = survol_symbol.AddFunctionCall(grph, call_node_prev, proc_node, func_name, dll_name) grph.add((call_node_prev, lib_properties.MakeProp("Call_depth"), lib_util.NodeLiteral(call_depth))) call_depth += 1 continue logging.debug("dot_line=%s", dot_line) logging.debug("Parsed cdb result") call_node_prev = survol_symbol.AddFunctionCall(grph, call_node_prev, proc_node, None, None) CIM_Process.AddInfo(grph, proc_node, [the_pid]) # http://msdn.microsoft.com/en-us/library/windows/hardware/ff539058(v=vs.85).aspx # # This section describes how to perform basic debugging tasks using # the Microsoft Console Debugger (CDB) and Microsoft NT Symbolic Debugger (NTSD). # CDB and NTSD are identical in every way, except that NTSD spawns # a new text window when it is started, whereas CDB inherits # the Command Prompt window from which it was invoked. # The instructions in this section are given for CDB, # but they work equally well for NTSD. For a discussion # of when to use CDB or NTSD, see Debugging Environments. cgiEnv.OutCgiRdf("LAYOUT_SPLINE")
def Main(): cgiEnv = lib_common.ScriptEnvironment() try: the_pid = int(cgiEnv.GetId()) except Exception: lib_common.ErrorMessageHtml("Must provide a pid") if not lib_util.isPlatformWindows: lib_common.ErrorMessageHtml("This works only on Windows platforms") # If cannot be the current pid, otherwise it will block. if the_pid == os.getpid(): lib_common.ErrorMessageHtml("Cannot debug current process") grph = cgiEnv.GetGraph() # Starts a second session cdb_fil = lib_util.TmpFile("CdbCommand", "cdb") cdb_fd = open(cdb_fil.Name, "w") cdb_fd.write("lmv\n") # List loaded modules, verbose mode. cdb_fd.write("qd\n") # Quit and detach. cdb_fd.close() cdb_cmd = "cdb -p " + str(the_pid) + " -cf " + cdb_fil.Name proc_node = lib_uris.gUriGen.PidUri(the_pid) logging.debug("Starting cdb_cmd=%s", cdb_cmd) try: cdb_pipe = lib_common.SubProcPOpen(cdb_cmd) except WindowsError as exc: lib_common.ErrorMessageHtml("cdb not available: Caught:%s" % str(exc)) logging.debug("Started cdb_cmd=%s", cdb_cmd) cdb_output, cdb_err = cdb_pipe.communicate() # Without decode, "TypeError: Type str does not support the buffer API" cdb_str = cdb_output.decode("utf-8", "ignore") prop_loaded_module = lib_common.MakeProp("Loaded module") for dot_line in cdb_str.split('\n'): # moduleName=uDWM moduleStatus=deferred file_name= # dot_line= Image path: C:\windows\system32\uDWM.dll # dot_line= Image name: uDWM.dll # dot_line= Timestamp: Tue Jul 14 02:33:35 2009 (4A5BE06F) # dot_line= CheckSum: 0005E9A4 # dot_line= ImageSize: 00057000 # dot_line= File version: 6.1.7600.16385 # dot_line= Product version: 6.1.7600.16385 # dot_line= File flags: 0 (Mask 3F) # dot_line= File OS: 40004 NT Win32 # dot_line= File type: 2.0 Dll # dot_line= File date: 00000000.00000000 # dot_line= Translations: 0409.04b0 # dot_line= CompanyName: Microsoft Corporation # dot_line= ProductName: Microsoft Windows Operating System # dot_line= InternalName: udwm.dll # dot_line= OriginalFilename: udwm.dll # dot_line= ProductVersion: 6.1.7600.16385 # dot_line= FileVersion: 6.1.7600.16385 (win7_rtm.090713-1255) # dot_line= FileDescription: Microsoft Desktop Window Manager # dot_line= LegalCopyright: Microsoft Corporation. All rights reserved. match_lin = re.match(" *Image path: *(.*)", dot_line) if match_lin: file_name = match_lin.group(1) file_name = CDB.TestIfKnownDll(file_name) file_name = file_name.strip() file_name = lib_util.standardized_file_path(file_name) file_node = lib_uris.gUriGen.FileUri(file_name) grph.add((proc_node, prop_loaded_module, file_node)) continue match_lin = re.match(" *CompanyName: *(.*)", dot_line) if match_lin: company_name = match_lin.group(1) grph.add((file_node, lib_common.MakeProp("Company Name"), lib_util.NodeLiteral(company_name))) continue match_lin = re.match(" *File OS: *(.*)", dot_line) if match_lin: file_os = match_lin.group(1) grph.add((file_node, lib_common.MakeProp("File OS"), lib_util.NodeLiteral(file_os))) continue match_lin = re.match(" *FileDescription: *(.*)", dot_line) if match_lin: file_description = match_lin.group(1) grph.add((file_node, lib_common.MakeProp("Description"), lib_util.NodeLiteral(file_description))) continue logging.debug("Parsed cdb result") CIM_Process.AddInfo(grph, proc_node, [the_pid]) cgiEnv.OutCgiRdf("LAYOUT_RECT", [prop_loaded_module])