fire2fire
驱动牛犊
驱动牛犊
  • 注册日期2004-03-04
  • 最后登录2013-04-07
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:1954回复:4

关于线形地址到物理地址转化(Ring3)

楼主#
更多 发布于:2005-05-22 13:39
ULONG MemoryMgr::GetDirectoryTableBase ( )
{
    HANDLE hProcess = OpenProcess ( PROCESS_ALL_ACCESS, 0, GetCurrentProcessId ( ) );
    if ( hProcess == NULL )
        return 0;

    PULONG pBuffer = ( PULONG )GetHandleList ( );
if ( pBuffer == NULL )
        return 0;

    PSYSTEM_HANDLE_INFORMATION objProcAddr = ( PSYSTEM_HANDLE_INFORMATION )
        GetObjectHandle ( pBuffer, hProcess, GetCurrentProcessId ( ) );

    ULONG dwEProcessAddr = ( ULONG ) objProcAddr->Object;

    if ( pBuffer != NULL )
        delete pBuffer;
    ///////////////////////////////////////////////////////////////////////////
    MEMORYSTATUS MemoryStatus;
    MemoryStatus.dwTotalPhys = 0;

    ::GlobalMemoryStatus ( &MemoryStatus );

    ULONG dwUpperAddress = MemoryStatus.dwTotalPhys;
    if ( dwUpperAddress == NULL )
        dwUpperAddress = 256*1024*1024;
    ///////////////////////////////////////////////////////////////////////////
    m_ulDirectoryTableBase = 0;
    ///////////////////////////////////////////////////////////////////////////
    for ( ULONG dwIter = 0x10000; dwIter < dwUpperAddress; dwIter += 0x1000 )
    {
        ULONG   dwAddr      = dwIter;
        ULONG   dwWantAddr  = dwAddr;
        ULONG   dwMapOffset = 0;
        ULONG   uLen        = 0x1000;
        PBYTE   pbPtr       = NULL;
        ULONG   dwData      = 0;

        // map in page
        if ( !PhysicalMemoryMapNT ( &dwAddr, &uLen, ( LPVOID * )&pbPtr ) )
            continue;

        dwMapOffset = dwWantAddr - dwAddr;

        dwData = * ( ( PULONG ) &pbPtr [ dwMapOffset+0xC00 ] );
  
        PhysicalMemoryUnMapNT ( ( ULONG )pbPtr );

        if ( ( dwData & 0xFFFFFE00 ) == dwIter )
        {
            dwAddr      = _LinearToPhysicalNT ( dwIter, dwEProcessAddr );
            dwWantAddr  = dwAddr;
            uLen        = 0x1000;
            
            if ( !PhysicalMemoryMapNT ( &dwAddr, &uLen, ( LPVOID * )&pbPtr ) )
                continue;

            dwMapOffset = dwWantAddr - dwAddr;

            //dwData = ( ( PEPROCESS )&pbPtr [ dwMapOffset ] )->Pcb.DirectoryTableBase [ 0 ];
            dwData = * ( ( ULONG * ) &pbPtr [ dwMapOffset + 0x18 ] );

            PhysicalMemoryUnMapNT ( ( ULONG )pbPtr );
            
            dwAddr = _LinearToPhysicalNT ( dwData, dwEProcessAddr );
            dwWantAddr = _LinearToPhysicalNT ( dwIter, dwEProcessAddr );

            if ( dwAddr == dwWantAddr )
            {
                m_ulDirectoryTableBase = dwData;
                m_ulDirectoryTableBaseSystem = dwIter;
                break;
            }
        }
    }
    ///////////////////////////////////////////////////////////////////////////
    ::CloseHandle ( hProcess );
    ///////////////////////////////////////////////////////////////////////////
    return m_ulDirectoryTableBase;
}

ULONG MemoryMgr::_LinearToPhysicalNT ( ULONG dwCr3, ULONG dwVAddr )
{
    ULONG   dwAddr      = dwCr3 & 0xFFFFF000;
    ULONG   dwWantAddr  = dwAddr;
    ULONG   dwMapOffset = 0;
    ULONG   uLen        = 0x1000;
    PBYTE   pbPtr       = NULL;
    ULONG   dwData      = 0;

    // map in page
    if ( !PhysicalMemoryMapNT ( &dwAddr, &uLen, ( LPVOID * )&pbPtr ) )
        return 0;

    dwMapOffset = dwWantAddr - dwAddr;

    dwData = * ( ( PULONG ) &pbPtr [ dwMapOffset + ( ( dwVAddr >> 22 ) << 2 ) ] );
  
    PhysicalMemoryUnMapNT ( ( ULONG ) pbPtr );

    //判断页目录是否有效,第0位 ( P )为存在位
    if ( ! ( dwData & 0x00000001 ) )
        return 0;

    if ( ( dwData & 0x80 ) )
        return ( dwData & 0xFFC00000 ) | ( dwVAddr & 0x3FFFFF );

    dwAddr      = dwData & 0xFFFFF000;
    dwWantAddr  = dwAddr;
    uLen        = 0x1000;

    if ( !PhysicalMemoryMapNT ( &dwAddr, &uLen, ( LPVOID * ) &pbPtr ) )
        return 0;

    dwMapOffset = dwWantAddr - dwAddr;

    dwData = * ( ( PULONG ) &pbPtr [ dwMapOffset + ( ( ( dwVAddr & 0x3FF000 ) >> 12 ) << 2 ) ] );
 
    PhysicalMemoryUnMapNT ( ( ULONG ) pbPtr );

    //判断页目录是否有效,第0位 ( P )为存在位
    if ( dwData & 0x00000001 )
        return ( ( dwData & 0xFFFFF000 ) | ( dwVAddr & 0x00000FFF ) );

    return 0;
}

最新喜欢:

zzzxxxcccc8zzzxxx...
fire2fire
驱动牛犊
驱动牛犊
  • 注册日期2004-03-04
  • 最后登录2013-04-07
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-05-22 13:44
// NT
ULONG MemoryMgr::PhysicalMemoryMapNT ( ULONG *pdwPhysicalAddr, ULONG *pdwLength, LPVOID *lpVirtualAddr )
{
    NTSTATUS        Status;         //NTDLL函数返回的状态
    LARGE_INTEGER   ViewBase;       //物理内存地址

    m_lpVAddress = 0;
    ViewBase.QuadPart = ( ULONGLONG ) ( *pdwPhysicalAddr );

    //映射物理内存地址到当前进程的虚地址空间
    Status = ZwMapViewOfSection (
                m_hPhysicalMemory,
                ( HANDLE ) -1,
                ( LPVOID * ) & m_lpVAddress,
                0,
                *pdwLength,
                &ViewBase,
                pdwLength,
                ViewShare,
                0,
                PAGE_READWRITE
                );

    if ( !NT_SUCCESS ( Status ) )
        return FALSE;

    *lpVirtualAddr = m_lpVAddress;
    *pdwPhysicalAddr = ViewBase.LowPart;

    return TRUE;
}
fire2fire
驱动牛犊
驱动牛犊
  • 注册日期2004-03-04
  • 最后登录2013-04-07
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-05-22 13:46
ULONG MemoryMgr::SetPhyscialMemorySectionCanBeWrited ( HANDLE hSection )
{
    PACL                    pDacl = NULL;
    PACL                    pNewDacl = NULL;
    PSECURITY_DESCRIPTOR    pSD=NULL;
    EXPLICIT_ACCESS         ea;
    ULONG                   dwRes;
    ULONG                    bRet = TRUE;
    TCHAR                   szUserName[] = _T ( \"CURRENT_USER\" );
    ULONG                   dwUserNameSize = MAX_PATH - 1;

    if ( dwRes = GetSecurityInfo ( hSection,
                                SE_KERNEL_OBJECT,
                                DACL_SECURITY_INFORMATION,
                                NULL,
                                NULL,
                                &pDacl,
                                NULL,
                                &pSD ) != ERROR_SUCCESS )
    {
        bRet = FALSE;
        goto CleanUp;
    }

    //GetUserName ( szUserName, &dwUserNameSize );

    ZeroMemory ( &ea, sizeof ( EXPLICIT_ACCESS ) );
    ea.grfAccessPermissions             = SECTION_MAP_WRITE;
    ea.grfAccessMode                    = GRANT_ACCESS;
    ea.grfInheritance                   = NO_INHERITANCE;
    ea.Trustee.pMultipleTrustee         = NULL;
    ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    ea.Trustee.TrusteeForm              = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType              = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName                = szUserName;

    if ( dwRes = SetEntriesInAcl ( 1, &ea, pDacl, &pNewDacl )!=ERROR_SUCCESS )
    {
        bRet = FALSE;
        goto CleanUp;
    }

    if ( dwRes = SetSecurityInfo ( hSection,
                                SE_KERNEL_OBJECT,
                                DACL_SECURITY_INFORMATION,
                                NULL,
                                NULL,
                                pNewDacl,
                                NULL ) != ERROR_SUCCESS )
    {
        bRet = FALSE;
        goto CleanUp;
    }

CleanUp:

    if ( pSD )
        LocalFree ( pSD );
    if ( pNewDacl )
        LocalFree ( pNewDacl );

    return bRet;
}

ULONG MemoryMgr::OpenPhysicalMemory ( )
{
    NTSTATUS            Status;
    UNICODE_STRING      PhysMemString;
    OBJECT_ATTRIBUTES   Attributes;

    RtlInitUnicodeString ( &PhysMemString, L\"\\\\Device\\\\PhysicalMemory\" );

    Attributes.Length                   = sizeof ( OBJECT_ATTRIBUTES );
    Attributes.RootDirectory            = NULL;
    Attributes.ObjectName               = &PhysMemString;
    Attributes.Attributes               = OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
    Attributes.SecurityDescriptor       = NULL;
    Attributes.SecurityQualityOfService = NULL;

    Status = ZwOpenSection ( &m_hPhysicalMemory, SECTION_MAP_READ | SECTION_MAP_WRITE, &Attributes );

    // STATUS_ACCESS_DENIED = 0x22
    if ( Status == STATUS_ACCESS_DENIED )
    {
        Status = ZwOpenSection ( &m_hPhysicalMemory, READ_CONTROL | WRITE_DAC, &Attributes );
        SetPhyscialMemorySectionCanBeWrited ( m_hPhysicalMemory );
        ::CloseHandle ( m_hPhysicalMemory );
        Status = ZwOpenSection ( &m_hPhysicalMemory, SECTION_MAP_READ | SECTION_MAP_WRITE, &Attributes );
    }

    if ( !NT_SUCCESS ( Status ) )
    {
        return FALSE;
    }

    return TRUE;
}
fire2fire
驱动牛犊
驱动牛犊
  • 注册日期2004-03-04
  • 最后登录2013-04-07
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-05-22 13:49
ULONG MemoryMgr::SetPhyscialMemorySectionCanBeWrited ( HANDLE hSection )
{
    PACL                    pDacl = NULL;
    PACL                    pNewDacl = NULL;
    PSECURITY_DESCRIPTOR    pSD=NULL;
    EXPLICIT_ACCESS         ea;
    ULONG                   dwRes;
    ULONG                    bRet = TRUE;
    TCHAR                   szUserName[] = _T ( \"CURRENT_USER\" );

    if ( dwRes = GetSecurityInfo ( hSection,
                                SE_KERNEL_OBJECT,
                                DACL_SECURITY_INFORMATION,
                                NULL,
                                NULL,
                                &pDacl,
                                NULL,
                                &pSD ) != ERROR_SUCCESS )
    {
        bRet = FALSE;
        goto CleanUp;
    }

    ZeroMemory ( &ea, sizeof ( EXPLICIT_ACCESS ) );
    ea.grfAccessPermissions             = SECTION_MAP_WRITE;
    ea.grfAccessMode                    = GRANT_ACCESS;
    ea.grfInheritance                   = NO_INHERITANCE;
    ea.Trustee.pMultipleTrustee         = NULL;
    ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    ea.Trustee.TrusteeForm              = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType              = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName                = szUserName;

    if ( dwRes = SetEntriesInAcl ( 1, &ea, pDacl, &pNewDacl )!=ERROR_SUCCESS )
    {
        bRet = FALSE;
        goto CleanUp;
    }

    if ( dwRes = SetSecurityInfo ( hSection,
                                SE_KERNEL_OBJECT,
                                DACL_SECURITY_INFORMATION,
                                NULL,
                                NULL,
                                pNewDacl,
                                NULL ) != ERROR_SUCCESS )
    {
        bRet = FALSE;
        goto CleanUp;
    }

CleanUp:

    if ( pSD )
        LocalFree ( pSD );
    if ( pNewDacl )
        LocalFree ( pNewDacl );

    return bRet;
}
zzzxxxcccc8
驱动牛犊
驱动牛犊
  • 注册日期2011-05-18
  • 最后登录2016-06-18
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2013-05-07 10:14
这个留下来学习学习
游客

返回顶部