首页
社区
课程
招聘
[求助]TSS异常
发表于: 2011-1-16 20:41 5076

[求助]TSS异常

2011-1-16 20:41
5076
已经从ring0进入ring3
当ring3返回ring0报TSS异常,也就是当用调用门时:
call gate:offset时tss异常了

代码如下:

%include "com.inc"
%include "os.inc"

;entry start

start:

  jmp dword BOOTSEG:go

go:

  mov  ax,cs

  mov  ds,ax

  mov  ss,ax

  mov  sp,0x800

  

        load_system:

  mov  dx,0x0000        ;DH-磁头号        DL-驱动器号       

  mov  cx,0x0002        ;CH-10位磁道号低八位        CL-位7、6是磁道号高两位,位0-5为起始扇区号

  mov  ax,SYSSEG        ;ES:BX-读入缓冲区位置(0x1000:0x0000)

  mov  es,ax                        ;AH-读扇区功能号        AL-需读的扇区数

  xor  bx,bx

  mov  ax,0x200+SYSLEN

  int   0x13

  jnc  ok_load               

die:

  jmp  die

ok_load:

  cli      ; no interrupts allowed !

  mov  ax, SYSSEG               

  mov  ds, ax

  xor  ax, ax

  mov  es, ax

  mov  cx, 0x2000

  sub        si,si

  sub        di,di

  rep  movsb                ;复制ds:[si](0x1000:0即0x10000)到es:[di](0:0),共cx字节

  mov  ax, BOOTSEG

  mov  ds, ax

  lidt  [idt_48]    ; load idt with 0,0

  lgdt  [gdt_48]    ; load gdt with whatever appropriate

; absolute address 0x00000, in 32-bit protected mode.

  mov  ax,0x0001  ; protected mode (PE) bit

  lmsw  ax    ; This is it!

  

  ;mov ax,Seclector_Ds

  ;mov ds,ax

  ;mov es,ax

  ;mov fs,ax

  ;mov gs,ax

  ;mov ss,ax

  

  jmp dword Selector_Cs:cs_start;+0x7c00  
  ;jmp 0x8:cs_start+0x7c00

cs_start:
        ;jmp ring3
        ; Load TSS

        mov ax,Selectot_LDT
        lldt ax

        mov        ax, SelectorTSS
        ltr        ax        ; 在任务内发生特权级变换时要切换堆栈,而内层堆栈的指针存放在当前任务的TSS中,所以要设置任务状态段寄存器 TR。

        push        Selector_Stack3
        push        TopOfStack3
        push        Selector_Ring3
        push        0
        retf                                ; Ring0 -> Ring3
ring3_start:
        ;db 0x66,0xB8,0x37,0x01,0x9A,0x00,0x00,0x00,0x00,0x43,0x00

        mov ax,0x137 ;测试代码
        ;call         Selector_Ring0:0
       
        call Selector_Gate:0        ;Ring3 -> Ring0 此句异常

idt_48:

  dw  0    ; idt limit=0

  dw  0,0    ; idt base=0L
gdt_48:        ;since we are in 0 start address,so no ds:
        dw GDT_Len-1
        dd 0x7c00+LGDT

LGDT:
        Descriptor 0,0,0       
LCs:
        ;Descriptor Ring3_Base,Ring3_Len,DA_CR;+DA_32
        ;Descriptor 0,0xfffff,DA_CR;+DA_32
        ;Descriptor Ring3_Base,Ring3_Len-1,DA_CR;+DA_32
        Descriptor Cs_Base,Cs_Len-1,DA_CR
LDs:
        Descriptor 0,0xfffff,DA_DRW
LRing3:
        Descriptor Ring3_Base,Ring3_Len-1,DA_CR+DA_DPL3                ;+DA_32
LRing0:       
        Descriptor Ring0_Base,Ring0_Len-1,DA_CR+DA_32+DA_DPL0
LStack:
        Descriptor Stack_Base,TopOfStack,DA_DRWA + DA_32; Stack, 32 位
LStack3:
        Descriptor Stack_Base3,TopOfStack3, DA_DRWA + DA_32 + DA_DPL3; Stack, 32 位
LTSS:
        Descriptor 0,TSSLen - 1,DA_386TSS; TSS
LGate:
        Gate Selector_Ring0,          0,      0, DA_386CGate + DA_DPL3
LDT:
        Descriptor               LDT_Base,          LDTLen - 1, DA_LDT;+ DA_DPL3                        ; LDT

        GDT_Len equ $-LGDT
        Selector_Ds equ LDs-LGDT
        Selector_Ring3 equ LRing3-LGDT+SA_RPL3
        Selector_Ring0 equ LRing0-LGDT+SA_RPL0
        Selector_Cs        equ LCs-LGDT
        Selector_Stack                equ        LStack        - LGDT
        Selector_Stack3                equ        LStack3        - LGDT + SA_RPL3
        SelectorTSS                equ        LTSS - LGDT
        Selector_Gate        equ        LGate        - LGDT + SA_RPL3
        Selectot_LDT        equ        LDT-LGDT
Ring3_Len equ bios_flag-ring3_start+2
Ring0_Len equ 4*512
Ring0_Base equ 0
Ring3_Base equ 0x7c00+ring3_start-start

;Cs_Base equ           Ring3_Base
;Cs_Len        equ           Ring3_Len
Cs_Base equ           0x7c00
Cs_Len        equ           512
Stack_Base equ 0x7c00+LABEL_STACK-start
Stack_Base3 equ 0x7c00+LABEL_STACK3-start
LDT_Base equ 0x7c00+LLDT-start
; 全局堆栈段
LABEL_STACK:
        times 88 db 0
TopOfStack        equ        $ - LABEL_STACK - 1

;Ring3 stack
LABEL_STACK3:
        times 88 db 0
TopOfStack3        equ        $ - LABEL_STACK3 - 1

; LDT
LLDT:
;                              段基址       段界限     ,   属性
LLDT_Code:       
Descriptor               Ring3_Base,    Ring3_Len-1 ,   DA_C + DA_32        ; Code, 32 位

LDTLen                equ        $ - LLDT

; LDT 选择子
Selector_LDTCode        equ        LLDT_Code        - LLDT + SA_TIL
; END of [SECTION .ldt]

LABEL_TSS:
                DD        0                        ; Back
                DD        TopOfStack                ; 0 级堆栈
                DD        Selector_Stack                ;
                DD        0                        ; 1 级堆栈
                DD        0                        ;
                DD        0                        ; 2 级堆栈
                DD        0                        ;
                DD        0                        ; CR3
                DD        0                        ; EIP
                DD        0                        ; EFLAGS
                DD        0                        ; EAX
                DD        0                        ; ECX
                DD        0                        ; EDX
                DD        0                        ; EBX
                DD        0                        ; ESP
                DD        0                        ; EBP
                DD        0                        ; ESI
                DD        0                        ; EDI
                DD        0                        ; ES
                DD        0                        ; CS
                DD        0                        ; SS
                DD        0                        ; DS
                DD        0                        ; FS
                DD        0                        ; GS
                DD        0                        ; LDT
                DW        0                        ; 调试陷阱标志
                DW        $ - LABEL_TSS + 2        ; I/O位图基址
                DB        0ffh                        ; I/O位图结束标志
TSSLen                equ        $ - LABEL_TSS

  times (510-($-start)) db 0         

bios_flag:

  db 0x55,0xaa  

调得头昏眼花,还是不能进入ring0
错误如下

(0).[26264713] [0x00007c74] 001b:00000003 (unk. ctxt): call far 0043:0000        ; 9a00004300
CPU 0: Exception 0x0a - (#TS) invalid TSS occured (error_code=0x0000)
CPU 0: Interrupt 0x0a occured (error_code=0x0000)
CPU 0: Exception 0x0d - (#GP) general protection fault occured (error_code=0x0052)
CPU 0: Exception 0x08 - (#DF) double fault occured (error_code=0x0000)
CPU 0: Interrupt 0x08 occured (error_code=0x0000)
CPU 0: Exception 0x0d - (#GP) general protection fault occured (error_code=0x0042)
有没有兄弟姐妹能解决的,感激不尽!
头文件
BOOTSEG equ 0x07c0
SYSSEG  equ 0x1000      ; system loaded at 0x10000 (65536).
SYSLEN  equ 4                ; sectors occupied.
;----------------------------------------------------------------------------
; 描述符类型值说明
; 其中:
;       DA_  : Descriptor Attribute
;       D    : 数据段
;       C    : 代码段
;       S    : 系统段
;       R    : 只读
;       RW   : 读写
;       A    : 已访问
;       其它 : 可按照字面意思理解
;----------------------------------------------------------------------------
DA_32                EQU        4000h        ; 32 位段

DA_DPL0                EQU          00h        ; DPL = 0
DA_DPL1                EQU          20h        ; DPL = 1
DA_DPL2                EQU          40h        ; DPL = 2
DA_DPL3                EQU          60h        ; DPL = 3
;----------------------------------------------------------------------------
; 存储段描述符类型值说明
;----------------------------------------------------------------------------
DA_DR                EQU        90h        ; 存在的只读数据段类型值
DA_DRW                EQU        92h        ; 存在的可读写数据段属性值
DA_DRWA                EQU        93h        ; 存在的已访问可读写数据段类型值
DA_C                EQU        98h        ; 存在的只执行代码段属性值
DA_CR                EQU        9Ah        ; 存在的可执行可读代码段属性值
DA_CCO                EQU        9Ch        ; 存在的只执行一致代码段属性值
DA_CCOR                EQU        9Eh        ; 存在的可执行可读一致代码段属性值
;----------------------------------------------------------------------------
; 系统段描述符类型值说明
;----------------------------------------------------------------------------
DA_LDT                EQU          82h        ; 局部描述符表段类型值
DA_TaskGate        EQU          85h        ; 任务门类型值
DA_386TSS        EQU          89h        ; 可用 386 任务状态段类型值
DA_386CGate        EQU          8Ch        ; 386 调用门类型值
DA_386IGate        EQU          8Eh        ; 386 中断门类型值
DA_386TGate        EQU          8Fh        ; 386 陷阱门类型值
;----------------------------------------------------------------------------

; 选择子图示:
;         ┏━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┓
;         ┃ 15 ┃ 14 ┃ 13 ┃ 12 ┃ 11 ┃ 10 ┃ 9  ┃ 8  ┃ 7  ┃ 6  ┃ 5  ┃ 4  ┃ 3  ┃ 2  ┃ 1  ┃ 0  ┃
;         ┣━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━╋━━╋━━┻━━┫
;         ┃                                 描述符索引                                 ┃ TI ┃   RPL    ┃
;         ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━┻━━━━━┛
;
; RPL(Requested Privilege Level): 请求特权级,用于特权检查。
;
; TI(Table Indicator): 引用描述符表指示位
;        TI=0 指示从全局描述符表GDT中读取描述符;
;        TI=1 指示从局部描述符表LDT中读取描述符。
;

;----------------------------------------------------------------------------
; 选择子类型值说明
; 其中:
;       SA_  : Selector Attribute

SA_RPL0                EQU        0        ; ┓
SA_RPL1                EQU        1        ; ┣ RPL
SA_RPL2                EQU        2        ; ┃
SA_RPL3                EQU        3        ; ┛

SA_TIG                EQU        0        ; ┓TI
SA_TIL                EQU        4        ; ┛
;----------------------------------------------------------------------------

DA_4G        EQU 0xC0;0x80

; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)
;        Attr:  dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3
        dw        %2 & 0FFFFh                                ; 段界限 1                                (2 字节)
        dw        %1 & 0FFFFh                                ; 段基址 1                                (2 字节)
        db        (%1 >> 16) & 0FFh                        ; 段基址 2                                (1 字节)
        dw        ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)        ; 属性 1 + 段界限 2 + 属性 2                (2 字节)
        db        (%1 >> 24) & 0FFh                        ; 段基址 3                                (1 字节)
%endmacro ; 共 8 字节
;
; 门
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4
        dw        (%2 & 0FFFFh)                                ; 偏移 1                                (2 字节)
        dw        %1                                        ; 选择子                                (2 字节)
        dw        (%3 & 1Fh) | ((%4 << 8) & 0FF00h)        ; 属性                                        (2 字节)
        dw        ((%2 >> 16) & 0FFFFh)                        ; 偏移 2                                (2 字节)
%endmacro ; 共 8 字节
;

%macro Set_Base_Address 2
        mov        eax, %1
        mov        word [%2+2], ax
        shr        eax, 16
        mov        byte [%2 + 3], al
        mov        byte [%2 + 7], ah
       
%endmacro

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 81
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
已解决,TSS基址没有设置正确,详情请参看我的博客文章
http://blog.sina.com.cn/s/blog_3d2149290100o069.html
2011-1-17 01:25
0
游客
登录 | 注册 方可回帖
返回
//