这几天在学习内核开发,当定位一些未导出函数时比较麻烦,特地写了一个内核符号文件搜索符号的代码,现在开放出来给大家用,技术太菜,欢迎大佬指导。
编译选择64位
其中编译时要用到了dbghelp.lib
另外要用到 DIA SDK(在visual studio 文件目录下可以找到)
下面是源码:
const char*sympath = "SRV*C:\\Symbols*http://msdl.microsoft.com/download/symbols";
HANDLE hSym= (HANDLE)0xDEADC0DE;
DWORD64 dllBase = NULL;
char* SymbolFile = NULL;
const wchar_t *g_szFilename;
IDiaDataSource *g_pDiaDataSource;
IDiaSession *g_pDiaSession;
IDiaSymbol *g_pGlobalSymbol;
DWORD g_dwMachineType = CV_CFL_80386;
typedef BOOL
(CALLBACK *EnumSymbolsCallBack)(
_In_ wchar_t* Name,
PVOID address);
_EXTERN_C
bool LoadDataFromPdb(
const wchar_t *szFilename,
IDiaDataSource **ppSource,
IDiaSession **ppSession,
IDiaSymbol **ppGlobal);
BOOL CALLBACK SymRegisterCallbackProc64(
HANDLE hProcess,
ULONG ActionCode,
ULONG64 CallbackData,
ULONG64 UserContext
)
{
switch (ActionCode)
{
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
return FALSE;
case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE:
{
char buffer[MAX_PATH];
if (SearchTreeForFile("C:\\Symbols", "ntkrnlmp.pdb", buffer))
{
SymbolFile = buffer;
}
else if (SearchTreeForFile("C:\\Symbols", "ntoskrnl.pdb", buffer))
{
SymbolFile = buffer;
}
if (SymbolFile != NULL)
{
const size_t cSize = strlen(SymbolFile) + 1;
wchar_t* wc = new wchar_t[cSize];
mbstowcs(wc, SymbolFile, cSize);
if (SymbolFile != NULL)
{
LoadDataFromPdb(wc, &g_pDiaDataSource, &g_pDiaSession, &g_pGlobalSymbol);
}
}
break;
}
default:
break;
}
return TRUE;
}
////////////////////////////////////////////////////////////
// Create an IDiaData source and open a PDB file
//
bool LoadDataFromPdb(
const wchar_t *szFilename,
IDiaDataSource **ppSource,
IDiaSession **ppSession,
IDiaSymbol **ppGlobal)
{
wchar_t wszExt[MAX_PATH];
const wchar_t *wszSearchPath = L"SRV**\\\\symbols\\symbols"; // Alternate path to search for debug data
DWORD dwMachType = 0;
HRESULT hr = CoInitialize(NULL);
// Obtain access to the provider
hr = CoCreateInstance(__uuidof(DiaSource),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IDiaDataSource),
(void **)ppSource);
if (FAILED(hr)) {
wprintf(L"CoCreateInstance failed - HRESULT = %08X\n", hr);
return false;
}
_wsplitpath_s(szFilename, NULL, 0, NULL, 0, NULL, 0, wszExt, MAX_PATH);
if (!_wcsicmp(wszExt, L".pdb")) {
// Open and prepare a program database (.pdb) file as a debug data source
hr = (*ppSource)->loadDataFromPdb(szFilename);
if (FAILED(hr)) {
wprintf(L"loadDataFromPdb failed - HRESULT = %08X\n", hr);
return false;
}
}
else {
// Open and prepare the debug data associated with the executable
//hr = (*ppSource)->loadDataForExe(szFilename, wszSearchPath, &callback);
if (FAILED(hr)) {
wprintf(L"loadDataForExe failed - HRESULT = %08X\n", hr);
return false;
}
}
// Open a session for querying symbols
hr = (*ppSource)->openSession(ppSession);
if (FAILED(hr)) {
wprintf(L"openSession failed - HRESULT = %08X\n", hr);
return false;
}
// Retrieve a reference to the global scope
hr = (*ppSession)->get_globalScope(ppGlobal);
if (hr != S_OK) {
wprintf(L"get_globalScope failed\n");
return false;
}
// Set Machine type for getting correct register names
if ((*ppGlobal)->get_machineType(&dwMachType) == S_OK) {
switch (dwMachType) {
case IMAGE_FILE_MACHINE_I386: g_dwMachineType = CV_CFL_80386; break;
case IMAGE_FILE_MACHINE_IA64: g_dwMachineType = CV_CFL_IA64; break;
case IMAGE_FILE_MACHINE_AMD64: g_dwMachineType = CV_CFL_AMD64; break;
}
}
return true;
}
bool __declspec(dllexport) init()
{
BOOL b;
::SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_FAVOR_COMPRESSED);
//::SymSetOptions(SYMOPT_UNDNAME);
b = ::SymInitialize(hSym, sympath, FALSE);
if (!b)
{
return false;
}
SymRegisterCallback64(hSym, SymRegisterCallbackProc64, NULL);
return true;
}
bool __declspec(dllexport) Ubloadsymbol()
{
::SymUnloadModule64(hSym, dllBase);
SymbolFile=NULL;
dllBase = NULL;
::SymCleanup(hSym);
if (g_pGlobalSymbol) {
g_pGlobalSymbol->Release();
g_pGlobalSymbol = NULL;
}
if (g_pDiaSession) {
g_pDiaSession->Release();
g_pDiaSession = NULL;
}
CoUninitialize();
return true;
}
bool __declspec(dllexport) LoadSymbolModule()
{
HMODULE imagebase;
char *FullName, *rootName=NULL;
DWORD64 moduleBase;
PULONG_PTR driverBase;
DWORD dummy, numOfDrivers;
bool b;
driverBase = new ULONG_PTR[1024];
if (!::EnumDeviceDrivers((PVOID *)driverBase, sizeof(ULONG_PTR) * 1024, &dummy)) {
delete[] driverBase;
return false;
}
numOfDrivers = dummy / sizeof(ULONG_PTR);
FullName = new char[MAX_PATH];
b = false;
for (DWORD i = 0; i < numOfDrivers; i++) {
if (::GetDeviceDriverBaseNameA((PVOID)driverBase[i], FullName, MAX_PATH)) {
if (!::_strnicmp("ntoskrnl.exe", FullName, MAX_PATH)) {
::GetDeviceDriverFileNameA((PVOID)driverBase[i], FullName, MAX_PATH);
moduleBase = driverBase[i];
dllBase = driverBase[i];
rootName = new char[MAX_PATH];
if (!::_strnicmp(FullName, "\\SystemRoot\\", strlen("\\SystemRoot\\"))) {
::GetWindowsDirectoryA(rootName, MAX_PATH);
::strcat_s(rootName, MAX_PATH, &FullName[strlen("\\SystemRoot")]);
}
else {
::GetEnvironmentVariableA("SystemDrive", rootName, MAX_PATH);
::strcat_s(rootName, MAX_PATH, FullName);
}
b = true;
break;
}
}
}
if (!b) {
delete[] FullName;
delete[] driverBase;
return false;
}
if (!::SymLoadModule64(hSym, NULL, rootName, NULL, moduleBase, 0)) {
delete[] FullName;
delete[] driverBase;
delete[] rootName;
return false;
}
return true;
}
ULONG64 __declspec(dllexport) FindSymbolByName(const char* Name)
{
ULONG64 buffer[(sizeof(SYMBOL_INFO) +
MAX_SYM_NAME * sizeof(TCHAR) +
sizeof(ULONG64) - 1) /
sizeof(ULONG64)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
if (SymFromName(hSym, Name, pSymbol))
{
return pSymbol->Address;
// SymFromName returned success
}
return NULL;
}
bool __declspec(dllexport) EnumSymbol(EnumSymbolsCallBack callback)
{
DWORD dwSymTag;
DWORD dwRVA;
DWORD dwSeg;
DWORD dwOff;
BSTR bstrName;
ULONG64 address;
IDiaEnumSymbols *pEnumSymbols;
BSTR bstrUndname;
if (FAILED(g_pGlobalSymbol->findChildren(SymTagPublicSymbol, NULL, nsNone, &pEnumSymbols)))
{
return false;
}
IDiaSymbol *pSymbol;
ULONG celt = 0;
while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1))
{
if (pSymbol->get_symTag(&dwSymTag) != S_OK)
{
continue;
}
if (pSymbol->get_relativeVirtualAddress(&dwRVA) != S_OK)
{
dwRVA = 0xFFFFFFFF;
}
address = dllBase + dwRVA;
if (pSymbol->get_name(&bstrName) == S_OK)
{
if (pSymbol->get_undecoratedName(&bstrUndname) == S_OK)
{
//wprintf(L"%s(%s)\n", bstrName, bstrUndname);
SysFreeString(bstrUndname);
}
callback(bstrName, (PVOID)address);
//PrintPublicSymbol(pSymbol);
SysFreeString(bstrName);
pSymbol->Release();
}
}
pEnumSymbols->Release();
return true;
}
_END_EXTERN_C
const char*sympath = "SRV*C:\\Symbols*http://msdl.microsoft.com/download/symbols";
HANDLE hSym= (HANDLE)0xDEADC0DE;
DWORD64 dllBase = NULL;
char* SymbolFile = NULL;
const wchar_t *g_szFilename;
IDiaDataSource *g_pDiaDataSource;
IDiaSession *g_pDiaSession;
IDiaSymbol *g_pGlobalSymbol;
DWORD g_dwMachineType = CV_CFL_80386;
typedef BOOL
(CALLBACK *EnumSymbolsCallBack)(
_In_ wchar_t* Name,
PVOID address);
_EXTERN_C
bool LoadDataFromPdb(
const wchar_t *szFilename,
IDiaDataSource **ppSource,
IDiaSession **ppSession,
IDiaSymbol **ppGlobal);
BOOL CALLBACK SymRegisterCallbackProc64(
HANDLE hProcess,
ULONG ActionCode,
ULONG64 CallbackData,
ULONG64 UserContext
)
{
switch (ActionCode)
{
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
return FALSE;
case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE:
{
char buffer[MAX_PATH];
if (SearchTreeForFile("C:\\Symbols", "ntkrnlmp.pdb", buffer))
{
SymbolFile = buffer;
}
else if (SearchTreeForFile("C:\\Symbols", "ntoskrnl.pdb", buffer))
{
SymbolFile = buffer;
}
if (SymbolFile != NULL)
{
const size_t cSize = strlen(SymbolFile) + 1;
wchar_t* wc = new wchar_t[cSize];
mbstowcs(wc, SymbolFile, cSize);
if (SymbolFile != NULL)
{
LoadDataFromPdb(wc, &g_pDiaDataSource, &g_pDiaSession, &g_pGlobalSymbol);
}
}
break;
}
default:
break;
}
return TRUE;
}
////////////////////////////////////////////////////////////
// Create an IDiaData source and open a PDB file
//
bool LoadDataFromPdb(
const wchar_t *szFilename,
IDiaDataSource **ppSource,
IDiaSession **ppSession,
IDiaSymbol **ppGlobal)
{
wchar_t wszExt[MAX_PATH];
const wchar_t *wszSearchPath = L"SRV**\\\\symbols\\symbols"; // Alternate path to search for debug data
DWORD dwMachType = 0;
HRESULT hr = CoInitialize(NULL);
// Obtain access to the provider
hr = CoCreateInstance(__uuidof(DiaSource),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IDiaDataSource),
(void **)ppSource);
if (FAILED(hr)) {
wprintf(L"CoCreateInstance failed - HRESULT = %08X\n", hr);
return false;
}
_wsplitpath_s(szFilename, NULL, 0, NULL, 0, NULL, 0, wszExt, MAX_PATH);
if (!_wcsicmp(wszExt, L".pdb")) {
// Open and prepare a program database (.pdb) file as a debug data source
hr = (*ppSource)->loadDataFromPdb(szFilename);
if (FAILED(hr)) {
wprintf(L"loadDataFromPdb failed - HRESULT = %08X\n", hr);
return false;
}
}
else {
// Open and prepare the debug data associated with the executable
//hr = (*ppSource)->loadDataForExe(szFilename, wszSearchPath, &callback);
if (FAILED(hr)) {
wprintf(L"loadDataForExe failed - HRESULT = %08X\n", hr);
return false;
}
}
// Open a session for querying symbols
hr = (*ppSource)->openSession(ppSession);
if (FAILED(hr)) {
wprintf(L"openSession failed - HRESULT = %08X\n", hr);
return false;
}
// Retrieve a reference to the global scope
hr = (*ppSession)->get_globalScope(ppGlobal);
if (hr != S_OK) {
wprintf(L"get_globalScope failed\n");
return false;
}
// Set Machine type for getting correct register names
if ((*ppGlobal)->get_machineType(&dwMachType) == S_OK) {
switch (dwMachType) {
case IMAGE_FILE_MACHINE_I386: g_dwMachineType = CV_CFL_80386; break;
case IMAGE_FILE_MACHINE_IA64: g_dwMachineType = CV_CFL_IA64; break;
case IMAGE_FILE_MACHINE_AMD64: g_dwMachineType = CV_CFL_AMD64; break;
}
}
return true;
}
bool __declspec(dllexport) init()
{
BOOL b;
::SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_FAVOR_COMPRESSED);
//::SymSetOptions(SYMOPT_UNDNAME);
b = ::SymInitialize(hSym, sympath, FALSE);
if (!b)
{
return false;
}
SymRegisterCallback64(hSym, SymRegisterCallbackProc64, NULL);
return true;
}
bool __declspec(dllexport) Ubloadsymbol()
{
::SymUnloadModule64(hSym, dllBase);
SymbolFile=NULL;
dllBase = NULL;
::SymCleanup(hSym);
if (g_pGlobalSymbol) {
g_pGlobalSymbol->Release();
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-10-26 09:07
被whathhh编辑
,原因: 添加一些使用说明