FLOSS string decoding algorithm arguments: vw: the workspace functions: addresses of the candidate decoding routines min_length: minimum string length max_insn_count: max number of instructions to emulate per function verbosity: verbosity level
(
vw: VivWorkspace,
functions: List[int],
min_length: int,
max_insn_count: int = DS_MAX_INSN_COUNT,
verbosity: int = Verbosity.DEFAULT,
disable_progress: bool = False,
)
| 123 | |
| 124 | |
| 125 | def decode_strings( |
| 126 | vw: VivWorkspace, |
| 127 | functions: List[int], |
| 128 | min_length: int, |
| 129 | max_insn_count: int = DS_MAX_INSN_COUNT, |
| 130 | verbosity: int = Verbosity.DEFAULT, |
| 131 | disable_progress: bool = False, |
| 132 | ) -> List[DecodedString]: |
| 133 | """ |
| 134 | FLOSS string decoding algorithm |
| 135 | |
| 136 | arguments: |
| 137 | vw: the workspace |
| 138 | functions: addresses of the candidate decoding routines |
| 139 | min_length: minimum string length |
| 140 | max_insn_count: max number of instructions to emulate per function |
| 141 | verbosity: verbosity level |
| 142 | disable_progress: no progress bar |
| 143 | """ |
| 144 | logger.info("decoding strings") |
| 145 | |
| 146 | decoded_strings = list() |
| 147 | function_index = viv_utils.InstructionFunctionIndex(vw) |
| 148 | |
| 149 | pb = floss.utils.get_progress_bar(functions, disable_progress, desc="decoding strings", unit=" functions") |
| 150 | with tqdm.contrib.logging.logging_redirect_tqdm(), floss.utils.redirecting_print_to_tqdm(): |
| 151 | for fva in pb: |
| 152 | seen: Set[str] = floss.utils.get_referenced_strings(vw, fva) |
| 153 | ctxs = extract_decoding_contexts(vw, fva, function_index) |
| 154 | n_calls = len(ctxs) |
| 155 | for n, ctx in enumerate(ctxs, 1): |
| 156 | if isinstance(pb, tqdm.tqdm): |
| 157 | pb.set_description(f"emulating function 0x{fva:x} (call {n}/{n_calls})") |
| 158 | |
| 159 | if should_shortcut(fva, n, n_calls, len(seen)): |
| 160 | break |
| 161 | |
| 162 | for delta in emulate_decoding_routine(vw, function_index, fva, ctx, max_insn_count): |
| 163 | for delta_bytes in extract_delta_bytes(delta, ctx.decoded_at_va, fva): |
| 164 | for s in floss.utils.extract_strings(delta_bytes.bytes, min_length, seen): |
| 165 | ds = DecodedString( |
| 166 | address=delta_bytes.address + s.offset, |
| 167 | address_type=delta_bytes.address_type, |
| 168 | string=s.string, |
| 169 | encoding=s.encoding, |
| 170 | decoded_at=delta_bytes.decoded_at, |
| 171 | decoding_routine=delta_bytes.decoding_routine, |
| 172 | ) |
| 173 | floss.results.log_result(ds, verbosity) |
| 174 | seen.add(ds.string) |
| 175 | decoded_strings.append(ds) |
| 176 | return decoded_strings |
| 177 | |
| 178 | |
| 179 | def emulate_decoding_routine(vw, function_index, function: int, context, max_instruction_count: int) -> List[Delta]: |
no test coverage detected