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

            牽著老婆滿街逛

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

            [轉(zhuǎn)載]Windows NT/2000/XP下不用驅(qū)動的Ring0代碼實(shí)現(xiàn)

            Windows?NT/2000/XP下不用驅(qū)動的Ring0代碼實(shí)現(xiàn)?????
            ??????????? WebCrazy(http://webcrazy.yeah.net/)

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

            ????Windows?NT/2000將設(shè)備驅(qū)動程序調(diào)入內(nèi)核區(qū)域(常見的位于地址0x80000000上),由DPL為0的GDT項(xiàng)8,即cs為8時實(shí)現(xiàn)Ring?0權(quán)限。本文通過在系統(tǒng)中構(gòu)造一個指向我們的代碼的調(diào)用門(CallGate),實(shí)現(xiàn)Ring0代碼?;谶@個思路,為實(shí)現(xiàn)這個目的主要是構(gòu)造自己的CallGate。CallGate由系統(tǒng)中叫Global?Descriptor?Table(GDT)的全局表指定。GDT地址可由i386指令sgdt獲得(sgdt不是特權(quán)級指令,普通Ring 3程序均可執(zhí)行)。GDT地址在Windows?NT/2000保存于KPCR(Processor?Control?Region)結(jié)構(gòu)中(見《再談Windows?NT/2000環(huán)境切換》)。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位于內(nèi)核區(qū)域,一般用戶態(tài)的程序是不可能對這段內(nèi)存區(qū)域有直接的訪問權(quán)。幸運(yùn)的是Windows?NT/2000提供了一個叫PhysicalMemory的Section內(nèi)核對象位于\Device的路徑下。顧名思義,通過這個Section對象可以對物理內(nèi)存進(jìn)行操作。用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可以看出默認(rèn)情況下只有SYSTEM用戶才有對這個對象的讀寫權(quán)限,即對物理內(nèi)存有讀寫能力,而Administrator只有讀權(quán)限,普通用戶根本就沒有權(quán)限。不過如果我們有Administrator權(quán)限就可以通過GetSecurityInfo、SetEntriesInAcl與SetSecurityInfo這些API來修改這個對象的ACE。這也是我提供的代碼需要Administrator的原因。實(shí)現(xiàn)的代碼如下:
            ???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權(quán)限的條件下就有了對物理內(nèi)存的讀寫能力。但若要修改GDT表實(shí)現(xiàn)Ring?0代碼。我們將面臨著另一個難題,因?yàn)閟gdt指令獲得的GDT地址是虛擬地址(線性地址),我們只有知道GDT表的物理地址后才能通過\Device\PhysicalMemory對象修改GDT表,這就牽涉到了線性地址轉(zhuǎn)化成物理地址的問題。我們先來看一看Windows?NT/2000是如何實(shí)現(xiàn)這個的:
            ????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范圍內(nèi),只是簡單的進(jìn)行移位操作(位于801374ff-80137519指令間),并未查頁表。我想Microsoft這樣安排肯定是出于執(zhí)行效率的考慮。這也為我們指明了一線曙光,因?yàn)镚DT表在Windows?NT/2000中一般情況下均位于這個區(qū)域(我不知道/3GB開關(guān)的Windows?NT/2000是不是這種情況)。

            ????經(jīng)過這樣的分析,我們就可以只通過用戶態(tài)程序修改GDT表了。而增加一個CallGate就不是我可以介紹的了,找本Intel手冊自己看一看了。具體實(shí)現(xiàn)代碼如下:
            ????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中就是因?yàn)楂@得Ring?0權(quán)限才有了一定的危害,但Windows?NT/2000畢竟不是Windows?9X,她已經(jīng)有了比較多的安全審核機(jī)制,本文提供的代碼也要求具有Administrator權(quán)限,但如果系統(tǒng)存在某種漏洞,如緩沖區(qū)溢出等等,還是有可能獲得這種權(quán)限的,所以我不對本文提供的方法負(fù)有任何的責(zé)任,所有討論只是一個技術(shù)熱愛者在討論技術(shù)而已。謝謝!?

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

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

            久久精品不卡| 狠狠狠色丁香婷婷综合久久俺| 婷婷综合久久狠狠色99h| 亚洲国产精品婷婷久久| 久久99亚洲综合精品首页| 青青热久久国产久精品| 日日噜噜夜夜狠狠久久丁香五月| 久久99国产综合精品| 久久午夜无码鲁丝片午夜精品| 伊人久久精品无码二区麻豆| 久久福利青草精品资源站| 久久人人爽人爽人人爽av| 91视频国产91久久久| 亚洲人成网站999久久久综合 | 国产精品久久久久…| 久久中文字幕无码专区| www.久久精品| 久久精品综合网| 国产—久久香蕉国产线看观看 | 一个色综合久久| 国产成人无码精品久久久免费 | 女人高潮久久久叫人喷水| 日产精品久久久久久久性色| 伊人情人综合成人久久网小说| 天天综合久久久网| 国产精品毛片久久久久久久| 久久国产欧美日韩精品| 久久久黄片| 日韩电影久久久被窝网| 久久最新免费视频| 久久男人中文字幕资源站| 国产精品无码久久四虎| 久久精品国产影库免费看| 久久永久免费人妻精品下载| 一本色道久久88精品综合| 久久中文字幕精品| 亚洲国产精品成人AV无码久久综合影院| 99久久国产免费福利| 国产99久久久国产精品~~牛| 久久se精品一区精品二区国产| 久久99免费视频|