- 论坛徽章:
- 0
|
有个项目在困扰着我,因为是别人遗留的项目,因此只得自己参详(也没有具体源码),具体如下:
- ========
- 例子1
- ========
- 编写一个函数库,提供对特殊代码的处理,且这个函数库里的函数可以被其他应用程序调用。遗留的设计(下面通过例子简要说明)如下:
- 假设待编写的函数库名为 obj_lib,使用obj_lib的应用程序名为 host_app ,待处理的代码名为 un_code 和 其处理后的结果 obj_code。当host_app要处理un_code时,它会调用obj_lib里的函数在host_app的内存空间里动态创建2个段,一个用来存放un_code,另一个用来存放obj_code。这2个段对应的描述符都将保存于LDT里。处理过程中,host_app会分析un_code,并将分析结果放入obj_code中(即放入第二个段里)。最后,host_app执行obj_code里的代码。
复制代码 问题如下:
1、为何要动态创建2个段来存放un_code及obj_code?按设计上说是这样可以进行段边界检测。即在执行obj_code的过程中,如果存在jmp的转移指令,则可以通过段界限去检测这个转移是否合法。对于段界限的检测,我以前只是知道有这么一回事,但从来没有去试验过。翻了一下资料,找到了一个例子,如下:
- ========
- 例子2
- ========
- //定义
- L_G : DESC 0, 0, 0
- L_CODE : DESC 0, lencode - 1, DA_C + DA_32
- L_VIDEO : DESC 0B8000h, 0ffffh, DA_DRW
- GLEN equ $ - L_G
- GPTR dw GLEN - 1
- dd 0
- selector_v equ L_VIDEO - L_G
- ........
- //配置
- mov ax, cs
- movzx eax, ax
- shl eax, 4
- add eax, L_CODE
- mov word [L_CODE + 2], ax
- shr eax, 16
- mov byte [L_CODE + 4], al
- mov byte [L_CODE + 7], ah
- ......
- //加载GDT
- xor eax, eax
- mov ax, ds
- shl eax, 4
- add eax, L_G ; eax <- gdt 基地址
- mov dword [GPTR + 2], eax ; [GPTR + 2] <- gdt 基地址
- lgdt [GPTR]
- .....
- //在保护模式里,配置视频段
- mov ax, selector_v
- mov gs, ax
- .....
- //用于测试视频段的函数片段
- ......
- xor edi, edi
- ......
- .1:
- lodsb
- test al, al
- jz .2
- mov [gs:edi], ax
- add edi, 2
- jmp .1
- .2: ; 显示完毕
- ......
-
复制代码 例子2对于视频段,对应的描述符为L_VIDEO,选择子为selector_v,而配置给视频段的是段寄存器gs,而显示输出的偏移为edi。由于显示的范围在描述符里已设定,即 0 <= edi <= 0ffffh。因此,edi不能显示0b8000:0ffff之后的内容(如果edi大于0ffffh,是简单的不显示还是出现异常报错?这个我还没有测试过)。视频段的例子与之前的un_code的段应该是差不多的,都是对数据的检测。不知道我理解的对不对?
2、例子2的代码段,其描述符为L_CODE,对应的段寄存器为CS,其段界限为lencode - 1。则对于代码段里的每条指令,其唯一的检索是CS:EIP。如果存在指令 JMP A,则A的范围为 cs:0 <= A <= cs:lencode - 1。那也就是在算界限的时候,必须使用到CS,不能简单地像视频段一样使用gs或fs。再说的清楚一点,对于之前的例子里的 obj_code段来说(跟这里的代码段是类似的),obj_code段必须是可以单独获得CPU调度的段,它的EIP是从0开始算的。即,如果host_app是系统里众多进程里的一个,那obj_code则是它的一个线程,可以被单独调度,拥有单独的EIP。否则,如果obj_code不是被单独调度的话,那它的首指令的EIP就不是0,而是obj_code首指令基于host_app的偏移。这样的偏移是无法通过obj_code里的段界限去约束obj_code段里的转移语句是否合法的。
也就是说,例子1成立的前提是运行在多线程环境里,且obj_code段对应一个线程,是可以被单独调度的。是这样吗?
3、如果以上都不对的话,那想请教该如何理解段界限的检测? |
|