def IconToFile(hlib, group_name): """The group might be a string or an integer and its type must be kept.""" # patch FindResourceW, ctypes.windll.kernel32.SizeofResource FindResourceW = ctypes.windll.kernel32.FindResourceW FindResourceW.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p ] FindResourceW.restype = ctypes.c_void_p SizeofResource = ctypes.windll.kernel32.SizeofResource SizeofResource.argtypes = [ctypes.c_void_p, ctypes.c_void_p] SizeofResource.restype = ctypes.c_size_t hRes = win32api.LoadResource(hlib, win32con.RT_GROUP_ICON, group_name) mem_icon_dir = ctypes.windll.kernel32.LockResource(hRes) # 32 bits color; 16 and 256 colors are too old icon_size = 256 icon_name = ctypes.windll.user32.LookupIconIdFromDirectoryEx( mem_icon_dir, True, icon_size, icon_size, 0x00000000) h_res_info = FindResourceW(hlib, icon_name, win32con.RT_ICON) size = ctypes.windll.kernel32.SizeofResource(hlib, h_res_info) rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name) mem_icon = ctypes.windll.kernel32.LockResource(rec) # And this is some differ (copy data to Python buffer) binary_data = (ctypes.c_ubyte * size)() ctypes.memmove(binary_data, mem_icon, size) h_icon_ret = ctypes.windll.user32.CreateIconFromResourceEx( binary_data, size, True, 0x00030000, 0, 0, 0x00000000) info = win32gui.GetIconInfo(h_icon_ret) bminfo = win32gui.GetObject(info[4]) # generate bitmap by drawing the icon hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) hbmp = win32ui.CreateBitmap() hbmp.CreateCompatibleBitmap(hdc, bminfo.bmWidth, bminfo.bmHeight) hcdc = hdc.CreateCompatibleDC() hcdc.SelectObject(hbmp) win32gui.DrawIconEx(hcdc.GetHandleOutput(), 0, 0, h_icon_ret, bminfo.bmWidth, bminfo.bmHeight, 0, 0, 0x0003) # MIME type is "image/bmp" # The group name might be a number: 110 etc... or a string such as 'ICO_MYCOMPUTER'. # This is the prefix of the temporary BMP file name containing the extracted icon. img_fil_nam_prefix = "icon-%03dx%03d-%s-%03d" % ( bminfo.bmWidth, bminfo.bmHeight, str(group_name), icon_name) # The destructor will remove the file. obj_temp_file = lib_util.TmpFile(img_fil_nam_prefix, "bmp") img_fil_nam = obj_temp_file.Name hbmp.SaveBitmapFile(hcdc, img_fil_nam) win32gui.DestroyIcon(h_icon_ret) return obj_temp_file
def output_rdf_graph_as_svg( page_title, error_msg, parameters, grph, parameterized_links, top_url, layout_style, collapsed_properties, commutative_properties): """ This transforms a RDF triplestore into a temporary DOT file, which is transformed by GraphViz into a SVG file sent to the HTTP browser. """ tmp_log_fil = lib_util.TmpFile("survol_graph_to_svg", "log") try: logfil = open(tmp_log_fil.Name, "w") except Exception as exc: logging.error("_graph_to_svg caught %s when opening:%s", str(exc), tmp_log_fil.Name) raise Exception("_graph_to_svg caught %s when opening:%s\n" % (str(exc), tmp_log_fil.Name)) logfil.write("Starting logging\n") tmp_dot_fil = lib_util.TmpFile("survol_graph_to_svg", "dot") dot_filnam_after = tmp_dot_fil.Name rdfoutfil = open(dot_filnam_after, "w") logfil.write(lib_util.TimeStamp() + " Created " + dot_filnam_after + "\n") dot_layout = write_dot_header(page_title, layout_style, rdfoutfil, grph) _write_dot_legend(page_title, top_url, error_msg, parameters, parameterized_links, rdfoutfil, grph) logfil.write(lib_util.TimeStamp() + " Legend written\n") _rdf_graph_to_dot_stream(grph, logfil, rdfoutfil, collapsed_properties, commutative_properties) logfil.write(lib_util.TimeStamp() + " About to close dot file\n") # BEWARE: Do this because the file is about to be reopened from another process. rdfoutfil.flush() os.fsync(rdfoutfil.fileno()) rdfoutfil.close() out_dest = lib_util.get_default_output_destination() logfil.flush() _dot_to_svg(dot_filnam_after, logfil, dot_layout, out_dest) logfil.flush() logfil.write(lib_util.TimeStamp() + " closing log file\n") logfil.close()
def Main(): paramkey_max_depth = "Maximum depth" paramkey_disp_packages = "Display packages" paramkey_disp_files = "Display files" cgiEnv = lib_common.ScriptEnvironment( {paramkey_max_depth: 1, paramkey_disp_packages: True, paramkey_disp_files: False}) package_nam = cgiEnv.GetId() max_depth = cgiEnv.get_parameters(paramkey_max_depth) disp_packages= cgiEnv.get_parameters(paramkey_disp_packages) disp_files = cgiEnv.get_parameters(paramkey_disp_files) package_node = survol_python_package.MakeUri(package_nam) logging.debug("package_nam=%s", package_nam) grph = cgiEnv.GetGraph() tmp_py_fil = lib_util.TmpFile("py_package_deps", "py") tmp_py_fil_name = tmp_py_fil.Name # This creates a temporary file which imports the package. tmp_fd = open(tmp_py_fil_name, "w") tmp_fd.write("import %s\n" % package_nam) tmp_fd.close() survol_python_package.AddImportedModules(grph, package_node, tmp_py_fil_name, max_depth, disp_packages, disp_files) try: the_module = importlib.import_module(package_nam) except Exception as exc: lib_common.ErrorMessageHtml("Package:%s Unexpected error:%s" % (package_nam, str(exc))) try: init_fil_nam = the_module.__file__ fil_node = lib_uris.gUriGen.FileUri(init_fil_nam) grph.add((package_node, survol_python_package.prop_python_package, fil_node)) try: survol_python.AddAssociatedFiles(grph,fil_node, init_fil_nam) except Exception as exc: lib_common.ErrorMessageHtml("File:%s Unexpected error:%s" % (init_fil_nam, str(exc))) except AttributeError: pass cgiEnv.OutCgiRdf("LAYOUT_SPLINE")
def _dot_to_svg(dot_filnam_after, logfil, viztype, out_dest): tmp_svg_fil = lib_util.TmpFile("survol_graph_to_svg", "svg") svg_out_filnam = tmp_svg_fil.Name # dot -Kneato # Dot/Graphviz no longer changes PATH at installation. It must be done BEFORE. dot_path = "dot" if lib_util.isPlatformLinux: # TODO: This is arbitrary because old Graphviz version. # TODO: Take the fonts from html_exports.css dot_fonts = [ # "-Gfontpath=/usr/share/fonts/dejavu", "-Gfontpath=/usr/share/fonts", "-Gfontnames=svg", "-Nfontname=DejaVuSans.ttf", "-Efontname=DejaVuSans.ttf"] else: dot_fonts = [] # Old versions of dot need the layout on the command line. # This is maybe a bit faster than os.open because no shell and direct write to the output. svg_command = [dot_path, "-K", viztype, "-Tsvg", dot_filnam_after, "-o", svg_out_filnam, "-v", "-Goverlap=false"] + dot_fonts str_command = " ".join(svg_command) logfil.write(TimeStamp() + " svg_command=" + str_command + "\n") try: ret = subprocess.call(svg_command, stdout=logfil, stderr=logfil, shell=False) except Exception as exc: raise Exception("ERROR:%s raised:%s" % (str_command, str(exc))) logfil.write(TimeStamp()+" Process ret=%d\n" % ret) if not os.path.isfile(svg_out_filnam): raise Exception("SVG file " + svg_out_filnam + " could not be created.") # TODO: If there is an error, we should write it as an HTML page. # On the other hand it is impossible to pipe the output because it would assume a SVG document. # https://stackoverflow.com/questions/5667576/can-i-set-the-html-title-of-a-pdf-file-served-by-my-apache-web-server dict_http_properties = [("Content-Disposition", 'inline; filename="Survol_Download"')] logfil.write(lib_util.TimeStamp() + " Writing SVG header\n") lib_util.WrtHeader("image/svg+xml", dict_http_properties) # Here, we are sure that the output file is closed. copy_to_output_destination(logfil, svg_out_filnam, out_dest)
def RunGdbCommand(the_pid, command): tmpGdb = lib_util.TmpFile("gdbstack", "gdb") gdbFilNam = tmpGdb.Name gdbFil = open(gdbFilNam, "w") gdbFil.write(command + "\n") gdbFil.write("quit\n") gdbFil.close() # TODO: See python/__init__.py which also runs a gdb command. gdb_cmd = ["gdb", "-q", "-p", str(the_pid), "-x", gdbFilNam] logging.debug("gdb command=%s", " ".join(gdb_cmd)) try: gdb_pipe = lib_common.SubProcPOpen(gdb_cmd) #except FileNotFoundError: # lib_common.ErrorMessageHtml("gdb is not available") except Exception as exc: lib_common.ErrorMessageHtml("Gdb:" + str(exc)) # TODO: How can we get the stderr message: "ptrace: Operation not permitted." which comes after "Attaching to process 6063" ???? gdb_last_output, gdb_err = gdb_pipe.communicate() resu = [] # Removes the heading information and the lines beginning with a prompt. # [jsmith@DuoLnx BY_process]$ gdb -q -p 6513 -x stack.gdb # Attaching to process 6513 # Reading symbols from /usr/bin/kdeinit...(no debugging symbols found)...done. for lin in gdb_last_output.split(b'\n'): if lib_util.is_py3: # This return a bytes. lin = lin.decode("utf-8") logging.debug("rungdb:%s", lin) # Not sure the prompt is displayed when in non-interactive mode. if lin.startswith("(gdb)"): continue if lin.startswith("Reading symbols "): continue if lin.startswith("Loaded symbols "): continue resu.append(lin) if len(gdb_err) != 0: logging.debug("Err:%s", gdb_err) lib_common.ErrorMessageHtml("No gdb output:" + gdb_err) return resu
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])
def Main(): paramkey_group_by_dirs = "Group by directories" cgiEnv = lib_common.ScriptEnvironment( parameters={paramkey_group_by_dirs: True}) flag_group_by_dirs = bool(cgiEnv.get_parameters(paramkey_group_by_dirs)) win_module = cgiEnv.GetId() lib_win32.CheckWindowsModule(win_module) # This has to be in the path. Is it the 32 bits or 64 bits one ? depends_bin = "depends.exe" logging.debug("depends_bin=%s", depends_bin) tmp_fil_obj = lib_util.TmpFile("depends") tmp_out_fil = tmp_fil_obj.Name args = [depends_bin, "/c", "/OC:", tmp_out_fil, win_module] logging.debug("Depends command=%s", str(args)) grph = cgiEnv.GetGraph() node_dll = lib_uris.gUriGen.FileUri(win_module) # TODO: Check the return value. # http://www.dependencywalker.com/help/html/hidr_command_line_help.htm p = lib_common.SubProcPOpen(args) nmap_last_output, nmap_err = p.communicate() for lin in nmap_last_output: continue # Wait for the end, otherwise the file will not be ready. try: logging.debug("Depends tmp_out_fil=%s", tmp_out_fil) input_file = open(tmp_out_fil, 'r') except Exception as exc: lib_common.ErrorMessageHtml("Caught " + str(exc) + " when processing:" + tmp_out_fil) # Status,Module,File Time Stamp,Link Time Stamp,File Size,Attr.,Link Checksum,Real Checksum,CPU,Subsystem,Symbols,Preferred Base,Actual Base,Virtual Size,Load Order,File Ver,Product Ver,Image Ver,Linker Ver,OS Ver,Subsystem Ver # ?,"MSVCR80D.DLL","Error opening file. The system cannot find the file specified (2).",,,,,,,,,,,,,,,,,, # D?,"XLCALL32.DLL","Error opening file. The system cannot find the file specified (2).",,,,,,,,,,,,,,,,,, # E6,"c:\windows\system32\ADVAPI32.DLL",2012-10-18 21:27:04,2012-10-18 21:27:12,876544,A,0x000D9B98,0x000D9B98,x64,Console,"CV",0x000007FF7FF10000,Unknown,0x000DB000,Not Loaded,6.1.7601.22137,6.1.7601.22137,6.1,9.0,6.1,6.1 # E6,"c:\windows\system32\API-MS-WIN-CORE-CONSOLE-L1-1-0.DLL",2013-08-02 03:12:18,2013-08-02 03:12:52,3072,HA,0x000081B6,0x000081B6,x64,Console,"CV",0x0000000000400000,Unknown,0x00003000,Not Loaded,6.1.7601.18229,6.1.7601.18229,6.1,9.0,6.1,6.1 # Used only if libraries are grouped by directory. dirs_to_nodes = {} for lin in input_file: # TODO: Beware of commas in file names!!!!! Maybe module shlex ? linargs = lin.split(',') module = linargs[1] # The library filename is enclosed in double-quotes, that we must remove. modul_nam = module[1:-1] lib_node = lib_uris.gUriGen.SharedLibUri(modul_nam) # If the libraries are displayed in groups belnging to a dir, this is clearer. if flag_group_by_dirs: dir_nam = os.path.dirname(modul_nam) if dir_nam == "": dir_nam = "Unspecified dir" try: dir_nod = dirs_to_nodes[dir_nam] except KeyError: # TODO: Beware, in fact this is a directory. dir_nod = lib_uris.gUriGen.FileUri(dir_nam) grph.add((node_dll, pc.property_library_depends, dir_nod)) dirs_to_nodes[dir_nam] = dir_nod grph.add((dir_nod, pc.property_library_depends, lib_node)) else: grph.add((node_dll, pc.property_library_depends, lib_node)) if linargs[0] != '?': cpu = linargs[8] if cpu not in ["", "CPU"]: grph.add((node_dll, pc.property_library_cpu, lib_util.NodeLiteral(cpu))) # Temporary file removed by constructor. input_file.close() cgiEnv.OutCgiRdf()