摘要:本节,我们将通过分析pmtest4来实现利用调用门进行段间转移。
一、背景与原理
在汇编语言中,我们不能执行这样的指令:mov ds 100h和mov cs,ax;也就是说,段寄存器的值,是不能像通用寄存器一样,随意赋值的。具体的cs寄存器而言,它涉及到程序的控制转移,需要借助jmp、call、ret、sysenter,sysexit,int n,iret来实现,或者通过中断和异常来完成。我们知道,jmp和call指令,实现的跳转形式如下jmp selector:offset,其中,selector可以指向:
2.程序流程概览:
pmtest4这个程序,我们主要将讲解如何通过调用门实现,低特权级代码向高特权级别的代码转移——就像鲤鱼越龙“门”。
1.GDT中注意:
上述多了一个调用门的选择子和描述符,它也被放在GDT之中
实际代码如下:
%include "head.inc" org 0100h jmp LABEL_BEGIN [SECTION .gdt] ;GDT base, length, attr LABEL_GDT: Descriptor 0, 0, 0 LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW LABEL_DESC_CODE16: Descriptor 0, 0FFFFH, DA_C LABEL_DESC_DATA: Descriptor 0, SegDataLen-1, DA_DRW LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA+DA_32 LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32 LABEL_DESC_CODE_DEST: Descriptor 0, SegCodeDestLen-1,DA_C+DA_32 LABEL_DESC_LDT: Descriptor 0, LDTLen-1, DA_LDT LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW LABEL_CALL_GATE_TEST: Gate SelectorCodeDest,0,0,DA_386CGate + DA_DPL0 GdtLen equ $-LABEL_GDT GdtPtr dw GdtLen-1;注意,长度都是实际长度减1 dd 0 ;段基地址,注意,这里之所以没有直接制定,是因为还没有确定保护模式下gdt的基地址 ;选择子 SelectorData equ LABEL_DESC_DATA - LABEL_GDT SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT SelectorStack equ LABEL_DESC_STACK - LABEL_GDT SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT SelectorLDT equ LABEL_DESC_LDT - LABEL_GDT SelectorCodeDest equ LABEL_DESC_CODE_DEST - LABEL_GDT SelectorCallGateTest equ LABEL_CALL_GATE_TEST - LABEL_GDT SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT ;end of section gdt ;-------------------------------------------------------------- [SECTION .data] [BITS 32] ALIGN 32 LABEL_SEG_DATA: SPValueInRealModel dw 0 PMMessage: db "Coming into protect mode now !",0 OffsetPMMessage equ PMMessage - $$ StrTest: db "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 OffsetStrTest equ StrTest - $$ SegDataLen equ $ - LABEL_SEG_DATA ;end of section data ;-----------------------------section:global stack------------------ [SECTION .gs] ALIGN 32 [BITS 32] LABEL_SEG_STACK: times 512 db 0 TopOfStack equ $-LABEL_SEG_STACK-1 ;----------------------section:LDT---------------------------------- [SECTION .ldt] align 32 [bits 32] LABEL_SEG_LDT: LABEL_DESC_CODEA: Descriptor 0,CodeALen -1,DA_C+DA_32 LDTLen equ $- LABEL_SEG_LDT SelectorCodeA equ LABEL_DESC_CODEA - LABEL_SEG_LDT + SA_TIL ;end of ldt segment ;-------------------------------section:codeA------------------------ [section .codeA] align 32 [bits 32] LABEL_SEG_CODEA: mov ax,SelectorVideo mov gs,ax mov ah,0ch mov al,'L' mov edi,(2*80+0)*2 mov [gs:edi],ax jmp SelectorCode16:0 CodeALen equ $-LABEL_SEG_CODEA ;end of secion codeA ;------------------------------section:s16 begin--------------------- [SECTION .s16] [BITS 16] LABEL_BEGIN: xchg bx,bx mov ax,cs mov ds,ax mov es,ax mov ss,ax mov sp,0100h mov [LABEL_GO_BACK_TO_REAL+3],ax mov [SPValueInRealModel],sp ;for segment code32 xor eax,eax mov eax,cs shl eax,4 add eax,LABEL_SEG_CODE32; mov word [LABEL_DESC_CODE32 +2],ax shr eax,16 mov byte [LABEL_DESC_CODE32 + 4],al mov byte [LABEL_DESC_CODE32 + 7],ah ;for segment code16 xor eax,eax mov ax,cs shl eax,4 add eax,LABEL_SEG_CODE16; mov word [LABEL_DESC_CODE16 +2],ax shr eax,16 mov byte [LABEL_DESC_CODE16 + 4],al mov byte [LABEL_DESC_CODE16 + 7],ah ;for segment data xor eax,eax mov eax,ds shl eax,4 add eax,LABEL_SEG_DATA; mov word [LABEL_DESC_DATA +2],ax shr eax,16 mov byte [LABEL_DESC_DATA + 4],al mov byte [LABEL_DESC_DATA + 7],ah ;for segment ldt xor eax,eax mov eax,ds shl eax,4 add eax,LABEL_SEG_LDT; mov word [LABEL_DESC_LDT +2],ax shr eax,16 mov byte [LABEL_DESC_LDT + 4],al mov byte [LABEL_DESC_LDT + 7],ah ;for segment codeA xor eax,eax mov eax,ds shl eax,4 add eax,LABEL_SEG_CODEA; mov word [LABEL_DESC_CODEA +2],ax shr eax,16 mov byte [LABEL_DESC_CODEA + 4],al mov byte [LABEL_DESC_CODEA + 7],ah ;for segment stack xor eax,eax mov eax,ds shl eax,4 add eax,LABEL_SEG_STACK; mov word [LABEL_DESC_STACK +2],ax shr eax,16 mov byte [LABEL_DESC_STACK+ 4],al mov byte [LABEL_DESC_STACK+ 7],ah ;no need for video base ;for segment dstcode xor eax,eax mov ax,cs shl eax,4 add eax,LABEL_SEG_CODE_DEST mov word [LABEL_DESC_CODE_DEST +2],ax shr eax,16 mov byte [LABEL_DESC_CODE_DEST +4],al mov byte [LABEL_DESC_CODE_DEST +7],ah xor eax,eax mov ax,ds shl eax,4 add eax, LABEL_GDT mov dword [GdtPtr +2 ],eax lgdt [GdtPtr] cli in al,92h or al,02h out 92h,al mov eax,cr0 or eax,1 mov cr0,eax jmp dword SelectorCode32:0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LABEL_REAL_ENTRY: ;come here from protect model mov ax,cs mov ds,ax mov es,ax mov ss,ax mov sp,[SPValueInRealModel] in al,92h and al,11111101b out 92h,al sti mov ax,4c00h int 21h ;end of section .s16 ;------------------------section:code32,start of protect model-------- [SECTION .s32] [BITS 32] LABEL_SEG_CODE32: mov ax,SelectorVideo mov gs,ax mov ax,SelectorData mov ds,ax mov ax,SelectorStack mov ss,ax mov esp,TopOfStack mov ah,0ch xor esi,esi xor edi,edi mov esi,OffsetPMMessage mov edi,(80*11+0)*2 cld .loopPmMessage: lodsb test al,al jz .end mov [gs:edi],ax add edi,2 jmp .loopPmMessage .end: ; call DispReturn call SelectorCallGateTest:0 ;Load LDT mov ax,SelectorLDT lldt ax jmp SelectorCodeA:0 ;function: read and print 8 byte from es:0 TestRead: xor esi,esi mov ecx,8 .loopForEightBype: mov al,[es:esi] call DispAL inc esi loop .loopForEightBype call DispReturn ret; be sure of this ;funtion: ;write 8byte to es:OffsetStrTest ;input:es TestWrite: push esi push edi xor esi,esi xor edi,edi mov esi,OffsetStrTest cld .loopForEightBype: lodsb ;ds:si->al test al,al jz .end mov [es:edi],al inc edi jmp .loopForEightBype .end: pop edi pop esi ret ;funtion DispAL ; display the number in AL ;input: AL-the number ; edi-the position to display ;modified:ax,edi DispAL: push ecx push edx mov ah,0ch mov dl,al shr al,4 mov ecx,2 .begin: and al,01111b cmp al,9 ja .moreThanNine add al,'0' jmp .end .moreThanNine: sub al,0ah add al,'A' .end: mov [gs:edi],ax add edi,2 mov al,dl loop .begin add edi,2 pop edx pop ecx ret ;DispAL ;function DispReturn ;if edi=(a*80 + b)*2 ;then edi=(a*80 + 80)*2 DispReturn: push eax push ebx mov eax,edi mov bl,160 div bl and eax,0ffh; inc eax mov bl,160 mul bl mov edi,eax pop ebx pop eax ret ;end for function DispReturn SegCode32Len equ $-LABEL_SEG_CODE32 ;end of section .s32 ;---------------------section s16code,before return to real----------- [SECTION .s16code] ALIGN 32 [BITS 16] LABEL_SEG_CODE16: ;return to real model mov ax,SelectorNormal mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax mov eax,cr0 and al,11111110b mov cr0,eax LABEL_GO_BACK_TO_REAL: jmp 0:LABEL_REAL_ENTRY; Code16Len equ $-LABEL_SEG_CODE16 ;end of section s16code ;---------------------section:sdest--------------------------------- [section .sdest] [bits 32] LABEL_SEG_CODE_DEST: mov ax,SelectorVideo mov gs,ax mov edi,(80*12+0)*2 mov ah,0ch mov al,'C' mov [gs:edi],ax retf SegCodeDestLen equ $-LABEL_SEG_CODE_DEST