Fix SymLoadModuleEx failing to find PDB files#33
Fix SymLoadModuleEx failing to find PDB files#33irp24 wants to merge 1 commit intoweak1337:masterfrom
Conversation
PDB loading fails when Alcatraz is run from a different directory than the target PE. Fixed by setting the symbol search path to the directory containing the target file.
There was a problem hiding this comment.
Pull request overview
This PR addresses PDB loading failures when Alcatraz is executed from a working directory different from the target PE’s directory by updating the DbgHelp symbol search path before calling SymLoadModuleEx.
Changes:
- Set the DbgHelp symbol search path to the directory containing the resolved PDB path prior to loading symbols.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| SymSetSearchPath(GetCurrentProcess(), std::filesystem::path(pdb_path).parent_path().string().c_str()); | ||
| this->module_base = |
There was a problem hiding this comment.
SymSetSearchPath's return value is ignored here. If it fails (e.g., invalid/empty parent path), the subsequent SymLoadModuleEx error will be misleading and harder to diagnose. Please check the BOOL result, and on failure surface GetLastError() (and consider skipping/avoiding setting an empty search path when parent_path() is empty).
| SymSetSearchPath(GetCurrentProcess(), std::filesystem::path(pdb_path).parent_path().string().c_str()); | |
| this->module_base = | |
| std::filesystem::path parent_path = std::filesystem::path(pdb_path).parent_path(); | |
| if (!parent_path.empty()) { | |
| std::string parent_path_str = parent_path.string(); | |
| if (!SymSetSearchPath(GetCurrentProcess(), parent_path_str.c_str())) { | |
| DWORD err = GetLastError(); | |
| throw std::runtime_error("SymSetSearchPath failed with error " + std::to_string(err)); | |
| } | |
| } | |
| this->module_base = |
|
|
||
| } | ||
|
|
||
| SymSetSearchPath(GetCurrentProcess(), std::filesystem::path(pdb_path).parent_path().string().c_str()); |
There was a problem hiding this comment.
SymSetSearchPath replaces the entire symbol search path for the process. Setting it to only the PDB’s parent directory can unintentionally drop existing paths (e.g., _NT_SYMBOL_PATH / symbol server settings) and break symbol resolution elsewhere. Consider reading the existing path (e.g., via SymGetSearchPath) and prepending/appending the target directory instead of overwriting it.
| SymSetSearchPath(GetCurrentProcess(), std::filesystem::path(pdb_path).parent_path().string().c_str()); | |
| std::string pdb_dir = std::filesystem::path(pdb_path).parent_path().string(); | |
| char existing_search_path[2048] = { 0 }; | |
| if (SymGetSearchPath(GetCurrentProcess(), existing_search_path, static_cast<DWORD>(sizeof(existing_search_path)))) { | |
| if (existing_search_path[0] != '\0') { | |
| std::string combined_search_path = pdb_dir + ";" + existing_search_path; | |
| SymSetSearchPath(GetCurrentProcess(), combined_search_path.c_str()); | |
| } | |
| else { | |
| SymSetSearchPath(GetCurrentProcess(), pdb_dir.c_str()); | |
| } | |
| } | |
| else { | |
| SymSetSearchPath(GetCurrentProcess(), pdb_dir.c_str()); | |
| } |
PDB loading fails when Alcatraz is run from a different directory than the target PE. Fixed by setting the symbol search path to the directory containing the target file.