阅读:2013回复:13
驱动程序内存补钉代码蓝屏现象请教
驱动程序内存补钉时
在Ring0将执行代码写入ExAllocatePoolWithTag申请的非分页内存并执行时蓝屏 发生错误代码 1000007f 参数1 00000008,参数2 80042000,参数3 00000000,参数4 00000000。 哪位高手可以帮我指出一条明路? |
|
沙发#
发布于:2008-04-16 15:10
Double Fault ,通常是程序流程问题或者内核栈崩溃
最常见的情况是死循环程序导致内核栈溢出 你COPY代码后做重定位了没有? |
|
|
板凳#
发布于:2008-04-16 15:21
这种问题调试下就清楚了,凭空想没用.
|
|
|
地板#
发布于:2008-04-16 16:32
我的代码很简单
就是把原流程中的EAX拿出来比较了一下 没有循环 也没有任何调用 所有代码如下: CMP EAX,0X00CCE980;--->跳入点,通过JMP跳转 JNA RETURN; CMP EAX,0X00EE8735; JNB RETURN; SUB EAX,0X00CCE980; ADD EAX,0X001CE980; RETURN: MOV DWORD PTR [EBP-0X1C], EAX;//原流程执行代码被替换部分 MOV ECX,EAX; //原流程执行代码被替换部分 NOP; NOP; PUSH 0XC336E16C; //返回地址 RET; |
|
地下室#
发布于:2008-04-16 16:39
打补钉的代码
DWORD *lpPoolPtr = (DWORD *)ExAllocatePoolWithTag(0,0x30,"DRVP"); if(lpPoolPtr == NULL) { pfnDbgPrint("ExAllocatePoolWithTag Failed"); return 0; } pfnDbgPrint("Allocated Memory @ %lp",lpPoolPtr); _asm{ cli; mov eax,cr0; mov OldCr0,eax; and eax,0xfffeffff; mov cr0,eax; } lpPoolPtr[0] = 0xCCE9803D; lpPoolPtr[1] = 0x3D117600; lpPoolPtr[2] = 0x00EE8735; lpPoolPtr[3] = 0x802d0a73; lpPoolPtr[4] = 0x0500CCE9; lpPoolPtr[5] = 0X001CE980; lpPoolPtr[6] = 0x8BE44589; lpPoolPtr[7] = 0x689090C8; lpPoolPtr[8] = 0XC336E16B; lpPoolPtr[9] = 0xCCCCCCC3; *(0XC336E165) = 0xe9;//JMP *(DWORD *)(0XC336E166) = (DWORD)lpPoolPtr - 0XC336E166 - 5; _asm { mov eax,OldCr0; mov cr0,eax; sti; } |
|
5楼#
发布于:2008-04-16 16:41
那串魔数就是写入的代码
地址是验证过的 实际地址是根据获取驱动基地址+偏移量得到的 为了看起来清爽,我用其中一次获得的实际地址替换了 |
|
6楼#
发布于:2008-04-16 16:44
发个可以编译啊
|
|
7楼#
发布于:2008-04-16 17:10
DWORD *)(0XC336E166) = (DWORD)lpPoolPtr - 0XC336E166 - 5;
这个错了 |
|
|
8楼#
发布于:2008-04-16 17:11
所以WOW说的没错,调一下什么都清楚了
|
|
|
9楼#
发布于:2008-04-16 17:32
*(DWORD *)(0XC336E166) = (DWORD)lpPoolPtr - 0XC336E165 - 5;
是我抄错了代码 内存补钉是不能编译的 整个代码发上来也太大了些 |
|
10楼#
发布于:2008-04-16 17:34
查了下代码,有可能是这错
不管怎样,先谢谢 我调调再通告各位结果 |
|
11楼#
发布于:2008-04-16 17:53
WQXNETQIQI指出的代码确实错了
但是改了 还是一样蓝脸 错误代码 1000007f 参数1 00000008,参数2 80042000,参数3 00000000,参数4 00000000。 |
|
12楼#
发布于:2008-04-16 19:11
现场跟踪报道:
目前的现象是 *(0XC336E165) = 0xe9;//JMP *(DWORD *)(0XC336E166) = (DWORD)lpPoolPtr - 0XC336E166 - 5; 执行时就已经发生异常 将原驱动的代码原样写也同样会出错 难道是内存保护机制? |
|
13楼#
发布于:2008-04-16 19:19
对了
驱动程序加载的基址是在用户态(Ring3)获得的 lpDriverBasePtr = (unsigned char *)GetModuleBase("NeedPatch.sys"); PVOID __stdcall GetModuleBase(PCSTR name) { NTSTATUS status; PVOID pBuffer, pModule; ULONG nRetSize, i, n; PSYSTEM_MODULE_INFORMATION pmi; pBuffer = LocalAlloc(LPTR, 0x1000); if (NULL == pBuffer) { printf("LocalAlloc[0] Failed: %d\n", GetLastError()); return NULL; } status = ZwQuerySystemInformation(SystemModuleInformation, pBuffer, 0x1000, &nRetSize); if (STATUS_INFO_LENGTH_MISMATCH == status) { // 缓冲区太小,重新分配 LocalFree(pBuffer); pBuffer = LocalAlloc(LPTR, nRetSize); if (NULL == pBuffer) { printf("LocalAlloc[1] Failed: %d\n", GetLastError()); return NULL; } status = ZwQuerySystemInformation(SystemModuleInformation, pBuffer, nRetSize, &nRetSize); } if (!NT_SUCCESS(status)) { printf("ZwQuerySystemInformation Failed: %d\n", LsaNtStatusToWinError(status)); LocalFree(pBuffer); return NULL; } pmi = (PSYSTEM_MODULE_INFORMATION)((ULONG)pBuffer + 4); n = *(ULONG*)pBuffer; pModule = NULL; // 搜索指定的模块名,获取基址 for (i=0; i<n; i++) { if (!_stricmp(pmi->ImageName+pmi->ModuleNameOffset, name)) { pModule = pmi->Base; dwSize = pmi->Size; break; } pmi++; } LocalFree(pBuffer); return pModule; } 会不会是用户态基址和核心态基址不同导致的? 但是通过同样的基址在核心态将驱动转储又没问题. |
|