Ejemplo n.º 1
0
def Main():
    cgiEnv = lib_common.CgiEnv()

    grph = cgiEnv.GetGraph()

    try:
        procid = int(cgiEnv.GetId())
    except Exception:
        lib_common.ErrorMessageHtml("Must provide a pid")

    objProc = CIM_Process.PsutilGetProcObj(procid)

    envProp = lib_common.MakeProp("environment")

    try:
        # Psutil version after 4.0.0
        envsDict = objProc.environ()
    except:
        exc = sys.exc_info()[1]
        lib_common.ErrorMessageHtml("Error:" + str(exc))

    node_process = lib_common.gUriGen.PidUri(procid)

    for envKey in envsDict:
        envVal = envsDict[envKey]
        DEBUG("envKey=%s envVal=%s", envKey, envVal)
        nodeEnvNam = lib_util.NodeLiteral(envKey)

        # When a file or a directory displayed with a node,
        # its name is shortened so it can fit into the table.,
        # so it is less visible.

        # Some are probably for Windows only.
        if envKey in ["PATH", "PSMODULEPATH", "PYPATH"]:
            valSplit = envVal.split(os.pathsep)
            nodFilArr = [
                lib_common.gUriGen.DirectoryUri(filNam) for filNam in valSplit
            ]
            nodFilArrNod = lib_util.NodeLiteral(nodFilArr)
            #for filNam in valSplit:
            #	nodFil = lib_common.gUriGen.DirectoryUri(filNam)
            grph.add((nodeEnvNam, pc.property_rdf_data_nolist2, nodFilArrNod))
        elif os.path.isdir(envVal):
            nodFil = lib_common.gUriGen.DirectoryUri(envVal)
            #grph.add((nodeEnvNam,pc.property_directory,nodFil))
            grph.add((nodeEnvNam, pc.property_rdf_data_nolist2, nodFil))
        elif os.path.exists(envVal):
            nodFil = lib_common.gUriGen.FileUri(envVal)
            grph.add((nodeEnvNam, pc.property_rdf_data_nolist2, nodFil))
            #grph.add((nodeEnvNam,pc.property_directory,nodFil))
        else:
            # TODO: Beware that "\L" is transformed into "<TABLE>" by Graphviz !!!
            envValClean = envVal.replace(">", "_").replace("<", "_").replace(
                "&", "_").replace("\\", "_")
            nodeEnvValue = lib_util.NodeLiteral(envValClean)
            grph.add((nodeEnvNam, pc.property_rdf_data_nolist2, nodeEnvValue))
        grph.add((node_process, envProp, nodeEnvNam))

    # cgiEnv.OutCgiRdf("LAYOUT_RECT", [pc.property_directory,envProp])
    cgiEnv.OutCgiRdf("LAYOUT_RECT", [envProp])
Ejemplo n.º 2
0
def FunctionProcess(mapToProc, proc):
    # The process might have left in the meantime.
    pid = proc.pid

    if lib_common.is_useless_process(proc):
        return

    try:
        all_maps = CIM_Process.PsutilProcMemmaps(proc)
    except:
        exc = sys.exc_info()[1]
        WARNING("get_memory_maps Pid=%d. Caught %s", pid, str(exc))
        return

    # This takes into account only maps accessed by several processes.
    # TODO: What about files on a shared drive?
    # To make things simple, for the moment mapped memory is processed like files.

    # sys.stderr.write("NbMaps=%d\n" % len(all_maps) )

    for map in all_maps:
        cleanPath = GoodMap(map.path)
        if cleanPath == "":
            continue

        # sys.stderr.write( "Adding cleanPath=%s\n" % cleanPath )
        try:
            theList = mapToProc[cleanPath]
            theList.append(pid)
        except KeyError:
            mapToProc[cleanPath] = [pid]
Ejemplo n.º 3
0
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:
            logging.warning("Circular pids tree:%d", the_pid)
            return
        pids_seen_set.add(the_pid)

        # Strange, but apparently it can happen.
        the_ppid = proc_obj.ppid()
        if the_ppid == 0:
            return

        node_process = lib_uris.gUriGen.PidUri(the_pid)
        node_pprocess = lib_uris.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 = psutil.Process(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
Ejemplo n.º 4
0
def Main():
    cgiEnv = lib_common.ScriptEnvironment()
    pid = int(cgiEnv.GetId())

    grph = cgiEnv.GetGraph()

    proc_obj = CIM_Process.PsutilGetProcObj(pid)

    node_process = lib_uris.gUriGen.PidUri(pid)

    try:
        all_maps = proc_obj.memory_maps()
    except Exception as exc:
        lib_common.ErrorMessageHtml("get_memory_maps Pid=%d. Caught %s\n" % (pid, str(exc)))

    propMemoryRSS = lib_common.MakeProp("Resident Set Size")
    for map_obj in all_maps:
        # This, because all Windows paths are "standardized" by us.
        # TODO: clean_map_path = lib_util.standardized_file_path(map_obj.path)
        clean_map_path = map_obj.path.replace("\\", "/")

        uri_mem_map = lib_uris.gUriGen.MemMapUri(clean_map_path)

        grph.add((uri_mem_map, propMemoryRSS, rdflib.Literal(map_obj.rss)))
        grph.add((node_process, pc.property_memmap, uri_mem_map))

    cgiEnv.OutCgiRdf( "LAYOUT_SPLINE")
Ejemplo n.º 5
0
def Main():
    cgiEnv = lib_common.ScriptEnvironment()
    user_name_with_host = cgiEnv.GetId()

    # Usernames have the syntax user@host
    # Example: [email protected]
    user_split = user_name_with_host.split('@')
    user_name = user_split[0]

    # TODO: Should factorize this code.
    if len(user_split) > 1:
        user_host = user_split[1]
        if user_host != lib_util.currentHostname:
            # TODO: Should interrogate other host with "finger" protocol.
            lib_common.ErrorMessageHtml("Cannot get user properties on different host:" + user_host)

    grph = cgiEnv.GetGraph()

    # It will be possible to transform this into a Json tree by
    # selecting only the RDF predicate property_ppid.
    # This will be done in a gui cgi script which takes as input
    # parameter a CGI script, visible by SLP, stored in a bookmark page
    # or anything else.

    # See http://stackoverflow.com/questions/17967686/retrieving-specific-rdf-graph-triples-based-on-predicate-nodes
    # on how to select triples on a given predicate only.

    # But in the general case, we cannot know if the RDF graph will be a tree,
    # something similar to a CSV file (That is, flat) or a general graph.

    # So we might have to process the resulting graph on the fly, to see
    # which visualising methods are applicable.

    # Also, in the case of a tree, we must find ourselves what is its root.

    for proc in psutil.process_iter():
        proc_username = CIM_Process.PsutilProcToUser(proc)

        # proc_username=EURO\\UK936025 user_name=UK936025
        # proc_username=NT AUTHORITY\\NETWORK SERVICE
        # proc_username=NT AUTHORITY\\SYSTEM
        # proc_username=EURO\\UK936025
        # proc_username=NT AUTHORITY\\SYSTEM
        if proc_username != user_name:
            continue

        pid = proc.pid
        parent_pid = proc.ppid()

        # Built the same way in other RDF documents.
        node_process = lib_uris.gUriGen.PidUri(pid)
        parent_node_process = lib_uris.gUriGen.PidUri(parent_pid)

        # We avoid duplicating the edges. Why would the RFD merge do?
        grph.add((node_process, pc.property_ppid, parent_node_process))
        grph.add((node_process, pc.property_pid, lib_util.NodeLiteral(pid)))
        # grph.add((node_process, pc.property_information, lib_util.NodeLiteral(proc_username)))

    cgiEnv.OutCgiRdf()
Ejemplo n.º 6
0
def Main():
    cgiEnv = lib_common.ScriptEnvironment()

    grph = cgiEnv.GetGraph()

    try:
        procid = int(cgiEnv.GetId())
    except Exception:
        lib_common.ErrorMessageHtml("Must provide a pid")

    obj_proc = CIM_Process.PsutilGetProcObj(procid)

    node_process = lib_uris.gUriGen.PidUri(procid)

    CIM_Process.add_command_line_arguments(grph, node_process, obj_proc)

    cgiEnv.OutCgiRdf("LAYOUT_RECT")
Ejemplo n.º 7
0
def Usable(entity_type, entity_ids_arr):
    """Python and Linux processes"""
    is_linux = lib_util.UsableLinux(entity_type, entity_ids_arr)
    if not is_linux:
        return False

    # This tells if it is a Python process.
    return CIM_Process.Usable(entity_type, entity_ids_arr)
Ejemplo n.º 8
0
def Main():
    cgiEnv = lib_common.CgiEnv()
    pidProc = int(cgiEnv.GetId())

    grph = cgiEnv.GetGraph()

    node_process = lib_common.gUriGen.PidUri(pidProc)
    proc_obj = CIM_Process.PsutilGetProcObj(pidProc)

    # Python 2
    # cmd_arr=['C:\\Python27\\python.exe', 'test_survol_client_library.py', '--debug', 'SurvolLocalTest.test_msdos_current_batch']
    # Python 3
    # cmd_arr=['C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python36_64\\python.exe', 'test_survol_client_library.py', '--debug', 'SurvolLocalTest.test_msdos_current_batch']
    argvArray = CIM_Process.PsutilProcToCmdlineArray(proc_obj)
    DEBUG("argvArray=%s", str(argvArray))

    # This extracts the command file name and creates a node for it.
    for theArg in argvArray[1:]:
        if theArg[0] == "/":
            continue

        # Check if the file exists in the current directory.
        currPwd, errMsg = CIM_Process.PsutilProcCwd(proc_obj)
        if not currPwd:
            break

        allDirsToSearch = [currPwd]

        envPath = CIM_Process.GetEnvVarProcess("PATH", proc_obj.pid)
        if envPath:
            allDirsToSearch += envPath.split(";")

        # Now tries all possible dirs, starting with current directory.
        for aDir in allDirsToSearch:
            fullScriptPath = os.path.join(aDir, theArg)
            DEBUG("fullScriptPath=%s", fullScriptPath)
            if os.path.isfile(fullScriptPath):
                DEBUG("fullScriptPath=%s", fullScriptPath)
                scriptNode = lib_common.gUriGen.FileUri(fullScriptPath)
                grph.add((node_process, pc.property_runs, scriptNode))
                break

        break

    cgiEnv.OutCgiRdf()
Ejemplo n.º 9
0
def Usable(entity_type, entity_ids_arr):
    """Python processes"""

    pidProc = entity_ids_arr[0]
    try:
        # Any error, no display.
        proc_obj = CIM_Process.PsutilGetProcObjNoThrow(int(pidProc))
    except:
        return False

    cmd_line = CIM_Process.PsutilProcToCmdline(proc_obj)

    cmdlinSplit = cmd_line.split(" ")
    execNam = cmdlinSplit[0]
    basNam = os.path.basename(execNam)

    # This is a python process because of the executable.
    return basNam.startswith("python")
Ejemplo n.º 10
0
def MakeProcDictWindows():
    procDict = dict()

    for proc in psutil.process_iter():
        procName = CIM_Process.PsutilProcToName(proc)
        # procName = proc.name

        # OK pour le process creer par httpd, sous Windows.
        # C:\Python\3.2.3-0.3\pythonw.exe -u D:/Projects/Divers/Reverse/PythonStyle/survol/task_control.py
        #if procName != "pythonw.exe":
        #	continue

        # Might be different depending on the Python interpreter.
        if procName != "python.exe":
            continue

        # With a real subtask:
        # python.exe	18980	24656	C:\Python\3.2.3-0.3\python.exe	C:\Python\3.2.3-0.3\python.exe -c from multiprocessing.forking import main; main() --multiprocessing-fork 788
        # python.exe	24656	14680	C:\Python\3.2.3-0.3\python.exe	python D:/Projects/Divers/Reverse/PythonStyle/survol/sources_top/psutil_processes_perf.py run

        procCmd = CIM_Process.PsutilProcToCmdline(proc)

        pid = proc.pid
        parent_pid = CIM_Process.PsutilProcToPPid(proc)

        # This differentiates between the feeder and the sub-server.
        # This test but get better, but it is OK for the moment.
        mtch_task = re.match(".*/survol/(.*) run", procCmd)
        if mtch_task:
            subDct = {'parentPid': parent_pid, 'script': mtch_task.group(1)}
            try:
                procDict[pid].update(subDct.items())
            except KeyError:
                procDict[pid] = subDct
            continue

        if re.match(".*multiprocessing.forking.*", procCmd):
            subDct = {'subPid': pid, 'subScript': procCmd}
            try:
                procDict[parent_pid].update(subDct.items())
            except KeyError:
                procDict[parent_pid] = subDct
            continue
    return procDict
Ejemplo n.º 11
0
def Main():
    cgiEnv = lib_common.ScriptEnvironment()
    pid_proc = int(cgiEnv.GetId())

    grph = cgiEnv.GetGraph()

    node_process = lib_uris.gUriGen.PidUri(pid_proc)
    proc_obj = CIM_Process.PsutilGetProcObj(int(pid_proc))

    # Now we are parsing the command line.
    argv_array = CIM_Process.PsutilProcToCmdlineArray(proc_obj)

    logging.debug("argv_array=%s", str(argv_array))

    # The difficulty is that filenames with spaces are split.
    # Therefore, entire filenames must be rebuilt from pieces.
    _add_nodes_from_command_line(argv_array, grph, node_process, proc_obj)

    cgiEnv.OutCgiRdf()
Ejemplo n.º 12
0
    def GetMemMaps(pidint):
        # TODO: Replace this by scanning /proc/<pid>/mmaps
        p = CIM_Process.PsutilGetProcObj(pidint)

        # Depending on psutil version.
        try:
            return p.get_memory_maps(grouped=False)
        except AttributeError:
            # New version.
            return p.memory_maps(grouped=False)
Ejemplo n.º 13
0
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")
Ejemplo n.º 14
0
def Main():
    cgiEnv = lib_common.CgiEnv()
    pidInt = int( cgiEnv.GetId() )

    grph = cgiEnv.GetGraph()

    node_process = lib_common.gUriGen.PidUri(pidInt)
    proc_obj = CIM_Process.PsutilGetProcObj(pidInt)

    cgiEnv.OutCgiRdf()
Ejemplo n.º 15
0
def MakeProcDictLinux():
    procDict = dict()

    for proc in psutil.process_iter():

        procName = proc.name

        # BEWARE: It depends on the interpreter.
        if procName != "python":
            continue

        # With a real subtask:
        # apache    8423     1  0 12:36 ?        00:00:00 python /home/rchateau/public_html/RevPython/survol/sources_top/tcpdump.py run
        # apache    8426  8423  0 12:36 ?        00:00:00 python /home/rchateau/public_html/RevPython/survol/sources_top/tcpdump.py run

        procCmd = CIM_Process.PsutilProcToCmdline(proc)

        pid = proc.pid
        parent_pid = CIM_Process.PsutilProcToPPid(proc)

        # This differentiates between the feeder and the sub-server.
        # This test but get better, but it is OK for the moment.
        mtch_task = re.match(".*/survol/(.*) run", procCmd)
        if mtch_task:
            if parent_pid == 1:
                subDct = {
                    'parentPid': parent_pid,
                    'script': mtch_task.group(1)
                }
                try:
                    procDict[pid].update(subDct.items())
                except KeyError:
                    procDict[pid] = subDct
            else:
                subDct = {'subPid': pid, 'subScript': procCmd}
                try:
                    procDict[parent_pid].update(subDct.items())
                except KeyError:
                    procDict[parent_pid] = subDct
            continue
    return procDict
Ejemplo n.º 16
0
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()
Ejemplo n.º 17
0
def Main():
    cgiEnv = lib_common.CgiEnv()

    grph = cgiEnv.GetGraph()

    # Not really useful.
    grph.add((lib_common.nodeMachine, pc.property_hostname,
              lib_common.NodeLiteral(lib_util.currentHostname)))

    mapToProc = {}

    for proc in CIM_Process.ProcessIter():

        # TODO: Instead, should test psutil version !!!
        try:
            FunctionProcess(mapToProc, proc)
        except CIM_Process.AccessDenied:
            pass
        except Exception:
            lib_common.ErrorMessageHtml("Unexpected error:" +
                                        str(sys.exc_info()[0]))
    # sys.stderr.write( "Leaving processes enumeration\n" )

    addedProcs = {}

    # Now display only memory maps with more than one process linked to it.
    for mapPath, procLst in lib_util.six_iteritems(mapToProc):
        if len(procLst) <= 0:
            continue

        uriMemMap = lib_common.gUriGen.MemMapUri(mapPath)

        for pid in procLst:
            try:
                nodeProcess = addedProcs[pid]
            except KeyError:
                nodeProcess = lib_common.gUriGen.PidUri(pid)
                addedProcs[pid] = nodeProcess

            grph.add((nodeProcess, pc.property_memmap, uriMemMap))
    # sys.stderr.write( "Leaving second maps enumeration\n" )

    # TODO: They could also be displayed based on the hierarchy of their
    # associated file in the directory tree.

    for pid, nodeProcess in lib_util.six_iteritems(addedProcs):
        grph.add((nodeProcess, pc.property_pid, lib_common.NodeLiteral(pid)))

    # TODO: Petit bug: Ca duplique les memmap. Forcement, l'affichage en tables
    # suppose que c'est un arbre. Mais c'est plus rapide et plus clair.
    # cgiEnv.OutCgiRdf("",[pc.property_memmap])
    cgiEnv.OutCgiRdf("LAYOUT_SPLINE")
Ejemplo n.º 18
0
def Main():
    cgiEnv = lib_common.CgiEnv()
    pidProc = int(cgiEnv.GetId())

    grph = cgiEnv.GetGraph()

    node_process = lib_common.gUriGen.PidUri(pidProc)
    proc_obj = CIM_Process.PsutilGetProcObj(int(pidProc))

    # Now we are parsing the command line.
    cmd_line = CIM_Process.PsutilProcToCmdline(proc_obj)

    sys.stderr.write("cmd_line=%s\n" % str(cmd_line))

    # Similar to split, but ignores white spaces in double quotes.
    argvArray = re.findall(r'(?:[^\s "]|"(?:\\.|[^"])*")+', cmd_line)

    sys.stderr.write("argvArray=%s\n" % str(argvArray))

    argvArgs = " ".join(argvArray[1:])

    sys.stderr.write("argvArgs=%s\n" % argvArgs)

    opts, otherArgs = getopt.getopt(argvArgs, "Bc:dEhim:ORQ:sStuvVW:x3")

    ignoreEnvs = False
    for opt, arg in opts:
        if opt == '-E':
            ignoreEnvs = True

    if otherArgs:
        filNam = otherArgs
        filNode = PyFilNode(proc_obj, filNam, ignoreEnvs)
        if filNode:
            grph.add((node_process, pc.property_runs, filNode))

        sys.stderr.write("filNam=%s\n" % filNam)

    cgiEnv.OutCgiRdf()
Ejemplo n.º 19
0
def Main():
    cgiEnv = lib_common.ScriptEnvironment()
    pid_proc = int(cgiEnv.GetId())

    grph = cgiEnv.GetGraph()

    node_process = lib_uris.gUriGen.PidUri(pid_proc)
    proc_obj = CIM_Process.PsutilGetProcObj(pid_proc)

    argv_array = CIM_Process.PsutilProcToCmdlineArray(proc_obj)
    logging.debug("argv_array=%s", str(argv_array))

    # This extracts the command file name and creates a node for it.
    for the_arg in argv_array[1:]:
        if the_arg[0] == "/":
            continue

        # Check if the file exists in the current directory.
        curr_pwd, err_msg = CIM_Process.PsutilProcCwd(proc_obj)
        if not curr_pwd:
            break

        all_dirs_to_search = [curr_pwd]

        env_path = CIM_Process.GetEnvVarProcess("PATH", proc_obj.pid)
        if env_path:
            all_dirs_to_search += env_path.split(";")

        # Now tries all possible dirs, starting with current directory.
        for a_dir in all_dirs_to_search:
            full_script_path = os.path.join(a_dir, the_arg)
            logging.debug("full_script_path=%s", full_script_path)
            if os.path.isfile(full_script_path):
                script_node = lib_uris.gUriGen.FileUri(full_script_path)
                grph.add((node_process, pc.property_runs, script_node))
                break

        break
    cgiEnv.OutCgiRdf()
Ejemplo n.º 20
0
def Main():
    cgiEnv = lib_common.ScriptEnvironment()

    grph = cgiEnv.GetGraph()

    try:
        procid = int(cgiEnv.GetId())
    except Exception:
        lib_common.ErrorMessageHtml("Must provide a pid")

    obj_proc = CIM_Process.PsutilGetProcObj(procid)

    env_prop = lib_common.MakeProp("environment")

    try:
        envs_dict = obj_proc.environ()
    except Exception as exc:
        lib_common.ErrorMessageHtml("Caught:%s" % exc)

    node_process = lib_uris.gUriGen.PidUri(procid)

    for env_key in envs_dict :
        env_val = envs_dict[env_key]
        logging.debug("env_key=%s env_val=%s", env_key, env_val)
        node_env_nam = lib_util.NodeLiteral(env_key)

        # When a file or a directory displayed with a node,
        # its name is shortened so it can fit into the table.,
        # so it is less visible.

        # Some are probably for Windows only.
        if env_key in ["PATH", "PSMODULEPATH", "PYPATH"]:
            val_split = env_val.split(os.pathsep)
            nod_fil_arr = [lib_uris.gUriGen.DirectoryUri(fil_nam) for fil_nam in val_split]
            nod_fil_arr_nod = lib_util.NodeLiteral(nod_fil_arr)
            grph.add((node_env_nam, pc.property_rdf_data_nolist2, nod_fil_arr_nod))
        elif os.path.isdir(env_val):
            nod_fil = lib_uris.gUriGen.DirectoryUri(env_val)
            grph.add((node_env_nam, pc.property_rdf_data_nolist2, nod_fil))
        elif os.path.exists(env_val):
            nod_fil = lib_uris.gUriGen.FileUri(env_val)
            grph.add((node_env_nam, pc.property_rdf_data_nolist2, nod_fil))
        else:
            # TODO: Beware that "\L" is transformed into "<TABLE>" by Graphviz !!!
            env_val_clean = env_val.replace(">", "_").replace("<", "_").replace("&", "_").replace("\\", "_")
            node_env_value = lib_util.NodeLiteral(env_val_clean)
            grph.add((node_env_nam, pc.property_rdf_data_nolist2, node_env_value))
        grph.add((node_process, env_prop, node_env_nam))

    cgiEnv.OutCgiRdf("LAYOUT_RECT", [env_prop])
Ejemplo n.º 21
0
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()
Ejemplo n.º 22
0
def Main():

    cgiEnv = lib_common.CgiEnv()
    hostname = cgiEnv.GetId()

    cgiEnv = lib_common.CgiEnv()

    grph = cgiEnv.GetGraph()

    hostAddr = lib_util.GlobalGetHostByName(hostname)

    hostNode = lib_common.gUriGen.HostnameUri(hostname)

    for proc in CIM_Process.ProcessIter():
        pid = proc.pid

    cgiEnv.OutCgiRdf()
Ejemplo n.º 23
0
def Main():
    cgiEnv = lib_common.CgiEnv()
    try:
        root_pid = int(cgiEnv.GetId())
    except KeyError:
        lib_common.ErrorMessageHtml("Process id should be provided")

    grph = cgiEnv.GetGraph()

    proc_obj = CIM_Process.PsutilGetProcObj(root_pid)

    # Sub-processes, recursion.
    tree_subprocesses(grph, proc_obj)

    # Now display the parent processes.
    # It could be done in a loop instead of recursive calls.
    tree_parent_process(grph, proc_obj, set())

    # This layout style, because the nodes are quite big.
    cgiEnv.OutCgiRdf("LAYOUT_RECT")
Ejemplo n.º 24
0
def DoAll(lstStructs, verbose=True):
    print("Starting")
    if len(sys.argv) > 1:
        maxDisplay = int(sys.argv[2])
    else:
        maxDisplay = 10

    # python -m cProfile mmapregex.py
    if len(sys.argv) > 2:
        pidint = int(sys.argv[1])
        ProcessMemoryScan(pidint, lstStructs, maxDisplay, verbose)
    else:
        for i in CIM_Process.ProcessIter():
            print("Pid=%d name=%s" % (i.pid, i.name()))
            try:
                ProcessMemoryScan(i.pid, lstStructs, maxDisplay, verbose)
                print("")
            except Exception:
                t, e = sys.exc_info()[:2]
                print("    Caught:" + str(e).replace("\n", " "))
                print("")
Ejemplo n.º 25
0
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()
Ejemplo n.º 26
0
def Main():
    paramkey_show_unconnected = "Show unconnected sockets"

    # TODO: At the moment, only uses false default values for boolean parameters,
    # TODO: because CGI and the CGI lib do not send empty strings.
    cgiEnv = lib_common.ScriptEnvironment(
        parameters={paramkey_show_unconnected: False})

    flag_show_unconnected = bool(
        cgiEnv.get_parameters(paramkey_show_unconnected))

    grph = cgiEnv.GetGraph()

    for proc in psutil.process_iter():
        try:
            pid = proc.pid

            # TCP sockets only.
            all_connect = CIM_Process.PsutilProcConnections(proc)
            if all_connect:
                node_process = lib_uris.gUriGen.PidUri(pid)

                # Not sure this is the best plmace to add this edge.
                grph.add(
                    (node_process, pc.property_host, lib_common.nodeMachine))
                grph.add(
                    (node_process, pc.property_pid, lib_util.NodeLiteral(pid)))

                # TODO: MAYBE CREATES ALL THE PROCESSES AND RUN THE THREADS ON THE COMPLETE LIST ???
                survol_addr.PsutilAddSocketToGraphAsync(
                    node_process, all_connect, grph, flag_show_unconnected)

        except Exception as exc:
            # This is for psutil.AccessDenied and psutil.NoSuchProcess but we do not want to import the module
            exc_str = str(exc)
            if (exc_str.find("AccessDenied") <
                    0) and (exc_str.find("NoSuchProcess") < 0):
                lib_common.ErrorMessageHtml("Caught:" + exc_str)

    cgiEnv.OutCgiRdf("LAYOUT_SPLINE")
Ejemplo n.º 27
0
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")
Ejemplo n.º 28
0
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])
Ejemplo n.º 29
0
def Main():
    cgiEnv = lib_common.CgiEnv()

    # userNameWithHost = cgiEnv.GetId()
    # Usernames have the syntax user@host
    # Example: [email protected]
    # userSplit = userNameWithHost.split('@')
    # userName = userSplit[0]

    userName = cgiEnv.m_entity_id_dict["Name"]

    try:
        # Exception if local machine.
        userHost = cgiEnv.m_entity_id_dict["Domain"]
    except KeyError:
        userHost = lib_util.currentHostname

    if userHost:
        # if userHost != lib_util.currentHostname:
        if not lib_util.IsLocalAddress(userHost):
            # TODO: Should interrogate other host with "finger" protocol.
            # Cannot get user properties on different host:rchateau-HP than rchateau-HP.home
            lib_common.ErrorMessageHtml(
                "Cannot get user properties on different host:%s than %s" %
                (userHost, lib_util.currentHostname))

    grph = cgiEnv.GetGraph()

    # It will be possible to transform this into a Json tree by
    # selecting only the RDF predicate property_ppid.
    # This will be done in a gui cgi script which takes as input
    # parameter a CGI script, visible by SLP, stored in a bookmark page
    # or anything else.

    # See http://stackoverflow.com/questions/17967686/retrieving-specific-rdf-graph-triples-based-on-predicate-nodes
    # on how to select triples on a given predicate only.

    # But in the general case, we cannot know if the RDF graph will be a tree,
    # something similar to a CSV file (That is, flat) or a general graph.

    # So we might have to process the resulting graph on the fly, to see
    # which visualising methods are applicable.

    # Also, in the case of a tree, we must find ourselves what is its root.

    for proc in CIM_Process.ProcessIter():

        procUsername = CIM_Process.PsutilProcToUser(proc)

        # sys.stderr.write("procUsername=%s userName=%s\n" % ( procUsername, userName ) )
        # procUsername=EURO\\UK936025 userName=UK936025
        # procUsername=NT AUTHORITY\\NETWORK SERVICE
        # procUsername=NT AUTHORITY\\SYSTEM
        # procUsername=EURO\\UK936025
        # procUsername=NT AUTHORITY\\SYSTEM
        if procUsername != userName:
            # On Windows, second chance with only the second part of the user.
            try:
                userShort = procUsername.split('\\')[1]
            except IndexError:
                userShort = procUsername
            if userShort != userName:
                continue

        if lib_common.is_useless_process(proc):
            continue

        procName = proc.name

        pid = proc.pid
        parent_pid = CIM_Process.PsutilProcToPPid(proc)

        # Built the same way in other RDF documents.
        node_process = lib_common.gUriGen.PidUri(pid)
        parent_node_process = lib_common.gUriGen.PidUri(parent_pid)

        # We avoid duplicating the edges. Why would the RFD merge do?
        grph.add((node_process, pc.property_ppid, parent_node_process))
        grph.add((node_process, pc.property_pid, lib_common.NodeLiteral(pid)))
        # grph.add( ( node_process, pc.property_information, lib_common.NodeLiteral(procUsername) ) )

    # We avoid duplicating the edges. Why would the RFD merge do?
    ############ grph.add( ( node_process, pc.property_ppid, parent_node_process ) )

    cgiEnv.OutCgiRdf()
Ejemplo n.º 30
0
def Main():
    paramkeyShowSharedLib = "Show shared libraries"
    paramkeyShowFontFiles = "Show font files"
    paramkeyShowNonShared = "Show non shared files"

    # TODO: At the moment, only uses false default values for boolean parameters,
    # TODO: because CGI and the CGI lib do not send empty strings.
    cgiEnv = lib_common.CgiEnv(
        parameters={
            paramkeyShowSharedLib: False,
            paramkeyShowFontFiles: False,
            paramkeyShowNonShared: False
        })

    flagShowSharedLib = bool(cgiEnv.GetParameters(paramkeyShowSharedLib))
    flagShowFontFiles = bool(cgiEnv.GetParameters(paramkeyShowFontFiles))
    flagShowNonShared = bool(cgiEnv.GetParameters(paramkeyShowNonShared))

    grph = cgiEnv.GetGraph()

    ################################################################################

    Main.dictPathToNod = {}

    AddPidFileLink.dictFiles = {}

    # Maybe this is done in another CGI. What happens when merging ?
    grph.add((lib_common.nodeMachine, pc.property_hostname,
              lib_common.NodeLiteral(lib_util.currentHostname)))

    # https://code.google.com/p/psutil/issues/detail?id=340
    # This might hang.

    for proc in CIM_Process.ProcessIter():
        try:
            if lib_common.UselessProc(proc):
                continue

            pid = proc.pid

            node_process = None

            # http://code.google.com/p/psutil/issues/detail?id=340
            # https://github.com/giampaolo/psutil/issues/340
            for fil in CIM_Process.PsutilProcOpenFiles(proc):

                # Some files are not interesting even if accessed by many processes.
                if lib_common.MeaninglessFile(fil.path, not flagShowSharedLib,
                                              not flagShowFontFiles):
                    continue

                # Adds the process node only if it has at least one open file.
                if node_process == None:
                    node_process = lib_common.gUriGen.PidUri(pid)
                    grph.add((node_process, pc.property_pid,
                              lib_common.NodeLiteral(pid)))

                # TODO: What about files on a shared drive?
                if flagShowNonShared:
                    fileNode = PathToNod(fil.path)
                    grph.add((node_process, pc.property_open_file, fileNode))
                else:
                    # This takes into account only files accessed by several processes.
                    AddPidFileLink(grph, node_process, fil.path)

        # except psutil.AccessDenied:
        #	pass
        except:
            exc = sys.exc_info()[1]
            sys.stderr.write("Exception:%s\n" % str(exc))
            pass

    cgiEnv.OutCgiRdf("LAYOUT_SPLINE")