VOID KdbSymProcessSymbols( IN PLDR_DATA_TABLE_ENTRY LdrEntry) { if (!LoadSymbols) { LdrEntry->PatchInformation = NULL; return; } /* Remove symbol info if it already exists */ if (LdrEntry->PatchInformation) KdbpSymRemoveCachedFile(LdrEntry->PatchInformation); /* Load new symbol information */ if (! RosSymCreateFromMem(LdrEntry->DllBase, LdrEntry->SizeOfImage, (PROSSYM_INFO*)&LdrEntry->PatchInformation)) { /* Error loading symbol info, try to load it from file */ KdbpSymLoadModuleSymbols(&LdrEntry->FullDllName, (PROSSYM_INFO*)&LdrEntry->PatchInformation); /* It already added symbols to cache */ } else { /* Add file to cache */ KdbpSymAddCachedFile(&LdrEntry->FullDllName, LdrEntry->PatchInformation); } DPRINT("Installed symbols: %wZ@%p-%p %p\n", &LdrEntry->BaseDllName, LdrEntry->DllBase, (PVOID)(LdrEntry->SizeOfImage + (ULONG_PTR)LdrEntry->DllBase), LdrEntry->PatchInformation); }
/*! \brief Loads a symbol file. * * \param FileName Filename of the symbol file to load. * \param RosSymInfo Pointer to a ROSSYM_INFO which gets filled. * * \sa KdbpSymUnloadModuleSymbols */ VOID KdbpSymLoadModuleSymbols( IN PUNICODE_STRING FileName, OUT PROSSYM_INFO *RosSymInfo) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandle; NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; PFILE_OBJECT FileObject; PROSSYM_KM_OWN_CONTEXT FileContext; /* Allow KDB to break on module load */ KdbModuleLoaded(FileName); if (!LoadSymbols) { *RosSymInfo = NULL; return; } /* Try to find cached (already loaded) symbol file */ *RosSymInfo = KdbpSymFindCachedFile(FileName); if (*RosSymInfo) { DPRINT("Found cached symbol file %wZ\n", FileName); return; } /* Open the file */ InitializeObjectAttributes(&ObjectAttributes, FileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); DPRINT("Attempting to open image: %wZ\n", FileName); Status = ZwOpenFile(&FileHandle, FILE_READ_ACCESS | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { DPRINT("Could not open image file(%x): %wZ\n", Status, FileName); return; } DPRINT("Loading symbols from %wZ...\n", FileName); Status = ObReferenceObjectByHandle (FileHandle, FILE_READ_DATA | SYNCHRONIZE, NULL, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT("Could not get the file object\n"); ZwClose(FileHandle); return; } if ((FileContext = KdbpCaptureFileForSymbols(FileObject))) { if (RosSymCreateFromFile(FileContext, RosSymInfo)) { /* add file to cache */ int i; UNICODE_STRING TruncatedName = *FileName; for (i = (TruncatedName.Length / sizeof(WCHAR)) - 1; i >= 0; i--) if (TruncatedName.Buffer[i] == '\\') { TruncatedName.Buffer += i+1; TruncatedName.Length -= (i+1)*sizeof(WCHAR); TruncatedName.MaximumLength -= (i+1)*sizeof(WCHAR); break; } KdbpSymAddCachedFile(&TruncatedName, *RosSymInfo); DPRINT("Installed symbols: %wZ %p\n", &TruncatedName, *RosSymInfo); } KdbpReleaseFileForSymbols(FileContext); } ObDereferenceObject(FileObject); ZwClose(FileHandle); }
/*! \brief Loads a symbol file. * * \param FileName Filename of the symbol file to load. * \param RosSymInfo Pointer to a ROSSYM_INFO which gets filled. * * \sa KdbpSymUnloadModuleSymbols */ static VOID KdbpSymLoadModuleSymbols( IN PUNICODE_STRING FileName, OUT PROSSYM_INFO *RosSymInfo) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandle; NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; /* Allow KDB to break on module load */ KdbModuleLoaded(FileName); if (!LoadSymbols) { *RosSymInfo = NULL; return; } /* Try to find cached (already loaded) symbol file */ *RosSymInfo = KdbpSymFindCachedFile(FileName); if (*RosSymInfo) { DPRINT("Found cached symbol file %wZ\n", FileName); return; } /* Open the file */ InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL); DPRINT("Attempting to open image: %wZ\n", FileName); Status = ZwOpenFile(&FileHandle, FILE_READ_ACCESS | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { DPRINT("Could not open image file: %wZ\n", FileName); return; } DPRINT("Loading symbols from %wZ...\n", FileName); if (!RosSymCreateFromFile(&FileHandle, RosSymInfo)) { DPRINT("Failed to load symbols from %wZ\n", FileName); return; } ZwClose(FileHandle); DPRINT("Symbols loaded.\n"); /* add file to cache */ KdbpSymAddCachedFile(FileName, *RosSymInfo); DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo); }