partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
阅读:2013回复:13

驱动程序内存补钉代码蓝屏现象请教

楼主#
更多 发布于:2008-04-16 14:33
驱动程序内存补钉时
在Ring0将执行代码写入ExAllocatePoolWithTag申请的非分页内存并执行时蓝屏
发生错误代码 1000007f
参数1 00000008,参数2 80042000,参数3 00000000,参数4 00000000。

哪位高手可以帮我指出一条明路?
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2008-04-16 15:10
Double Fault ,通常是程序流程问题或者内核栈崩溃

最常见的情况是死循环程序导致内核栈溢出

你COPY代码后做重定位了没有?
驱动开发者 呵呵
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2008-04-16 15:21
这种问题调试下就清楚了,凭空想没用.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地板#
发布于: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;
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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;
        }
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-04-16 16:41
那串魔数就是写入的代码
地址是验证过的
实际地址是根据获取驱动基地址+偏移量得到的
为了看起来清爽,我用其中一次获得的实际地址替换了
GoodOnline
驱动小牛
驱动小牛
  • 注册日期2007-04-11
  • 最后登录2009-02-28
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望204点
  • 贡献值0点
  • 好评度191点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-04-16 16:44
发个可以编译啊
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2008-04-16 17:10
DWORD *)(0XC336E166) = (DWORD)lpPoolPtr - 0XC336E166 - 5;

这个错了
驱动开发者 呵呵
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
8楼#
发布于:2008-04-16 17:11
所以WOW说的没错,调一下什么都清楚了
驱动开发者 呵呵
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2008-04-16 17:32
*(DWORD *)(0XC336E166) = (DWORD)lpPoolPtr - 0XC336E165 - 5;
是我抄错了代码

内存补钉是不能编译的
整个代码发上来也太大了些
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2008-04-16 17:34
查了下代码,有可能是这错
不管怎样,先谢谢

我调调再通告各位结果
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2008-04-16 17:53
WQXNETQIQI指出的代码确实错了
但是改了
还是一样蓝脸

错误代码 1000007f
参数1 00000008,参数2 80042000,参数3 00000000,参数4 00000000。
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2008-04-16 19:11
现场跟踪报道:

目前的现象是
*(0XC336E165)    = 0xe9;//JMP
*(DWORD *)(0XC336E166) = (DWORD)lpPoolPtr - 0XC336E166 - 5;
执行时就已经发生异常

将原驱动的代码原样写也同样会出错

难道是内存保护机制?
partime
驱动牛犊
驱动牛犊
  • 注册日期2002-02-27
  • 最后登录2009-11-09
  • 粉丝0
  • 关注0
  • 积分211分
  • 威望61点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
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;
}

会不会是用户态基址和核心态基址不同导致的?
但是通过同样的基址在核心态将驱动转储又没问题.
游客

返回顶部