首页
社区
课程
招聘
[原创]通过符号表找到系统未导出的函数地址源码
发表于: 2007-12-9 19:24 17638

[原创]通过符号表找到系统未导出的函数地址源码

2007-12-9 19:24
17638

说明:第一步设置符号表路径.比如 E:\WINDOWS\system32\Symbols\
第二步指定系统动态库,比如user32.dll
第三步指定系统库函数名比如ValidateHwnd.
如果调用成功的话,返回值就为未导出的库函数地址.

例外说明.使用ollydbg设置好了符号表路径,好像是没有效果.
只有把符号文件放到系统目录\system32\symbols\里面才能加载.

class ProcedureAddrRetrieve
{
public:
        ProcedureAddrRetrieve(TCHAR *PdbSearchPath,DWORD _Options = NULL);
        ~ProcedureAddrRetrieve();
        BOOL LoadSymbol(TCHAR *DllName);
        BOOL EnumSymbol(TCHAR *pSearchMask = NULL);
        DWORD64 RetrieveAddr(TCHAR *_szProcedureName);
protected:
private:
        BOOL GetFileSize( const TCHAR* pFileName, DWORD& FileSize );
        static BOOL CALLBACK EnumSymbolsCallback( SYMBOL_INFO* pSymInfo, ULONG SymbolSize, PVOID UserContext );
        DWORD64 ModBase64;
        char szProcedureName[MAX_PATH];
        DWORD64 Address;
};
void test();

#include <windows.h>
#include <tchar.h>
#include <io.h>
#include <stdio.h>
#include <dbghelp.h>
#include <stdio.h>
#include "lib.h"
#pragma comment( lib, "dbghelp.lib" )
void test()
{
        ProcedureAddrRetrieve par("E:\\WINDOWS\\system32\\Symbols\\");
        par.LoadSymbol("User32.dll");
        par.RetrieveAddr("ValidateHwnd");
}
ProcedureAddrRetrieve::ProcedureAddrRetrieve(TCHAR *PdbSearchPath,DWORD _Options )
{
        BOOL bRet = FALSE;
        ZeroMemory(this,sizeof(ProcedureAddrRetrieve));
        // Set options
        DWORD Options = SymGetOptions();

        // SYMOPT_DEBUG option asks DbgHelp to print additional troubleshooting
        // messages to debug output - use the debugger's Debug Output window
        // to view the messages

        Options =Options | SYMOPT_DEBUG | _Options/*|SYMOPT_ALLOW_ABSOLUTE_SYMBOLS*/;

        SymSetOptions( Options );
        // Initialize DbgHelp and load symbols for all modules of the current process

        bRet = SymInitialize (
                GetCurrentProcess(),  // Process handle of the current process
                PdbSearchPath,                 // user-defined search path -> use default
                FALSE                 // Do not load symbols for modules in the current process
                );

        if( !bRet )
        {
                _tprintf(_T("Error: SymInitialize() failed. Error code: %u \n"), ::GetLastError());
                return ;
        }
}
BOOL ProcedureAddrRetrieve::LoadSymbol(TCHAR *DllName)
{
        HMODULE ModBase;
        TCHAR DllFullPath[MAX_PATH];
        DWORD     FileSize  = 0;

        //Get DLL full path.
        ModBase = GetModuleHandle(DllName);
        if(ModBase == NULL)
        {
                ModBase = LoadLibrary(DllName);
                if(ModBase == NULL)
                        return FALSE;
        }
        GetModuleFileName(ModBase,DllFullPath,MAX_PATH);

        GetFileSize(DllFullPath,FileSize);

        if(ModBase64)
        {
                // Unload symbols for the module
                if(!SymUnloadModule64( GetCurrentProcess(), ModBase64 ))
                {
                        _tprintf( _T("Error: SymUnloadModule64() failed. Error code: %u \n"), ::GetLastError() );
                        return FALSE;
                }
        }

        // Load symbols for the module
        _tprintf( _T("Loading symbols for: %s ... \n"), DllFullPath );

        ModBase64 = SymLoadModule64 (
                GetCurrentProcess(), // Process handle of the current process
                NULL,                // Handle to the module's image file (not needed)
                DllFullPath,           // Path/name of the file
                NULL,                // User-defined short name of the module (it can be NULL)
                (DWORD64)ModBase,            // Base address of the module (cannot be NULL if .PDB file is used, otherwise it can be NULL)
                FileSize             // Size of the file (cannot be NULL if .PDB file is used, otherwise it can be NULL)
                );

        if( ModBase == 0 )
        {
                _tprintf(_T("Error: SymLoadModule64() failed. Error code: %u \n"), ::GetLastError());
                return FALSE;
        }
        return TRUE;
}
BOOL ProcedureAddrRetrieve::GetFileSize( const TCHAR* pFileName, DWORD& FileSize )
{
        // Check parameters
        if( pFileName == 0 )
        {
                return FALSE;
        }

        // Open the file
        HANDLE hFile = CreateFile( pFileName, GENERIC_READ, FILE_SHARE_READ,
                NULL, OPEN_EXISTING, 0, NULL );

        if( hFile == INVALID_HANDLE_VALUE )
        {
                _tprintf( _T("CreateFile() failed. Error: %u \n"), ::GetLastError() );
                return FALSE;
        }

        // Obtain the size of the file
        FileSize = ::GetFileSize( hFile, NULL );
        if( FileSize == INVALID_FILE_SIZE )
        {
                _tprintf( _T("GetFileSize() failed. Error: %u \n"), ::GetLastError() );
                // and continue ...
        }

        // Close the file
        if( !CloseHandle( hFile ) )
        {
                _tprintf( _T("CloseHandle() failed. Error: %u \n"), ::GetLastError() );
                // and continue ...
        }
        // Complete

        return ( FileSize != INVALID_FILE_SIZE );

}
ProcedureAddrRetrieve::~ProcedureAddrRetrieve()
{
        if(ModBase64)
        {
                // Unload symbols for the module
                if(!SymUnloadModule64( GetCurrentProcess(), ModBase64 ))
                {
                        _tprintf( _T("Error: SymUnloadModule64() failed. Error code: %u \n"), ::GetLastError() );
                }
        }
}
BOOL ProcedureAddrRetrieve::EnumSymbol(TCHAR *pSearchMask)
{
        BOOL bRet = TRUE;
       
        // Enumerate symbols and display information about them
       
        if( pSearchMask != NULL )
                _tprintf( _T("Search mask: %s \n"), pSearchMask );

        _tprintf( _T("Symbols: \n") );

        bRet = ::SymEnumSymbols(
                GetCurrentProcess(),   // Process handle of the current process
                ModBase64,               // Base address of the module
                pSearchMask,           // Mask (NULL -> all symbols)
                EnumSymbolsCallback, // The callback function
                this                   // A used-defined context can be passed here, if necessary
                );

        if( !bRet )
        {
                _tprintf( _T("Error: SymEnumSymbols() failed. Error code: %u \n"), ::GetLastError() );
        }
        return TRUE;
}
BOOL CALLBACK ProcedureAddrRetrieve::EnumSymbolsCallback( SYMBOL_INFO* pSymInfo, ULONG SymbolSize, PVOID UserContext )
{
        ProcedureAddrRetrieve *pPar = (ProcedureAddrRetrieve *)UserContext;
        if( pSymInfo != 0 )
        {
                if(*pPar->szProcedureName)
                {
                        if(strcmp(pPar->szProcedureName,pSymInfo->Name)==0)
                        {
                                pPar->Address = pSymInfo->Address;
                                return FALSE;
                        }
                }
                else
                {
                        _tprintf(pSymInfo->Name);
                        _tprintf("\n");
                }
        }
        return TRUE;
}
DWORD64 ProcedureAddrRetrieve::RetrieveAddr(TCHAR *_szProcedureName)
{
        strncpy(szProcedureName,_szProcedureName,MAX_PATH);
        Address = 0;
        if(!EnumSymbol(""))
                return NULL;
        return Address;
}


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
美文。
2007-12-9 20:06
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
3
终于有人肯发了
2007-12-11 01:43
0
雪    币: 97697
活跃值: (200834)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
4
Thanks.
2007-12-11 01:54
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
5
好文。学习ing...
2007-12-11 09:37
0
雪    币: 1919
活跃值: (901)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
6
学习中~~~
2007-12-11 12:24
0
雪    币: 27
活跃值: (12)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
学习学习` ``
2007-12-12 13:09
0
雪    币: 223
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
收藏,学习!
2007-12-14 17:04
0
游客
登录 | 注册 方可回帖
返回
//