Windows程序运行中有时会出现异常对话框,提示“XX指令访问非法内存”之类的,但是出现异常的DLL是操作系统自身的,比如kernel32.dll或ntdll.dll,根据经验这些问题都是我们自己的程序出了问题导致的,这类问题是否可以根据指令找到DLL中的相应函数?比如提示:"0x77FCB03D"指令引用的"0x00000000"内存。该内存不能为"written"。
能否根据上述提示找到0x77FCB03D指令对应的函数?

解决方案 »

  1.   

    Yes.You just need to install debug symbol files for system Dlls.http://msdn.microsoft.com/msdnmag/issues/02/06/Bugslayer/
      

  2.   

    可以直接查到0x77FCB03D是哪个函数的。
      

  3.   

    to sevencat(七猫:
    如果没有安装相关的DBG文件,只根据DLL能否查到0x77FCB03D是哪个函数的?怎么查?
      

  4.   

    > 只根据DLL能否查到0x77FCB03D是哪个函数的?怎么查?dumpbin gdi32.dll /exports
      

  5.   

    袁大侠,我想请教个问题,GdiQueryTable这个函数在2003下好像不起作用,有没有什么代替的办法?
      

  6.   

    PGDI_TABLE_ENTRY GdiQueryTable(VOID)
    {
       return (PGDI_TABLE_ENTRY)*((PULONG)0x77c13000);
    }
    这样应该是可以的吧?
      

  7.   

    > GdiQueryTable这个函数在2003下好像不起作用Now that I work for Microsoft, I should not talk about undocumented functions.
      

  8.   

    袁大侠是我的偶像啊:
    下午又找到了另一个方法:
    TEB *pteb=NULL; 
    __asm mov eax,fs:[18h] 
    __asm mov pteb,eax PEB *ppeb=pteb->Peb; 
    PVOID phddd=ppeb->GdiSharedHandleTable;
      

  9.   

    to 袁老大:
    dumpbin gdi32.dll /exports 出来的结果是这样的:
        ordinal hint RVA      name          1    0 00028AA3 AbortDoc
              2    1 00028FA9 AbortPath
              3    2 00020C61 AddFontMemResourceEx
              4    3 0001DF87 AddFontResourceA
              5    4 00020B24 AddFontResourceExA
              6    5 00020EDA AddFontResourceExW
              7    6 00020C94 AddFontResourceTracking
              ......还是不能知道0x77FCB03D地址的函数。
    而且0x77FCB03D地址应该是落在ntdll.dll的范围内,也不应该是gdi32.dll啊?
      

  10.   

    操作系统自身的DLL被装载的基地址是不变的,可以用Dependency Walker看到,比如ntdll.dll是0x77F80000,那dumpbin/exports出来的结果中RVA字段是否是函数基于基地址的偏移量?
      

  11.   

    Where is your call stack?
    If you are debugging the release build, you should enable the debug information.
    see 
    http://blog.joycode.com/jiangsheng/archive/2006/02/05/71101.aspx
      

  12.   

    TO:bmon_xyz(钳工) 
    你有IDA你可以试一下。我这边是2003,所以跟你的地址不一样。
    没法告诉你在哪个函数。
    to:jiangsheng(蒋晟.Net[MVP]) 
    不需要调试信息,一样能知道是在哪个函数里。
      

  13.   

    根据dll加载的基地址和导出函数相对地址,可以算出来。
      

  14.   

    北京奥赛尔生物工程技术有限公司     是一家位于北京市中关村科技园海淀园区,是由海外留学 人员创建的一家高新技术企业 ,并被评为 中关村留学人员创业园优秀企业 。(www.allshare.com.cn)  地址:北京、海淀、上地信息路26号、中关村留学生创业大厦 Tel : 010-82898000; 13601182765; 13683076911 现因业务拓展,需要组建新的团队,招聘以下人员:职务 名额   职务描述 
    1、美工 1名 软件界面设计 
    2、网站制作 1名 HTML + JavaScript(PHP) 
    3、程序员 2名  Win32 API + C\C++ 
    4、数据库管理员 1名 Oracle; SQL Sever 2000 
      

  15.   

    to idAnts(Coil & Nova Since 1985):
    根据dll加载的基地址和导出函数相对地址,可以算出来。怎么算?能否举个实际的例子?
      

  16.   

    大多数情况都是代码的问题.
    For example:memcpy越界就会造成.
      

  17.   

    举个例子,你的程序调用了CopyFileA这个函数,它在Kernel32.dll中,调试的时候看下Kernel32.dll加载的基地址,比如是:0x7c800000,而用dependency walker看CopyFileA在kernel32.dll中的0x00030053,那么在你的程序里,调用的地址就是0x7c800000 + 0x00030053 = 0x7c830053了.
      

  18.   

    to idAnts(Coil & Nova Since 1985):
    你这个方法只能算出函数CopyFileA的地址,但是现在我的问题是根据地址找对应的函数,你举的例子中如果出错的地址是0x7c830053,那很清楚就是CopyFileA函数,但是如果出错地址是0x7c830000,就很难界定了,而实际情况下一般都是这样,出错的指令地址一般都是很随机的。
      

  19.   

    一定要这样找...只能够用GetProcAddress来或得API地址然后跟堆栈里的数据比较
    或者使用symbols
      

  20.   

    你可以看一下MSDN的有关调试的文档:
    在Platform SDK > Debugging and Error Handling > Using DbgHelp
    在这里有很详细的示例代码,你可以枚举出所有与你exe可执行文件相关的动态库(Module DLL)以及这些动态库中的函数(Function)和符号地址(Symbol Address)。试着将这些信息保存在一个文件ModuleInfo.txt中,当这个exe文件Crash时,你的栈最终定位到0x77FCB03D,并且在Module中你确信这个指向Kernel32.dll,那么,通过ModuleInfo.txt便可以找到0x77FCB03D所指向的函数了,如果找不到,可能是其它错误。