• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            每天早晨叫醒你的不是鬧鐘,而是夢(mèng)想

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              62 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(1)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            我們知道,在NT/2K/XP中,操作系統(tǒng)利用虛擬內(nèi)存管理技術(shù)來(lái)維護(hù)地址空間映像,每個(gè)進(jìn)程分配一個(gè)4GB的虛擬地址空間。運(yùn)行在用戶態(tài)的應(yīng)用程序,不能直接訪問(wèn)物理內(nèi)存地址;而運(yùn)行在核心態(tài)的驅(qū)動(dòng)程序,能將虛擬地址空間映射為物理地址空間,從而訪問(wèn)物理內(nèi)存地址。

            如果要在應(yīng)用程序中以物理地址方式訪問(wèn)內(nèi)存,自然而然的辦法,是編寫一個(gè)專用的驅(qū)動(dòng)程序(如大家熟悉的WinIO),里面設(shè)置一定的IOCTL碼,應(yīng)用程序通過(guò)調(diào)用DeviceIoCtrol()來(lái)實(shí)現(xiàn)這樣的功能。

            那么,有沒(méi)有一種方法,省去編寫專用驅(qū)動(dòng)程序這一步,很方便地就能訪問(wèn)物理內(nèi)存呢?答案是肯定的。實(shí)際上,微軟早就給我們準(zhǔn)備好了一套辦法,只是他們秘而不宣罷了。系統(tǒng)內(nèi)建一個(gè)叫做PhysicalMemory的內(nèi)核對(duì)象,可以通過(guò)系統(tǒng)核心文件NTDLL.DLL中的有關(guān)API進(jìn)行操縱,從而實(shí)現(xiàn)物理內(nèi)存的直接訪問(wèn)。微軟聲稱這些API是用于驅(qū)動(dòng)程序開(kāi)發(fā)的,在VC/.NET中未提供原型說(shuō)明和庫(kù)文件,然而事實(shí)證明在應(yīng)用程序中調(diào)用它們是沒(méi)有問(wèn)題的。我們感興趣的API主要包括:

            ZwOpenSection 或 NtOpenSection - 打開(kāi)內(nèi)核對(duì)象
            ZwMapViewOfSection 或 NtMapViewOfSection - 映射虛擬地址空間
            ZwUnmapViewOfSection 或 NtUnmapViewOfSection - 取消地址空間映射
            RtlInitUnicodeString - 用UNICODE串初始化UNICODE描述的結(jié)構(gòu)
            以下的代碼描述了如何利用NTDLL.DLL中的上述幾個(gè)API,實(shí)現(xiàn)對(duì)物理內(nèi)存的讀取。需要指出的是,只有system擁有讀寫權(quán)限,administrator只有讀權(quán)限,而user連讀權(quán)限都沒(méi)有。這一點(diǎn),是不能與專用驅(qū)動(dòng)程序方法向相比的。

            在VC/.NET中,由于沒(méi)有相應(yīng)的原型說(shuō)明和庫(kù)文件,我們用GetProcAddress()進(jìn)行DLL顯式調(diào)用。前面大段的代碼,用于說(shuō)明必需的類型和結(jié)構(gòu)。讀取物理內(nèi)存的主要步驟為:打開(kāi)內(nèi)核對(duì)象 → 映射虛擬地址空間 → 讀取(復(fù)制)內(nèi)存 → 取消地址空間映射。

            typedef LONG    NTSTATUS;
             
            typedef struct _UNICODE_STRING
            {
                USHORT Length;
                USHORT MaximumLength;
                PWSTR Buffer;
            } UNICODE_STRING, *PUNICODE_STRING;
             
            typedef enum _SECTION_INHERIT
            {
                ViewShare = 1,
                ViewUnmap = 2
            } SECTION_INHERIT, *PSECTION_INHERIT;
             
            typedef struct _OBJECT_ATTRIBUTES
            {
                ULONG Length;
                HANDLE RootDirectory;
                PUNICODE_STRING ObjectName;
                ULONG Attributes;
                PVOID SecurityDescriptor;
                PVOID SecurityQualityOfService;
            } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
             
            #define InitializeObjectAttributes( p, n, a, r, s ) { \
                (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
                (p)->RootDirectory = r; \
                (p)->Attributes = a; \
                (p)->ObjectName = n; \
                (p)->SecurityDescriptor = s; \
                (p)->SecurityQualityOfService = NULL; \
            }
             
            // Interesting functions in NTDLL
            typedef NTSTATUS (WINAPI *ZwOpenSectionProc)
            (
                PHANDLE SectionHandle,
                DWORD DesiredAccess,
                POBJECT_ATTRIBUTES ObjectAttributes
            );
            typedef NTSTATUS (WINAPI *ZwMapViewOfSectionProc)
            (
                HANDLE SectionHandle,
                HANDLE ProcessHandle,
                PVOID *BaseAddress,
                ULONG ZeroBits,
                ULONG CommitSize,
                PLARGE_INTEGER SectionOffset,
                PULONG ViewSize,
                SECTION_INHERIT InheritDisposition,
                ULONG AllocationType,
                ULONG Protect
            );
            typedef NTSTATUS (WINAPI *ZwUnmapViewOfSectionProc)
            (
                HANDLE ProcessHandle,
                PVOID BaseAddress
            );
            typedef VOID (WINAPI *RtlInitUnicodeStringProc)
            (
                IN OUT PUNICODE_STRING DestinationString,
                IN PCWSTR SourceString
            );
             
            // Global variables
            static HMODULE hModule = NULL;
            static HANDLE hPhysicalMemory = NULL;
            static ZwOpenSectionProc ZwOpenSection;
            static ZwMapViewOfSectionProc ZwMapViewOfSection;
            static ZwUnmapViewOfSectionProc ZwUnmapViewOfSection;
            static RtlInitUnicodeStringProc RtlInitUnicodeString;
             
            // initialize
            BOOL InitPhysicalMemory()
            {
                if (!(hModule = LoadLibrary("ntdll.dll")))
                {
                    return FALSE;
                }
             
                // 以下從NTDLL獲取我們需要的幾個(gè)函數(shù)指針
                if (!(ZwOpenSection = (ZwOpenSectionProc)GetProcAddress(hModule, "ZwOpenSection")))
                {
                    return FALSE;
                }
             
                if (!(ZwMapViewOfSection = (ZwMapViewOfSectionProc)GetProcAddress(hModule, "ZwMapViewOfSection")))
                {
                    return FALSE;
                }
             
                if (!(ZwUnmapViewOfSection = (ZwUnmapViewOfSectionProc)GetProcAddress(hModule, "ZwUnmapViewOfSection")))
                {
                    return FALSE;
                }
             
                if (!(RtlInitUnicodeString = (RtlInitUnicodeStringProc)GetProcAddress(hModule, "RtlInitUnicodeString")))
                {
                    return FALSE;
                }
             
                // 以下打開(kāi)內(nèi)核對(duì)象
                WCHAR PhysicalMemoryName[] = L"\\Device\\PhysicalMemory";
                UNICODE_STRING PhysicalMemoryString;
                OBJECT_ATTRIBUTES attributes;
                RtlInitUnicodeString(&PhysicalMemoryString, PhysicalMemoryName);
                InitializeObjectAttributes(&attributes, &PhysicalMemoryString, 0, NULL, NULL);
                NTSTATUS status = ZwOpenSection(&hPhysicalMemory, SECTION_MAP_READ, &attributes );
             
                return (status >= 0);
            }
             
            // terminate -- free handles
            void ExitPhysicalMemory()
            {
                if (hPhysicalMemory != NULL)
                {
                    CloseHandle(hPhysicalMemory);
                }
             
                if (hModule != NULL)
                {
                    FreeLibrary(hModule);
                }
            }
             
            BOOL ReadPhysicalMemory(PVOID buffer, DWORD address, DWORD length)
            {
                DWORD outlen;            // 輸出長(zhǎng)度,根據(jù)內(nèi)存分頁(yè)大小可能大于要求的長(zhǎng)度
                PVOID vaddress;          // 映射的虛地址
                NTSTATUS status;         // NTDLL函數(shù)返回的狀態(tài)
                LARGE_INTEGER base;      // 物理內(nèi)存地址
             
                vaddress = 0;
                outlen = length;
                base.QuadPart = (ULONGLONG)(address);
             
                // 映射物理內(nèi)存地址到當(dāng)前進(jìn)程的虛地址空間
                status = ZwMapViewOfSection(hPhysicalMemory,
                    (HANDLE) -1,
                    (PVOID *)&vaddress,
                    0,
                    length,
                    &base,
                    &outlen,
                    ViewShare,
                    0,
                    PAGE_READONLY);
             
                if (status < 0)
                {
                    return FALSE;
                }
             
                // 當(dāng)前進(jìn)程的虛地址空間中,復(fù)制數(shù)據(jù)到輸出緩沖區(qū)
                memmove(buffer, vaddress, length);
             
                // 完成訪問(wèn),取消地址映射
                status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)vaddress);
             
                return (status >= 0);
            }
             
            // 一個(gè)測(cè)試函數(shù),從物理地址0xfe000開(kāi)始,讀取4096個(gè)字節(jié)
            // 對(duì)于Award BIOS,可以從這段數(shù)據(jù)找到序列號(hào)等信息
            BOOL test()
            {
                UCHAR buf[4096];
             
                if (!InitPhysicalMemory())
                {
                    return FALSE;
                }
             
                if (!ReadPhysicalMemory(buf, 0xfe000, 4096))
                {
                    // ... 成功讀取了指定數(shù)據(jù)
                    ExitPhysicalMemory();
                    return FALSE;
                }
             
                ExitPhysicalMemory();
             
                return TRUE;
            }

            補(bǔ)充說(shuō)明一點(diǎn),由于Windows虛擬內(nèi)存頁(yè)面大小默認(rèn)是4KB,NtMapViewOfSection()返回的虛擬空間基址是按照4KB對(duì)齊的,返回的

            本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/coffeemay/archive/2006/10/28/1354465.aspx

            posted on 2011-04-29 11:00 沛沛 閱讀(746) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Windows
            久久AAAA片一区二区| 久久综合鬼色88久久精品综合自在自线噜噜 | 国产福利电影一区二区三区,免费久久久久久久精 | 亚洲精品第一综合99久久| 人人狠狠综合久久亚洲婷婷| 久久综合九色综合欧美狠狠| 久久99精品国产麻豆婷婷| 国产精品亚洲综合久久| 97久久精品无码一区二区 | 久久免费精品视频| 中文字幕精品无码久久久久久3D日动漫| 久久精品国产99国产精品亚洲| 色综合久久天天综合| 久久天天婷婷五月俺也去| 7777久久亚洲中文字幕| 亚洲精品久久久www| 久久久久四虎国产精品| 日韩精品久久无码中文字幕| 国产成人综合久久久久久| 色狠狠久久AV五月综合| 无码精品久久一区二区三区 | 欧美亚洲国产精品久久高清| 国产99精品久久| 亚洲国产精品无码久久久不卡| 久久99精品九九九久久婷婷| 精品免费tv久久久久久久| 无码人妻久久一区二区三区免费| 日韩精品无码久久一区二区三| 色综合合久久天天综合绕视看| av国内精品久久久久影院| 欧美国产成人久久精品| 天天综合久久一二三区| 欧美久久一区二区三区| 精品久久久久国产免费| 99久久精品无码一区二区毛片| 好久久免费视频高清| 久久亚洲国产午夜精品理论片| 香港aa三级久久三级| 97久久精品人人澡人人爽| 国产99久久久久久免费看| 久久99精品免费一区二区|