예제 #1
0
def test_format_ctypes(configfile, c_header):
    c = conf.Config(configfile)
    conf.config = c
    defs = list(parse(c_header, tag="test"))
    x = ccore.from_db(defs[0])
    assert x._is_macro
    assert x.show(form="ctypes") == "MYCONST = 16"
    x = ccore.from_db(defs[5])
    assert x._is_typedef
    assert (x.show(form="ctypes") ==
            "foo = POINTER(CFUNCTYPE(c_int, c_int, c_byte, c_uint, c_void_p))")
    x = ccore.from_db(defs[8])
    assert x._is_typedef
    assert (x.show(
        form="ctypes"
    ) == "foo2 = POINTER(CFUNCTYPE(POINTER(c_void_p*3), c_int, c_void_p))*2")
    x = ccore.from_db(defs[10])
    assert x._is_struct
    assert (x.show(form="ctypes") ==
            """struct__mystruct = type('struct__mystruct',(Structure,),{})

struct__mystruct._fields_ = [("I", myinteger),
                             ("tab", c_int*12),
                             ("p", c_ubyte*16),
                             ("s", POINTER(c_short)),
                             ("next", POINTER(struct__mystruct)),
                             ("func", foo),
                             ("bar", struct__bar*2)]""")
예제 #2
0
def test_format_C(configfile, c_header):
    c = conf.Config(configfile)
    conf.config = c
    defs = list(parse(c_header, tag="test"))
    x = ccore.from_db(defs[0])
    assert x._is_macro
    assert x.show(form="C") == "#define MYCONST  0x10;"
    x = ccore.from_db(defs[5])
    assert x._is_typedef
    assert x.show(
        form="C") == "typedef int (*foo)(int, char, unsigned int, void *);"
    x = ccore.from_db(defs[8])
    assert x._is_typedef
    assert x.show(form="C") == "typedef void *(*(*foo2[2])(int, void **))[3];"
    x = ccore.from_db(defs[10])
    assert x._is_struct
    assert (x.show(form="C") == """struct _mystruct {
  myinteger I;
  int tab[12];
  unsigned char p[16];
  short *s;
  struct _mystruct *next;
  foo func;
  struct _bar bar[2];
};""")
예제 #3
0
파일: test_conf.py 프로젝트: sthagen/ccrawl
def test_Config(configfile):
    c = conf.Config(configfile)
    assert c.src is not None
    assert c.Terminal.debug is False
    assert conf.DEBUG is False
    assert c.Terminal.console == "ipython"
    assert not c.Collect.strict
    assert c.Collect.cxx
    assert c.Database.local == "test.db"
    assert c.Database.url == "mongodb://localhost:27017"
예제 #4
0
def test_format_C(configfile,c_header):
    c = conf.Config(configfile)
    conf.config = c
    defs = list(parse(c_header,tag='test'))
    x = ccore.from_db(defs[0])
    assert x._is_macro
    assert x.show(form='C') == '#define MYCONST  0x10;'
    x = ccore.from_db(defs[5])
    assert x._is_typedef
    assert x.show(form='C') == 'typedef int (*foo)(int, char, unsigned int, void *);'
    x = ccore.from_db(defs[8])
    assert x._is_typedef
    assert x.show(form='C') == 'typedef void *(*(*foo2[2])(int, void **))[3];'
    x = ccore.from_db(defs[10])
    assert x._is_struct
    assert x.show(form='C') == """struct _mystruct {
예제 #5
0
def test_format_amoco(configfile,c_header):
    c = conf.Config(configfile)
    conf.config = c
    defs = list(parse(c_header,tag='test'))
    x = ccore.from_db(defs[0])
    assert x._is_macro
    assert x.show(form='amoco') == 'MYCONST = 0x10'
    x = ccore.from_db(defs[5])
    assert x._is_typedef
    assert x.show(form='amoco') == "TypeDefine('foo','P')"
    x = ccore.from_db(defs[8])
    assert x._is_typedef
    assert x.show(form='amoco') == "TypeDefine('foo2','P * 2')"
    x = ccore.from_db(defs[10])
    assert x._is_struct
    assert x.show(form='amoco') == '@StructDefine("""\nmyinteger : I ;comment for field I\ni * 12 : tab ;modern comment for tab\ns * 16 : p ;\nP : s ;\nP : next ;\nfoo : func ;\nstruct__bar * 2 : bar ;\n""")\nclass struct__mystruct(StructFormatter):\n    def __init__(self,data="",offset=0):\n        if data: self.unpack(data,offset)\n    '
예제 #6
0
def test_format_ctypes(configfile,c_header):
    c = conf.Config(configfile)
    conf.config = c
    defs = list(parse(c_header,tag='test'))
    x = ccore.from_db(defs[0])
    assert x._is_macro
    assert x.show(form='ctypes') == 'MYCONST = 16'
    x = ccore.from_db(defs[5])
    assert x._is_typedef
    assert x.show(form='ctypes') == 'foo = POINTER(CFUNCTYPE(c_int, c_int, c_byte, c_uint, c_void_p))'
    x = ccore.from_db(defs[8])
    assert x._is_typedef
    assert x.show(form='ctypes') == 'foo2 = POINTER(CFUNCTYPE(POINTER(c_void_p*3), c_int, c_void_p))*2'
    x = ccore.from_db(defs[10])
    assert x._is_struct
    assert x.show(form='ctypes') ==  """struct__mystruct = type('struct__mystruct',(Structure,),{})
예제 #7
0
파일: main.py 프로젝트: bdcht/ccrawl
def cli(ctx, verbose, quiet, db, local, configfile, tag):
    ctx.obj = {}
    c = conf.config = conf.Config(configfile)
    if quiet:
        verbose = False
    debug = c.Terminal.debug
    c.Terminal.verbose = verbose | debug
    c.Terminal.quiet = quiet
    c.Terminal.width = click.get_terminal_size()[0]
    if conf.VERBOSE:
        if c.src:
            click.echo("config file '%s' loaded" % c.f)
        else:
            click.echo("default config loaded (file '%s' not found)" % c.f)
    if db:
        c.Database.url = db
    if local:
        c.Database.local = local
    if conf.VERBOSE:
        click.echo('loading local database %s ...' % c.Database.local,
                   nl=False)
    try:
        ctx.obj['db'] = Proxy(c.Database)
        if tag: ctx.obj['db'].set_tag(tag)
    except Exception:
        click.secho('failed', fg='red', err=True)
        exit(1)
    if conf.VERBOSE:
        click.echo('done')
        if c.Database.url and ctx.obj['db'].rdb:
            click.echo('remote database is: %s' % c.Database.url)
        elif c.Database.url:
            click.secho('remote database (%s) not connected' % c.Database.url,
                        fg='red',
                        err=True)
        else:
            click.echo('no remote database')
    if ctx.invoked_subcommand is None:
        spawn_console(ctx)
    else:
        if conf.DEBUG:
            click.echo('COMMAND: %s' % ctx.invoked_subcommand)
예제 #8
0
def parse(filename,
          args=None,
          unsaved_files=None,
          options=None,
          kind=None,
          tag=None):
    """Function that parses the input filename and returns the
    dictionary of name:object
    """
    # clang parser cindex options:
    if options is None:
        # (detailed processing allows to get macros in iterated cursors)
        options = TranslationUnit.PARSE_NONE
        options = TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD
        options |= TranslationUnit.PARSE_INCOMPLETE
        options |= TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION
        # (preprocessor options not exported in the python bindings):
        RetainExcludedConditionalBlocks = 0x8000
        KeepGoing = 0x200
        options |= RetainExcludedConditionalBlocks
        options |= KeepGoing
    if args is None:
        # mandatory if only libclang python binding is installed, since then the llvm-headers
        # are probably missing we need to use the builtin modulemap:
        _args = [
            "-ferror-limit=0",
            "-fmodules",
            "-fbuiltin-module-map",
        ]
    else:
        _args = args[:]
    if conf.config is None:
        conf.config = conf.Config()
    cxx_args = ["-x", "c++", "-std=c++11", "-fno-delayed-template-parsing"]
    if conf.config.Collect.cxx:
        if filename.endswith(".hpp") or filename.endswith(".cpp"):
            _args.extend(cxx_args)
    cxx = "c++" in _args
    if not conf.config.Collect.strict:
        # in non strict mode, we allow missing includes
        fd, depf = tempfile.mkstemp(prefix="ccrawl-")
        os.close(fd)
        _args += ["-M", "-MG", "-MF%s" % depf]
    if conf.DEBUG:
        echo("\nfilename: %s, args: %s" % (filename, _args))
    if unsaved_files is None:
        # unsaved files are also used to replace existing files by these if the
        # filename matches,
        # TODO: allowing to "preload" headers like stddef.h for example...
        unsaved_files = []
    if kind is None:
        kind = CHandlers
    else:
        for k in kind:
            assert k in CHandlers
    if conf.config.Collect.allc is False:
        options |= TranslationUnit.PARSE_SKIP_FUNCTION_BODIES
    defs = OrderedDict()
    index = Index.create()
    # call clang parser:
    try:
        tu = index.parse(filename, _args, unsaved_files, options)
        for err in tu.diagnostics:
            if conf.DEBUG:
                secho(err.format(), fg="yellow")
            if err.severity == 3:
                # common errors when parsing c++ as c:
                if ("expected ';'" in err.spelling) or ("'namespace'"
                                                        in err.spelling):
                    if conf.config.Collect.cxx:
                        if conf.DEBUG:
                            secho("reparse as c++ input...", fg="cyan")
                        cxx = True
                        tu = index.parse(filename, _args + cxx_args,
                                         unsaved_files, options)
                        break
                    else:
                        secho("[c++]".rjust(12), fg="yellow")
                        return []
            elif err.severity == 4:
                # this should not happen anymore thanks to -M -MG opts...
                # we keep it here just in case.
                if conf.VERBOSE:
                    secho(err.format(), bg="red", err=True)
                raise StandardError
    except Exception:
        if not conf.QUIET:
            secho("[err]", fg="red")
            if conf.VERBOSE:
                secho("clang index.parse error", fg="red", err=True)
        return []
    else:
        if conf.VERBOSE:
            echo(":")
    if not conf.config.Collect.strict:
        os.remove(depf)
    # walk down all AST to get all top-level cursors:
    pool = [(c, []) for c in tu.cursor.get_children()]
    #name = str(tu.cursor.extent.start.file.name)
    diag = {}
    for r in tu.diagnostics:
        if selected_errs(r):
            if not r.location.file.name in diag:
                diag[r.location.file.name] = defaultdict(list)
            diag[r.location.file.name][r.location.line].append(r)
    # map diagnostics to cursors:
    for cur, errs in pool:
        if cur.location.file is None or (cur.location.file.name not in diag):
            continue
        span = range(cur.extent.start.line, cur.extent.end.line + 1)
        if cur.location.line not in span:
            span = range(cur.location.line, cur.location.line + 1)
        for l in span:
            errs.extend(diag.get(cur.location.file.name, None)[l])
    # now finally call the handlers:
    for cur, errs in pool:
        if conf.DEBUG and cur.location.file:
            echo("-" * 80)
            echo("%s: %s [%d errors]" % (cur.kind, cur.spelling, len(errs)))
        if cur.kind in kind:
            kv = CHandlers[cur.kind](cur, cxx, errs)
            # fill defs with collected cursors:
            if kv:
                ident, cobj = kv
                if cobj:
                    for x in cobj.to_db(ident, tag, cur.location.file.name):
                        defs[x["id"]] = x
    if not conf.QUIET:
        secho(("[%3d]" % len(defs)).rjust(12),
              fg="green" if not cxx else "cyan")
    return defs.values()
예제 #9
0
파일: ghidra.py 프로젝트: sthagen/ccrawl
    return header + struct.pack(">Q", length) + archive.getvalue()


try:
    import ghidra_bridge

    b = ghidra_bridge.GhidraBridge(namespace=locals())
except ImportError:
    secho("ghidra_bridge package not found", fg="red")
except AttributeError:
    secho("ghidra_bridge is not started", fg="red")
except ConnectionRefusedError:
    secho("ghidra_bridge connection error", fg="red")
else:
    if conf.config is None:
        conf.config = conf.Config()
    if conf.config.Ghidra.manager == "program":
        dtm = currentProgram.getDataTypeManager()
        if conf.VERBOSE:
            secho("ghidra_bridge connection with data type manager %s" % dtm,
                  fg="blue")
        tr = dtm.startTransaction("ccrawl")
        root = dtm.getRootCategory()
        catp = root.createCategory(conf.config.Ghidra.category)
        dtm.endTransaction(tr, True)
        if conf.VERBOSE:
            secho("importing types in ccrawl category...", fg="blue")
    else:
        dtm = ghidra.program.model.data.StandAloneDataTypeManager(
            conf.config.Ghidra.category)
        if conf.VERBOSE: