⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r32r0.cpp

📁 Windows2000 XP 从Ring3层进入Ring0层的一种方法
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                                                  SE_KERNEL_OBJECT,
                                                  DACL_SECURITY_INFORMATION,
                                                  NULL,
                                                  NULL,
                                                  &OldDACLs,
                                                  NULL,
                                                  &SecurityDescriptor
                                              );
    if ( ret != ERROR_SUCCESS )
    {
        PrintWin32Error( "GetSecurityInfo() failed", ret );
        boolean_ret = FALSE;
        goto SetPhysicalMemoryDACLs_return;
    }
    /*
     * DWORD SetEntriesInAcl
     * (
     *     ULONG             cCountOfExplicitEntries,
     *     PEXPLICIT_ACCESS  pListOfExplicitEntries,
     *     PACL              OldAcl,
     *     PACL             *NewAcl
     * );
     */
    ZeroMemory( &Access, sizeof( Access ) );
    Access.grfAccessPermissions             = SECTION_ALL_ACCESS;
    Access.grfAccessMode                    = GRANT_ACCESS;
    Access.grfInheritance                   = NO_INHERITANCE;
    Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    Access.Trustee.TrusteeForm              = TRUSTEE_IS_NAME;
    Access.Trustee.TrusteeType              = TRUSTEE_IS_USER;
    Access.Trustee.ptstrName                = ptstrName;
    ret                                     = SetEntriesInAcl( 1, &Access, OldDACLs, &NewDACLs );
    if ( ret != ERROR_SUCCESS )
    {
        PrintWin32Error( "SetEntriesInAcl() failed", ret );
        boolean_ret = FALSE;
        goto SetPhysicalMemoryDACLs_return;
    }
    /*
     * DWORD SetSecurityInfo
     * (
     *     HANDLE               handle,
     *     SE_OBJECT_TYPE       ObjectType,
     *     SECURITY_INFORMATION SecurityInfo,
     *     PSID                 psidOwner,
     *     PSID                 psidGroup,
     *     PACL                 pDacl,
     *     PACL                 pSacl
     * );
     */
    ret                                     = SetSecurityInfo
                                              (
                                                  handle,
                                                  SE_KERNEL_OBJECT,
                                                  DACL_SECURITY_INFORMATION,
                                                  NULL,
                                                  NULL,
                                                  NewDACLs,
                                                  NULL
                                              );
    if ( ret != ERROR_SUCCESS )
    {
        PrintWin32Error( "SetSecurityInfo() failed", ret );
        boolean_ret = FALSE;
        goto SetPhysicalMemoryDACLs_return;
    }

SetPhysicalMemoryDACLs_return:

    if ( NewDACLs != NULL )
    {
        LocalFree( NewDACLs );
        NewDACLs = NULL;
    }
    if ( SecurityDescriptor != NULL )
    {
        LocalFree( SecurityDescriptor );
        SecurityDescriptor = NULL;
    }
    return( boolean_ret );
}  /* end of SetPhysicalMemoryDACLs */

static VOID UnmapPhysicalMemory ( IN PVOID LinearAddress )
{
    NTSTATUS status;
    char     error_msg[256];

    /*
     * NTSTATUS ZwUnmapViewOfSection
     * (
     *     IN HANDLE ProcessHandle,
     *     IN PVOID  BaseAddress
     * );
     */
    status = ZwUnmapViewOfSection( ( HANDLE )-1, LinearAddress );
    if ( !NT_SUCCESS( status ) )
    {
        sprintf( error_msg, "Could not unmap LinearAddress from 0x%08X", ( unsigned int )LinearAddress );
        PrintZwError( error_msg, status );
    }
    return;
}  /* end of UnmapPhysicalMemory */

static void usage ( char *arg )
{
    fprintf( stderr, "Usage: %s [-h] [-g Gdtrbase] [-a Address] [-l Length]\n", arg );
    exit( EXIT_FAILURE );
}  /* end of usage */

int main ( int argc, char * argv[] )
{
    int                 i;
    GATEDESCRIPTOR     *callgate           = NULL;
    GATEDESCRIPTOR      orig_callgate;
    unsigned short int  selector           = RING0_CODE_SELECTOR;
    ULONG               Ring0CodeLength    = 0;
    CALL_ARG_0          call_arg_0;
    CALL_ARG_1          call_arg_1;
    CALL_ARG_2          call_arg_2;
    PSEUDODESCRIPTOR    GDTR;
    WORD                CURRENT_CS, CURRENT_DS, CURRENT_ES, CURRENT_SS, CURRENT_FS;
    HANDLE              mem                = NULL;
    PVOID               orig_GdtMapAddress = NULL;
    PVOID               GdtMapAddress      = NULL;
    ULONG               GdtMapSize         = 0;
    PHYSICAL_ADDRESS    orig_GdtPhysicalAddress;
    PHYSICAL_ADDRESS    GdtPhysicalAddress;
    ULONG               Address            = 0;
    ULONG               Length             = 0;
    unsigned char       buf[8192];

    ZeroMemory( &GDTR, sizeof( GDTR ) );
    /*
     * 从argv[1]开始循环处理命令行参数
     */
    for ( i = 1; i < argc; i++ )
    {
        /*
         * 同时支持-和/两种引入命令行参数的方式
         */
        if ( ( argv[i][0] == '-' ) || ( argv[i][0] == '/' ) )
        {
            /*
             * 在这个字节上,大小写不敏感
             */
            switch ( tolower( argv[i][1] ) )
            {
            case 'a':
                /*
                 * 欲访问的线性地址
                 */
                Address    = strtoul( argv[++i], NULL, 0 );
                break;
            case 'g':
                /*
                 * 有些环境中sgdt失灵,可通过-g指定GDTR的基址。但此时指定
                 * 的limit很冒险。
                 */
                GDTR.base  = ( unsigned int )strtoul( argv[++i], NULL, 0 );
                GDTR.limit = 0x03FF;
                break;
            case 'l':
                Length     = strtoul( argv[++i], NULL, 0 );
                break;
            case 'h':
            case '?':
            default:
                usage( argv[0] );
            }  /* end of switch */
        }
        else
        {
            usage( argv[0] );
        }
    }  /* end of for */
    if ( GDTR.base < 0x80000000 || GDTR.base >= 0xa0000000 )
    {
        /*
         * 获取GDTR寄存器的值。这个动作无法在VMware Workstation 3.2中完成,返
         * 回的线性基址不正确,必须在真实主机上测试。
         */
        __asm
        {
            sgdt    GDTR
            mov     CURRENT_CS,cs
            mov     CURRENT_DS,ds
            mov     CURRENT_ES,es
            mov     CURRENT_SS,ss
            mov     CURRENT_FS,fs
        }
        printf( "GDTR.base             = 0x%08X\n"
                "GDTR.limit            = 0x%04X\n"
                "CURRENT_CS            = 0x%04X\n"
                "CURRENT_DS            = 0x%04X\n"
                "CURRENT_ES            = 0x%04X\n"
                "CURRENT_SS            = 0x%04X\n"
                "CURRENT_FS            = 0x%04X\n",
                GDTR.base, GDTR.limit, CURRENT_CS, CURRENT_DS,
                CURRENT_ES, CURRENT_SS, CURRENT_FS );
        if ( GDTR.base < 0x80000000 || GDTR.base >= 0xa0000000 )
        {
            fprintf( stderr, "Checking your GDTR.base( 0x%08X )\n", GDTR.base );
            return( EXIT_FAILURE );
        }
    }
    /*
     * 如果没有指定线性地址,缺省处理GDT
     */
    if ( 0 == Address )
    {
        Address = GDTR.base;
    }
    if ( FALSE == LocateNtdllEntry() )
    {
        fprintf( stderr, "LocateNtdllEntry() failed\n" );
        return( EXIT_FAILURE );
    }
    if ( FALSE == LocateNtoskrnlEntry() )
    {
        fprintf( stderr, "LocateNtoskrnlEntry() failed\n" );
        return( EXIT_FAILURE );
    }
    ZeroMemory( &system_info, sizeof( system_info ) );
    GetSystemInfo( &system_info );
    printf( "PageSize              = 0x%08X\n"
            "AllocationGranularity = 0x%08X\n",
            system_info.dwPageSize, system_info.dwAllocationGranularity );
    /*
     * 如果没有指定长度,缺省按一页处理。
     */
    if ( 0 == Length )
    {
        Length = system_info.dwPageSize;
    }
    if ( Length > sizeof( buf ) )
    {
        Length = sizeof( buf );
    }
    /*
     * GDTR.limit对应的是最后有效偏移,不要先增一再强制类型转换,否则可能
     * 发生短整型溢出,这是编译器相关的。
     */
    GdtMapSize              = ( ULONG )GDTR.limit + 1;
    ZeroMemory( &orig_GdtPhysicalAddress, sizeof( orig_GdtPhysicalAddress ) );
    ZeroMemory( &GdtPhysicalAddress, sizeof( GdtPhysicalAddress ) );
    /*
     * 为映射GDT作准备
     */
    orig_GdtPhysicalAddress = PrivateMmGetPhysicalAddress( ( PVOID )GDTR.base );
    if ( orig_GdtPhysicalAddress.LowPart == 0 )
    {
        fprintf( stderr, "orig_GdtPhysicalAddress.LowPart == 0\n" );
        return( EXIT_FAILURE );
    }
    GdtPhysicalAddress      = orig_GdtPhysicalAddress;
    /*
     * 为读写DACLs而打开句柄
     */
    if ( ( mem = OpenPhysicalMemory( READ_CONTROL | WRITE_DAC ) ) == NULL )
    {
        return( EXIT_FAILURE );
    }
    else
    {
        SetPhysicalMemoryDACLs( mem, "CURRENT_USER" );
        ZwClose( mem );
        mem = NULL;
    }
    /*
     * 试图读写打开"\Device\PhysicalMemory"
     */
    if ( ( mem = OpenPhysicalMemory( SECTION_MAP_READ | SECTION_MAP_WRITE ) ) == NULL )
    {
        return( EXIT_FAILURE );
    }
    /*
     * 读/写映射GDT
     */
    if ( TRUE == MapPhysicalMemory( mem, &GdtMapAddress, &GdtMapSize, &GdtPhysicalAddress, PAGE_READWRITE ) )
    {
        orig_GdtMapAddress = ( unsigned char * )GdtMapAddress + ( orig_GdtPhysicalAddress.LowPart - GdtPhysicalAddress.LowPart );
        /*
         * 搜索空闲描述符并设置调用门
         */
        callgate = InstallCallgate( ( ULONG )orig_GdtMapAddress, 
                                    ( ULONG )GDTR.limit, 
                                    ( DWORD )Ring0Code, 
                                    &orig_callgate );
        if ( NULL != callgate )
        {
            /*
             * 指向GDT中调用门的选择子,RPL等于0。
             */
            selector                 = ( unsigned short int )( ( unsigned char * )callgate - ( unsigned char * )orig_GdtMapAddress );
            printf( "idle selector         = 0x%04X\n", selector );
            /*
             * 获取Ring 0权限,执行Ring 0代码
             */
            ZeroMemory( &call_arg_0, sizeof( call_arg_0 ) );
            Ring0CodeLength          = ( ULONG )( ( unsigned char * )SetPhysicalMemoryDACLs - ( unsigned char * )Ring0Code );
            ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 0, &call_arg_0 );
            printf( "CR0                   = 0x%08X\n"
                    "CR2                   = 0x%08X\n"
                    "CR3                   = 0x%08X\n"
                    "DR0                   = 0x%08X\n"
                    "DR1                   = 0x%08X\n"
                    "DR2                   = 0x%08X\n"
                    "DR3                   = 0x%08X\n"
                    "DR6                   = 0x%08X\n"
                    "DR7                   = 0x%08X\n",
                    call_arg_0.cr0, call_arg_0.cr2, call_arg_0.cr3, 
                    call_arg_0.dr0, call_arg_0.dr1, call_arg_0.dr2, 
                    call_arg_0.dr3, call_arg_0.dr6, call_arg_0.dr7 );
            ZeroMemory( &call_arg_1, sizeof( call_arg_1 ) );
            call_arg_1.LinearAddress = ( PVOID )( GDTR.base );
            ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 1, &call_arg_1 );
            printf( "GDTR.base(Physical)   = 0x%08X\n", call_arg_1.PhysicalAddress.LowPart );
            ZeroMemory( &call_arg_1, sizeof( call_arg_1 ) );
            call_arg_1.LinearAddress = ( PVOID )0xc0300000;
            ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 1, &call_arg_1 );
            /*
             * 注意与CR3的值作比较,如果没出错的话,CR3 == PDR
             */
            printf( "PDR(Physical)         = 0x%08X\n", call_arg_1.PhysicalAddress.LowPart );
            ZeroMemory( &call_arg_2, sizeof( call_arg_2 ) );
            /*
             * 如果Address导致异常,结果未知,别问我。
             */
            call_arg_2.src           = ( PVOID )Address;
            call_arg_2.dst           = ( PVOID )buf;
            call_arg_2.len           = Length;
            ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 2, &call_arg_2 );
            outputBinary( stdout, ( const unsigned char * )call_arg_2.dst, ( const size_t )call_arg_2.len );
            /*
             * 恢复被征用的"空闲"描述符
             */
            memcpy( callgate, &orig_callgate, sizeof( GATEDESCRIPTOR ) );
        }
        /*
         * 解除对GDT的映射
         */
        UnmapPhysicalMemory( GdtMapAddress );
    }
    if ( mem != NULL )
    {
        ZwClose( mem );
        mem = NULL;
    }
    return( EXIT_SUCCESS );
}  /* end of main */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -