Skip to content

Harden scc_lib.dll load against search-order hijack#148

Open
JustinMDotNet wants to merge 1 commit into
wopss:masterfrom
JustinMDotNet:fix/scc-lib-safe-loadlibrary
Open

Harden scc_lib.dll load against search-order hijack#148
JustinMDotNet wants to merge 1 commit into
wopss:masterfrom
JustinMDotNet:fix/scc-lib-safe-loadlibrary

Conversation

@JustinMDotNet

Copy link
Copy Markdown

Closes #138.

What this changes

In ExecuteProcess.cpp, the load of scc_lib.dll is hardened in two ways:

  1. Reject non-absolute scc paths. If aCommand is relative, replace_filename produces a relative path and the original LoadLibrary would fall back to the standard search order (application dir, system dirs, current dir, %PATH%). We now log a warning and chain to the original Global_ExecuteProcess without doing the in-process load.
  2. Use LoadLibraryExW with safe-search flags. Even when the path is absolute, the previous code allowed scc_lib.dll's own dependencies to be resolved with the default search order. The new call passes LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32, which restricts the search to the directory scc_lib.dll was loaded from plus System32.

Why

bin\x64 is writable by the user who runs the game, and the process working directory often is too. Either an attacker-planted DLL named scc_lib.dll or one of its imports could end up loaded into the game process. Per the LoadLibraryEx docs, the LOAD_LIBRARY_SEARCH_* flag family is the documented way to opt out of the legacy search-order behavior.

Design choice

Flag combination is LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32:

  • LOAD_LIBRARY_SEARCH_DLL_LOAD_DIRscc_lib.dll's dependencies resolve from the directory it lives in (the redscript install dir), which is what the previous behavior intended for normal users.
  • LOAD_LIBRARY_SEARCH_SYSTEM32 — system DLLs (kernel32, vcruntime, etc.) resolve from System32 only.

Notably not included:

  • LOAD_LIBRARY_SEARCH_APPLICATION_DIR — would let bin\x64 win, which is exactly the surface we want to close.
  • LOAD_LIBRARY_SEARCH_USER_DIRS — would honor anything added via AddDllDirectory, which we do not want a third-party plugin to influence.

If redscript ships scc_lib.dll next to its other dependencies (the usual case), this is sufficient. If a future scc bundle relies on a DLL from somewhere else, we will see a clean LoadLibrary failure with ERROR_MOD_NOT_FOUND and can add the flag deliberately — much better than silently picking up a planted DLL.

Happy to switch to LOAD_LIBRARY_SEARCH_DEFAULT_DIRS instead if you would rather match the documented "modern safe default."

What I tested

Local rebuild. I did not exercise the redscript path itself; the change is mechanical and the docs match what we want here. If you have an existing scc smoke test, that would be the easiest validation.

The previous LoadLibrary(sccLib.c_str()) call had two problems:
first, if the scc command was ever a relative path,
replace_filename produced a relative path and LoadLibrary fell back
to the standard search order (CWD, %PATH%); second, even with an
absolute path, scc_lib.dll's own imports were resolved with the
default search order because no LOAD_LIBRARY_SEARCH_* flags were
passed. Both paths let an attacker-writable directory win.

Refuse to do the in-process load when sccPath is not absolute (fall
back to chaining the original Global_ExecuteProcess), and use
LoadLibraryExW with LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
LOAD_LIBRARY_SEARCH_SYSTEM32 so scc_lib.dll's dependencies resolve
from its own directory plus System32 only.

Fixes wopss#138

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@alphanin9

Copy link
Copy Markdown
Contributor

Do you know what else is writable by the users? ./red4ext/plugins

@GreemDev

GreemDev commented Jun 1, 2026

Copy link
Copy Markdown

Average slop PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

scc_lib.dll loaded with bare LoadLibrary (search-order/dependency hijack)

4 participants