登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 298|回复: 0

使用符号获取结构体成员的偏移

[复制链接]

171

主题

21

回帖

1106

积分

管理员

积分
1106
发表于 2024-12-24 19:58:57 | 显示全部楼层 |阅读模式
由于WIN10更新太猛,直接把结构体成员偏移写死在代码里已经不可靠了,所以在可以联网的情况下,我建议使用符号获取结构体成员的偏移
编译以下代码后,需要在EXE文件的同目录下放置dbghelp.dll、symsrv.dll、symsrv.yes。如果不知道在哪里获得这些文件,可以先下载并运行一次WKE,然后把WKE输出的相关文件复制过来即可。
以下是完整可编译的C代码,演示了获取fltmgr!_FLT_FILTER结构体里Operations成员的偏移:
#include <stdio.h>
#include <Windows.h>
#include <psapi.h>
#include <Imagehlp.h>

#pragma comment(lib, "PSAPI.lib")
#pragma comment(lib, "DbgHelp.lib")
#pragma comment(lib, "ImageHlp.lib")

/*enum SymTagEnum
{
        SymTagNull,
        SymTagExe,
        SymTagCompiland,
        SymTagCompilandDetails,
        SymTagCompilandEnv,
        SymTagFunction,
        SymTagBlock,
        SymTagData,
        SymTagAnnotation,
        SymTagLabel,
        SymTagPublicSymbol,
        SymTagUDT,
        SymTagEnum,
        SymTagFunctionType,
        SymTagPointerType,
        SymTagArrayType,
        SymTagBaseType,
        SymTagTypedef,
        SymTagBaseClass,
        SymTagFriend,
        SymTagFunctionArgType,
        SymTagFuncDebugStart,
        SymTagFuncDebugEnd,
        SymTagUsingNamespace,
        SymTagVTableShape,
        SymTagVTable,
        SymTagCustom,
        SymTagThunk,
        SymTagCustomType,
        SymTagManagedType,
        SymTagDimension
};*/

typedef struct _SYMBOL_GET_STRUCT_OFFSET
{
        char StructureName[64];
        WCHAR MemberName[30];
        ULONG offset;
}SYMBOL_GET_STRUCT_OFFSET, *PSYMBOL_GET_STRUCT_OFFSET;

PVOID GetDriverBaseA(char *DriverName)
{
        DWORD cbNeed = 0,i = 0;
        PVOID *ppDrvBas = NULL, RetVal = NULL;
        if(EnumDeviceDrivers(NULL,0,&cbNeed))
        {
                ppDrvBas = (PVOID*)malloc(cbNeed);
                if(ppDrvBas)
                {
                        if(EnumDeviceDrivers(ppDrvBas,cbNeed,&cbNeed))
                        {
                                for(i=0;i<cbNeed/sizeof(SIZE_T);i++)
                                {
                                        char path[MAX_PATH]={0};
                                        if(GetDeviceDriverBaseNameA(ppDrvBas[i],path,MAX_PATH))
                                        {
                                                if(!stricmp(path,DriverName))
                                                {
                                                        RetVal = ppDrvBas[i];
                                                        break;
                                                }
                                        }
                                }
                        }
                        free(ppDrvBas);
                }
        }
        return RetVal;
}

BOOLEAN CALLBACK EnumSymbolStructureRoutine(PSYMBOL_INFO psi, ULONG SymSize, PVOID Context)
{
        if(Context)
        {
                PSYMBOL_GET_STRUCT_OFFSET pInfo = (PSYMBOL_GET_STRUCT_OFFSET)Context;
                if(!strcmp(psi->Name,(const char*)(pInfo->StructureName)))
                {
                        DWORD i, dwChildrenCount = 0;
                        if(SymGetTypeInfo(GetCurrentProcess(), psi->ModBase, psi->TypeIndex, TI_GET_CHILDRENCOUNT, &dwChildrenCount))
                        {
                                TI_FINDCHILDREN_PARAMS *pChildren = (TI_FINDCHILDREN_PARAMS *)malloc(sizeof(TI_FINDCHILDREN_PARAMS) + sizeof(DWORD) * dwChildrenCount);
                                if(pChildren)
                                {
                                    pChildren->Count = dwChildrenCount;
                                    pChildren->Start = 0;
                                        if(SymGetTypeInfo(GetCurrentProcess(), psi->ModBase, psi->TypeIndex, TI_FINDCHILDREN, pChildren))
                                        {
                                            if(psi->Tag==SymTagUDT)
                                            {
                                                        for(i = 0; i < dwChildrenCount; i++)
                                                        {
                                                                WCHAR *pwszTypeName = NULL;
                                                                if(SymGetTypeInfo(GetCurrentProcess(), psi->ModBase, pChildren->ChildId[i], TI_GET_SYMNAME, &pwszTypeName))
                                                                {
                                                                        if(!wcscmp(pwszTypeName, (const wchar_t*)(pInfo->MemberName)))
                                                                        {
                                                                                DWORD dwMemberOffset;
                                                                                if(SymGetTypeInfo(GetCurrentProcess(), psi->ModBase, pChildren->ChildId[i], TI_GET_OFFSET, &dwMemberOffset))
                                                                                {
                                                                                        pInfo->offset = dwMemberOffset;
                                                                                }
                                                                        }
                                                                        LocalFree(pwszTypeName);
                                                                        if(pInfo->offset)
                                                                        {
                                                                                break;
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                        free(pChildren);
                                        if(pInfo->offset)
                                        {
                                                return FALSE;
                                        }
                                }
                        }
                }
        }
        return TRUE;
}

ULONG SymbolGetStructureOffset(PVOID DriverBase, PCHAR StructureName, PWCHAR MemberName)
{
        SYMBOL_GET_STRUCT_OFFSET info = {0};
        strcpy(info.StructureName, StructureName);
        wcscpy(info.MemberName, MemberName);
        SymEnumTypes(GetCurrentProcess(),(ULONG64)DriverBase,(PSYM_ENUMERATESYMBOLS_CALLBACK)EnumSymbolStructureRoutine,&info);
        return info.offset;
}

void main()
{
        if(SymInitialize(GetCurrentProcess(), "srv*c:\\symbols*http://msdl.microsoft.com/download/symbols", 0))
        {
                PVOID fmbase = GetDriverBaseA("fltmgr.sys");printf("base: 0x%p\r\n",fmbase);
                if(fmbase)
                {
                        DWORD64 base = SymLoadModule64(GetCurrentProcess(), 0, "c:\\windows\\system32\\drivers\\fltmgr.sys", 0, (DWORD64)fmbase, 0);
                        if(base)
                        {
                                ULONG offset = SymbolGetStructureOffset(fmbase,"_FLT_FILTER",L"Operations");
                                printf("_FLT_FILTER->Operations: 0x%x\r\n",offset);
                        }
                }
        }
        SymCleanup(GetCurrentProcess());system("pause");
}





您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-4-11 18:07 , Processed in 0.104513 second(s), 23 queries , Yac On.

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表