抑制或拦截来自其他dll的CRT实例的CRT检查
||
我的程序加载了几个dll并调用了它们的函数。 dll可以使用不同版本的CRT。
当C运行时检查参数的有效性并发现问题时,它将调用无效的参数句柄,依次使用或不使用“发送-不发送”对话框来关闭应用程序。
我尝试调用* _set_invalid_parameter_handler *,但只有在错误的dll中调用它时,它才有效。我尝试了SetErrorMode,但是我要做的就是在没有对话框的情况下杀死进程。
有什么办法可以处理这些异常?我不在乎某些资源是否受到损害。我只想允许用户保存配置。如果出现对话框,则单击该对话框并终止进程。
编辑
事实证明,加载所有版本的CRT或枚举所有DLL的解决方案均失败。为了清楚起见,下面是一个小示例:
这将是我的主要应用程序(我们将其称为文件application.c):
#include <windows.h>
void myInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) {
wprintf(L\"Invalid parameter detected in function %s. File: %s Line: %d\\n\", function, file, line);
wprintf(L\"Expression: %s\\n\", expression);
}
void fixMyProblem() {
}
int main(int argc, char **argv) {
HMODULE hModule = LoadLibrary(\"extension.dll\");
void (WINAPI *function)() = GetProcAddress(hModule, \"function\");
fixMyProblem();
function();
}
该应用程序加载了一个执行不良操作的dll(不是我开发的,因此我不会接受任何解决方案告诉我修复那里的错误)。让我们将该文件扩展名命名为c。
#include <stdio.h>
__declspec(dllexport) void function() {
printf(\"do bad stuff\");
fopen(NULL, \"r\");
}
要进行编译,请执行以下操作:
cl extension.c /link /OUT:extension.dll /DLL
cl application.c
问题是我该如何在fixMyProblem()函数中执行操作,以便在XP上不会出现“发送/不发送”对话框,或者应用程序已在7上停止工作。
根据David Gladfelter的说法,我应该做
void fixMyProblem() {
_set_invalid_parameter_handler(myInvalidParameterHandler);
}
并针对每个可用的CRT版本执行此操作。事实证明,即使使用一个单一版本的CRT(我对exe和dll都使用相同的版本),它仍然不起作用。它们都使用相同的CRT版本,但是似乎它们并不使用相同的CRT。
如果是这种情况,我假设我必须更改的内容在DLL内部。当然,它不会导出* _set_invalid_parameter_handler *。
但公平地说,这是他的解决方案的实现:
#include <Psapi.h>
#pragma comment(lib, \"Psapi.lib\")
void fixMyProblem() {
HANDLE hProcess = GetCurrentProcess();
HMODULE *hModules;
DWORD requiredSize = 0;
DWORD secondRequiredSize = 0;
if (!EnumProcessModules(hProcess, NULL, 0, &requiredSize)) {
printf(\"oops\\n\");
return;
}
hModules = malloc(requiredSize);
if (EnumProcessModules(hProcess, hModules, requiredSize, &secondRequiredSize)) {
int i;
int loadedModules = min(requiredSize, secondRequiredSize) / sizeof(HMODULE);
for (i = 0; i < loadedModules; i++) {
void *(WINAPI *_set_invalid_parameter_handler_function)(void *) = (void *(WINAPI *)(void *)) GetProcAddress(hModules[i], \"_set_invalid_parameter_handler\");
if (_set_invalid_parameter_handler_function != NULL) {
_set_invalid_parameter_handler_function(myInvalidParameterHandler);
printf(\"fixed dll %d\\n\", i);
}
}
} else {
printf(\"oops\\n\");
}
free(hModules);
}
对于我的实际应用程序(不是此测试),我得到了1个固定的dll(msvcp90.dll)。它仍然不能解决我的问题。
对于解决此问题,我将不胜感激。
没有找到相关结果
已邀请:
3 个回复
玩翁文醚碱
或ѭ7functions之类的函数,从而使dll使用您自己的函数代替。您可以通过分析已加载的dll的导入地址表,搜索您感兴趣的函数名称并更改地址以指向您的函数来执行此操作。
才改隘瘁
闯舱酮