ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- PKoH]vG.G. __main__.pynu[#!/usr/bin/env python3 import argparse import sys import json import os import pycriu from . import __version__ def inf(opts): if opts['in']: return open(opts['in'], 'rb') else: if sys.stdin.isatty(): # If we are reading from a terminal (not a pipe) we want text input and not binary return sys.stdin return sys.stdin.buffer def outf(opts, decode): # Decode means from protobuf to JSON. # Use text when writing to JSON else use binaray mode if opts['out']: mode = 'wb+' if decode: mode = 'w+' return open(opts['out'], mode) else: if decode: return sys.stdout return sys.stdout.buffer def dinf(opts, name): return open(os.path.join(opts['dir'], name), mode='rb') def decode(opts): indent = None try: img = pycriu.images.load(inf(opts), opts['pretty'], opts['nopl']) except pycriu.images.MagicException as exc: print("Unknown magic %#x.\n" "Maybe you are feeding me an image with " "raw data(i.e. pages.img)?" % exc.magic, file=sys.stderr) sys.exit(1) if opts['pretty']: indent = 4 f = outf(opts, True) json.dump(img, f, indent=indent) if f == sys.stdout: f.write("\n") def encode(opts): try: img = json.load(inf(opts)) except UnicodeDecodeError: print("Cannot read JSON.\n" "Maybe you are feeding me an image with protobuf data? " "Encode expects JSON input.", file=sys.stderr) sys.exit(1) pycriu.images.dump(img, outf(opts, False)) def info(opts): infs = pycriu.images.info(inf(opts)) json.dump(infs, sys.stdout, indent=4) print() def get_task_id(p, val): return p[val] if val in p else p['ns_' + val][0] # # Explorers # class ps_item: def __init__(self, p, core): self.pid = get_task_id(p, 'pid') self.ppid = p['ppid'] self.p = p self.core = core self.kids = [] def show_ps(p, opts, depth=0): print("%7d%7d%7d %s%s" % (p.pid, get_task_id(p.p, 'pgid'), get_task_id(p.p, 'sid'), ' ' * (4 * depth), p.core['tc']['comm'])) for kid in p.kids: show_ps(kid, opts, depth + 1) def explore_ps(opts): pss = {} ps_img = pycriu.images.load(dinf(opts, 'pstree.img')) for p in ps_img['entries']: core = pycriu.images.load( dinf(opts, 'core-%d.img' % get_task_id(p, 'pid'))) ps = ps_item(p, core['entries'][0]) pss[ps.pid] = ps # Build tree psr = None for pid in pss: p = pss[pid] if p.ppid == 0: psr = p continue pp = pss[p.ppid] pp.kids.append(p) print("%7s%7s%7s %s" % ('PID', 'PGID', 'SID', 'COMM')) show_ps(psr, opts) files_img = None def ftype_find_in_files(opts, ft, fid): global files_img if files_img is None: try: files_img = pycriu.images.load(dinf(opts, "files.img"))['entries'] except Exception: files_img = [] if len(files_img) == 0: return None for f in files_img: if f['id'] == fid: return f return None def ftype_find_in_image(opts, ft, fid, img): f = ftype_find_in_files(opts, ft, fid) if f: if ft['field'] in f: return f[ft['field']] else: return None if ft['img'] is None: ft['img'] = pycriu.images.load(dinf(opts, img))['entries'] for f in ft['img']: if f['id'] == fid: return f return None def ftype_reg(opts, ft, fid): rf = ftype_find_in_image(opts, ft, fid, 'reg-files.img') return rf and rf['name'] or 'unknown path' def ftype_pipe(opts, ft, fid): p = ftype_find_in_image(opts, ft, fid, 'pipes.img') return p and 'pipe[%d]' % p['pipe_id'] or 'pipe[?]' def ftype_unix(opts, ft, fid): ux = ftype_find_in_image(opts, ft, fid, 'unixsk.img') if not ux: return 'unix[?]' n = ux['name'] and ' %s' % ux['name'] or '' return 'unix[%d (%d)%s]' % (ux['ino'], ux['peer'], n) file_types = { 'REG': { 'get': ftype_reg, 'img': None, 'field': 'reg' }, 'PIPE': { 'get': ftype_pipe, 'img': None, 'field': 'pipe' }, 'UNIXSK': { 'get': ftype_unix, 'img': None, 'field': 'usk' }, } def ftype_gen(opts, ft, fid): return '%s.%d' % (ft['typ'], fid) files_cache = {} def get_file_str(opts, fd): key = (fd['type'], fd['id']) f = files_cache.get(key, None) if not f: ft = file_types.get(fd['type'], {'get': ftype_gen, 'typ': fd['type']}) f = ft['get'](opts, ft, fd['id']) files_cache[key] = f return f def explore_fds(opts): ps_img = pycriu.images.load(dinf(opts, 'pstree.img')) for p in ps_img['entries']: pid = get_task_id(p, 'pid') idi = pycriu.images.load(dinf(opts, 'ids-%s.img' % pid)) fdt = idi['entries'][0]['files_id'] fdi = pycriu.images.load(dinf(opts, 'fdinfo-%d.img' % fdt)) print("%d" % pid) for fd in fdi['entries']: print("\t%7d: %s" % (fd['fd'], get_file_str(opts, fd))) fdi = pycriu.images.load(dinf(opts, 'fs-%d.img' % pid))['entries'][0] print("\t%7s: %s" % ('cwd', get_file_str(opts, { 'type': 'REG', 'id': fdi['cwd_id'] }))) print("\t%7s: %s" % ('root', get_file_str(opts, { 'type': 'REG', 'id': fdi['root_id'] }))) class vma_id: def __init__(self): self.__ids = {} self.__last = 1 def get(self, iid): ret = self.__ids.get(iid, None) if not ret: ret = self.__last self.__last += 1 self.__ids[iid] = ret return ret def explore_mems(opts): ps_img = pycriu.images.load(dinf(opts, 'pstree.img')) vids = vma_id() for p in ps_img['entries']: pid = get_task_id(p, 'pid') mmi = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0] print("%d" % pid) print("\t%-36s %s" % ('exe', get_file_str(opts, { 'type': 'REG', 'id': mmi['exe_file_id'] }))) for vma in mmi['vmas']: st = vma['status'] if st & (1 << 10): fn = ' ' + 'ips[%lx]' % vids.get(vma['shmid']) elif st & (1 << 8): fn = ' ' + 'shmem[%lx]' % vids.get(vma['shmid']) elif st & (1 << 11): fn = ' ' + 'packet[%lx]' % vids.get(vma['shmid']) elif st & ((1 << 6) | (1 << 7)): fn = ' ' + get_file_str(opts, { 'type': 'REG', 'id': vma['shmid'] }) if vma['pgoff']: fn += ' + %#lx' % vma['pgoff'] if st & (1 << 7): fn += ' (s)' elif st & (1 << 1): fn = ' [stack]' elif st & (1 << 2): fn = ' [vsyscall]' elif st & (1 << 3): fn = ' [vdso]' elif vma['flags'] & 0x0100: # growsdown fn = ' [stack?]' else: fn = '' if not st & (1 << 0): fn += ' *' prot = vma['prot'] & 0x1 and 'r' or '-' prot += vma['prot'] & 0x2 and 'w' or '-' prot += vma['prot'] & 0x4 and 'x' or '-' astr = '%08lx-%08lx' % (vma['start'], vma['end']) print("\t%-36s%s%s" % (astr, prot, fn)) def explore_rss(opts): ps_img = pycriu.images.load(dinf(opts, 'pstree.img')) for p in ps_img['entries']: pid = get_task_id(p, 'pid') vmas = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]['vmas'] pms = pycriu.images.load(dinf(opts, 'pagemap-%d.img' % pid))['entries'] print("%d" % pid) vmi = 0 pvmi = -1 for pm in pms[1:]: pstr = '\t%lx / %-8d' % (pm['vaddr'], pm['nr_pages']) while vmi < len(vmas) and vmas[vmi]['end'] <= pm['vaddr']: vmi += 1 pme = pm['vaddr'] + (pm['nr_pages'] << 12) vstr = '' while vmi < len(vmas) and vmas[vmi]['start'] < pme: vma = vmas[vmi] if vmi == pvmi: vstr += ' ~' else: vstr += ' %08lx / %-8d' % ( vma['start'], (vma['end'] - vma['start']) >> 12) if vma['status'] & ((1 << 6) | (1 << 7)): vstr += ' ' + get_file_str(opts, { 'type': 'REG', 'id': vma['shmid'] }) pvmi = vmi vstr += '\n\t%23s' % '' vmi += 1 vmi -= 1 print('%-24s%s' % (pstr, vstr)) explorers = { 'ps': explore_ps, 'fds': explore_fds, 'mems': explore_mems, 'rss': explore_rss } def explore(opts): explorers[opts['what']](opts) def main(): desc = 'CRiu Image Tool' parser = argparse.ArgumentParser( description=desc, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('--version', action='version', version=__version__) subparsers = parser.add_subparsers( help='Use crit CMD --help for command-specific help') # Decode decode_parser = subparsers.add_parser( 'decode', help='convert criu image from binary type to json') decode_parser.add_argument( '--pretty', help='Multiline with indents and some numerical fields in field-specific format', action='store_true') decode_parser.add_argument( '-i', '--in', help='criu image in binary format to be decoded (stdin by default)') decode_parser.add_argument( '-o', '--out', help='where to put criu image in json format (stdout by default)') decode_parser.set_defaults(func=decode, nopl=False) # Encode encode_parser = subparsers.add_parser( 'encode', help='convert criu image from json type to binary') encode_parser.add_argument( '-i', '--in', help='criu image in json format to be encoded (stdin by default)') encode_parser.add_argument( '-o', '--out', help='where to put criu image in binary format (stdout by default)') encode_parser.set_defaults(func=encode) # Info info_parser = subparsers.add_parser('info', help='show info about image') info_parser.add_argument("in") info_parser.set_defaults(func=info) # Explore x_parser = subparsers.add_parser('x', help='explore image dir') x_parser.add_argument('dir') x_parser.add_argument('what', choices=['ps', 'fds', 'mems', 'rss']) x_parser.set_defaults(func=explore) # Show show_parser = subparsers.add_parser( 'show', help="convert criu image from binary to human-readable json") show_parser.add_argument("in") show_parser.add_argument('--nopl', help='do not show entry payload (if exists)', action='store_true') show_parser.set_defaults(func=decode, pretty=True, out=None) opts = vars(parser.parse_args()) if not opts: sys.stderr.write(parser.format_usage()) sys.stderr.write("crit: error: too few arguments\n") sys.exit(1) opts["func"](opts) if __name__ == '__main__': main() PKoH]L((#__pycache__/__main__.cpython-36.pycnu[3  iG.@sHddlZddlZddlZddlZddlZddlmZddZddZdd Z d d Z d d Z ddZ ddZ GdddZd9ddZddZdaddZddZddZddZd d!Zedd"d#edd$d#edd%d#d&Zd'd(ZiZd)d*Zd+d,ZGd-d.d.Zd/d0Zd1d2Zeeeed3Zd4d5Z d6d7Z!e"d8krDe!dS):N) __version__cCs2|drt|ddStjjr&tjStjjSdS)Ninrb)opensysstdinisattybuffer)optsr /usr/lib/python3.6/__main__.pyinf s  rcCs8|dr"d}|rd}t|d|S|r,tjStjjSdS)Noutzwb+zw+)rrstdoutr )r decodemoder r r outfsrcCsttjj|d|ddS)Ndirr)r)rospathjoin)r namer r r dinf#srcCsd}y tjjt||d|d}WnDtjjk rh}z$td|jtjdtj dWYdd}~XnX|drvd}t |d}t j |||d|tj kr|jd dS) NprettynoplzSUnknown magic %#x. Maybe you are feeding me an image with raw data(i.e. pages.img)?)filerT)indent )pycriuimagesloadrZMagicExceptionprintmagicrstderrexitrjsondumprwrite)r rimgexcfr r r r's   rc CsXytjt|}Wn,tk r>tdtjdtjdYnXtj j |t |ddS)NzbCannot read JSON. Maybe you are feeding me an image with protobuf data? Encode expects JSON input.)rrF) r'r"rUnicodeDecodeErrorr#rr%r&r r!r(r)r r*r r r encode;s r.cCs,tjjt|}tj|tjddtdS)Nr)r) r r!inforr'r(rrr#)r Zinfsr r r r/Fsr/cCs ||kr||S|d|dS)NZns_rr )pvalr r r get_task_idLsr2c@seZdZddZdS)ps_itemcCs,t|d|_|d|_||_||_g|_dS)Npidppid)r2r4r5r0corekids)selfr0r6r r r __init__Vs   zps_item.__init__N)__name__ __module__ __qualname__r9r r r r r3Usr3cCs^td|jt|jdt|jddd||jddfx|jD]}t|||dqBWdS) Nz%7d%7d%7d %s%sZpgidZsid rZtcZcommr)r#r4r2r0r6r7show_ps)r0r depthZkidr r r r>^s  r>c Csi}tjjt|d}xH|dD]<}tjjt|dt|d}t||dd}|||j<q Wd}x:|D]2}||}|jdkr|}qj||j}|jj |qjWt dd t ||dS) Nz pstree.imgentriesz core-%d.imgr4rz%7s%7s%7s %sPIDPGIDSIDCOMM)rArBrCrD) r r!r"rr2r3r4r5r7appendr#r>) r Zpssps_imgr0r6psZpsrr4Zppr r r explore_psfs"    rHc Csntdkr} d} x|t|kr||d| kr||} ||kr,| d7} nR| d| d| d | dd?f7} | dd@rz| dt|d| dd7} |}| dd7} |d 7}qW|d 8}td| | fqWqWdS) Nz pstree.imgr@r4z mm-%d.imgrrjzpagemap-%d.imgz%drz %lx / %-8dZvaddrZnr_pagesr| rTr{z ~z %08lx / %-8drkrprqr=rYrm)r]rIz %23sz%-24s%sr}r~r)r r!r"rr2r#rLrb) r rFr0r4rjZpmsZvmiZpvmiZpmZpstrZpmeZvstrrr r r explore_rss9s<   " "     r)rGfdsmemsrsscCst|d|dS)Nwhat) explorers)r r r r explorehsrc Csd}tj|tjd}|jddtd|jdd}|jdd d}|jd d d d |jdddd|jdddd|jtdd|jddd}|jdddd|jdddd|jt d|jddd}|jd|jt d|jddd}|jd |jd!d"d#d$d%gd&|jt d|jd'd(d}|jd|jd)d*d d |jtd+dd,t |j }|stjj|jtjjd-tjd.|d/|dS)0NzCRiu Image Tool) descriptionZformatter_classz --versionversion)actionrz-Use crit CMD --help for command-specific help)helprz+convert criu image from binary type to jsonz--prettyzIMultiline with indents and some numerical fields in field-specific format store_true)rrz-iz--inzrHrJrOrQrRrSrVr_r\r^rbrerfrrrrrr:r r r r sZ        5(E PKoH]3I-#__pycache__/__init__.cpython-36.pycnu[3  i!@sddlmZdS)) __version__N)versionrrr/usr/lib/python3.6/__init__.pysPKoH]G"__pycache__/version.cpython-36.pycnu[3 1j@sdZdS)z4.2N) __version__rr/usr/lib/python3.6/version.pysPKoH]3I-)__pycache__/__init__.cpython-36.opt-1.pycnu[3  i!@sddlmZdS)) __version__N)versionrrr/usr/lib/python3.6/__init__.pysPKoH]G(__pycache__/version.cpython-36.opt-1.pycnu[3 1j@sdZdS)z4.2N) __version__rr/usr/lib/python3.6/version.pysPKoH]L(()__pycache__/__main__.cpython-36.opt-1.pycnu[3  iG.@sHddlZddlZddlZddlZddlZddlmZddZddZdd Z d d Z d d Z ddZ ddZ GdddZd9ddZddZdaddZddZddZddZd d!Zedd"d#edd$d#edd%d#d&Zd'd(ZiZd)d*Zd+d,ZGd-d.d.Zd/d0Zd1d2Zeeeed3Zd4d5Z d6d7Z!e"d8krDe!dS):N) __version__cCs2|drt|ddStjjr&tjStjjSdS)Ninrb)opensysstdinisattybuffer)optsr /usr/lib/python3.6/__main__.pyinf s  rcCs8|dr"d}|rd}t|d|S|r,tjStjjSdS)Noutzwb+zw+)rrstdoutr )r decodemoder r r outfsrcCsttjj|d|ddS)Ndirr)r)rospathjoin)r namer r r dinf#srcCsd}y tjjt||d|d}WnDtjjk rh}z$td|jtjdtj dWYdd}~XnX|drvd}t |d}t j |||d|tj kr|jd dS) NprettynoplzSUnknown magic %#x. Maybe you are feeding me an image with raw data(i.e. pages.img)?)filerT)indent )pycriuimagesloadrZMagicExceptionprintmagicrstderrexitrjsondumprwrite)r rimgexcfr r r r's   rc CsXytjt|}Wn,tk r>tdtjdtjdYnXtj j |t |ddS)NzbCannot read JSON. Maybe you are feeding me an image with protobuf data? Encode expects JSON input.)rrF) r'r"rUnicodeDecodeErrorr#rr%r&r r!r(r)r r*r r r encode;s r.cCs,tjjt|}tj|tjddtdS)Nr)r) r r!inforr'r(rrr#)r Zinfsr r r r/Fsr/cCs ||kr||S|d|dS)NZns_rr )pvalr r r get_task_idLsr2c@seZdZddZdS)ps_itemcCs,t|d|_|d|_||_||_g|_dS)Npidppid)r2r4r5r0corekids)selfr0r6r r r __init__Vs   zps_item.__init__N)__name__ __module__ __qualname__r9r r r r r3Usr3cCs^td|jt|jdt|jddd||jddfx|jD]}t|||dqBWdS) Nz%7d%7d%7d %s%sZpgidZsid rZtcZcommr)r#r4r2r0r6r7show_ps)r0r depthZkidr r r r>^s  r>c Csi}tjjt|d}xH|dD]<}tjjt|dt|d}t||dd}|||j<q Wd}x:|D]2}||}|jdkr|}qj||j}|jj |qjWt dd t ||dS) Nz pstree.imgentriesz core-%d.imgr4rz%7s%7s%7s %sPIDPGIDSIDCOMM)rArBrCrD) r r!r"rr2r3r4r5r7appendr#r>) r Zpssps_imgr0r6psZpsrr4Zppr r r explore_psfs"    rHc Csntdkr} d} x|t|kr||d| kr||} ||kr,| d7} nR| d| d| d | dd?f7} | dd@rz| dt|d| dd7} |}| dd7} |d 7}qW|d 8}td| | fqWqWdS) Nz pstree.imgr@r4z mm-%d.imgrrjzpagemap-%d.imgz%drz %lx / %-8dZvaddrZnr_pagesr| rTr{z ~z %08lx / %-8drkrprqr=rYrm)r]rIz %23sz%-24s%sr}r~r)r r!r"rr2r#rLrb) r rFr0r4rjZpmsZvmiZpvmiZpmZpstrZpmeZvstrrr r r explore_rss9s<   " "     r)rGfdsmemsrsscCst|d|dS)Nwhat) explorers)r r r r explorehsrc Csd}tj|tjd}|jddtd|jdd}|jdd d}|jd d d d |jdddd|jdddd|jtdd|jddd}|jdddd|jdddd|jt d|jddd}|jd|jt d|jddd}|jd |jd!d"d#d$d%gd&|jt d|jd'd(d}|jd|jd)d*d d |jtd+dd,t |j }|stjj|jtjjd-tjd.|d/|dS)0NzCRiu Image Tool) descriptionZformatter_classz --versionversion)actionrz-Use crit CMD --help for command-specific help)helprz+convert criu image from binary type to jsonz--prettyzIMultiline with indents and some numerical fields in field-specific format store_true)rrz-iz--inzrHrJrOrQrRrSrVr_r\r^rbrerfrrrrrr:r r r r sZ        5(E PKoH]sD version.pynu[__version__ = '4.2' PKoH]!! __init__.pynu[from .version import __version__ PKoH]vG.G. __main__.pynu[PKoH]L((#.__pycache__/__main__.cpython-36.pycnu[PKoH]3I-#V__pycache__/__init__.cpython-36.pycnu[PKoH]G"W__pycache__/version.cpython-36.pycnu[PKoH]3I-)X__pycache__/__init__.cpython-36.opt-1.pycnu[PKoH]G(Y__pycache__/version.cpython-36.opt-1.pycnu[PKoH]L(()zZ__pycache__/__main__.cpython-36.opt-1.pycnu[PKoH]sD version.pynu[PKoH]!! 2__init__.pynu[PK B