查看文章
 
(转贴)ring0调用ring3代码。
2009-05-15 14:11

转贴一篇文章,原来找了好久的..... 驱动调用用户层代码

1、 KeUserModeCallBack
NTSTATUS
CallRing3()
{
    PLIST_ENTRY                Next;
    PPEB                    Peb;
    PLDR_DATA_TABLE_ENTRY    Entry;
    PVOID                    dll_addr, func_addr, pMem = NULL, OutputBuffer, lpTextAddr;
    UNICODE_STRING            us;
    NTSTATUS                status;
    ULONG                    OutputLength, dwSize = PAGE_SIZE, KernelCallbackTable = 0, TableIndex, dwUserCodeSize;
    MSGBOX_PARAMS            StackParams;
   
    Peb = GetCurrentProcessPeb();
    if (Peb) {
        // 鸯妁屙桢 忮玟?钿桧嚓钼? 礤 耱嚯 忭铖栩?桤戾礤龛 br />         // ?铒桉囗桢 PEB 桤 msdn :)
        KernelCallbackTable = *(ULONG*)((ULONG)Peb + 0x2C);
        RtlInitUnicodeString(&us, L"user32.dll");
                   
        Next = Peb->Ldr->InMemoryOrderModuleList.Flink;
        while (Next != &Peb->Ldr->InMemoryOrderModuleList) {
            Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, MemoryOrder);
                       
            if(!RtlCompareUnicodeString(&Entry->ModuleName, &us, TRUE)) {
                dll_addr = Entry->ModuleBaseAddress;
                func_addr = KernelGetProcAddress(dll_addr, "MessageBoxA");
                DbgPrint("user32.dll found at %x", dll_addr);
                DbgPrint("user32.dll->MessageBoxA found at %x", func_addr);
                           
                status = ZwAllocateVirtualMemory((HANDLE)-1, &pMem, 0, &dwSize, MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE);
                if (NT_SUCCESS(status)) {
                    DbgPrint("Memory allocated at %x", pMem);
                    *(ULONG*)pMem = (ULONG)pMem + 4;
                    TableIndex = ((ULONG)pMem - KernelCallbackTable) / sizeof(ULONG);
                    dwUserCodeSize = (ULONG)Ring3Code_End - (ULONG)Ring3Code;
                    lpTextAddr = (PVOID)((ULONG)pMem + 4 + dwUserCodeSize);
                               
                    DbgPrint("KernelCallbackTable == %x", KernelCallbackTable);
                    DbgPrint("OurTableIndex == %x", TableIndex);
                               
                    __try {
                                   
                        RtlCopyMemory((PVOID)((ULONG)pMem + 4), Ring3Code, dwUserCodeSize);
                        RtlCopyMemory(lpTextAddr, HELLOSTR, strlen(HELLOSTR));
                       
                        RtlZeroMemory(&StackParams, sizeof(MSGBOX_PARAMS));
                        StackParams.MessageBoxA = func_addr;
                        StackParams.lpText = lpTextAddr;
                       
                        DbgPrint("Call user mode...");
                        status = KeUserModeCallback( TableIndex,
                                                    &StackParams,
                                                    sizeof(MSGBOX_PARAMS),
                                                    &OutputBuffer,
                                                    &OutputLength );
                        DbgPrint("KeUserModeCallback return %x", status);
                       
                        }
                    __except (EXCEPTION_EXECUTE_HANDLER) {
                        DbgPrint("Exception");
                        }
                       
                    ZwFreeVirtualMemory((HANDLE)-1, &pMem, &dwSize, MEM_DECOMMIT);
                    } // if
                           
                break;
                } // if
                       
            Next = Next->Flink;
            } // while
        } // if Peb
   
    return STATUS_DEVICE_CONFIGURATION_ERROR;
}


2、 apc

//=====================================================================================//
//Name: void RunProcess()                                                              //
//                                                                                     //
//Descripion: This routine retrieves the list of all processes running on the machine, //
//            searches for 'explorer.exe', gets one thread from it's PEPROCESS struct, //
//            then it queues an APC to that thread                                     //
//=====================================================================================//
void RunProcess(LPSTR lpProcess)
{
    //全部定义为ULONG类型
    ULONG pTargetProcess;     //self explanatory
    ULONG pTargetThread;     //thread that can be either alerable or non-alertable
    ULONG pNotAlertableThread; //non-alertable thread
    ULONG pSystemProcess;     //May not necessarily be the 'System' process
    ULONG pTempThread;
    ULONG pNextEntry, pListHead, pThNextEntry,pThListHead;


    if(strlen(lpProcess)>300) return; //name not longer than 300 characters
    //获得系统进程
    pSystemProcess =(ULONG)PsGetCurrentProcess(); //make sure you are running at IRQL PASSIVE_LEVEL

    if(!pSystemProcess)
    {
        DbgPrint("KernelExec -> Cannot find 'System' process!");
        return;
    }
    //获取进程列表头(+0x088 ActiveProcessLinks : _LIST_ENTRY)
    pListHead=pSystemProcess+0x88;
    //得到下一个EPROCESS结构的ActiveProcessLinks偏移地址
    pNextEntry=*(ULONG*)pListHead;
    if(!pNextEntry)
        DbgPrint("KernelExec -> No processes found!");
    else
    {

        while(pNextEntry != pListHead) //start looping through the available processes
        {    //得到EPROCESS的首地址
            pSystemProcess =pNextEntry-0x88;
            //进程名偏移
            //+0x174 ImageFileName:[16] UChar
            DbgPrint("ProcessName %s \n",(char*)pSystemProcess+0x174);
                    //Is this explorer.exe?
                    if(_strnicmp((char*)pSystemProcess+0x174,"explorer.exe",12)==0)
                    {    //得到进程的EPROCESS结构的地址
                        pTargetProcess = pSystemProcess; //Yes,we have found it!
                        DbgPrint("yes,we have found explorer.exe!");
                       
                        pTargetThread = pNotAlertableThread = 0;
                        //获取线程列表头
                        //+0x050 ThreadListHead   : _LIST_ENTRY
                        //也就是_KPROCESS(PCB)中ThreadListHead的偏移地址
                        pThListHead = pSystemProcess+0x50;
                        //得到ETHREAD结构中_KTHREAD(Tcb)的+0x1b0 ThreadListEntry : _LIST_ENTRY地址
                        pThNextEntry=*(ULONG *)pThListHead;
                        //Now we loop through it's threads, seeking an alertable thread
                        while(pThNextEntry != pThListHead)
                        {    //所属ETHREAD的首地址
                            pTempThread =pThNextEntry-0x1b0;
                            DbgPrint("ethread address is:0x%x\n",(ULONG *)pTempThread);
                            //线程ID
                            //ETHREAD+0x1ec Cid : _CLIENT_ID为进程ID
                            //再向下+4为线程ID
                            DbgPrint("thread Id is %d\n",*(ULONG *)(pTempThread+0x1f0));
                            //是否警告状态
                            //+0x164 Alertable : UChar
                            DbgPrint("Alertable is:%x",*(char *)(pTempThread+0x164));
                            //tcb=*(PKTHREAD)pTempThread;
                            if(*(char *)(pTempThread+0x164)) //Tcb is the KTHREAD of this ETHREAD and stands for 'Thread Control Block'
                            {
                                //Good, an alertable thread was found.
                                //得到explorer.exe中符合条件的线程PKTHREAD(ETHREAD)结构的地址
                                pTargetThread =pTempThread;

                                DbgPrint("KernelExec -> Found alertable thread");
                                //We will be using this one, so break now
                                break;
                            }
                            else
                            {
                                //Didn't find an alertable thread yet, so we'll keep this one
                                //just in case we won't find ANY alertable threads
                                //至少需要一个非警告状态的线程
                                pNotAlertableThread =pTempThread;
                            }
                            //下一个线程块
                            pThNextEntry = *(ULONG *)pThNextEntry; //check next thread
                        }
                        break;   
                    }
            //下一个进程块
            pNextEntry = *(ULONG *)pNextEntry; //get next process
        }
    }
   
    if(!pTargetProcess)
    {
        DbgPrint("KernelExec -> Couldn't find Explorer.exe!");
        return;
    }
    if(!pTargetThread)
    {
        //No alertable thread was found, so let's hope we've at least got a non-alertable one (we'll set its alertable flag ON)
        //There's no problem with non-alertable threads, except for the fact that it takes
        //a little longer for them to return from KernelMode. (that means our process execution will be delayed)
        pTargetThread = pNotAlertableThread;
    }

    if(pTargetThread)
    {
        DbgPrint("KernelExec -> Targeted thread: 0x%p",pTargetThread);
        //We have one thread (alertable or n/a), now install the APC
        InstallUserModeApc(lpProcess,pTargetThread,pTargetProcess);
    }
    else
        DbgPrint("KernelExec -> No thread found!"); //Explorer exe with NO threads (???)*/
}

3、ExRaiseHardError
01 typedef enum _HARDERROR_RESPONSE_OPTION {
02 OptionAbortRetryIgnore,
03 OptionOk,
04 OptionOkCancel,
05 OptionRetryCancel,
06 OptionYesNo,
07 OptionYesNoCancel,
08 OptionShutdownSystem,
09 OptionExplorerTrayBaloon,
10 OptionCancelTryAgainContinue
11 } HARDERROR_RESPONSE_OPTION, *PHARDERROR_RESPONSE_OPTION;
12
13 typedef enum _HARDERROR_RESPONSE {
14 ResponseReturnToCaller,
15 ResponseNotHandled,
16 ResponseAbort,
17 ResponseCancel,
18 ResponseIgnore,
19 ResponseNo,
20 ResponseOk,
21 ResponseRetry,
22 ResponseYes,
23 ResponseTryAgain,
24 ResponseContinue
25 } HARDERROR_RESPONSE, *PHARDERROR_RESPONSE;
26
27 NTSTATUS
28 NTAPI
29 ExRaiseHardError(
30 IN NTSTATUS ErrorStatus,
31 IN ULONG NumberOfParameters,
32 IN ULONG UnicodeStringParameterMask,
33 IN PVOID Parameters,
34 IN ULONG ResponseOption,
35 OUT PULONG Response );
36
37
38 ULONG
39 DisplayMessage (
40 PWSTR MessageString,
41 ULONG ResponseOption
42 )
43 {
44 NTSTATUS St;
45 UNICODE_STRING Message;
46 PVOID Parameters[] = {
47 &Message, //内容
48 0, //这是传说中的窗体标题...
49 0,
50 0
51 };
52 ULONG Response = 0;
53
54 RtlInitUnicodeString (&Message, MessageString);
55
56 St = ExRaiseHardError (
57 STATUS_FATAL_APP_EXIT,
58 1,
59 1,
60 &Parameters,
61 ResponseOption,
62 &Response
63 );
64
65 return Response;
66 }
67
68
69 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
70 {
71 ULONG r;
72 r = DisplayMessage (L"Do you want a girl?", OptionYesNo);
73 KdPrint(("The answer was %d \n", r));
74
75 return STATUS_UNSUCCESSFUL;
76 }


类别:默认分类||添加到搜藏 |分享到i贴吧|浏览(2064)|评论 (0)
 
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu