首页
社区
课程
招聘
[求助]小弟不才 问一个50错误问题
发表于: 2011-10-3 16:29 2767

[求助]小弟不才 问一个50错误问题

2011-10-3 16:29
2767
一直蓝屏 提示访问违规地址

#include <ntddk.h>
#include <wdm.h>

char g_oricode[7]={0};
ULONG g_uCr0;
char *non_paged_memory;

unsigned long reentry_address;
unsigned long g_fakeZwCallAddr;

void WPOFF()
{

        ULONG uAttr;

        _asm
        {
                        push eax
                        mov eax, cr0
                        mov uAttr, eax
                        and eax, 0FFFEFFFFh // CR0 16 BIT = 0
                        mov cr0, eax
                        pop eax
                        cli
        };

        g_uCr0 = uAttr;

}

VOID WPON()
{

        _asm
        {
                        sti
                        push eax
                        mov eax, g_uCr0
                        mov cr0, eax
                        pop eax
        };

}
typedef NTSTATUS ( *pNtQueryValueKey)(
        IN HANDLE  KeyHandle,
        IN PUNICODE_STRING  ValueName,
        IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
        OUT PVOID  KeyValueInformation,
        IN ULONG  Length,
        OUT PULONG  ResultLength
        );

NTSTATUS retAddress;

UNICODE_STRING Path;
TCHAR fakeUrl[]="http://www.baidu.com/";
PKEY_VALUE_PARTIAL_INFORMATION valueInfoP;
NTSTATUS ntStatus;

//#pragma alloc_text(PAGE, My_function_detour_NtQueryValueKey)

__declspec(naked)
        NTSTATUS NTAPI My_function_detour_NtQueryValueKey(
        IN HANDLE  KeyHandle,
        IN PUNICODE_STRING  ValueName,
        IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
        OUT PVOID  KeyValueInformation,
        IN ULONG  Lengthx,
        OUT PULONG  ResultLength
        )
{       

        __asm
        {
                /*
                push [ebp+1Ch]//ResultLength
                push [ebp+18h]//Length               
                push [ebp+14h]//KeyValueInformation       
                push [ebp+10h]                                                                       
                push [ebp+0Ch]//ValueName        
                push [ebp+8]
                */

                        add esp,1Ch
                        mov esp,ebp
                        pop ebp

                        push ebp
                        mov ebp,esp
                        pushad
                        pushfd

                        push ResultLength
                        push Lengthx
                        push KeyValueInformation
                        push KeyValueInformationClass
                        push ValueName
                        push KeyHandle

        }

        __asm{
                jmp forwArd
bAck:

                __asm{
                                push    68h
                                push    804eb510h ;//修复扣过来的地址
                                _emit 0xEA ;//构造长jmp far xxxx:xxxxxxxx
                                _emit 0xAA
                                _emit 0xAA
                                _emit 0xAA
                                _emit 0xAA
                                _emit 0x08
                                _emit 0x00
                }

forwArd:
                call bAck

                        mov retAddress,eax
        }

        /*
        __asm{
        call oldAddr
        mov ntStatus,eax
        test eax,eax
        jz quit
        }
        */

        valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueInformation;
        RtlInitUnicodeString(&Path,L"Start Page");

        if(RtlCompareUnicodeString(&Path,ValueName,FALSE)==0)
        {

                RtlZeroMemory(valueInfoP->Data,valueInfoP->DataLength);
                valueInfoP->DataLength=sizeof(fakeUrl)+sizeof(UCHAR)*256;
                memcpy(valueInfoP->Data,fakeUrl,sizeof(fakeUrl));

                __asm
                {
                                popfd
                                popad
                                mov esp,ebp
                                pop ebp
                                mov eax,retAddress
                                ret 0x18
                }
        }

quit:        __asm
                {
                                popfd
                                popad
                                mov esp,ebp
                                pop ebp
                                mov eax,retAddress
                                ret 0x18
                }
}

/*
typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
ULONG   TitleIndex;
ULONG   Type;
ULONG   DataLength;
UCHAR   Data[1];            // Variable size
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
*/

VOID DetourFunctionNtQueryValueKey()
{
        unsigned long detour_address;
        KIRQL oldIrql;
        int i;
        char *actual_function;
        char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00};

        ULONG actual_code=0x80574037;//nt地址硬编码

        actual_function=(char*)actual_code;

        KdPrint(("DetourFunctionNtQueryValueKey()"));

        reentry_address = ((unsigned long)actual_code+7);
        KdPrint(("0x%.8X",reentry_address));
        non_paged_memory = (char *)ExAllocatePool(NonPagedPool, 512);

        for(i=0;i<512;i++)
        {
                ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)My_function_detour_NtQueryValueKey)[i];
        }

        detour_address = (unsigned long)non_paged_memory;

        *( (unsigned long *)(&newcode[1]) ) = detour_address;

        for(i=0;i<512;i++)
        {
                if( (0xAA == ((unsigned char *)non_paged_memory)[i]) &&
                        (0xAA == ((unsigned char *)non_paged_memory)[i+1]) &&
                        (0xAA == ((unsigned char *)non_paged_memory)[i+2]) &&
                        (0xAA == ((unsigned char *)non_paged_memory)[i+3]))
                {
                        *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address;
                        KdPrint(("0x%.8X",reentry_address));
                        break;
                }
        }

        WPOFF();
        oldIrql = KeRaiseIrqlToDpcLevel();
        for(i=0;i < 7;i++)
        {
                g_oricode[i] = actual_function[i];
                actual_function[i] = newcode[i];
        }
        KeLowerIrql(oldIrql);
        WPON();

}

VOID UnDetourFunction()
{
        char *actual_function;
        ULONG actual_code=0x80574037;//nt地址硬编码
        actual_function=(char*)actual_code;
        KIRQL oldIrql;
        int i;

        WPOFF();
        oldIrql = KeRaiseIrqlToDpcLevel();

        for(i=0;i < 7;i++)
        {
                actual_function[i] = g_oricode[i];
        }
        KeLowerIrql(oldIrql);
        WPON();
        ExFreePool(non_paged_memory);
}

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
        KdPrint(("My Driver Unloaded!"));
        UnDetourFunction();
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
        KdPrint(("My Driver Loaded!"));
        theDriverObject->DriverUnload = OnUnload;

        DetourFunctionNtQueryValueKey();

        return STATUS_SUCCESS;
}

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//