Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions SyringeDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,19 @@ static void ResolveRelativeOperands(
}

std::vector<BYTE> SyringeDebugger::RebuildInstructions(
BYTE const* bytes, size_t size, DWORD originalAddr, DWORD newAddr)
BYTE const* bytes, size_t size, DWORD originalAddr, DWORD newAddr,
std::string_view const hookLibraries)
{
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_COMPAT_32, ZYDIS_STACK_WIDTH_32);

std::string hookContext;
if (!hookLibraries.empty())
{
hookContext = " in DLL(s): ";
hookContext += hookLibraries;
}

// --- Pass 1: decode all instructions and classify relative branches ---

struct InstructionInfo
Expand Down Expand Up @@ -147,9 +155,9 @@ std::vector<BYTE> SyringeDebugger::RebuildInstructions(
Log::WriteLine(
__FUNCTION__ ": Failed to decode instruction at 0x%08X, "
"copying remaining %u bytes verbatim. This could mean "
"there is a faulty return 0 hook at 0x%08X.",
"there is a faulty return 0 hook at 0x%08X%s.",
static_cast<DWORD>(srcAddr), static_cast<unsigned>(size - offset),
originalAddr);
originalAddr, hookContext.c_str());

tailOffset = offset;
break;
Expand Down Expand Up @@ -205,10 +213,10 @@ std::vector<BYTE> SyringeDebugger::RebuildInstructions(
Log::WriteLine(
__FUNCTION__ ": Relative instruction "
"at 0x%08X has an intra-prologue target "
"but no near encoding. Hook at 0x%08X "
"but no near encoding. Hook at 0x%08X%s "
"may not work correctly.",
static_cast<DWORD>(srcAddr),
originalAddr);
static_cast<DWORD>(srcAddr), originalAddr,
hookContext.c_str());
}
}
}
Expand Down Expand Up @@ -555,6 +563,27 @@ DWORD SyringeDebugger::HandleException(DEBUG_EVENT const& dbgEvent)
continue;
}

std::set<std::string_view> rebuildLibraries;
for (auto const& hook : it.second.hooks)
{
if (hook.proc_address && hook.num_overridden == overridden)
{
rebuildLibraries.emplace(hook.lib);
}
}

std::string rebuildLibraryNames;
for (auto const library : rebuildLibraries)
{
if (!rebuildLibraryNames.empty())
{
rebuildLibraryNames += ", ";
}
rebuildLibraryNames += '"';
rebuildLibraryNames += library;
rebuildLibraryNames += '"';
}

// read the overridden bytes from the target process
std::vector<BYTE> original_bytes(overridden);
ReadMem(it.first, original_bytes.data(), overridden);
Expand Down Expand Up @@ -595,7 +624,8 @@ DWORD SyringeDebugger::HandleException(DEBUG_EVENT const& dbgEvent)
base + (p_code - code.data()));

auto rebuilt = RebuildInstructions(
original_bytes.data(), overridden, originalAddr, newAddr);
original_bytes.data(), overridden, originalAddr, newAddr,
rebuildLibraryNames);

std::memcpy(p_code, rebuilt.data(), rebuilt.size());
p_code += rebuilt.size();
Expand Down
4 changes: 3 additions & 1 deletion SyringeDebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@
{
dlls.emplace_back(flagView.begin() + pos + INCLUDE_FLAG.size(), flagView.end());
}
else if (auto const pos = flagView.find(DETACH_FLAG); pos != std::string_view::npos)

Check warning on line 54 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 54 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 54 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]

Check warning on line 54 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 54 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 54 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]
{
bDetachWhenDone = true;
}
else if (auto const pos = flagView.find(NODETACH_FLAG); pos != std::string_view::npos)

Check warning on line 58 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 58 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 58 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]

Check warning on line 58 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 58 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 58 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]
{
bDetachWhenDone = false;
}
else if (auto const pos = flagView.find(NOWAIT_FLAG); pos != std::string_view::npos)

Check warning on line 62 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 62 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]

Check warning on line 62 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 62 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]
{
bWaitForProcessEnd = false;
}
else if (auto const pos = flagView.find(HANDSHAKES_FLAG); pos != std::string_view::npos)

Check warning on line 66 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 66 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Debug)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]

Check warning on line 66 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Tests.vcxproj]

Check warning on line 66 in SyringeDebugger.h

View workflow job for this annotation

GitHub Actions / build (Release)

declaration of 'pos' hides previous local declaration [D:\a\SyringeEx\SyringeEx\Debugger.vcxproj]
{
bHandshakes = true;
}
Expand Down Expand Up @@ -107,7 +107,9 @@
#ifdef SYRINGE_TESTING
public:
#endif
static std::vector<BYTE> RebuildInstructions(BYTE const* bytes, size_t size, DWORD originalAddr, DWORD newAddr);
static std::vector<BYTE> RebuildInstructions(
BYTE const* bytes, size_t size, DWORD originalAddr, DWORD newAddr,
std::string_view hookLibraries = {});
#ifdef SYRINGE_TESTING
private:
#endif
Expand Down
Loading