Ethereal-dev: Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Gilbert Ramirez <gram@xxxxxxxxxxxxxxx>
Date: Thu, 21 Feb 2002 10:20:46 -0600
On Wed, 20 Feb 2002 16:02:40 Gilbert Ramirez wrote: > > Using gdb on the core file, one could actually extract the current > packet from the core file. I'm working on a script to do that. > Instead of using 'expect' to interact with gdb, I intend to call > gdb a few times, each time passing it a --command switch, giving it > a file of commands to run. I should be able to get the packet and save > it either as a text file for text2pcap to convert, or as a libpcap file. > > --gilbert > I just now checked in my first attempt at a script to do exactly this. It's tools/pkt-from-core.py. It's a python script that takes a core file and tries to extract the packet that was being dissected. It looks for a call to epan_dissect_run() in the backtrace, and if it finds that, uses gdb to query the variables. It then writes a hex dump of the packet to a temporary file, and calls text2pcap to create a libpcap file. You invoke it like you do gdb, with the name of the executable file and a core file. Additionally, -w is used to give the name of the capture file that you wish to create. pkt-from-core.py -w capture_file executable-file (core-file or process-id) Given an executable file and a core file, this tool uses gdb to retrieve the packet that was being dissected at the time ethereal/tethereal stopped running. The packet is saved in the capture_file specified by the -w option. Marcin, do you want to see if it works on your system? The script is attached to this e-mail. --gilbert
#!/bin/sh echo MANGLED_ON_PURPOSE.306090 exit #!/usr/bin/env python """ Retrieve a packet from a ethereal/tethereal core file and save it in a packet-capture file. """ import getopt import os import re import sys import tempfile exec_file = None core_file = None output_file = None class BackTrace: re_frame = re.compile(r"^#(?P<num>\d+) ") re_func1 = re.compile(r"^#\d+\s+(?P<func>\w+) \(") re_func2 = re.compile(r"^#\d+\s+0x[A-Fa-f\d]+ in (?P<func>\w+) \(") def __init__(self, lines): # In order; each item is the function name. self.frames = [] found_non_bt_frame = 0 frame_will_be = 0 for line in lines: m = self.re_frame.search(line) if m: # Skip the first frame that gdb shows, # which is not part of the backtrace. if not found_non_bt_frame: found_non_bt_frame = 1 continue # Get the frame number and make sure it's # what we expect it should be. frame_num = int(m.group("num")) if frame_num != frame_will_be: sys.exit("Found frame %d instead of %d" % \ (frame_num, frame_will_be)) # Find the function name. XXX - need to handle '???' n = self.re_func1.search(line) if not n: n = self.re_func2.search(line) if n: func = n.group("func") else: sys.exit("Function name not found in %s" % (line,)) # Save the info self.frames.append(func) frame_will_be += 1 def Frames(self): return self.frames def HasFunction(self, func): return func in self.frames def Frame(self, func): return self.frames.index(func) # Some values from wiretap; wiretap should be a shared # libray and a Python module should be created for it so # this program could just write a libpcap file directly. WTAP_ENCAP_PER_PACKET = -1 WTAP_ENCAP_UNKNOWN = 0 WTAP_ENCAP_ETHERNET = 1 WTAP_ENCAP_TOKEN_RING = 2 WTAP_ENCAP_SLIP = 3 WTAP_ENCAP_PPP = 4 WTAP_ENCAP_FDDI = 5 WTAP_ENCAP_FDDI_BITSWAPPED = 6 WTAP_ENCAP_RAW_IP = 7 WTAP_ENCAP_ARCNET = 8 WTAP_ENCAP_ATM_RFC1483 = 9 WTAP_ENCAP_LINUX_ATM_CLIP = 10 WTAP_ENCAP_LAPB = 11 WTAP_ENCAP_ATM_SNIFFER = 12 WTAP_ENCAP_NULL = 13 WTAP_ENCAP_ASCEND = 14 WTAP_ENCAP_LAPD = 15 WTAP_ENCAP_V120 = 16 WTAP_ENCAP_PPP_WITH_PHDR = 17 WTAP_ENCAP_IEEE_802_11 = 18 WTAP_ENCAP_SLL = 19 WTAP_ENCAP_FRELAY = 20 WTAP_ENCAP_CHDLC = 21 WTAP_ENCAP_CISCO_IOS = 22 WTAP_ENCAP_LOCALTALK = 23 WTAP_ENCAP_PRISM_HEADER = 24 WTAP_ENCAP_PFLOG = 25 WTAP_ENCAP_AIROPEEK = 26 WTAP_ENCAP_HHDLC = 27 # last WTAP_ENCAP_ value + 1 WTAP_NUM_ENCAP_TYPES = 28 wtap_to_pcap_map = { WTAP_ENCAP_NULL : 0, WTAP_ENCAP_ETHERNET : 1, WTAP_ENCAP_TOKEN_RING : 6, WTAP_ENCAP_ARCNET : 7, WTAP_ENCAP_SLIP : 8, WTAP_ENCAP_PPP : 9, WTAP_ENCAP_FDDI_BITSWAPPED : 10, WTAP_ENCAP_FDDI : 10, WTAP_ENCAP_ATM_RFC1483 : 11, WTAP_ENCAP_RAW_IP : 12, WTAP_ENCAP_LINUX_ATM_CLIP : 16, # or 18, or 19... WTAP_ENCAP_CHDLC : 104, WTAP_ENCAP_IEEE_802_11 : 105, WTAP_ENCAP_SLL : 113, WTAP_ENCAP_LOCALTALK : 114, WTAP_ENCAP_PFLOG : 117, WTAP_ENCAP_CISCO_IOS : 118, WTAP_ENCAP_PRISM_HEADER : 119, WTAP_ENCAP_HHDLC : 121, } wtap_name = { WTAP_ENCAP_UNKNOWN : "Unknown", WTAP_ENCAP_ETHERNET : "Ethernet", WTAP_ENCAP_TOKEN_RING : "Token-Ring", WTAP_ENCAP_SLIP : "SLIP", WTAP_ENCAP_PPP : "PPP", WTAP_ENCAP_FDDI : "FDDI", WTAP_ENCAP_FDDI_BITSWAPPED : "FDDI (Bitswapped)", WTAP_ENCAP_RAW_IP : "Raw IP", WTAP_ENCAP_ARCNET : "ARCNET", WTAP_ENCAP_ATM_RFC1483 : "ATM RFC1483", WTAP_ENCAP_LINUX_ATM_CLIP : "Linux ATM CLIP", WTAP_ENCAP_LAPB : "LAPB", WTAP_ENCAP_ATM_SNIFFER : "ATM Sniffer", WTAP_ENCAP_NULL : "Null", WTAP_ENCAP_ASCEND : "Ascend", WTAP_ENCAP_LAPD : "LAPD", WTAP_ENCAP_V120 : "V.120", WTAP_ENCAP_PPP_WITH_PHDR : "PPP (with PHDR)", WTAP_ENCAP_IEEE_802_11 : "IEEE 802.11", WTAP_ENCAP_SLL : "SLL", WTAP_ENCAP_FRELAY : "Frame Relay", WTAP_ENCAP_CHDLC : "Cisco HDLC", WTAP_ENCAP_CISCO_IOS : "Cisco IOS", WTAP_ENCAP_LOCALTALK : "LocalTalk", WTAP_ENCAP_PRISM_HEADER : "Prism Header", WTAP_ENCAP_PFLOG : "PFLog", WTAP_ENCAP_AIROPEEK : "AiroPeek", WTAP_ENCAP_HHDLC : "HHDLC", } def wtap_to_pcap(wtap): if not wtap_to_pcap_map.has_key(wtap): sys.exit("Don't know how to convert wiretap encoding %d to libpcap." % \ (wtap)) return wtap_to_pcap_map[wtap] def run_gdb(*commands): if len(commands) == 0: return [] # Create a temporary file fname = tempfile.mktemp() try: fh = open(fname, "w") except IOError, err: sys.exit("Cannot open %s for writing: %s" % (fname, err)) # Put the commands in it for cmd in commands: fh.write(cmd) fh.write("\n") fh.write("quit\n") try: fh.close() except IOError, err: try: os.unlink(fname) except: pass sys.exit("Cannot close %s: %s" % (fname, err)) # Run gdb cmd = "gdb --nw --quiet --command=%s %s %s" % (fname, exec_file, core_file) # print "Command is %s" % (cmd,) try: pipe = os.popen(cmd) except OSError, err: try: os.unlink(fname) except: pass sys.exit("Cannot run gdb: %s" % (err,)) # Get gdb's output result = pipe.readlines() error = pipe.close() if error != None: try: os.unlink(fname) except: pass sys.exit("gdb returned an exit value of %s" % (error,)) # Remove the temp file and return the results try: os.unlink(fname) except: pass return result def get_value_from_frame(frame_num, variable, fmt=""): cmds = [] if frame_num > 0: cmds.append("up %d" % (frame_num,)) cmds.append("print %s %s" % (fmt, variable)) lines = apply(run_gdb, cmds) LOOKING_FOR_START = 0 READING_VALUE = 1 state = LOOKING_FOR_START result = "" for line in lines: if line[-1] == "\n": line = line[0:-1] if line[-1] == "\r": line = line[0:-1] if state == LOOKING_FOR_START: if len(line) < 4: continue else: if line[0:4] == "$1 =": result = line[4:] state = READING_VALUE elif state == READING_VALUE: result += line return result def get_int_from_frame(frame_num, variable): text = get_value_from_frame(frame_num, variable) try: integer = int(text) except ValueError: sys.exit("Could not convert '%s' to integer." % (text,)) return integer def get_byte_array_from_frame(frame_num, variable, length): var = "{char}%s@%d" % (variable, length) text = get_value_from_frame(frame_num, var, "/u") # Remove curly braces i = text.find("{") if i == -1: sys.exit("Left curly brace not found in '%s'" % (text,)) text = text[i+1:] i = text.find("}") if i == -1: sys.exit("Right curly brace not found in '%s'" % (text,)) text = text[:i] # Split the string until many little strings, each representing a byte # in decimal values_as_text = text.split(',') # And get the numeric values return map(int, values_as_text) def make_cap_file(pkt_data, lnk_t): pcap_lnk_t = wtap_to_pcap(lnk_t) # Create a temporary file fname = tempfile.mktemp() try: fh = open(fname, "w") except IOError, err: sys.exit("Cannot open %s for writing: %s" % (fname, err)) print "Packet Data:" # Put the hex dump in it offset = 0 BYTES_IN_ROW = 16 for byte in pkt_data: if (offset % BYTES_IN_ROW) == 0: print >> fh, "\n%08X " % (offset,), print "\n%08X " % (offset,), print >> fh, "%02X " % (byte,), print "%02X " % (byte,), offset += 1 print >> fh, "\n" print "\n" try: fh.close() except IOError, err: try: os.unlink(fname) except: pass sys.exit("Cannot close %s: %s" % (fname, err)) # Run text2pcap cmd = "text2pcap -q -l %s %s %s" % (pcap_lnk_t, fname, output_file) # print "Command is %s" % (cmd,) try: retval = os.system(cmd) except OSError, err: try: os.unlink(fname) except: pass sys.exit("Cannot run text2pcap: %s" % (err,)) # Remove the temp file try: os.unlink(fname) except: pass if retval == 0: print "%s created with %d bytes in packet, and %s encoding." % \ (output_file, len(pkt_data), wtap_name[lnk_t]) else: sys.exit("text2pcap did not run succesfully.") def run(): # Get the back trace bt_text = run_gdb("bt") bt = BackTrace(bt_text) if not bt.HasFunction("epan_dissect_run"): print "epan_dissect_run() not found in backtrace." print "A packet cannot be pulled from this core." sys.exit(1) # Figure out where the call to epan_dissect_run is. frame_num = bt.Frame("epan_dissect_run") # Get the capture length cap_len = get_int_from_frame(frame_num, "fd->cap_len") # Get the encoding type lnk_t = get_int_from_frame(frame_num, "fd->lnk_t") # Get the packet data pkt_data = get_byte_array_from_frame(frame_num, "data", cap_len) # print "Length=%d" % (cap_len,) # print "Encoding=%d" % (lnk_t,) # print "Data (%d bytes) = %s" % (len(pkt_data), pkt_data) make_cap_file(pkt_data, lnk_t) def usage(): print "pkt-from-core.py -w capture_file executable-file (core-file or process-id)" print "" print "\tGiven an executable file and a core file, this tool" print "\tuses gdb to retrieve the packet that was being dissected" print "\tat the time ethereal/tethereal stopped running. The packet" print "\tis saved in the capture_file specified by the -w option." sys.exit(1) def main(): global exec_file global core_file global output_file optstring = "w:" try: opts, args = getopt.getopt(sys.argv[1:], optstring) except getopt.error: usage() for opt, arg in opts: if opt == "-w": output_file = arg else: assert 0 if output_file == None: usage() if len(args) != 2: usage() exec_file = args[0] core_file = args[1] run() if __name__ == '__main__': main()
This message has been 'sanitized'. This means that potentially dangerous content has been rewritten or removed. The following log describes which actions were taken. Sanitizer (start="1014308447"): Part (pos="1565"): SanitizeFile (filename="unnamed.txt", mimetype="text/plain"): Match (rule="2"): Enforced policy: accept Part (pos="3164"): SanitizeFile (filename="pkt-from-core.py", mimetype="text/script"): Match (rule="default"): Enforced policy: accept Defanged UNIX shell script(s). Total modifications so far: 1 Anomy 0.0.0 : Sanitizer.pm $Id: Sanitizer.pm,v 1.32 2001/10/11 19:27:15 bre Exp $
- References:
- [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Marcin Gryszkalis
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Guy Harris
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Marcin Gryszkalis
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Guy Harris
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Ronnie Sahlberg
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Marcin Gryszkalis
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Ronnie Sahlberg
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Guy Harris
- Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- From: Gilbert Ramirez
- [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- Prev by Date: [Ethereal-dev] patch for Openwave WSP decoding
- Next by Date: Re: [Ethereal-dev] Fragments of PDU in TCP packets.
- Previous by thread: Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- Next by thread: Re: [Ethereal-dev] packet-smb.c:11327 - si->info_level = t2i->info_level
- Index(es):