Exemplo n.º 1
0
def create_rekall_profiles(injector: Injector):
    tmp = None

    for file in dll_file_list:
        try:
            logging.info(f"Fetching rekall profile for {file.path}")

            local_dll_path = os.path.join(PROFILE_DIR, file.dest)
            guest_dll_path = str(PureWindowsPath("C:/", file.path))

            cmd = injector.read_file(guest_dll_path, local_dll_path)
            out = json.loads(cmd.stdout.decode())
            if out["Status"] == "Error" and out["Error"] in [
                    "ERROR_FILE_NOT_FOUND", "ERROR_PATH_NOT_FOUND"
            ]:
                raise FileNotFoundError
            if out["Status"] != "Success":
                logging.debug("stderr: " + cmd.stderr.decode())
                logging.debug(out)
                # Take care if the error message is changed
                raise Exception("Some error occurred in injector")

            guid = pdb_guid(local_dll_path)
            tmp = fetch_pdb(guid["filename"], guid["GUID"], PROFILE_DIR)

            logging.debug("Parsing PDB into JSON profile...")
            profile = make_pdb_profile(tmp)
            with open(os.path.join(PROFILE_DIR, f"{file.dest}.json"),
                      'w') as f:
                f.write(profile)
        except json.JSONDecodeError:
            logging.debug(f"stdout: {cmd.stdout}")
            logging.debug(f"stderr: {cmd.stderr}")
            logging.debug(traceback.format_exc())
            raise Exception(f"Failed to parse json response on {file.path}")
        except FileNotFoundError:
            logging.warning(f"Failed to copy file {file.path}, skipping...")
        except RuntimeError:
            logging.warning(
                f"Failed to fetch profile for {file.path}, skipping...")
        except Exception as e:
            # Take care if the error message is changed
            if str(e) == "Some error occurred in injector":
                raise
            else:
                logging.warning(
                    f"Unexpected exception while creating rekall profile for {file.path}, skipping..."
                )
                # Can help in debugging
                logging.debug("stderr: " + cmd.stderr.decode())
                logging.debug(out)
                logging.debug(traceback.format_exc())
        finally:
            safe_delete(local_dll_path)
            # was crashing here if the first file reached some exception
            if tmp is not None:
                safe_delete(os.path.join(PROFILE_DIR, tmp))
Exemplo n.º 2
0
def create_rekall_profile(injector: Injector, file: DLL, raise_on_error=False):
    pdb_tmp_filepath = None
    cmd = None
    out = None
    try:
        logging.info(f"Fetching rekall profile for {file.path}")

        local_dll_path = os.path.join(PROFILE_DIR, file.dest)
        guest_dll_path = str(PureWindowsPath("C:/", file.path))

        cmd = injector.read_file(guest_dll_path, local_dll_path)
        out = json.loads(cmd.stdout.decode())
        if out["Status"] == "Error" and out["Error"] in [
                "ERROR_FILE_NOT_FOUND",
                "ERROR_PATH_NOT_FOUND",
        ]:
            raise FileNotFoundError
        if out["Status"] != "Success":
            logging.debug("stderr: " + cmd.stderr.decode())
            logging.debug(out)
            # Take care if the error message is changed
            raise Exception("Some error occurred in injector")

        static_apiscout_dll_profile = make_static_apiscout_profile_for_dll(
            local_dll_path)
        with open(os.path.join(APISCOUT_PROFILE_DIR, f"{file.dest}.json"),
                  "w") as f:
            f.write(
                json.dumps(static_apiscout_dll_profile,
                           indent=4,
                           sort_keys=True))

        codeview_data = pe_codeview_data(local_dll_path)
        pdb_tmp_filepath = fetch_pdb(codeview_data["filename"],
                                     codeview_data["symstore_hash"],
                                     PROFILE_DIR)

        logging.debug("Parsing PDB into JSON profile...")
        profile = make_pdb_profile(
            pdb_tmp_filepath,
            dll_origin_path=guest_dll_path,
            dll_path=local_dll_path,
            dll_symstore_hash=codeview_data["symstore_hash"],
        )
        with open(os.path.join(PROFILE_DIR, f"{file.dest}.json"), "w") as f:
            f.write(profile)
    except json.JSONDecodeError:
        logging.debug(f"stdout: {cmd.stdout}")
        logging.debug(f"stderr: {cmd.stderr}")
        logging.debug(traceback.format_exc())
        raise Exception(f"Failed to parse json response on {file.path}")
    except FileNotFoundError as e:
        on_create_rekall_profile_failure(f"Failed to copy file {file.path}",
                                         raise_on_error, e)
    except RuntimeError as e:
        on_create_rekall_profile_failure(
            f"Failed to fetch profile for {file.path}", raise_on_error, e)
    except subprocess.TimeoutExpired as e:
        on_create_rekall_profile_failure(f"Injector timed out for {file.path}",
                                         raise_on_error, e)
    except Exception as e:
        # Take care if the error message is changed
        if str(e) == "Some error occurred in injector":
            raise
        else:
            # Can help in debugging
            if cmd:
                logging.debug("stdout: " + cmd.stdout.decode())
                logging.debug("stderr: " + cmd.stderr.decode())
                logging.debug("rc: " + str(cmd.returncode))
            logging.debug(traceback.format_exc())
            on_create_rekall_profile_failure(
                f"Unexpected exception while creating rekall profile for {file.path}",
                raise_on_error,
                e,
            )
    finally:
        safe_delete(local_dll_path)
        # was crashing here if the first file reached some exception
        if pdb_tmp_filepath is not None:
            safe_delete(os.path.join(PROFILE_DIR, pdb_tmp_filepath))