物理内存和虚拟内存之间的影射问题

heshu   2007-9-22 16:43 楼主
在XP系统下想读出0x6c304464位置的的一个DWORD数据。自己写的程序放在A机台上正常读出,程序放在B机台上不能读出,程序Hold在读取0x6C306646转换得到的系统内存位置

   DWORD value = (PBYTE)*phyaddr;
              
试了很多种方法,我无法可解。
  但在DOS下能正常读出,在XP下用其他第三方软件也可以正常读出。

我做了如下尝试:
  (1):使用winio.sys中的方法来读取
     发现不能在B机台上得到系统地址。

  (2):修改winio.sys中对内存的读部分代码

   NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,ULONG PhysMemSizeInBytes,PVOID *PhysMemLin)
{       
        PHYSICAL_ADDRESS   pStartPhysAddress;
        OutputDebugString ("dhahelper: entering MapPhysicalMemoryToLinearSpace");
        pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress;       
          SystemVirtualAddress=MmMapIoSpace(pStartPhysAddress,PhysMemSizeInBytes, MmNonCached);        /*MmNonCached ;  MmWriteCombined; MmWriteCombined*/
          if(!SystemVirtualAddress)
        {       
                OutputDebugString("dhahelper: MmMapIoSpace failed");       
                return STATUS_INVALID_PARAMETER;       
          }        
          OutputDebugString("dhahelper: SystemVirtualAddress ");       
          Mdl=IoAllocateMdl(SystemVirtualAddress, PhysMemSizeInBytes, FALSE, FALSE,NULL);       
          if(!Mdl)
        {
                OutputDebugString("dhahelper: IoAllocateMdl failed");       
                return STATUS_INSUFFICIENT_RESOURCES;       
          }       
          OutputDebugString("dhahelper");       
          MmBuildMdlForNonPagedPool(Mdl);       
          UserVirtualAddress = (PVOID)(((ULONG)PAGE_ALIGN(MmMapLockedPages(Mdl,UserMode))) + MmGetMdlByteOffset(Mdl));       
          if(!UserVirtualAddress)
        {       
                OutputDebugString("dhahelper: MmMapLockedPages failed");       
                return STATUS_INSUFFICIENT_RESOURCES;       
          }       
          OutputDebugString("dhahelper: UserVirtualAddress ");       
       
        *PhysMemLin = UserVirtualAddress;
        //memset(*PhysMemLin, 0x11, 4);
        memsize = PhysMemSizeInBytes;
        OutputDebugString("dhahelper: leaving MapPhysicalMemoryToLinearSpace");       
        return STATUS_SUCCESS;
}

    发同得到了系统地址,但不能读取,使用XP-DDK编译

   (3):在VC中使用load ntdll.dll库
  #include "windows.h"
#include "accctrl.h"
#include "aclapi.h"
#include "mem2k.h"
#include "stdio.h"

RTLINITUNICODESTRING  RtlInitUnicodeString;
ZWOPENSECTION         ZwOpenSection;
HMODULE               g_hNtDLL = NULL;
PVOID                 g_pMapPhysicalMemory = NULL;
HANDLE                g_hMPM = NULL;


BOOL InitNTDLL()
{
        g_hNtDLL = LoadLibrary("ntdll.dll");
        if(!g_hNtDLL)
        {
                return FALSE;
        }
        RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress(g_hNtDLL,
                "RtlInitUnicodeString");
        ZwOpenSection = (ZWOPENSECTION)GetProcAddress(g_hNtDLL, "ZwOpenSection");
        return TRUE;                  
}

BOOL SetData(PVOID addr, ULONG data)
{
        ULONG phys = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, (PVOID)addr);
        PULONG tmp = (PULONG)MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys & 0xFFFFF000, 0x1000);
        if(tmp == 0)
        {
                return FALSE;
        }
        tmp[(phys & 0xFFF) >> 2] = data;
        UnmapViewOfFile(tmp);
        return TRUE;
}

VOID CloseNTDLL()
{
        if(g_hNtDLL != NULL)
        {
                FreeLibrary(g_hNtDLL);
        }
}

VOID SetPhyscialmemorySectionCanBeWrited(HANDLE hSection)
{
        PACL pDacl = NULL;
        PACL pNewDacl = NULL;
        PSECURITY_DESCRIPTOR pSD = NULL;
       
        EXPLICIT_ACCESS ea;

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

        ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
        ea.grfAccessPermissions = SECTION_MAP_WRITE;
        ea.grfAccessMode = GRANT_ACCESS;
        ea.grfInheritance = NO_INHERITANCE;
        ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
        ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
        ea.Trustee.ptstrName = "CURRENT_USER";

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

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

CleanUp:
        if(pSD)
        {
                LocalFree(pSD);
        }
        if(pNewDacl)
        {
                LocalFree(pNewDacl);
        }
}

VOID showMesg(char *mesg)
{
        MessageBox(NULL, mesg, "mem2k", MB_OK);
}


HANDLE 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               = 0;
        attributes.SecurityDescriptor       = NULL;
        attributes.SecurityQualityOfService = NULL;

        status = ZwOpenSection(&g_hMPM, SECTION_MAP_READ, &attributes);

        if(status == STATUS_ACCESS_DENIED)
        {
                status = ZwOpenSection(&g_hMPM, READ_CONTROL|WRITE_DAC, &attributes);
                SetPhyscialmemorySectionCanBeWrited(g_hMPM);
                CloseHandle(g_hMPM);
                status = ZwOpenSection(&g_hMPM, SECTION_MAP_READ, &attributes);
        }

        if(!NT_SUCCESS(status))
        {
                return NULL;
        }

        g_pMapPhysicalMemory = MapViewOfFile(g_hMPM, 4, 0, 0x39000, 0x1000);
        if(g_pMapPhysicalMemory == NULL)
        {
                return NULL;
        }
        return g_hMPM;
}

PVOID  LinearToPhys(PULONG BaseAddress, PVOID addr)
{
        ULONG VAddr = (ULONG) addr;
        ULONG PGDE;
        ULONG PTE;
        ULONG PAddr;
        PGDE = BaseAddress[VAddr >> 22];
        if((PGDE & 1) != 0)
        {
                ULONG tmp = PGDE & 0x00000080;
                if(tmp != 0)
                {
                        PAddr = (PGDE & 0xFFC00000) + (VAddr & 0x003FFFFF);
                }
                else
                {
                        PGDE = (ULONG)MapViewOfFile(g_hMPM, 4, 0, PGDE & 0xFFFFF000, 0x1000);
                        PTE = ((PULONG)PGDE)[(VAddr & 0x003FF000) >> 12];
                        if((PTE & 1) != 0)
                        {
                                PAddr = (PTE & 0xFFFFF000) + (VAddr & 0x00000FFF);
                                UnmapViewOfFile((PVOID)PGDE);
                        }
                        else
                        {
                                return 0;
                        }
                }
        }
        else
        {
                return 0;
        }
        return (PVOID)PAddr;
}

ULONG  GetData(PVOID addr)
{
        ULONG phys = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, (PVOID)addr);
        PULONG tmp = (PULONG)MapViewOfFile(g_hMPM, 4, 0, phys & 0xFFFFF000, 0x1000);
        ULONG ret;
        if(tmp == 0)
        {
                return 0;
        }
        ret = tmp[(phys & 0xFFF) >> 2];
        UnmapViewOfFile(tmp);
        return ret;
}

int main()
{
        ULONG value = 0;
        if(InitNTDLL())
        {
                if(OpenPhysicalMemory() == 0)
                {
                        return 1;
                }

                value = GetData((PVOID)0x6C304464);
                printf("Value: %0x\n", value);
                UnmapViewOfFile(g_pMapPhysicalMemory);
                CloseHandle(g_hMPM);
                CloseNTDLL();               
        }
        return 0;
}

  同样无法记取。
  
请大侠指点
谢谢

回复评论 (3)

自己搞定了。
CSD真是个好地方。
每次搞不定的事,上来一发帖,问题就能自行解决。
嘿。。。。
点赞  2007-9-24 08:50
楼主的水平还真高啊,我还有些看不懂.
点赞  2007-9-25 12:52
RootKit那本书上面有
就是打破内存边界,读别人的内存
点赞  2007-9-26 10:24
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复