def unpack_package(name): package_source = get_config('package_source') package_arch = get_config('package_arch') package_options = get_config('package_options') dir = tempfile.mkdtemp('', '', get_temp_dir()) os.chdir(dir) try: filename = download_from_apt(name, package_source, package_arch, package_options) result = re.match('([^_]+)_([^_]+)_([^.]+).deb', filename) if not result: raise Exception("\'" + name + "\' is not properly downloaded") name = result.group(1) version = result.group(2) arch = result.group(3) result = subprocess.call(["dpkg", "-x", filename, "."], stdout=null_dev, stderr=null_dev) if result != 0: raise Exception("Cannot unpack \'" + name + "\'") except: os.chdir(root_dir) package.remove_dir(dir) raise os.chdir(root_dir) return (dir, name, version)
def BinarySymbol(jmgr, os_target, sql, args): sql.connect_table(tables['binary_list']) sql.connect_table(tables['binary_symbol']) pkgname = args[0] bin = args[1] dir = args[2] if len(args) > 3: ref = args[3] if not package.reference_exists(dir, ref): dir = None ref = None else: ref = None unpacked = False if not dir: (dir, pkgname, _) = package.unpack_package(os_target, args[0]) if not dir: return unpacked = True exc = None try: path = dir + '/' + bin if not os.path.exists(path): raise Exception('path ' + path + ' does not exist') symbols = os_target.get_binary_symbols(dir, bin) pkg_id = get_package_id(sql, pkgname) bin_id = get_binary_id(sql, bin) condition = 'pkg_id=' + Table.stringify( pkg_id) + ' and bin_id=' + Table.stringify(bin_id) sql.delete_record(tables['binary_symbol'], condition) for sym in symbols: values = dict() values['pkg_id'] = pkg_id values['bin_id'] = bin_id values['symbol_name'] = sym.name values['version'] = sym.version values['func_addr'] = sym.addr sql.append_record(tables['binary_symbol'], values) sql.update_record(tables['binary_list'], {'callgraph': False}, condition) sql.commit() except Exception as err: exc = sys.exc_info() if (ref and package.dereference_dir(dir, ref)) or unpacked: package.remove_dir(dir) if exc: raise exc[1], None, exc[2]
def BinaryInstr(jmgr, os_target, sql, args): sql.connect_table(tables['binary_call']) sql.connect_table(tables['binary_call_unknown']) sql.connect_table(tables['binary_opcode_usage']) sql.connect_table(tables['binary_call_missrate']) # sql.connect_table(tables['instr_list']) # sql.connect_table(tables['prefix_counts']) pkgname = args[0] bin = args[1] dir = args[2] pkg_id = get_package_id(sql, pkgname) if len(args) > 3: ref = args[3] if not package.reference_exists(dir, ref): dir = None ref = None else: ref = None unpacked = False if not dir: (dir, pkgname, _) = package.unpack_package(os_target, args[0]) if not dir: return unpacked = True exc = None try: if not os.path.exists(dir + bin): raise Exception('path ' + dir + bin + ' does not exist') bin_id = get_binary_id(sql, bin) os_target.analysis_binary_instr_linear(sql, dir, bin, pkg_id, bin_id) condition = 'pkg_id=' + Table.stringify( pkg_id) + ' and bin_id=' + Table.stringify(bin_id) sql.update_record(tables['binary_list'], {'callgraph': False}, condition) sql.commit() except Exception as err: exc = sys.exc_info() if (ref and package.dereference_dir(dir, ref)) or unpacked: package.remove_dir(dir) if exc: raise exc[1], None, exc[2]
def download_package_source(name, unpack=False): package_source = get_config('package_source') package_arch = get_config('package_arch') package_options = get_config('package_options') dir = tempfile.mkdtemp('', '', get_temp_dir()) os.chdir(dir) try: download_source_from_apt(name, package_source, package_arch, package_options, unpack) except: os.chdir(root_dir) package.remove_dir(dir) raise os.mkdir(dir + '/refs') os.chdir(root_dir) return dir
def unpack_package(name): package_source = get_config('package_source') package_arch = get_config('package_arch') package_options = get_config('package_options') dir = tempfile.mkdtemp('', '', get_temp_dir()) os.chdir(dir) try: #filename = download_from_apt(name, package_source, # package_arch, package_options) #compile_package(name) directoryname = "/filer/bin/gcc-nostripopt/" + name filename1 = '' for filename in (os.listdir(directoryname)): result = re.match('([^_]+)_([^_]+)_([^.]+).deb', filename) if not result: raise Exception("\'" + name + "\' is not properly downloaded") name1 = result.group(1) version = result.group(2) arch = result.group(3) if name1 == name: filename1 = filename break if filename1 != '': result = subprocess.call( ["dpkg", "-x", directoryname + "/" + filename1, "."], stdout=null_dev, stderr=null_dev) else: raise Exception("File not found \'" + name + "\'") if result != 0: raise Exception("Cannot unpack \'" + name + "\'") except: os.chdir(root_dir) package.remove_dir(dir) raise os.chdir(root_dir) return (dir, name, version)
def BinaryDependency(jmgr, os_target, sql, args): sql.connect_table(tables['binary_dependency']) sql.connect_table(tables['binary_interp']) pkgname = args[0] bin = args[1] dir = args[2] if len(args) > 3: ref = args[3] if not package.reference_exists(dir, ref): dir = None ref = None else: ref = None unpacked = False if not dir: (dir, pkgname, _) = package.unpack_package(os_target, args[0]) if not dir: return unpacked = True exc = None try: if not os.path.exists(dir + bin): raise Exception('path ' + dir + bin + ' does not exist') dependencies = os_target.get_binary_dependencies(dir, bin) interp = os_target.get_binary_interpreter(dir, bin) pkg_id = get_package_id(sql, pkgname) bin_id = get_binary_id(sql, bin) if interp: interp = get_binary_id(sql, interp) condition = 'pkg_id=' + Table.stringify( pkg_id) + ' and bin_id=' + Table.stringify(bin_id) sql.delete_record(tables['binary_dependency'], condition) sql.delete_record(tables['binary_interp'], condition) for dep in dependencies: values = dict() values['pkg_id'] = pkg_id values['bin_id'] = bin_id values['dependency'] = dep sql.append_record(tables['binary_dependency'], values) if interp: values = dict() values['pkg_id'] = pkg_id values['bin_id'] = bin_id values['interp'] = interp sql.append_record(tables['binary_interp'], values) sql.update_record(tables['binary_list'], {'linking': False}, condition) sql.commit() except Exception as err: exc = sys.exc_info() if (ref and package.dereference_dir(dir, ref)) or unpacked: package.remove_dir(dir) if exc: raise exc[1], None, exc[2]
def get_package_info(pkgname): package_source = get_config('package_source') package_arch = get_config('package_arch') package_options = get_config('package_options') cmd = [] if package_source: cmd += apt_options_for_source(package_source) if package_arch: cmd += ["-o", "APT::Architectures=" + package_arch] if package_options: for (opt, val) in package_options.items(): cmd += ["-o", opt + "=" + val] process = subprocess.Popen(["apt-get"] + cmd + ["download", "--print-uris", pkgname], stdout=subprocess.PIPE, stderr=null_dev) (stdout, _) = process.communicate() for line in stdout.split('\n'): m = re.match( '\'([^\']+)\'\s+[^\s_]+_([^\s_]+)_([^\s_]+).deb\s+\d+\s+(\S+)', line) if m: uri = m.group(1) version = m.group(2) arch = m.group(3) hash = m.group(4) has_source = False extensions = [".c", ".cpp", ".c++", ".cxx", ".cc", ".cp"] dir = None process = None try: dir = download_package_source(pkgname) if (dir): for (root, subdirs, files) in os.walk(dir): for f in files: args = None if f.endswith(".tar"): args = "-tf" elif f.endswith(".tar.gz") or f.endswith(".tgz"): args = "-tzf" elif f.endswith(".tar.bz2"): args = "-tjf" elif f.endswith(".tar.xz"): args = "-tJf" if args is None: continue process = subprocess.Popen(["tar", args, root + "/" + f], stdout=subprocess.PIPE, stderr=null_dev) for line in process.stdout: line = line.strip() for ext in extensions: if line.endswith(ext): has_source = True except Exception as e: logging.info(str(e)) pass if process: process.kill() if dir: package.remove_dir(dir) return { 'arch': arch, 'version': version, 'uri': uri, 'opensource': has_source, 'hash': hash }