zoukankan      html  css  js  c++  java
  • DLL注入实现子进程Runtime Error检测

         好久之前写的Offline Judge,当时RE评测结果功能的实现使用的是debug api,结果有一个bug,此功能就暂时被删掉了。昨天和学长讨论,说debug api可能会影响运行时间的评测结果,当时我还觉不使用debug api怎么能捕捉到子进程的异常呢。今天突然想到不用debug api的方法:注入dll,挂钩UnhandledExceptionFilter。然而写好之后令我没想到的是,一个7KB的DLL文件注入之后居然多占用了1.5M的内存,这样内存使用的信息也就只能“仅作参考”了。目前我还没有想到解决办法。对于一些对内存使用量不敏感的应用来说,这种方法也可以考虑,当然前提是程序内部没有对异常做出处理。

         最开始想到的方法是注入之后调用SetUnhandledExceptionFilter,不过发现居然没用(也许是在我的dll注入进去之后UnhandledExceptionFilter又被改掉了?还是什么?)。然后想到挂钩SetUnhandledExceptionFilter让所有人都靠边站,不过既然这样为何不直接挂钩UnhandledExceptionFilter呢,因为每次异常发生(测试用的是一个人为除零的小程序)都是windows的“xxxx已停止工作……”,这说明最后是UnhandledExceptionFilter得到控制权的(这也是一定的),而且并不是所有未处理异常都会被SetUnhandledExceptionFilter所设置的函数拦截到的。于是,动工。

    void HookUnhandledExceptionFilter(){
    	BYTE fakeEntry[5];
    	fakeEntry[0] = 0xE9;
    	LPVOID pFunc = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "UnhandledExceptionFilter");
    	*((PDWORD)(&fakeEntry[1])) = (DWORD)NewExceptionFilter - (DWORD)pFunc - 5;
    	DWORD dwProtect, dwWrite;
    	VirtualProtect(pFunc, 5, PAGE_READWRITE, &dwProtect);
    	WriteProcessMemory(GetCurrentProcess(), pFunc, fakeEntry, 5, &dwWrite);
    	VirtualProtect(pFunc, 5, dwProtect, NULL);
    	return 0;
    }
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
    	switch(reason) {
    	case DLL_PROCESS_ATTACH:
    		HookUnhandledExceptionFilter();
    	break;
    	}
    	return 1;
    }

         HookUnhandledExceptionFilter函数把原来的UnhandledExceptionFilter函数的前5个字节改成了跳转。其中的NewExceptionFilter是我们新的UnhandledExceptionFilter函数。

         NewExceptionFilter的作用就很简单了,得到ExceptionCode,根据异常类型向主程序传递信息。传递信息这里我是直接通过StdErr实现的,主程序通过匿名管道实现StdErr的重定向,只要检测是否有错误输出就可以知道是否有Runtime Error了。如果是其他应用,使用命名管道之类的手段即可。

        

        这是一种不用debug api来获得子进程异常的方法,也算作是一种思路吧。

  • 相关阅读:
    权值线段树模版
    P2679 [NOIP2015 提高组] 子串
    P3747 [六省联考 2017] 相逢是问候
    P2822 [NOIP2016 提高组] 组合数问题
    P2331 [SCOI2005]最大子矩阵
    P1854 花店橱窗布置
    P5888 传球游戏
    Hard | LeetCode 42. 接雨水 | 单调栈 | 双指针
    Medium | LeetCode 621. 任务调度器 | 设计
    Medium | LeetCode 166. 分数到小数 | 数学
  • 原文地址:https://www.cnblogs.com/tuesday/p/2329791.html
Copyright © 2011-2022 走看看