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

📄 phys.c

📁 Windows 95 系統程式設計大奧秘书籍源码
💻 C
字号:
//==================================
// PHYS - Matt Pietrek 1995
// FILE: PHYS.C
//==================================

#include <windows.h>
#include <stdio.h>
#include <conio.h>

DWORD GetPhysicalAddrFromLinear(DWORD linear);  // Prototype helper funcs
WORD __stdcall GetRing0Callgate( DWORD addr, unsigned cParams );
BOOL __stdcall FreeRing0Callgate( WORD callgate );
DWORD _GetPhysicalAddrFromLinear(DWORD linear);     // ASM version
DWORD _GetPageAttributes(DWORD linear);     // ASM version

HMODULE WINAPI LoadLibrary16( LPCSTR lpLibFileName );
BOOL WINAPI FreeLibrary16( HINSTANCE hLibModule );

void ShowPhysicalPages(void);
void CreateSharedMemoryRegion(void);
void DeleteSharedMemoryRegion(void);
void ModifyCodePage(void);
DWORD Get_KRNL386_DGROUP_LinearAddress(void);
PSTR GetPageAttributesAsString(DWORD linear);

BOOL FirstInstance = TRUE;
WORD callgate1 = 0;
WORD callgate2 = 0;
PBYTE PMemMapFileRegion;

#pragma data_seg("SHAREDAT")        // Declare a variable in a shared
int MySharedSectionVariable = 0;    // Section.  The variable must be
#pragma data_seg()                  // initialized for the linker to put it
                                    // in the specified section

int main()
{
    CreateSharedMemoryRegion();

    if ( FirstInstance )
        printf("***** FIRST INSTANCE *****\n");
    else
        printf("***** SECONDARY INSTANCE *****\n");

    ShowPhysicalPages();

    printf("Press any key...\n");
    getch();

    if ( FirstInstance )
    {
        printf("\nNow modifying the code page\n");
        ModifyCodePage();
        ShowPhysicalPages();
    }
    
    FreeRing0Callgate( callgate1 );
    FreeRing0Callgate( callgate2 );

    DeleteSharedMemoryRegion();

    return 0;
}

void ShowPhysicalPages(void)
{
    DWORD linearAddr;
    MEMORY_BASIC_INFORMATION mbi;

    //
    // Get the address of a 16 bit DLL that's below 1MB (KRNL386's DGROUP)
    //
    linearAddr = Get_KRNL386_DGROUP_LinearAddress();
    printf( "KRNL386 DGROUP      - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Get the starting address of the code area.  We'll pass VirtualQuery
    // the address of a routine within the code area.
    //
    VirtualQuery( ShowPhysicalPages, &mbi, sizeof(mbi) );
    linearAddr = (DWORD)mbi.BaseAddress;
    printf( "First code page     - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Get the starting address of the data area.  We'll pass VirtualQuery
    // the address of a global variable within the data area.
    //
    VirtualQuery( &callgate1, &mbi, sizeof(mbi) );
    linearAddr = (DWORD)mbi.BaseAddress;
    printf( "First data page     - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Get the address of a data section with the SHARED attribute
    //
    MySharedSectionVariable = 1;    // Touch it to force it present
    linearAddr = (DWORD)&MySharedSectionVariable;
    printf( "Shared section      - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Get the address of a resource within the module
    //
    linearAddr = (DWORD)
            FindResource(GetModuleHandle(0), MAKEINTATOM(1), RT_STRING);
    printf( "Resources           - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );
    
    //
    // Get the starting address of the process heap area.
    //
    linearAddr = (DWORD)GetProcessHeap();
    printf( "Process Heap        - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Get the starting address of the process environment area.
    //
    VirtualQuery( GetEnvironmentStrings(), &mbi, sizeof(mbi) );
    linearAddr = (DWORD)mbi.BaseAddress;
    printf( "Environment area    - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Get the starting address of the stack area.  We'll pass
    // the address of a stack variable to VirtualQuery
    //
    VirtualQuery( &linearAddr, &mbi, sizeof(mbi) );
    linearAddr = (DWORD)mbi.BaseAddress;
    printf( "Current Stack page  - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Show the address of a memory mapped file
    //
    linearAddr = (DWORD)PMemMapFileRegion;
    printf( "Memory Mapped file  - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );

    //
    // Show the address of a routine in KERNEL32.DLL
    //
    linearAddr = (DWORD)
        GetProcAddress( GetModuleHandle("KERNEL32.DLL"), "VirtualQuery" );
    printf( "KERNEL32.DLL        - Linear:%08X  Physical:%08X  %s\n",
            linearAddr,
            GetPhysicalAddrFromLinear(linearAddr),
            GetPageAttributesAsString(linearAddr) );
}

HANDLE HFileMapping;

void CreateSharedMemoryRegion(void)
{
    BYTE myByte;
    
    HFileMapping = CreateFileMapping( (HANDLE)0xFFFFFFFF,   // File handle
                                    0,                      // security
                                    PAGE_READWRITE,         // protection
                                    0, 0x1000,              // size
                                    "MyFileMapping" );

    // In the above call, we can pass PAGE_WRITECOPY instead of
    // PAGE_READWRITE, but then the subsequent MapViewOfFile will fail

    if ( !HFileMapping )
    {
        printf("Couldn't create file mapping!\n");
        return;
    }

    if ( GetLastError() == ERROR_ALREADY_EXISTS )
        FirstInstance = FALSE;

    PMemMapFileRegion = MapViewOfFile( HFileMapping,            // hMapObject
                                        FILE_MAP_ALL_ACCESS,    // access
                                        0, 0,                   // offset
                                        0 );                    // size
    if ( !PMemMapFileRegion )
    {
        printf("Couldn't map view of file!\n");
        return;
    }
    
    myByte = *PMemMapFileRegion;    // Touch the memory to force it present
}

void DeleteSharedMemoryRegion(void)
{
    if ( PMemMapFileRegion )
        UnmapViewOfFile( PMemMapFileRegion );
    
    if ( HFileMapping )
        CloseHandle( HFileMapping );
}

void Dummy(void)    // Exists solely for us to bash
{
}

void ModifyCodePage(void)
{
    BYTE srcByte = 0xCC;
    DWORD cbWritten;
    
    if ( !WriteProcessMemory(GetCurrentProcess(), Dummy, &srcByte,
                                1, &cbWritten) || (cbWritten != 1) )
        printf("Couldn't write to code page!\n");
}

DWORD Get_KRNL386_DGROUP_LinearAddress(void)
{
    HMODULE hModKRNL386;
    LDT_ENTRY selectorEntry;
    
    hModKRNL386 = LoadLibrary16("KRNL386.EXE");
    if ( hModKRNL386 < (HMODULE)0x20 )
    {
        printf("Couldn't get selector of KRNL386 DGROUP");
        return 0;
    }

    if ( !GetThreadSelectorEntry( GetCurrentThread(), (DWORD)hModKRNL386, 
                                    &selectorEntry ) )
    {
        printf("GetThreadSelectorEntry failed!");
        return 0;
    }

    FreeLibrary16( hModKRNL386 );

    return  (selectorEntry.HighWord.Bytes.BaseHi << 24)
            + (selectorEntry.HighWord.Bytes.BaseMid << 16)
            + selectorEntry.BaseLow;
}

DWORD GetPhysicalAddrFromLinear(DWORD linear)
{
    if ( !callgate1 )
        callgate1 = GetRing0Callgate( (DWORD)_GetPhysicalAddrFromLinear, 1 );
    
    if ( callgate1 )
    {
        WORD myFwordPtr[3];
        
        myFwordPtr[2] = callgate1;
        __asm   push    [linear]
        __asm   cli
        __asm   call    fword ptr [myFwordPtr]
        __asm   sti

        // The return value is in EAX.  The compiler will complain, but...
    }
    else
        return 0xFFFFFFFF;
}

DWORD GetPageAttributes(DWORD linear)
{
    if ( !callgate2 )
        callgate2 = GetRing0Callgate( (DWORD)_GetPageAttributes, 1 );
    
    if ( callgate2 )
    {
        WORD myFwordPtr[3];
        
        myFwordPtr[2] = callgate2;
        __asm   push    [linear]
        __asm   cli
        __asm   call    fword ptr [myFwordPtr]
        __asm   sti

        // The return value is in EAX.  The compiler will complain, but...
    }
    else
        return 0xFFFFFFFF;
}

PSTR GetPageAttributesAsString(DWORD linear)
{
    DWORD attr;
    static char szRetBuffer[128];
    
    attr = GetPageAttributes(linear);
    if ( (attr & 1) == 0  )
        return "not present";
    
    strcpy( szRetBuffer, attr & 2 ? "Read/Write" : "ReadOnly" );
    strcat( szRetBuffer, " " );
    strcat( szRetBuffer, attr & 4 ? "USER" : "SPRVSR" );
    
    return szRetBuffer;
}

⌨️ 快捷键说明

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