好像是用VirtualQuery,我也记不清了。

解决方案 »

  1.   

    我给你一个大概的思路hInstance中存放的是模块的起始地址在函数中看回溯调用栈
    被调用的函数中[ebp+4](好像是)中放的是调用者的地址
    调用栈最后的栈底肯定是某个exe
    但是如果其中有个DLL,则一定是在DLL中调用
      

  2.   

    为什么不给我加分?????现在的csdn怎么搞的
      

  3.   

    用工具函数Imagehlp系列的函数就可以办到了,自己回去查一查
      

  4.   

    To Kevin_qing
    调用一个函数时,将所有参数压栈后,系统会自动将返回地址(IP)压栈
    所以在被调用函数中[ebp+4]永远都是调用者的地址
    然后一个函数一个函数的回溯,就能得到完成的调用栈
    VC的调试器能看call stack,也是利用这个方法
      

  5.   

    似乎你的说法有问题啊,VC能看call stack是因为他能知道所有函数的参数,及其类型。
    否则不可能回溯到正确的地址啊。比如
    _f2:
    push ebp
    mov  ebp,esp
    push 1
    push 2
    push 3
    call _vv
    pop  ebp
    ret  4
    _f1:
    push ebp
    mov  ebp,esp
    push 1
    call f2
    pop  ebp
    你在_vv里面如何得道f2里面esp的值啊~
      

  6.   

    MEMORY_BASIC_INFORMATION mbi;
    VirtualQuery(函数名,&mbi,sizeof(mbi));
    HMODULE hmod=(HMODULE)mbi.AllocationBase;
    //这是函数所在模块的句柄。
    char fn[128];
    GetModuleFileName(hmod,fn,128);
    //fn是文件名。
      

  7.   

    上铺的兄弟,VirtualQuery第一参数应是地址,而不是函数名(除非这段代码与参数在同一个工程中并一起编译),但您的代码得到结果是函数所在的文件名.
    To Kevin_qing:您的问题应该是问“一个函数如何知道它自己是在DLL还是在EXE里面被调用”吧?如果说运行,那应该在函数所在的文件本身里运行!
    若要知道在那个文件中调用,可以如下试试:
    DWORD addr;
    asm{
       pop eax
       ...
    /*以上调用pop次数=你的函数的参数,若是高级语言编写可以不用,因为高级语言在编译时会自动把参数传给变量*/
       pop ebp /*获取栈中返回地址*/
       mov dword ptr addr,ebp
       push ebp /*保存返回地址,防止程序出错*/
    }
    MEMORY_BASIC_INFORMATION mbi;
    VirtualQuery(addr,&mbi,sizeof(mbi));
    HMODULE hmod=(HMODULE)mbi.AllocationBase;
    //这是调用该函数所在模块的句柄。
    char fn[128];
    GetModuleFileName(hmod,fn,128);
    //fn是文件名。   
      

  8.   

    我试了,在win9x中不行.在win2000中用这个函数DWORD GetModuleFileNameEx(HANDLE hProcess,MODULE hModule,LPTSTR lpFilename, DWORD nSize );要用汇编语言可行。