关于保护模式,任务段跳转问题

问题:关于保护模式,任务段跳转

无法成功跳转,麻烦帮忙看下问题。

代码:

/*
当使用JMP FAR来实现任务切换时,TSS结构体中的Previous Task Link的值在任务切换完成之后为0,CPU不会为其赋值;如果使用CALL FAR来实现任务切换,Previous Task Link的值在任务切换完成之后会CPU会将其填充为原来的TSS段选择子
当使用JMP FAR来实现任务切换时,EFLAGS寄存器中的NT位不变;当使用CALL FAR来实现任务切换时,EFLAGS寄存器中的NT位就会被置1(NT位会对iret指令产生影响 NT位如果为0,iret的值从堆栈中取(中断返回);如果NT位为1,会找TSS中的Previous Task Link进行返回)

*/

// 实现的主要代码
#include "windows.h"
#include "stdio.h"
DWORD eaxV;
DWORD fsV;
DWORD temp;


**//一个完整的TSS结构**
typedef struct TSS {
    DWORD link; // 保存前一个 TSS 段选择子,使用 call 指令切换寄存器的时候由CPU填写。
    // 这 6 个值是固定不变的,用于提权,CPU 切换栈的时候用
    DWORD esp0; // 保存 0 环栈指针
    DWORD ss0;  // 保存 0 环栈段选择子
    DWORD esp1; // 保存 1 环栈指针
    DWORD ss1;  // 保存 1 环栈段选择子
    DWORD esp2; // 保存 2 环栈指针
    DWORD ss2;  // 保存 2 环栈段选择子
    // 下面这些都是用来做切换寄存器值用的,切换寄存器的时候由CPU自动填写。
    DWORD cr3; 
    DWORD eip;  
    DWORD eflags;
    DWORD eax;
    DWORD ecx;
    DWORD edx;
    DWORD ebx;
    DWORD esp;
    DWORD ebp;
    DWORD esi;
    DWORD edi;
    DWORD es;
    DWORD cs;
    DWORD ss;
    DWORD ds;
    DWORD fs;
    DWORD gs;
    DWORD ldt;
    // 这个暂时忽略
    DWORD io_map;
} TSS;

TSS tss={0};
DWORD cr3V=0;
BYTE byteArrayR0[0x10]={0};
BYTE byteArrayR3[0x10]={0};
BYTE jmpAddr[]={0,0,0,0,0x4B,0};
BYTE  retAddr[]={0x35,0x15,0x41,0x0,0x1B,0x0};
**//通过调用门调用的函数
**void _declspec(naked)  tssFun()
{
    __asm{

        //----------------代码    
        //断点,中断查看栈
        /*

        */
        push fs
        pushfd
        int 3
        popfd
        pop fs
        //读取高g内存
        mov eax,0xf82B140C
        mov ebx,[eax]
        mov temp,ebx
**      //返回
**      //jmp far retAddr
        iretd;
    }
}
/*
---获取真实地址
*/
VOID getRealAddr(OUT PDWORD addrPtr,IN DWORD fun){
    PBYTE jmpArray=(PBYTE)fun;
    *addrPtr=fun+0x5+*(PDWORD)(jmpArray+1);
}

int main()
{


    //DWORD tssFunAddress=(DWORD)tssFun;
    DWORD tssFunAddress=(DWORD)tssFun;
    getRealAddr(&tssFunAddress,(DWORD)tssFun);
    PWORD tssFunPtr=(PWORD)(&tssFunAddress);
    PDWORD tssPtr=(PDWORD)(&tss);
    PBYTE tssSecondPtr=(PBYTE)(&tssPtr);
**  //tss赋值
**  tss.esp0=(DWORD)(byteArrayR0);//esp0
    tss.ss0=0x00000010;//ss0
    tss.eip=tssFunAddress;//函数地址
    tss.esp=(DWORD)(byteArrayR0);//esp
    tss.es=0x00000023;//es  
    tss.cs= 0x00000008;//cs  
    tss.ss= 0x00000010;//ss
    tss.ds= 0x00000023;//ds
    tss.fs= 0x00000030;//fs
    tss.io_map= 0x20ac0000; //IO
    printf( "tss地址:%08X\n" , tssPtr );
    printf( "调用门函数tssFun地址:%08X\n" ,((DWORD)tssFun) );
    printf("请在windbg中执行如下命令:eq 8003f048 %02X00e9%02X`%04X0068, tss\n",*(tssSecondPtr+3),*(tssSecondPtr+2),*(PWORD)tssSecondPtr);
    system( "pause" );

    printf("!process 0 0  tssDescriptior.exe查看cr3 ,请input cr3:");
    scanf_s("%x",&cr3V);
    tss.cr3 = cr3V;

    _asm {
**      //jmp到任务段,任务段保存的指向
**      call far jmpAddr

    }
    printf( "提权后读取的高g内容::%08X\n" , temp );
    system( "pause" );
}

https://blog.csdn.net/rongwenbin/article/details/18989801