• <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>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            [轉載]Windows NT/2000/XP下不用驅動的Ring0代碼實現

            Windows?NT/2000/XP下不用驅動的Ring0代碼實現?????
            ??????????? WebCrazy(http://webcrazy.yeah.net/)

            ????大家知道,Windows?NT/2000為實現其可靠性,嚴格將系統劃分為內核模式與用戶模式,在i386系統中分別對應CPU的Ring0與Ring3級別。Ring0下,可以執行特權級指令,對任何I/O設備都有訪問權等等。要實現從用戶態進入核心態,即從Ring?3進入Ring?0必須借助CPU的某種門機制,如中斷門、調用門等。而Windows?NT/2000提供用戶態執行系統服務(Ring?0例程)的此類機制即System?Service的int?2eh中斷服務等,嚴格的參數檢查,只能嚴格的執行Windows?NT/2000提供的服務,而如果想執行用戶提供的Ring?0代碼(指運行在Ring?0權限的代碼),常規方法似乎只有編寫設備驅動程序。本文將介紹一種在用戶態不借助任何驅動程序執行Ring0代碼的方法。

            ????Windows?NT/2000將設備驅動程序調入內核區域(常見的位于地址0x80000000上),由DPL為0的GDT項8,即cs為8時實現Ring?0權限。本文通過在系統中構造一個指向我們的代碼的調用門(CallGate),實現Ring0代碼。基于這個思路,為實現這個目的主要是構造自己的CallGate。CallGate由系統中叫Global?Descriptor?Table(GDT)的全局表指定。GDT地址可由i386指令sgdt獲得(sgdt不是特權級指令,普通Ring 3程序均可執行)。GDT地址在Windows?NT/2000保存于KPCR(Processor?Control?Region)結構中(見《再談Windows?NT/2000環境切換》)。GDT中的CallGate是如下的格式:
            ????typedef?struct
            ????
            {?
            ????????unsigned?
            short??offset_0_15;
            ????????unsigned?
            short??selector;

            ????????unsigned?
            char????param_count?:?4;
            ????????unsigned?
            char????some_bits???:?4;

            ????????unsigned?
            char????type????????:?4;
            ????????unsigned?
            char????app_system??:?1;
            ????????unsigned?
            char????dpl?????????:?2;
            ????????unsigned?
            char????present?????:?1;
            ????
            ????????unsigned?
            short??offset_16_31;
            ?????}
            ?CALLGATE_DESCRIPTOR;
            ????GDT位于內核區域,一般用戶態的程序是不可能對這段內存區域有直接的訪問權。幸運的是Windows?NT/2000提供了一個叫PhysicalMemory的Section內核對象位于\Device的路徑下。顧名思義,通過這個Section對象可以對物理內存進行操作。用objdir.exe對這個對象分析如下:
            ????C:\NTDDK\bin>objdir?/D?\Device

            ????PhysicalMemory???????????????????
            ????????Section
            ????????DACL?
            -?
            ???????????Ace[?
            0]?-?Grant?-?0xf001f?-?NT?AUTHORITY\SYSTEM
            ?????????????????????????????Inherit:?
            ?????????????????????????????Access:?
            0x001F??and??(?D?RCtl?WOwn?WDacl?)

            ???????????Ace[?
            1]?-?Grant?-?0x2000d?-?BUILTIN\Administrators
            ?????????????????????????????Inherit:?
            ?????????????????????????????Access:?
            0x000D??and??(?RCtl?)
            ???從dump出的這個對象DACL的Ace可以看出默認情況下只有SYSTEM用戶才有對這個對象的讀寫權限,即對物理內存有讀寫能力,而Administrator只有讀權限,普通用戶根本就沒有權限。不過如果我們有Administrator權限就可以通過GetSecurityInfo、SetEntriesInAcl與SetSecurityInfo這些API來修改這個對象的ACE。這也是我提供的代碼需要Administrator的原因。實現的代碼如下:
            ???VOID?SetPhyscialMemorySectionCanBeWrited(HANDLE?hSection)
            ????
            {?

            ???????PACL?pDacl
            =NULL;
            ???????PACL?pNewDacl
            =NULL;
            ???????PSECURITY_DESCRIPTOR?pSD
            =NULL;
            ???????DWORD?dwRes;
            ???????EXPLICIT_ACCESS?ea;

            ???????
            if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
            ??????????????????NULL,NULL,
            &pDacl,NULL,&pSD)!=ERROR_SUCCESS)
            ??????????
            {?
            ?????????????printf(?
            "GetSecurityInfo?Error?%u\n",?dwRes?);
            ?????????????
            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(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
            ??????????
            {?
            ?????????????printf(?
            "SetEntriesInAcl?%u\n",?dwRes?);
            ?????????????
            goto?CleanUp;
            ???????????}


            ???????
            if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
            ??????????
            {?
            ?????????????printf(
            "SetSecurityInfo?%u\n",dwRes);
            ?????????????
            goto?CleanUp;
            ???????????}


            ????CleanUp:

            ???????
            if(pSD)
            ??????????LocalFree(pSD);
            ???????
            if(pNewDacl)
            ??????????LocalFree(pSD);
            ?????}


            ????這段代碼對給定HANDLE的對象增加了如下的ACE:?

            ????PhysicalMemory???????????????????
            ????????Section
            ????????DACL?
            -?
            ???????????Ace[?
            0]?-?Grant?-?0x2?-?WEBCRAZY\Administrator
            ?????????????????????????????Inherit:?
            ?????????????????????????????Access:?
            0x0002????//SECTION_MAP_WRITE

            ???這樣我們在有Administrator權限的條件下就有了對物理內存的讀寫能力。但若要修改GDT表實現Ring?0代碼。我們將面臨著另一個難題,因為sgdt指令獲得的GDT地址是虛擬地址(線性地址),我們只有知道GDT表的物理地址后才能通過\Device\PhysicalMemory對象修改GDT表,這就牽涉到了線性地址轉化成物理地址的問題。我們先來看一看Windows?NT/2000是如何實現這個的:
            ????kd>?u?nt!MmGetPhysicalAddress?l?30
            ????ntoskrnl
            !MmGetPhysicalAddress:
            ????801374e0?
            56???????????????push????esi
            ????801374e1?8b742408?????????mov?????esi,[esp
            +0x8]
            ????801374e5?33d2?????????????xor?????edx,edx
            ????801374e7?81fe00000080?????cmp?????esi,
            0x80000000
            ????801374ed?722c?????????????jb????ntoskrnl
            !MmGetPhysicalAddress+0x2b?(8013751b)
            ????801374ef?81fe000000a0?????cmp?????esi,
            0xa0000000
            ????801374f5?
            7324?????????????jnb???ntoskrnl!MmGetPhysicalAddress+0x2b?(8013751b)
            ????801374f7?39153ce71780?????cmp?????[ntoskrnl
            !MmKseg2Frame?(8017e73c)],edx
            ????801374fd?741c?????????????jz????ntoskrnl
            !MmGetPhysicalAddress+0x2b?(8013751b)
            ????801374ff?8bc6?????????????mov?????eax,esi
            ????
            80137501?c1e80c???????????shr?????eax,0xc
            ????
            80137504?25ffff0100???????and?????eax,0x1ffff
            ????
            80137509?6a0c?????????????push????0xc
            ????8013750b?
            59???????????????pop?????ecx
            ????8013750c?e8d3a7fcff???????call????ntoskrnl
            !_allshl?(80101ce4)
            ????
            80137511?81e6ff0f0000?????and?????esi,0xfff
            ????
            80137517?03c6?????????????add?????eax,esi
            ????
            80137519?eb17?????????????jmp???ntoskrnl!MmGetPhysicalAddress+0x57?(80137532)
            ????8013751b?8bc6?????????????mov?????eax,esi
            ????8013751d?c1e80a???????????shr?????eax,
            0xa
            ????
            80137520?25fcff3f00???????and?????eax,0x3ffffc
            ????
            80137525?2d00000040???????sub?????eax,0x40000000
            ????8013752a?8b00?????????????mov?????eax,[eax]
            ????8013752c?a801?????????????test????al,
            0x1
            ????8013752e?
            7506?????????????jnz???ntoskrnl!MmGetPhysicalAddress+0x44?(80137536)
            ????
            80137530?33c0?????????????xor?????eax,eax
            ????
            80137532?5e???????????????pop?????esi
            ????
            80137533?c20400???????????ret?????0x4
            ????從這段匯編代碼可看出如果線性地址在0x80000000與0xa0000000范圍內,只是簡單的進行移位操作(位于801374ff-80137519指令間),并未查頁表。我想Microsoft這樣安排肯定是出于執行效率的考慮。這也為我們指明了一線曙光,因為GDT表在Windows?NT/2000中一般情況下均位于這個區域(我不知道/3GB開關的Windows?NT/2000是不是這種情況)。

            ????經過這樣的分析,我們就可以只通過用戶態程序修改GDT表了。而增加一個CallGate就不是我可以介紹的了,找本Intel手冊自己看一看了。具體實現代碼如下:
            ????typedef?struct?gdtr?{?
            ????????
            short?Limit;
            ????????
            short?BaseLow;
            ????????
            short?BaseHigh;
            ?????}
            ?Gdtr_t,?*PGdtr_t;

            ????ULONG?MiniMmGetPhysicalAddress(ULONG?virtualaddress)
            ????
            {?
            ????????
            if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
            ???????????
            return?0;
            ????????
            return?virtualaddress&0x1FFFF000;
            ?????}


            ????BOOL?ExecRing0Proc(ULONG?Entry,ULONG?seglen)
            ????
            {?
            ???????Gdtr_t?gdt;
            ???????__asm?sgdt?gdt;
            ?????
            ???????ULONG?mapAddr
            =MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
            ???????
            if(!mapAddr)?return?0;

            ???????HANDLE???hSection
            =NULL;
            ???????NTSTATUS?status;
            ???????OBJECT_ATTRIBUTES????????objectAttributes;
            ???????UNICODE_STRING?objName;
            ???????CALLGATE_DESCRIPTOR?
            *cg;

            ???????status?
            =?STATUS_SUCCESS;
            ???
            ???????RtlInitUnicodeString(
            &objName,L"\\Device\\PhysicalMemory");

            ???????InitializeObjectAttributes(
            &objectAttributes,
            ??????????????????????????????????
            &objName,
            ??????????????????????????????????OBJ_CASE_INSENSITIVE?
            |?OBJ_KERNEL_HANDLE,
            ??????????????????????????????????NULL,
            ?????????????????????????????????(PSECURITY_DESCRIPTOR)?NULL);

            ???????status?
            =?ZwOpenSection(&hSection,SECTION_MAP_READ|SECTION_MAP_WRITE,&objectAttributes);

            ???????
            if(status?==?STATUS_ACCESS_DENIED){?
            ??????????status?
            =?ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
            ??????????SetPhyscialMemorySectionCanBeWrited(hSection);
            ??????????ZwClose(hSection);
            ??????????status?
            =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
            ????????}


            ???????
            if(status?!=?STATUS_SUCCESS)
            ?????????
            {?
            ????????????printf(
            "Error?Open?PhysicalMemory?Section?Object,Status:%08X\n",status);
            ????????????
            return?0;
            ??????????}

            ??????
            ???????PVOID?BaseAddress;

            ???????BaseAddress
            =MapViewOfFile(hSection,
            ?????????????????????FILE_MAP_READ
            |FILE_MAP_WRITE,
            ?????????????????????
            0,
            ?????????????????????mapAddr,????
            //low?part
            ?????????????????????(gdt.Limit+1));

            ???????
            if(!BaseAddress)
            ??????????
            {?
            ?????????????printf(
            "Error?MapViewOfFile:");
            ?????????????PrintWin32Error(GetLastError());
            ?????????????
            return?0;
            ???????????}


            ???????BOOL?setcg
            =FALSE;

            ???????
            for(cg=(CALLGATE_DESCRIPTOR?*)((ULONG)BaseAddress+(gdt.Limit&0xFFF8));(ULONG)cg>(ULONG)BaseAddress;cg--)
            ???????????
            if(cg->type?==?0){?
            ?????????????cg
            ->offset_0_15?=?LOWORD(Entry);
            ?????????????cg
            ->selector?=?8;
            ?????????????cg
            ->param_count?=?0;
            ?????????????cg
            ->some_bits?=?0;
            ?????????????cg
            ->type?=?0xC;??????????//?386?call?gate
            ?????????????cg->app_system?=?0;??????//?A?system?descriptor
            ?????????????cg->dpl?=?3;?????????????//?Ring?3?code?can?call
            ?????????????cg->present?=?1;
            ?????????????cg
            ->offset_16_31?=?HIWORD(Entry);
            ?????????????setcg
            =TRUE;
            ?????????????
            break;
            ???????????}


            ???????
            if(!setcg){?
            ????????????ZwClose(hSection);
            ????????????
            return?0;
            ????????}


            ???????
            short?farcall[3];

            ???????farcall[
            2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3;??//Ring?3?callgate;

            ???????
            if(!VirtualLock((PVOID)Entry,seglen))
            ??????????
            {?
            ?????????????printf(
            "Error?VirtualLock:");
            ?????????????PrintWin32Error(GetLastError());
            ?????????????
            return?0;
            ???????????}


            ???????SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

            ???????Sleep(
            0);

            ???????_asm?call?fword?ptr?[farcall]

            ???????SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);

            ???????VirtualUnlock((PVOID)Entry,seglen);

            ???????
            //Clear?callgate
            ???????*(ULONG?*)cg=0;
            ???????
            *((ULONG?*)cg+1)=0;

            ???????ZwClose(hSection);
            ???????
            return?TRUE;

            ?????}


            ????我在提供的代碼中演示了對Control?Register與I/O端口的操作。CIH病毒在Windows?9X中就是因為獲得Ring?0權限才有了一定的危害,但Windows?NT/2000畢竟不是Windows?9X,她已經有了比較多的安全審核機制,本文提供的代碼也要求具有Administrator權限,但如果系統存在某種漏洞,如緩沖區溢出等等,還是有可能獲得這種權限的,所以我不對本文提供的方法負有任何的責任,所有討論只是一個技術熱愛者在討論技術而已。謝謝!?

            ????參考資料:
            ??????1.Intel Corp<<Intel Architecture Software Developer's Manual,Volume 3>>?

            posted on 2006-04-14 18:54 楊粼波 閱讀(639) 評論(0)  編輯 收藏 引用 所屬分類: 文章收藏

            一本久久a久久精品vr综合| 99久久国产精品免费一区二区| 一本色道久久88综合日韩精品 | 无码日韩人妻精品久久蜜桃| 久久精品这里只有精99品| 欧美亚洲国产精品久久蜜芽| 久久亚洲私人国产精品| 亚洲精品国产美女久久久| 日韩欧美亚洲综合久久| 一本色道久久88综合日韩精品 | 国产精品对白刺激久久久| 久久天天躁狠狠躁夜夜96流白浆| 久久WWW免费人成一看片| 漂亮人妻被中出中文字幕久久| 青青热久久国产久精品 | 久久中文字幕人妻熟av女| 一本一道久久a久久精品综合| 四虎久久影院| 久久精品国产99国产精品亚洲 | 亚洲国产成人久久综合碰碰动漫3d| 久久久久无码精品国产| 亚洲αv久久久噜噜噜噜噜| 亚洲av伊人久久综合密臀性色 | 99久久综合狠狠综合久久止| 69久久精品无码一区二区| 久久精品国产半推半就| 精品久久久久中文字幕一区| 久久亚洲国产成人精品无码区| 久久人人爽人人爽AV片| 伊人久久大香线蕉无码麻豆| 99久久无色码中文字幕人妻| 99久久婷婷国产综合亚洲| 曰曰摸天天摸人人看久久久| 久久天天躁狠狠躁夜夜2020老熟妇| 久久一区二区免费播放| 亚洲熟妇无码另类久久久| 青青草国产精品久久| 久久人人爽人人爽人人片AV高清 | 人妻无码中文久久久久专区| 午夜不卡888久久| 久久久久久免费视频|