Skip to content

Commit 2a54040

Browse files
committed
Implement -ignore_duplicates_module
1 parent e651645 commit 2a54040

4 files changed

Lines changed: 24 additions & 5 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ In addition to the general-purpose API documented above, TinyInst also implement
186186

187187
`-indirect_instrumentation [none|local|global|auto]` which instrumentation to use for indirect jump/calls
188188

189+
`-ignore_duplicates_module [module name]` Ensures only the first loaded instance of `[module name]` is instrumented, ignoring subsequent duplicates. Useful when instrumenting system libraries (e.g., `CoreAudio`) on macOS Sequoia and later, where multiple distinct libraries with the same name may be loaded.
190+
189191
`-patch_return_addresses` - replaces return address with the original value, causes returns to be instrumented using whatever `-indirect_instrumentation` method is specified
190192

191193
`-generate_unwind` - Generates stack unwinding data for instrumented code (for faster C++ exception handling). Note that it might not work correctly on some older Windows versions.

hook.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ It is expected that most hooking operations can be performed just using the brea
2323

2424
If a hook needs to add additional assembly code, this can be done by implementing `WriteCodeBefore`/`WriteCodeAfter` methods of the hook class. Assembly code can be inserted by calling the `WriteCode` function with the buffer containing the assembly to be inserted. Note that both `WriteCodeBefore`/`WriteCodeAfter` get called during instrumentation time (before the function gets run) and, due to how `HookBeginEnd` is implemented, `WriteCodeAfter` can be called multiple times for a single hooked function.
2525

26-
Once the hook classes have been implemented for each function the user wants to hook, the user can register them by calling `RegisterHook` method inside their clien's constructor.
26+
Once the hook classes have been implemented for each function the user wants to hook, the user can register them by calling `RegisterHook` method inside their client's constructor.
2727

2828
### Example
2929

tinyinst.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ ModuleInfo::ModuleInfo() {
4343
max_address = 0;
4444
loaded = false;
4545
instrumented = false;
46+
ignore_duplicates = false;
4647
instrumented_code_local = NULL;
4748
instrumented_code_remote = NULL;
4849
instrumented_code_remote_previous = NULL;
@@ -849,6 +850,8 @@ void TinyInst::OnModuleInstrumented(ModuleInfo* module) {
849850
}
850851
if(address) {
851852
resolved_hooks[address] = hook;
853+
} else {
854+
FATAL("Could not resolve function %s in module %s", hook->GetFunctionName().c_str(), hook->GetModuleName().c_str());
852855
}
853856
}
854857
}
@@ -1071,9 +1074,14 @@ void TinyInst::OnInstrumentModuleLoaded(void *module, ModuleInfo *target_module)
10711074
target_module->module_header &&
10721075
(target_module->module_header != (void *)module))
10731076
{
1074-
WARN("Instrumented module loaded on a different address than seen previously\n"
1075-
"Module will need to be re-instrumented. Expect a drop in performance.");
1076-
ClearInstrumentation(target_module);
1077+
if (target_module->ignore_duplicates) {
1078+
WARN("Skipping duplicate module %s.", target_module->module_name.c_str());
1079+
return;
1080+
} else {
1081+
WARN("Instrumented module loaded on a different address than seen previously\n"
1082+
"Module will need to be re-instrumented. Expect a drop in performance.");
1083+
ClearInstrumentation(target_module);
1084+
}
10771085
}
10781086

10791087
target_module->module_header = (void *)module;
@@ -1091,7 +1099,7 @@ void TinyInst::OnInstrumentModuleLoaded(void *module, ModuleInfo *target_module)
10911099
}
10921100
}
10931101

1094-
// called when a potentialy interesting module gets loaded
1102+
// called when a potentially interesting module gets loaded
10951103
void TinyInst::OnModuleLoaded(void *module, char *module_name) {
10961104
Debugger::OnModuleLoaded(module, module_name);
10971105

@@ -1261,6 +1269,9 @@ void TinyInst::Init(int argc, char **argv) {
12611269
std::list <char *> module_names;
12621270
GetOptionAll("-instrument_module", argc, argv, &module_names);
12631271

1272+
std::list <char *> ignored_duplicate_modules;
1273+
GetOptionAll("-ignore_duplicates_module", argc, argv, &ignored_duplicate_modules);
1274+
12641275
#if defined(__APPLE__) && defined(ARM64)
12651276
std::set <std::string> orig_uniq_mod_names;
12661277
std::set <std::string> new_uniq_mod_names;
@@ -1300,6 +1311,11 @@ void TinyInst::Init(int argc, char **argv) {
13001311
for (const auto module_name: module_names) {
13011312
ModuleInfo *new_module = new ModuleInfo();
13021313
new_module->module_name = module_name;
1314+
for (const auto& ignored_module : ignored_duplicate_modules) {
1315+
if (strcmp(ignored_module, module_name) == 0) {
1316+
new_module->ignore_duplicates = true;
1317+
}
1318+
}
13031319
instrumented_modules.push_back(new_module);
13041320
// SAY("--- %s\n", module_name);
13051321
}

tinyinst.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ class ModuleInfo {
292292
size_t code_size;
293293
bool loaded;
294294
bool instrumented;
295+
bool ignore_duplicates;
295296
std::list<AddressRange> executable_ranges;
296297

297298
size_t instrumented_code_size;

0 commit comments

Comments
 (0)