Skip to content

Commit e778f9d

Browse files
committed
FaultyFileDetector: Fix garbage names appearing in RE9
1 parent 9e3b6b4 commit e778f9d

1 file changed

Lines changed: 21 additions & 16 deletions

File tree

src/mods/FaultyFileDetector.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -224,32 +224,30 @@ bool FaultyFileDetector::scan_resource_process_parse_and_hook() {
224224
if (instr->Instruction == ND_INS_CALLNI) {
225225
if (instr->OperandsCount >= 1 && instr->Operands[0].Type == ND_OP_MEM) {
226226
auto mem_operand = instr->Operands[0].Info.Memory;
227-
if (mem_operand.Base == NDR_RAX) {
227+
if (mem_operand.HasBase && mem_operand.Base == NDR_RAX) {
228228
if (mem_operand.Disp == first_call_vtable_offset && !found[0]) {
229229
// First call found
230230
current_calls_found++;
231-
start_searching_resource_access_ptr = after_call_ptr + instr->Length;
231+
start_searching_resource_access_ptr = (uint8_t*)(ctx.addr + instr->Length); // The instruction that accesses resource after the call is usually right after the call instruction, so we can start searching from there
232232
found[0] = true;
233-
spdlog::info("[FaultyFileDetector]: Found first call at 0x{:X}", (uintptr_t)after_call_ptr);
233+
spdlog::info("[FaultyFileDetector]: Found first call at 0x{:X}", (uintptr_t)ctx.addr);
234234
} else if (mem_operand.Disp == second_call_vtable_offset && !found[1]) {
235235
// Second call found
236236
current_calls_found++;
237-
parse_call_ptr = after_call_ptr;
238-
parse_call_return_address = after_call_ptr + instr->Length;
237+
parse_call_ptr = (uint8_t*)(ctx.addr);
238+
parse_call_return_address = (uint8_t*)(ctx.addr + instr->Length);
239239
found[1] = true;
240-
spdlog::info("[FaultyFileDetector]: Found second call at 0x{:X}", (uintptr_t)after_call_ptr);
240+
spdlog::info("[FaultyFileDetector]: Found second call at 0x{:X}", (uintptr_t)ctx.addr);
241241
} else if (mem_operand.Disp == third_call_vtable_offset && !found[2]) {
242242
// Third call found
243243
current_calls_found++;
244244
found[2] = true;
245-
spdlog::info("[FaultyFileDetector]: Found third call at 0x{:X}", (uintptr_t)after_call_ptr);
245+
spdlog::info("[FaultyFileDetector]: Found third call at 0x{:X}", (uintptr_t)ctx.addr);
246246
}
247247
}
248248
}
249249
}
250250

251-
after_call_ptr += instr->Length;
252-
253251
// step over calls.
254252
if (instr->Category == ND_CAT_CALL) {
255253
return utility::ExhaustionResult::STEP_OVER;
@@ -269,23 +267,30 @@ bool FaultyFileDetector::scan_resource_process_parse_and_hook() {
269267
std::uint8_t *resource_argument_assigned_ptr = nullptr;
270268

271269
// Very fragile way, but it works for now
272-
for (int i = 0; i < resource_register_search_max_num_instructions; i++) {
273-
auto instrux = utility::decode_one(instr_ptr);
274-
if (instrux && std::string_view(instrux->Mnemonic).starts_with("MOV")) {
270+
//for (int i = 0; i < resource_register_search_max_num_instructions; i++) {
271+
//auto instrux = utility::decode_one(instr_ptr);
272+
utility::exhaustive_decode((uint8_t*)start_searching_resource_access_ptr, resource_register_search_max_num_instructions, [&](utility::ExhaustionContext& ctx) -> utility::ExhaustionResult {
273+
if (resource_argument_assigned_ptr != nullptr) {
274+
return utility::ExhaustionResult::BREAK;
275+
}
276+
277+
auto instrux = &ctx.instrux;
278+
if (std::string_view(instrux->Mnemonic).starts_with("MOV")) {
275279
bool is_first_operator_first_arg = instrux->OperandsCount >= 1 && instrux->Operands[0].Type == ND_OP_REG && instrux->Operands[0].Info.Register.Reg == NDR_RCX;
276280
bool is_second_operator_register = instrux->OperandsCount >= 2 && instrux->Operands[1].Type == ND_OP_REG;
277281
// Seen in RE9
278282
bool is_second_operator_rsp_based = instrux->OperandsCount >= 2 && instrux->Operands[1].Type == ND_OP_MEM && instrux->Operands[1].Info.Memory.Base == NDR_RSP;
279283

280284
if (is_first_operator_first_arg && (is_second_operator_register || is_second_operator_rsp_based)) {
281-
resource_argument_assigned_ptr = instr_ptr + instrux->Length;
285+
resource_argument_assigned_ptr = (uint8_t*)(ctx.addr + instrux->Length); // The instruction that uses the resource argument is the next instruction after the assignment
282286
spdlog::info("[FaultyFileDetector]: Found resource argument assign at 0x{:x}, hooking to extract it at: 0x{:x}", (uintptr_t)instr_ptr, (uintptr_t)resource_argument_assigned_ptr);
283287

284-
break;
288+
return utility::ExhaustionResult::BREAK;
285289
}
286290
}
287-
instr_ptr += instrux ? instrux->Length : 1;
288-
}
291+
292+
return utility::ExhaustionResult::CONTINUE;
293+
});
289294

290295
if (resource_argument_assigned_ptr == nullptr) {
291296
spdlog::warn("[FaultyFileDetector]: Failed to find resource argument assign from 0x{:X}", (uintptr_t)parse_call_ptr);

0 commit comments

Comments
 (0)