📄 00000003.htm
字号:
dd 0,0,0,0,0 <BR> dw offset enter_v86,0000h ;EIP <BR> dd 00000200h ;EFlag <BR> dd 0,0,0,0 <BR> dd 0000ff00h ;ESP <BR> dd 0,0,0 <BR> dw 0010h,0000h ;ES.0 <BR> dw 0008h,0000h ;CS.0 <BR> dw 0028h,0000h ;SS.0 <BR> dw 0010h,0000h ;DS,0 <BR> dw 0010h,0000h ;FS.0 <BR> dw 0010h,0000h ;GS.0 <BR> dw 0000h,0000h ;LDT.0 <BR> dw 0000h,0068h ;0.IOMAP起点 <BR> db 1000h dup (0) ;4K IOMAP 表 <BR> dw 0ffffh <BR> <BR> <BR> 如果您的程式使用 JMP XXXX:YYYYYYYY 的方式跳到本区节的话 ,原本指定的 <BR>YYYYYYYY 将无用途 ,因为所有的暂存器将被替换成此表格的数值(含CS.EIP) ,并 <BR>完成等级切换的动作。 <BR> <BR> <BR>-------------------------------------------------------------------------- <BR>┌———————┐ <BR>│进入 V86 模式│ <BR>└———————┘ <BR> <BR> cli <BR> lgdt fword ptr cs:gdtadds <BR> lidt fword ptr cs:idtadds <BR> mov eax,cr0 <BR> or al,01h <BR> mov cr0,eax <BR> mov bx,0018h <BR> ltr bx ;发生工作切换时 ,SS:ESP 将参考 0018 的区段表格 <BR> jmp 0020h:0000h ;进入工作切换 ,会跳到此表格内指定的 CS:EIP <BR> (LTR.JMP 不可指向同一表格) <BR> <BR>enter_v86 : ;假设您已将 CS:EIP 指向此处继续执行 <BR> xor eax,eax <BR> mov ax,code <BR> push eax ;GS <BR> push eax ;FS <BR> push eax ;DS <BR> push eax ;ES <BR> push eax ;SS <BR> mov ax,0f000h <BR> push eax ;ESP <BR> mov eax,00023000h ;设定VM=1 等级=3 <BR> push eax ;Eflag <BR> xor eax,eax <BR> mov ax,code <BR> push eax ;CS <BR> mov ax,offset return_dos <BR> push eax ;EIP <BR> clts ;将 387 切换成 32 位元模式 <BR> iretd ;回到 V86 (共弹出24h BYTE) <BR> <BR>紧接著就程式回到 V86 下继续执行著... <BR>-------------------------------------------------------------------------- <BR>┌————————┐ <BR>│中断向量表的处理│ <BR>└————————┘ <BR> 在 V86 下产生中断後 ,电脑会自动切回保护模式 ,并从 LTR 所指定的位址取得 <BR>TSS 表格 ,然後以表格内的资料重新设定 SS.ESP ,然後把 V86 下的各暂存器值摆入 <BR>此堆叠内 ,在此需注意的是它摆放在堆叠的资料是32位元方式 ,所以对於 DS.ES.... <BR>这类16位元暂存器摆於堆叠 ,不足部份补 '0000' ,用以凑足 32Bit。 <BR> <BR> 简单来说 ,在真实模式下或 V86下使用一组 SS:SP ,一但透过中断进入保护模式 <BR>後 ,原先的 SS:SP 暂存器将被置换另一组数值(定义於TSS表) ,然後再将大部份的暂 <BR>存器值摆放在这个新堆叠区内(包含SS.ESP) ,直到执行 IRETD 回到 V86 後 ,SS:ESP <BR>暂存器值才会从原先堆叠中弹出。换句话说 ,在 V86下发生中断会使用自己的堆叠 , <BR>而不会破坏 V86 的堆叠区 ,这也就是为什麽像 S-ICE 除错程式执行 'T' 的命令却 <BR>不会更动 User 的堆叠资料。 <BR> <BR> 存於保护模式堆叠内的 CS:EIP 会指向 V86下 "INT_X" 的下一行 ,而 SS:SP 值 <BR>却仍维持原来数值(不像以往产生中断会自动减6 ,然後堆叠内摆入 FLAG.CS.IP),因 <BR>此保护模式下处理中断的程式必需修改 V86 的 SP 值减6 ,并将 V86 的 CS.IP.FLAG <BR>摆入 V86 的堆叠 ,最後再去查 0000:0000 的表格 ,将保护模式堆叠内的 CS:EIP 值 <BR>修改、指向此中断向量表 ,最後保护模式的程式执行 IRETD 返回 V86 後 ,跳到 V86 <BR>下的中断所指位址 ,这样便完成整个模拟 DOS 中断的效果。 <BR> <BR>PS:保护模式下堆叠会存放 EFLAG.EIP.ECS.ESP.SS...... 忘了 ,比 Real Mode 还要 <BR> 多好多喔。 <BR> <BR> 底下仅列出部份中断的处理方式....您必需处理 256 个中断表。 <BR> <BR>new_20 : <BR> push 0020h <BR> jmp int_emu <BR>new_21 : <BR> push 0021h <BR> jmp int_emu <BR>new_22 : <BR> push 0022h <BR> jmp int_emu <BR>new_23 : <BR> push 0023h <BR> jmp int_emu <BR> <BR>int_emu : <BR> push bp <BR> mov bp,sp <BR> add bp,04h <BR> push eax <BR> push ebx <BR> mov ax,0010h ; <BR> mov ds,ax ;(Selector 0010h 的 Base=0) <BR> mov ax,ss:[bp+0ch] ; <BR> sub ax,06h ;改V86的SP-6 <BR> mov ss:[bp+0ch],ax ; <BR> xor eax,eax ; <BR> xor ebx,ebx ;修改V86下的SS:SP ,帮它摆入 <BR> mov ax,ss:[bp+10h] ;INT_X 後的下一行位址 ,供V86 <BR> shl eax,04h ;下的程式IRET返回INT_X的下一行用 <BR> mov bx,ss:[bp+0ch] ; <BR> add ebx,eax ; <BR> mov ax,ss:[bp+00h] ; <BR> mov ds:[ebx],ax ; <BR> mov ax,ss:[bp+04h] ; <BR> mov ds:[ebx+02h],ax ; <BR> mov ax,ss:[bp+08h] ; <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -