Skip to content

Commit 88b42ad

Browse files
authored
Merge pull request #1 from dillonfranke/ignore-duplicate-modules-option
Implement -ignore_duplicates_module
2 parents ed07784 + 8517901 commit 88b42ad

4 files changed

Lines changed: 26 additions & 5 deletions

File tree

README.md

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

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

191+
`-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.
192+
191193
`-patch_return_addresses` - replaces return address with the original value, causes returns to be instrumented using whatever `-indirect_instrumentation` method is specified
192194

193195
`-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: 22 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;
@@ -850,6 +851,8 @@ void TinyInst::OnModuleInstrumented(ModuleInfo* module) {
850851
}
851852
if(address) {
852853
resolved_hooks[address] = hook;
854+
} else {
855+
FATAL("Could not resolve function %s in module %s", hook->GetFunctionName().c_str(), hook->GetModuleName().c_str());
853856
}
854857
}
855858
}
@@ -1075,9 +1078,14 @@ void TinyInst::OnInstrumentModuleLoaded(void *module, ModuleInfo *target_module)
10751078
target_module->module_header &&
10761079
(target_module->module_header != (void *)module))
10771080
{
1078-
WARN("Instrumented module loaded on a different address than seen previously\n"
1079-
"Module will need to be re-instrumented. Expect a drop in performance.");
1080-
ClearInstrumentation(target_module);
1081+
if (target_module->ignore_duplicates) {
1082+
WARN("Skipping duplicate module %s.", target_module->module_name.c_str());
1083+
return;
1084+
} else {
1085+
WARN("Instrumented module loaded on a different address than seen previously\n"
1086+
"Module will need to be re-instrumented. Expect a drop in performance.");
1087+
ClearInstrumentation(target_module);
1088+
}
10811089
}
10821090

10831091
target_module->module_header = (void *)module;
@@ -1095,7 +1103,7 @@ void TinyInst::OnInstrumentModuleLoaded(void *module, ModuleInfo *target_module)
10951103
}
10961104
}
10971105

1098-
// called when a potentialy interesting module gets loaded
1106+
// called when a potentially interesting module gets loaded
10991107
void TinyInst::OnModuleLoaded(void *module, char *module_name) {
11001108
Debugger::OnModuleLoaded(module, module_name);
11011109

@@ -1277,6 +1285,9 @@ void TinyInst::Init(int argc, char **argv) {
12771285
std::list <char *> module_names;
12781286
GetOptionAll("-instrument_module", argc, argv, &module_names);
12791287

1288+
std::list <char *> ignored_duplicate_modules;
1289+
GetOptionAll("-ignore_duplicates_module", argc, argv, &ignored_duplicate_modules);
1290+
12801291
#if defined(__APPLE__) && defined(ARM64)
12811292
std::set <std::string> orig_uniq_mod_names;
12821293
std::set <std::string> new_uniq_mod_names;
@@ -1314,6 +1325,13 @@ void TinyInst::Init(int argc, char **argv) {
13141325
#endif
13151326

13161327
for (const auto module_name: module_names) {
1328+
ModuleInfo *new_module = new ModuleInfo();
1329+
new_module->module_name = module_name;
1330+
for (const auto& ignored_module : ignored_duplicate_modules) {
1331+
if (strcmp(ignored_module, module_name) == 0) {
1332+
new_module->ignore_duplicates = true;
1333+
}
1334+
}
13171335
AddInstrumentedModule(module_name, true);
13181336
// SAY("--- %s\n", module_name);
13191337
}

tinyinst.h

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

298299
size_t instrumented_code_size;

0 commit comments

Comments
 (0)