C++ DLL 获取调用者信息

时间:2021-07-21 07:34:17
例如, 
A.EXE 调用 B.DLL
B.DLL 调用 C.DLL 
B 、C 中可以获取 A.EXE的信息。 
请问 C.DLL 可以获取 B.DLL 的信息吗? 
比如文件大小、修改时间、路径等信息。

20 个解决方案

#1


比如
A\B\C 都可以获取自己的路径
B\C 可以获取 A 的路径
C 如何获取 B 的路径?

#2


调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。

#3


查MSDN是Windows程序员必须掌握的技能之一。

GetModuleFileNameEx
The GetModuleFileNameEx function retrieves the fully qualified path for the specified module. 

DWORD GetModuleFileNameEx(
  HANDLE hProcess,    // handle to the process
  HMODULE hModule,    // handle to the module
  LPTSTR lpFilename,  // buffer that receives the path
  DWORD nSize         // size of the buffer
);
 
Parameters
hProcess 
Handle to the process that contains the module. 
hModule 
Handle to the module. 
lpFilename 
Pointer to the buffer that receives the fully qualified path to the module. 
nSize 
Specifies the size, in bytes, of the lpFilename buffer. 
Return Value
If the function succeeds, the return value specifies the length of the string copied to the buffer. 

If the function fails, the return value is zero. To get extended error information, call GetLastError. 

See Also
Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleBaseName 

 

#4


引用 2 楼 sunyongliang118 的回复:
调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?

#5


引用 4 楼 wlb315153 的回复:
Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。

#6


引用 5 楼 sunyongliang118 的回复:
Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


天气很热? C++ DLL 获取调用者信息

#7


引用 6 楼 wlb315153 的回复:
Quote: 引用 5 楼 sunyongliang118 的回复:

Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


天气很热? C++ DLL 获取调用者信息

可能我说话有些重,但是你确实需要自己在思考问题的能力上下功夫,不单单编程,将来处理其他问题也可以游刃有余。
人生不单单是书本上的东西,不单单是编程,还有更多复杂难解的问题,你将会遇到。

学会独立思考,在别人的经验和前行的路上树立起自己不一样的创见,才是青出于蓝而胜于蓝,才是芝麻开花节节高,才是日出江花红胜火,春来江水绿如蓝。

#8


引用 5 楼 sunyongliang118 的回复:
Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


真还有可能两个文件的路径一样,比如说文件系统驱动重定向

#9


引用 3 楼 zhao4zhong1 的回复:
查MSDN是Windows程序员必须掌握的技能之一。

GetModuleFileNameEx
The GetModuleFileNameEx function retrieves the fully qualified path for the specified module. 

DWORD GetModuleFileNameEx(
  HANDLE hProcess,    // handle to the process
  HMODULE hModule,    // handle to the module
  LPTSTR lpFilename,  // buffer that receives the path
  DWORD nSize         // size of the buffer
);
 
Parameters
hProcess 
Handle to the process that contains the module. 
hModule 
Handle to the module. 
lpFilename 
Pointer to the buffer that receives the fully qualified path to the module. 
nSize 
Specifies the size, in bytes, of the lpFilename buffer. 
Return Value
If the function succeeds, the return value specifies the length of the string copied to the buffer. 

If the function fails, the return value is zero. To get extended error information, call GetLastError. 

See Also
Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleBaseName 

 

多谢 赵4老师, MSDN,我有查找学习,但是可能知识面太窄,没有找到合适的方式解决。
是可以 找到 Process 里 所有的 module ,可是我不知道怎么确定是 谁调用的。

比如, A.EXE 调用了 B.DLL ,C.DLL  ,B.DLL 调用了 C.DLL
A.EXE 运行的时候, C.DLL  如何确定 什么时候 是 A.EXE 调用的,什么时候是B.DLL 调用的
或者说,如何做到 C.DLL 只允许通过 B.DLL 调用,不允许直接调用。
不好意思,不知道描述的是否清楚。 谢谢。

#10


引用 8 楼 ID870177103 的回复:
Quote: 引用 5 楼 sunyongliang118 的回复:

Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


真还有可能两个文件的路径一样,比如说文件系统驱动重定向

C++ DLL 获取调用者信息恭喜成为诺贝尔获奖者

#11


引用 10 楼 wlb315153 的回复:
Quote: 引用 8 楼 ID870177103 的回复:

Quote: 引用 5 楼 sunyongliang118 的回复:

Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


真还有可能两个文件的路径一样,比如说文件系统驱动重定向

C++ DLL 获取调用者信息恭喜成为诺贝尔获奖者

呵呵 C++ DLL 获取调用者信息

#12


假定你在 C 模块中设计一个导出符号 F。
那么这个符号可能会被 B 或者 A 调用,甚至可以被 Z 调用。
那么可能需要确定到底是 BAZ 谁在调用。比如说只允许 AB 调用等等。

那么此时在 F 函数中使用 _ReturnAddress 获取这个函数的返回地址,这个地址只能在 BAZ 之中。
使用GetModuleHandleEx 就可以或者 BAZ 的模块句柄。
有了这个句柄就可以判断是否是 AB 还是 Z 了。

#13


引用 12 楼 Saleayas 的回复:
假定你在 C 模块中设计一个导出符号 F。
那么这个符号可能会被 B 或者 A 调用,甚至可以被 Z 调用。
那么可能需要确定到底是 BAZ 谁在调用。比如说只允许 AB 调用等等。

那么此时在 F 函数中使用 _ReturnAddress 获取这个函数的返回地址,这个地址只能在 BAZ 之中。
使用GetModuleHandleEx 就可以或者 BAZ 的模块句柄。
有了这个句柄就可以判断是否是 AB 还是 Z 了。


C++ DLL 获取调用者信息
多谢,这个测试行得通。
但是 如果 模块中 有 托管 DLL ,则无法返回正确地址,有没有解决的办法?  再次多谢/

#14


引用 13 楼 wlb315153 的回复:
Quote: 引用 12 楼 Saleayas 的回复:

假定你在 C 模块中设计一个导出符号 F。
那么这个符号可能会被 B 或者 A 调用,甚至可以被 Z 调用。
那么可能需要确定到底是 BAZ 谁在调用。比如说只允许 AB 调用等等。

那么此时在 F 函数中使用 _ReturnAddress 获取这个函数的返回地址,这个地址只能在 BAZ 之中。
使用GetModuleHandleEx 就可以或者 BAZ 的模块句柄。
有了这个句柄就可以判断是否是 AB 还是 Z 了。


C++ DLL 获取调用者信息
多谢,这个测试行得通。
但是 如果 模块中 有 托管 DLL ,则无法返回正确地址,有没有解决的办法?  再次多谢/

比如 AZ 为非托管DLL ,B 为托管DLL,可以识别AZ,但是无法识别 B

#15


你理解错误了。
托管的 DLL 呼叫非托管的 DLL,系统会呼叫一个中间的 DLL (clr.dll) 来转换的。
此时你获取的呼叫方 DLL 就是 clr.dll。
如果你需要区分这种情况,需要自己的判断。

#16


引用 15 楼 Saleayas 的回复:
你理解错误了。
托管的 DLL 呼叫非托管的 DLL,系统会呼叫一个中间的 DLL (clr.dll) 来转换的。
此时你获取的呼叫方 DLL 就是 clr.dll。
如果你需要区分这种情况,需要自己的判断。

不知道为什么,调试状态返回的是 clr.dll ,直接运行的话 GetModuleHandleEx 返回 FALSE。
即便都返回 clr.dll ,是不是也没有办法判断具体的呼叫方?

#17


引用 16楼我是你的主体 的回复:
Quote: 引用 15 楼 Saleayas 的回复:

你理解错误了。
托管的 DLL 呼叫非托管的 DLL,系统会呼叫一个中间的 DLL (clr.dll) 来转换的。
此时你获取的呼叫方 DLL 就是 clr.dll。
如果你需要区分这种情况,需要自己的判断。

不知道为什么,调试状态返回的是 clr.dll ,直接运行的话 GetModuleHandleEx 返回 FALSE。
即便都返回 clr.dll ,是不是也没有办法判断具体的呼叫方?
EnumProcessModules,里面有clr.dll ,没有 托管的呼叫方

#18


难者不会,会者不难。
clr也有堆栈可供查询。
我还真没见过不靠堆栈实现函数调用的环境。
建议学习使用WinDbg

#19


clr.dll 可能是托管环境和非托管环境的交互。
类似系统的门调用。
没有类似 DLL 的呼叫和被叫的关系的。
也就是说,堆栈回溯是回溯不到的。
也就是说 clr.dll 是系统呼叫的。

我没有具体的测试过,仅仅是猜测而已。

#20


结帖散分,多谢各位! C++ DLL 获取调用者信息

#1


比如
A\B\C 都可以获取自己的路径
B\C 可以获取 A 的路径
C 如何获取 B 的路径?

#2


调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。

#3


查MSDN是Windows程序员必须掌握的技能之一。

GetModuleFileNameEx
The GetModuleFileNameEx function retrieves the fully qualified path for the specified module. 

DWORD GetModuleFileNameEx(
  HANDLE hProcess,    // handle to the process
  HMODULE hModule,    // handle to the module
  LPTSTR lpFilename,  // buffer that receives the path
  DWORD nSize         // size of the buffer
);
 
Parameters
hProcess 
Handle to the process that contains the module. 
hModule 
Handle to the module. 
lpFilename 
Pointer to the buffer that receives the fully qualified path to the module. 
nSize 
Specifies the size, in bytes, of the lpFilename buffer. 
Return Value
If the function succeeds, the return value specifies the length of the string copied to the buffer. 

If the function fails, the return value is zero. To get extended error information, call GetLastError. 

See Also
Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleBaseName 

 

#4


引用 2 楼 sunyongliang118 的回复:
调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?

#5


引用 4 楼 wlb315153 的回复:
Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。

#6


引用 5 楼 sunyongliang118 的回复:
Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


天气很热? C++ DLL 获取调用者信息

#7


引用 6 楼 wlb315153 的回复:
Quote: 引用 5 楼 sunyongliang118 的回复:

Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


天气很热? C++ DLL 获取调用者信息

可能我说话有些重,但是你确实需要自己在思考问题的能力上下功夫,不单单编程,将来处理其他问题也可以游刃有余。
人生不单单是书本上的东西,不单单是编程,还有更多复杂难解的问题,你将会遇到。

学会独立思考,在别人的经验和前行的路上树立起自己不一样的创见,才是青出于蓝而胜于蓝,才是芝麻开花节节高,才是日出江花红胜火,春来江水绿如蓝。

#8


引用 5 楼 sunyongliang118 的回复:
Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


真还有可能两个文件的路径一样,比如说文件系统驱动重定向

#9


引用 3 楼 zhao4zhong1 的回复:
查MSDN是Windows程序员必须掌握的技能之一。

GetModuleFileNameEx
The GetModuleFileNameEx function retrieves the fully qualified path for the specified module. 

DWORD GetModuleFileNameEx(
  HANDLE hProcess,    // handle to the process
  HMODULE hModule,    // handle to the module
  LPTSTR lpFilename,  // buffer that receives the path
  DWORD nSize         // size of the buffer
);
 
Parameters
hProcess 
Handle to the process that contains the module. 
hModule 
Handle to the module. 
lpFilename 
Pointer to the buffer that receives the fully qualified path to the module. 
nSize 
Specifies the size, in bytes, of the lpFilename buffer. 
Return Value
If the function succeeds, the return value specifies the length of the string copied to the buffer. 

If the function fails, the return value is zero. To get extended error information, call GetLastError. 

See Also
Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleBaseName 

 

多谢 赵4老师, MSDN,我有查找学习,但是可能知识面太窄,没有找到合适的方式解决。
是可以 找到 Process 里 所有的 module ,可是我不知道怎么确定是 谁调用的。

比如, A.EXE 调用了 B.DLL ,C.DLL  ,B.DLL 调用了 C.DLL
A.EXE 运行的时候, C.DLL  如何确定 什么时候 是 A.EXE 调用的,什么时候是B.DLL 调用的
或者说,如何做到 C.DLL 只允许通过 B.DLL 调用,不允许直接调用。
不好意思,不知道描述的是否清楚。 谢谢。

#10


引用 8 楼 ID870177103 的回复:
Quote: 引用 5 楼 sunyongliang118 的回复:

Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


真还有可能两个文件的路径一样,比如说文件系统驱动重定向

C++ DLL 获取调用者信息恭喜成为诺贝尔获奖者

#11


引用 10 楼 wlb315153 的回复:
Quote: 引用 8 楼 ID870177103 的回复:

Quote: 引用 5 楼 sunyongliang118 的回复:

Quote: 引用 4 楼 wlb315153 的回复:

Quote: 引用 2 楼 sunyongliang118 的回复:

调用方:A 模块
被调用动态库:B模块。
我觉得你可以在调用的同时把调用方A模块的信息以只读参数的方式传进B的接口函数中,供B模块存储解析。这样B模块就知道是谁调用它了。

无非就是模块之间的通信联系,设计好接口函数即可。。


那如果有 X 模块 模仿 A 把 相同的信息传递给了B , B  还是区分不了 是不是真的 A 在调用。
GetModuleFileName 
MSDN  If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
可以返回 executable file ,也可以返回 selfModule.

但是   现在 想返回 中间调用DLL 的信息 ,应如何?


你是不是没思考我说的话???

X模块的动态库路经和A的路径能完全一样吗?什么叫模仿A把相同信息传给了B,X传的是X自身的信息,是X的独有基因(比如X文件所在全路径),A传的是A自身的信息,是A的独有基因,。。。。

学编程这么死板。

最笨的方法你不会在接口函数中定义主调方的全路径字符串???两个文件的全路径能完全一样???你给我找出这样的操作系统,你就是诺贝尔奖获得者。人还有身份证呢,何况严谨的计算机2进制系统。

再者,你动态生成调用标识也可以。

方法多了去了。我说到这份上,你还不能解决这个问题,只能说你没动脑筋。这不是编程经验和知识多少的问题,是思维懒惰,伸手要,开口求的典型代表。


真还有可能两个文件的路径一样,比如说文件系统驱动重定向

C++ DLL 获取调用者信息恭喜成为诺贝尔获奖者

呵呵 C++ DLL 获取调用者信息

#12


假定你在 C 模块中设计一个导出符号 F。
那么这个符号可能会被 B 或者 A 调用,甚至可以被 Z 调用。
那么可能需要确定到底是 BAZ 谁在调用。比如说只允许 AB 调用等等。

那么此时在 F 函数中使用 _ReturnAddress 获取这个函数的返回地址,这个地址只能在 BAZ 之中。
使用GetModuleHandleEx 就可以或者 BAZ 的模块句柄。
有了这个句柄就可以判断是否是 AB 还是 Z 了。

#13


引用 12 楼 Saleayas 的回复:
假定你在 C 模块中设计一个导出符号 F。
那么这个符号可能会被 B 或者 A 调用,甚至可以被 Z 调用。
那么可能需要确定到底是 BAZ 谁在调用。比如说只允许 AB 调用等等。

那么此时在 F 函数中使用 _ReturnAddress 获取这个函数的返回地址,这个地址只能在 BAZ 之中。
使用GetModuleHandleEx 就可以或者 BAZ 的模块句柄。
有了这个句柄就可以判断是否是 AB 还是 Z 了。


C++ DLL 获取调用者信息
多谢,这个测试行得通。
但是 如果 模块中 有 托管 DLL ,则无法返回正确地址,有没有解决的办法?  再次多谢/

#14


引用 13 楼 wlb315153 的回复:
Quote: 引用 12 楼 Saleayas 的回复:

假定你在 C 模块中设计一个导出符号 F。
那么这个符号可能会被 B 或者 A 调用,甚至可以被 Z 调用。
那么可能需要确定到底是 BAZ 谁在调用。比如说只允许 AB 调用等等。

那么此时在 F 函数中使用 _ReturnAddress 获取这个函数的返回地址,这个地址只能在 BAZ 之中。
使用GetModuleHandleEx 就可以或者 BAZ 的模块句柄。
有了这个句柄就可以判断是否是 AB 还是 Z 了。


C++ DLL 获取调用者信息
多谢,这个测试行得通。
但是 如果 模块中 有 托管 DLL ,则无法返回正确地址,有没有解决的办法?  再次多谢/

比如 AZ 为非托管DLL ,B 为托管DLL,可以识别AZ,但是无法识别 B

#15


你理解错误了。
托管的 DLL 呼叫非托管的 DLL,系统会呼叫一个中间的 DLL (clr.dll) 来转换的。
此时你获取的呼叫方 DLL 就是 clr.dll。
如果你需要区分这种情况,需要自己的判断。

#16


引用 15 楼 Saleayas 的回复:
你理解错误了。
托管的 DLL 呼叫非托管的 DLL,系统会呼叫一个中间的 DLL (clr.dll) 来转换的。
此时你获取的呼叫方 DLL 就是 clr.dll。
如果你需要区分这种情况,需要自己的判断。

不知道为什么,调试状态返回的是 clr.dll ,直接运行的话 GetModuleHandleEx 返回 FALSE。
即便都返回 clr.dll ,是不是也没有办法判断具体的呼叫方?

#17


引用 16楼我是你的主体 的回复:
Quote: 引用 15 楼 Saleayas 的回复:

你理解错误了。
托管的 DLL 呼叫非托管的 DLL,系统会呼叫一个中间的 DLL (clr.dll) 来转换的。
此时你获取的呼叫方 DLL 就是 clr.dll。
如果你需要区分这种情况,需要自己的判断。

不知道为什么,调试状态返回的是 clr.dll ,直接运行的话 GetModuleHandleEx 返回 FALSE。
即便都返回 clr.dll ,是不是也没有办法判断具体的呼叫方?
EnumProcessModules,里面有clr.dll ,没有 托管的呼叫方

#18


难者不会,会者不难。
clr也有堆栈可供查询。
我还真没见过不靠堆栈实现函数调用的环境。
建议学习使用WinDbg

#19


clr.dll 可能是托管环境和非托管环境的交互。
类似系统的门调用。
没有类似 DLL 的呼叫和被叫的关系的。
也就是说,堆栈回溯是回溯不到的。
也就是说 clr.dll 是系统呼叫的。

我没有具体的测试过,仅仅是猜测而已。

#20


结帖散分,多谢各位! C++ DLL 获取调用者信息

#21