首页
社区
课程
招聘
[分享]Pdb获取符号表
发表于: 2014-6-22 22:22 16831

[分享]Pdb获取符号表

2014-6-22 22:22
16831
  这个不是原创,只是一个改进和思路。起因是学习了大牛分享的一份代码之后,学到了查找符号表的方法,但是发现了一个可以改进的地方,所以研究了一下Pdb文件。
  开源的代码获取符号表是SymFromNameW这个函数获得符号表的,不过需要加载dll,也就是只能查询r3的函数,比如常见的RtlDispatchApc,LdrLoadDll(或者LoadLibrary),然后插入apc回调加载自己的dll。之前写了一篇获取符号表的帖子http://bbs.pediy.com/showthread.php?t=188881,原理就是用DONT_RESOLVE_DLL_REFERENCES加载ntoskrnl.exe,把内核文件当dll加载到地址Loc1,然后用NtQuerySystemInformation查询ntoskrnl.exe加载到地址Loc2。再用SymLoadModuleExW加载一次ntoskrnl.exe到Loc2(测试发现不加载无法解析符号不知道什么原因)。然后再SymFromNameW获取符号。得到符号的Rva,然后Rva = Rva +Loc1-Loc2,就正好能算出符号的偏移,测试了一下KiDeliverApc,发现正常就以为ok了,可是第二天用到NtQueueApcThread发现出错。又搜了半天试了半天api,还是无解。就跟了一下SymFromNameW,发现里面太复杂了,放弃。最后只有解析pdb文件,pdb里面一定有各种信息,包括Rva。然后查到原来还有个dll是可以用的,叫做msdia.dll。
  这个是COM组件实现了,我也不懂,不过调用还是很容易的。基本就是调用接口来查询。具体可以参考….\Microsoft Visual Studio 10.0\DIA SDK\Samples\DIA2Dump里面的代码,改一下就可以用了。
  简单说一下调用的方法。
  PVOID GetProcAddrFromKernelPdb(LPCWSTR szPdbName,LPCWSTR szApiName)
{
  PSYSTEM_MODULE_INFORMATION SystemInfo;
  DWORD dwBufferSize;
  DWORD ret =0;
  if(LoadDataFromPdb(szPdbName,&g_pDiaDataSource,&g_pDiaSession,&g_pGlobalSymbol)){
    FindPublic(g_pGlobalSymbol,szApiName,&ret);
    Cleanup();
  }
  if(ret){
    NtQuerySystemInformation((SYSTEMINFOCLASS)11,0,0,&dwBufferSize);
    SystemInfo = (PSYSTEM_MODULE_INFORMATION)malloc(dwBufferSize);
    NtQuerySystemInformation((SYSTEMINFOCLASS)11,SystemInfo,dwBufferSize,0);
    ret  += (DWORD)SystemInfo->aSM[0].Base;
    free(SystemInfo);
  }
  return (PVOID)ret;
}

  先LoadPdb,在FindPublic查询符号的Rva,然后清理。如果查到了,就计算ntoskrnl.exe的基地址,然后加一下就ok了。
  FindPublic主要又会用个新结构循环查询Pdb里面每一个符号。主要是从ms的源代码抄过来的,ms的命名很规范,使用的方法很简单,就不说了,工程打包放上来。(之前的代码也放进去了,不知道为什么用SymFromNameW查不到很多符号,但是少部分如KiDeliverApc却能查到)。
  注意几点:
  1,不要用Release版本调试,有的地方会很蛋疼的。
  2,有的符号解析不出来不加修饰的原始符号名(不知道为何bstrNam和bstrUndname都是一样)。比如KiRetireDpcList是个fastcall,是@ KiRetireDpcList@开头的,在处理的时候我对api名字修改了下
  wcscpy(szName,L"_");
  wcscat(szName,szApiName);
  wcscat(szName,L"@");

  wcscpy(szName1,L"@");
  wcscat(szName1,szApiName);
  wcscat(szName1,L"@");

  两个名字满足一个就ok,如果查不出来,可以用dia2dump,命令行解析一下pdb到一个文本文件,然后搜索看看,改下代码就ok了,
  3,在没有安装vs2010的虚拟机中,用regsvr32 注册一下msdia100.dll,另外获得pdb的路径没有设置,需要用windbg下载一个内核pdb,放到一个目录。还有内核文件的问题,ntkrnlpa会显示ntkrpamp
LZ 看下你内核文件 ntkrnlpa.exe 属性中的原始文件名是啥


  另外,求一份工作,本人应届生(硕士),非计算机专业,理工科,希望有公司收留,虽然技术菜,但是工作认真,人品还可以,按本科工资或者低一点都行,有公司差人我就发份简历过去(最好是武汉的,外地也行),马上离校了,被父母和亲戚催的不行,真的是感觉压力山山山山大,哎,早上调试了一会儿程序想到无工作都没心思了,感觉被xx教育毒害了。
  另外的另外,希望和想一起进步的朋友以及大牛交个朋友,现实里面也很少有朋友能聊上天,基本都不搞编程,本人也是无妹子无房子无车子的屌丝一枚。。。。

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 10
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
武汉滴???
2014-6-22 22:24
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
是的。。。
2014-6-22 22:30
0
雪    币: 10
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
,你湖北人?
2014-6-22 22:32
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
是啊,武汉人。
2014-6-22 22:36
0
雪    币: 10
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
,老乡...
2014-6-22 22:37
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
7
老乡见老乡,两眼泪汪汪!  
2014-6-22 22:42
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
好多老乡。。。
2014-6-22 22:46
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
9
楼主 你在文中提到的 “起因是学习了大牛分享的一份代码之后,学到了查找符号表的方法” 能告诉我怎么找到这份代码吗 谢谢
2014-10-22 11:52
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
可能是这个,我也不确定,很久没看代码了,上班有点忙。
2014-10-22 18:39
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
11
好的  谢谢楼主的回复~
2014-10-23 09:00
0
雪    币: 22
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
怎么查找全局变量?
2018-4-12 14:41
0
游客
登录 | 注册 方可回帖
返回
//