第三章 pmtest4源码解析——利用门调用实现特权级转移

摘要:本节,我们将通过分析pmtest4来实现利用调用门进行段间转移。


一、背景与原理

在汇编语言中,我们不能执行这样的指令:mov ds100h和movcs,ax;也就是说,段寄存器的值,是不能像通用寄存器一样,随意赋值的。具体的cs寄存器而言,它涉及到程序的控制转移,需要借助jmp、call、ret、sysenter,sysexit,int n,iret来实现,或者通过中断和异常来完成。我们知道,jmp和call指令,实现的跳转形式如下jmp selector:offset,其中,selector可以指向:


1)目标代码段
2)调用门描述符(->目标代码段选择子)
3)TSS(->目标代码段选择子)
4)任务门(->tss-->目标代码段)
其中第一类属于直接转移,剩下三种属于简介转移。


我们知道,通过jmp和call指令的一般转移,对于非一致性代码段,只能在同特权级之间进行。如果想在不同特权级之间自由切换,需要借助门描述符或者TSS。门描述符有任务门、中断门、陷阱门、异常门:其中中断门和陷阱门属于特殊的调用门。门描述符(目标选择子+入口地址+属性)的结构可以参考这里:http://blog.csdn.net/trochiluses/article/details/20312479


但是,call和jmp在控制转移的时候,作用不是完全相同的,如果代码段A通过调用门G转移到代码段B,call和jmp对应的特权级规则如下:
也就是说,通过call和调用门,可以实现从低特权级转移到高特权级。


2.程序流程概览:

pmtest4这个程序,我们主要将讲解如何通过调用门实现,低特权级代码向高特权级别的代码转移——就像鲤鱼越龙“门”。


实模式初始段:初始化GDT中的相关数据,为进入保护模式做准备,通过一个长跳转jmp,进入保护模式
保护模式下32b代码段:打印初始化字符,通过调用门,进入目标代码段32b
目标代码段:打印字符C,然后通过retf指令,返回32b代码段
32b代码段:通过jmp,进入LDT中的codeA段,、
LDT中的codeA段:打印字符L,通过jmp指令,回到16b代码段
16b代码段:回到实模式下

通过以上分析,我们知道:只需要在pmtest3的代码中添加目标代码段和门描述符就可以了。

二、代码解惑



按照以往的惯例,我们仍然采用分段的方式,分析代码:


1.GDT中注意:

上述多了一个调用门的选择子和描述符,它也被放在GDT之中


2.调用门目标段中的retf指令和ret指令有哪些不同?
retf指令的意义
ret 弹出一个参数,给ip,返回
retf 弹出2个参数,一个给 ip,一个给 cs
iref 弹出 3个参数,一个给 ip,一个 给 cs ,一个 给 flag标志位
他们都是返回调用点的,看你调用的时候,用的什么调用的,是 call 段内转移 ,还是call 段间转移,还是int 调用中断。

3.对于实模式第一个段的分析:
1)、为什么需要在这里初始化各个段描述符的相关属性呢?
答:开始,没有进入保护模式。同时CS的值已经被刷新。目前,程序运行的代码已经被dos加载到内存的相关部分,GDT的表才刚刚落户,所以我们才刚刚得到GDT的基地址,所以我们在这个时候刷新各个段的描述符属性。
2)、为何要加载GDT?
加载GDT是能够进行保护模式寻址的关键,不然我们仅仅知道段选择子,还是没法找到段描述符。GDTR中包含32b段基地址和16b段限长,这一点我们已经在gdt段中定义过了。
3)、重新回到实模式以后,是否有必要刷新ds、es、ss、sp等?
这是程序编写的一般流程,即使不刷新,也不一定会产生错误,我们可以亲自尝试一下。

4.保护模式
1)、这个段完成了什么功能?
显示初始化的字符串;通过调用门完成打印字母‘C’;通过跳入局部任务,打印字母‘L’;定义了一个局部程序DisplayReturn
2)、为什么要在jmp之前,设置ldt?
和GDT的设定是同样的道理。

实际代码如下:

  1. %include    "head.inc"  
  2. org 0100h  
  3.     jmp LABEL_BEGIN  
  4.   
  5. [SECTION .gdt]  
  6. ;GDT                            base,   length, attr  
  7.   
  8. LABEL_GDT:      Descriptor         0,                0, 0   
  9. LABEL_DESC_NORMAL:  Descriptor      0,  0ffffh,     DA_DRW  
  10. LABEL_DESC_CODE16:  Descriptor      0,  0FFFFH,     DA_C  
  11. LABEL_DESC_DATA:    Descriptor      0,  SegDataLen-1,   DA_DRW  
  12. LABEL_DESC_STACK:   Descriptor      0,  TopOfStack,     DA_DRWA+DA_32  
  13. LABEL_DESC_CODE32:  Descriptor      0,  SegCode32Len-1, DA_C+DA_32  
  14. LABEL_DESC_CODE_DEST: Descriptor    0,  SegCodeDestLen-1,DA_C+DA_32  
  15. LABEL_DESC_LDT:     Descriptor      0,  LDTLen-1,   DA_LDT  
  16. LABEL_DESC_VIDEO:   Descriptor  0B8000h,    0ffffh, DA_DRW  
  17. LABEL_CALL_GATE_TEST:   Gate    SelectorCodeDest,0,0,DA_386CGate + DA_DPL0  
  18.   
  19. GdtLen  equ $-LABEL_GDT  
  20. GdtPtr  dw  GdtLen-1;注意,长度都是实际长度减1  
  21.         dd  0   ;段基地址,注意,这里之所以没有直接制定,是因为还没有确定保护模式下gdt的基地址  
  22.   
  23. ;选择子  
  24. SelectorData        equ     LABEL_DESC_DATA     -   LABEL_GDT     
  25. SelectorCode16      equ     LABEL_DESC_CODE16   -   LABEL_GDT  
  26. SelectorCode32      equ     LABEL_DESC_CODE32   -   LABEL_GDT  
  27. SelectorStack       equ     LABEL_DESC_STACK    -   LABEL_GDT   
  28. SelectorNormal      equ     LABEL_DESC_NORMAL   -   LABEL_GDT   
  29. SelectorLDT         equ     LABEL_DESC_LDT      -   LABEL_GDT   
  30. SelectorCodeDest    equ     LABEL_DESC_CODE_DEST -  LABEL_GDT   
  31. SelectorCallGateTest equ    LABEL_CALL_GATE_TEST -  LABEL_GDT   
  32. SelectorVideo       equ     LABEL_DESC_VIDEO    -   LABEL_GDT  
  33. ;end of section gdt  
  34. ;--------------------------------------------------------------  
  35. [SECTION .data]  
  36. [BITS 32]  
  37. ALIGN 32  
  38. LABEL_SEG_DATA:  
  39.     SPValueInRealModel  dw  0  
  40. PMMessage:      db      "Coming into protect mode now !",0  
  41. OffsetPMMessage equ PMMessage - $$  
  42. StrTest:        db  "ABCDEFGHIJKLMNOPQRSTUVWXYZ",   0  
  43. OffsetStrTest   equ StrTest - $$  
  44. SegDataLen          equ     $ - LABEL_SEG_DATA   
  45. ;end of section data  
  46. ;-----------------------------section:global stack------------------  
  47. [SECTION .gs]  
  48. ALIGN   32  
  49. [BITS 32]  
  50. LABEL_SEG_STACK:  
  51.     times   512 db  0  
  52. TopOfStack  equ $-LABEL_SEG_STACK-1  
  53. ;----------------------section:LDT----------------------------------  
  54. [SECTION .ldt]  
  55. align   32  
  56. [bits   32]  
  57. LABEL_SEG_LDT:  
  58.   
  59. LABEL_DESC_CODEA:   Descriptor  0,CodeALen -1,DA_C+DA_32  
  60.   
  61.   
  62. LDTLen      equ     $- LABEL_SEG_LDT  
  63.   
  64. SelectorCodeA   equ     LABEL_DESC_CODEA - LABEL_SEG_LDT + SA_TIL  
  65.   
  66. ;end of ldt segment  
  67. ;-------------------------------section:codeA------------------------  
  68. [section    .codeA]  
  69. align   32  
  70. [bits   32]   
  71. LABEL_SEG_CODEA:  
  72.     mov     ax,SelectorVideo  
  73.     mov     gs,ax  
  74.   
  75.     mov     ah,0ch  
  76.     mov     al,'L'  
  77.     mov     edi,(2*80+0)*2  
  78.     mov     [gs:edi],ax  
  79.     jmp     SelectorCode16:0  
  80. CodeALen equ    $-LABEL_SEG_CODEA   
  81. ;end of secion codeA  
  82. ;------------------------------section:s16 begin---------------------  
  83. [SECTION .s16]  
  84. [BITS 16]  
  85. LABEL_BEGIN:  
  86.     xchg    bx,bx  
  87.     mov     ax,cs  
  88.     mov     ds,ax  
  89.     mov     es,ax  
  90.     mov     ss,ax  
  91.     mov     sp,0100h  
  92.       
  93.     mov     [LABEL_GO_BACK_TO_REAL+3],ax  
  94.     mov     [SPValueInRealModel],sp  
  95.   
  96.     ;for segment code32  
  97.     xor     eax,eax  
  98.     mov     eax,cs  
  99.     shl     eax,4  
  100.     add     eax,LABEL_SEG_CODE32;  
  101.     mov     word    [LABEL_DESC_CODE32 +2],ax  
  102.     shr     eax,16  
  103.     mov     byte    [LABEL_DESC_CODE32 + 4],al  
  104.     mov     byte    [LABEL_DESC_CODE32 + 7],ah  
  105.   
  106.     ;for segment code16  
  107.     xor     eax,eax  
  108.     mov     ax,cs  
  109.     shl     eax,4  
  110.     add     eax,LABEL_SEG_CODE16;  
  111.     mov     word    [LABEL_DESC_CODE16 +2],ax  
  112.     shr     eax,16  
  113.     mov     byte    [LABEL_DESC_CODE16 + 4],al  
  114.     mov     byte    [LABEL_DESC_CODE16 + 7],ah  
  115.   
  116.     ;for segment data  
  117.     xor     eax,eax  
  118.     mov     eax,ds  
  119.     shl     eax,4  
  120.     add     eax,LABEL_SEG_DATA;  
  121.     mov     word    [LABEL_DESC_DATA +2],ax  
  122.     shr     eax,16  
  123.     mov     byte    [LABEL_DESC_DATA + 4],al  
  124.     mov     byte    [LABEL_DESC_DATA + 7],ah  
  125.   
  126.     ;for segment ldt  
  127.     xor     eax,eax  
  128.     mov     eax,ds  
  129.     shl     eax,4  
  130.     add     eax,LABEL_SEG_LDT;  
  131.     mov     word    [LABEL_DESC_LDT +2],ax  
  132.     shr     eax,16  
  133.     mov     byte    [LABEL_DESC_LDT + 4],al  
  134.     mov     byte    [LABEL_DESC_LDT + 7],ah  
  135.       
  136.     ;for segment codeA  
  137.     xor     eax,eax  
  138.     mov     eax,ds  
  139.     shl     eax,4  
  140.     add     eax,LABEL_SEG_CODEA;  
  141.     mov     word    [LABEL_DESC_CODEA  +2],ax  
  142.     shr     eax,16  
  143.     mov     byte    [LABEL_DESC_CODEA + 4],al  
  144.     mov     byte    [LABEL_DESC_CODEA + 7],ah  
  145.       
  146.     ;for segment stack  
  147.     xor     eax,eax  
  148.     mov     eax,ds  
  149.     shl     eax,4  
  150.     add     eax,LABEL_SEG_STACK;  
  151.     mov     word    [LABEL_DESC_STACK +2],ax  
  152.     shr     eax,16  
  153.     mov     byte    [LABEL_DESC_STACK+ 4],al  
  154.     mov     byte    [LABEL_DESC_STACK+ 7],ah  
  155.   
  156.     ;no need for video base  
  157.     ;for segment dstcode  
  158.     xor     eax,eax  
  159.     mov     ax,cs  
  160.     shl     eax,4  
  161.     add     eax,LABEL_SEG_CODE_DEST  
  162.     mov     word    [LABEL_DESC_CODE_DEST +2],ax  
  163.     shr     eax,16  
  164.     mov     byte    [LABEL_DESC_CODE_DEST +4],al  
  165.     mov     byte    [LABEL_DESC_CODE_DEST +7],ah  
  166.   
  167.     xor     eax,eax  
  168.     mov     ax,ds  
  169.     shl     eax,4  
  170.     add     eax, LABEL_GDT  
  171.     mov     dword   [GdtPtr +2 ],eax  
  172.   
  173.     lgdt    [GdtPtr]  
  174.   
  175.     cli  
  176.   
  177.     in      al,92h  
  178.     or      al,02h  
  179.     out     92h,al  
  180.   
  181.     mov     eax,cr0  
  182.     or      eax,1  
  183.     mov     cr0,eax  
  184.   
  185.     jmp     dword SelectorCode32:0  
  186.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
  187. LABEL_REAL_ENTRY:   ;come here from protect model  
  188.     mov     ax,cs  
  189.     mov     ds,ax  
  190.     mov     es,ax  
  191.     mov     ss,ax  
  192.   
  193.     mov     sp,[SPValueInRealModel]  
  194.   
  195.     in      al,92h  
  196.     and     al,11111101b  
  197.     out     92h,al  
  198.   
  199.     sti  
  200.   
  201.     mov     ax,4c00h  
  202.     int     21h  
  203. ;end of section .s16  
  204. ;------------------------section:code32,start of protect model--------  
  205. [SECTION .s32]  
  206. [BITS   32]  
  207. LABEL_SEG_CODE32:  
  208.         mov     ax,SelectorVideo  
  209.         mov     gs,ax  
  210.           
  211.         mov     ax,SelectorData  
  212.         mov     ds,ax  
  213.   
  214.   
  215.         mov     ax,SelectorStack  
  216.         mov     ss,ax  
  217.           
  218.         mov     esp,TopOfStack  
  219.   
  220.         mov     ah,0ch  
  221.         xor     esi,esi  
  222.         xor     edi,edi  
  223.         mov     esi,OffsetPMMessage  
  224.         mov     edi,(80*11+0)*2  
  225.         cld  
  226. .loopPmMessage:  
  227.         lodsb  
  228.         test    al,al  
  229.         jz  .end  
  230.         mov     [gs:edi],ax  
  231.         add     edi,2  
  232.         jmp .loopPmMessage  
  233.   
  234. .end:   ;  
  235.   
  236.         call    DispReturn  
  237.         call    SelectorCallGateTest:0  
  238.   
  239.         ;Load LDT  
  240.         mov     ax,SelectorLDT  
  241.         lldt    ax  
  242.               
  243.         jmp     SelectorCodeA:0   
  244.   
  245.   
  246. ;function: read and print 8 byte from es:0  
  247. TestRead:  
  248.         xor     esi,esi  
  249.         mov     ecx,8  
  250. .loopForEightBype:  
  251.         mov     al,[es:esi]  
  252.         call    DispAL  
  253.         inc     esi  
  254.         loop    .loopForEightBype  
  255.           
  256.         call    DispReturn  
  257.           
  258.         ret; be sure of this  
  259.   
  260. ;funtion:  
  261.     ;write 8byte to es:OffsetStrTest  
  262.     ;input:es  
  263. TestWrite:  
  264.         push    esi  
  265.         push    edi  
  266.       
  267.         xor     esi,esi  
  268.         xor     edi,edi  
  269.         mov     esi,OffsetStrTest  
  270.         cld  
  271.   
  272.     .loopForEightBype:  
  273.         lodsb   ;ds:si->al  
  274.         test    al,al  
  275.         jz  .end  
  276.         mov     [es:edi],al  
  277.         inc     edi  
  278.         jmp     .loopForEightBype  
  279.     .end:  
  280.         pop     edi  
  281.         pop     esi  
  282.   
  283.         ret  
  284.   
  285.   
  286. ;funtion DispAL  
  287. ;   display the number in AL  
  288. ;input: AL-the number  
  289. ;       edi-the position to display  
  290. ;modified:ax,edi  
  291. DispAL:  
  292.     push    ecx  
  293.     push    edx  
  294.     mov     ah,0ch  
  295.     mov     dl,al  
  296.     shr     al,4  
  297.     mov     ecx,2  
  298. .begin:  
  299.     and     al,01111b  
  300.     cmp     al,9  
  301.     ja      .moreThanNine  
  302.     add     al,'0'  
  303.     jmp     .end  
  304. .moreThanNine:  
  305.     sub     al,0ah  
  306.     add     al,'A'  
  307. .end:  
  308.     mov     [gs:edi],ax  
  309.     add     edi,2  
  310.   
  311.     mov     al,dl  
  312.     loop    .begin  
  313.     add     edi,2  
  314.   
  315.     pop     edx  
  316.     pop     ecx  
  317.           
  318.     ret  
  319. ;DispAL  
  320.   
  321. ;function DispReturn  
  322. ;if edi=(a*80 + b)*2  
  323. ;then edi=(a*80 + 80)*2  
  324. DispReturn:  
  325.     push    eax  
  326.     push    ebx  
  327.     mov     eax,edi   
  328.     mov     bl,160  
  329.     div     bl  
  330.     and     eax,0ffh;  
  331.     inc     eax  
  332.     mov     bl,160  
  333.     mul     bl  
  334.     mov     edi,eax  
  335.     pop     ebx  
  336.     pop     eax  
  337.   
  338.     ret  
  339. ;end for function DispReturn  
  340.     SegCode32Len    equ     $-LABEL_SEG_CODE32  
  341. ;end of section .s32  
  342.   
  343. ;---------------------section s16code,before return to real-----------  
  344.   
  345. [SECTION .s16code]  
  346. ALIGN   32  
  347. [BITS 16]  
  348. LABEL_SEG_CODE16:  
  349.     ;return to real model  
  350.     mov     ax,SelectorNormal   
  351.     mov     ds,ax  
  352.     mov     es,ax  
  353.     mov     fs,ax  
  354.     mov     gs,ax  
  355.     mov     ss,ax  
  356.   
  357.     mov     eax,cr0  
  358.     and al,11111110b  
  359.     mov     cr0,eax  
  360.   
  361. LABEL_GO_BACK_TO_REAL:  
  362.     jmp     0:LABEL_REAL_ENTRY;  
  363. Code16Len   equ $-LABEL_SEG_CODE16  
  364.   
  365. ;end of section s16code  
  366. ;---------------------section:sdest---------------------------------  
  367. [section    .sdest]  
  368. [bits   32]  
  369.   
  370. LABEL_SEG_CODE_DEST:  
  371.     mov     ax,SelectorVideo  
  372.     mov     gs,ax  
  373.   
  374.     mov     edi,(80*12+0)*2  
  375.     mov     ah,0ch  
  376.     mov     al,'C'  
  377.     mov     [gs:edi],ax  
  378.   
  379.     retf  
  380. SegCodeDestLen  equ     $-LABEL_SEG_CODE_DEST
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值