|
11 | 11 | #include <fstream> |
12 | 12 | #include <memory> |
13 | 13 | #include <numeric> |
| 14 | +#include <set> |
14 | 15 |
|
15 | 16 | #include <DbgHelp.h> |
16 | 17 |
|
@@ -145,6 +146,73 @@ DWORD SyringeDebugger::HandleException(DEBUG_EVENT const& dbgEvent) |
145 | 146 | Log::WriteLine(__FUNCTION__ ": Finished retrieving proc addresses."); |
146 | 147 | bDLLsLoaded = true; |
147 | 148 |
|
| 149 | + if (!v_FeatureFlags.empty()) |
| 150 | + { |
| 151 | + Log::WriteLine(__FUNCTION__ ": Starting feature flags resolution..."); |
| 152 | + loop_FeatureFlags = v_FeatureFlags.begin(); |
| 153 | + auto const& entry = *loop_FeatureFlags; |
| 154 | + PatchMem(&GetData()->LibName, entry.lib, MaxNameLength); |
| 155 | + PatchMem(&GetData()->ProcName, entry.symbol, MaxNameLength); |
| 156 | + |
| 157 | + context.Eip = reinterpret_cast<DWORD>(&GetData()->LoadLibraryFunc); |
| 158 | + } |
| 159 | + else |
| 160 | + { |
| 161 | + bFeaturesSet = true; |
| 162 | + context.Eip = reinterpret_cast<DWORD>(pcEntryPoint); |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + // single step mode |
| 167 | + context.EFlags |= 0x100; |
| 168 | + context.ContextFlags = CONTEXT_CONTROL; |
| 169 | + SetThreadContext(currentThread, &context); |
| 170 | + |
| 171 | + threadInfo.lastBP = exceptAddr; |
| 172 | + |
| 173 | + return DBG_CONTINUE; |
| 174 | + } |
| 175 | + |
| 176 | + // set feature flags in loaded DLLs |
| 177 | + if (!bFeaturesSet) |
| 178 | + { |
| 179 | + // restore |
| 180 | + PatchMem(exceptAddr, &Breakpoints[exceptAddr].original_opcode, 1); |
| 181 | + |
| 182 | + // read the resolved address of the feature flag in the target process |
| 183 | + void* flagAddr = nullptr; |
| 184 | + ReadMem(&GetData()->ProcAddress, &flagAddr, 4); |
| 185 | + |
| 186 | + if (flagAddr) |
| 187 | + { |
| 188 | + BYTE const trueVal = 1; |
| 189 | + PatchMem(flagAddr, &trueVal, 1); |
| 190 | + Log::WriteLine( |
| 191 | + __FUNCTION__ ": Set feature flag \"%s\" in \"%s\" at 0x%08X", |
| 192 | + loop_FeatureFlags->symbol, loop_FeatureFlags->lib, flagAddr); |
| 193 | + } |
| 194 | + else |
| 195 | + { |
| 196 | + Log::WriteLine( |
| 197 | + __FUNCTION__ ": Feature flag \"%s\" not exported by \"%s\", skipping.", |
| 198 | + loop_FeatureFlags->symbol, loop_FeatureFlags->lib); |
| 199 | + } |
| 200 | + |
| 201 | + ++loop_FeatureFlags; |
| 202 | + |
| 203 | + if (loop_FeatureFlags != v_FeatureFlags.end()) |
| 204 | + { |
| 205 | + auto const& entry = *loop_FeatureFlags; |
| 206 | + PatchMem(&GetData()->LibName, entry.lib, MaxNameLength); |
| 207 | + PatchMem(&GetData()->ProcName, entry.symbol, MaxNameLength); |
| 208 | + |
| 209 | + context.Eip = reinterpret_cast<DWORD>(&GetData()->LoadLibraryFunc); |
| 210 | + } |
| 211 | + else |
| 212 | + { |
| 213 | + Log::WriteLine(__FUNCTION__ ": Finished setting feature flags."); |
| 214 | + bFeaturesSet = true; |
| 215 | + |
148 | 216 | context.Eip = reinterpret_cast<DWORD>(pcEntryPoint); |
149 | 217 | } |
150 | 218 |
|
@@ -505,6 +573,7 @@ void SyringeDebugger::Run(std::string_view const arguments) |
505 | 573 | // breakpoints for DLL loading and proc address retrieving |
506 | 574 | bDLLsLoaded = false; |
507 | 575 | bHooksCreated = false; |
| 576 | + bFeaturesSet = false; |
508 | 577 | loop_LoadLibrary = v_AllHooks.end(); |
509 | 578 |
|
510 | 579 | // set breakpoint |
@@ -779,6 +848,29 @@ void SyringeDebugger::FindDLLs() |
779 | 848 | } |
780 | 849 |
|
781 | 850 | Log::WriteLine(__FUNCTION__ ": Done (%d hooks added).", v_AllHooks.size()); |
| 851 | + |
| 852 | + // build feature flag entries for each unique DLL |
| 853 | + v_FeatureFlags.clear(); |
| 854 | + { |
| 855 | + std::set<std::string> uniqueLibs; |
| 856 | + for (auto const& hook : v_AllHooks) |
| 857 | + { |
| 858 | + if (uniqueLibs.insert(hook->lib).second) |
| 859 | + { |
| 860 | + for (auto const& flagName : FeatureFlagNames) |
| 861 | + { |
| 862 | + FeatureFlagEntry entry{}; |
| 863 | + strncpy_s(entry.lib, hook->lib, MaxNameLength - 1); |
| 864 | + flagName.copy(entry.symbol, MaxNameLength - 1); |
| 865 | + v_FeatureFlags.push_back(entry); |
| 866 | + } |
| 867 | + } |
| 868 | + } |
| 869 | + } |
| 870 | + |
| 871 | + Log::WriteLine( |
| 872 | + __FUNCTION__ ": %d feature flag entries prepared.", |
| 873 | + v_FeatureFlags.size()); |
782 | 874 | Log::WriteLine(); |
783 | 875 | } |
784 | 876 |
|
|
0 commit comments