免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2585 | 回复: 1
打印 上一主题 下一主题

段界限检查 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-15 12:31 |只看该作者 |倒序浏览
有个项目在困扰着我,因为是别人遗留的项目,因此只得自己参详(也没有具体源码),具体如下:

  1. ========
  2. 例子1
  3. ========

  4. 编写一个函数库,提供对特殊代码的处理,且这个函数库里的函数可以被其他应用程序调用。遗留的设计(下面通过例子简要说明)如下:

  5. 假设待编写的函数库名为 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的转移指令,则可以通过段界限去检测这个转移是否合法。对于段界限的检测,我以前只是知道有这么一回事,但从来没有去试验过。翻了一下资料,找到了一个例子,如下:

  1. ========
  2. 例子2
  3. ========

  4. //定义
  5. L_G        :        DESC                0,             0,        0
  6. L_CODE        :        DESC                0, lencode - 1,        DA_C + DA_32
  7. L_VIDEO        :         DESC          0B8000h,          0ffffh,        DA_DRW

  8. GLEN        equ        $ - L_G
  9. GPTR        dw        GLEN - 1
  10.         dd        0

  11. selector_v        equ        L_VIDEO        - L_G

  12. ........

  13. //配置
  14.         mov        ax, cs
  15.         movzx        eax, ax
  16.         shl        eax, 4
  17.         add        eax, L_CODE
  18.         mov        word [L_CODE + 2], ax
  19.         shr        eax, 16
  20.         mov        byte [L_CODE + 4], al
  21.         mov        byte [L_CODE + 7], ah

  22. ......

  23. //加载GDT
  24.         xor        eax, eax
  25.         mov        ax, ds
  26.         shl        eax, 4
  27.         add        eax, L_G                ; eax <- gdt 基地址
  28.         mov        dword [GPTR + 2], eax        ; [GPTR + 2] <- gdt 基地址

  29.         lgdt        [GPTR]

  30. .....

  31. //在保护模式里,配置视频段
  32.         mov        ax, selector_v
  33.         mov        gs, ax

  34. .....

  35. //用于测试视频段的函数片段
  36. ......
  37.         xor        edi, edi
  38. ......
  39. .1:
  40.         lodsb
  41.         test        al, al
  42.         jz        .2
  43.         mov        [gs:edi], ax
  44.         add        edi, 2
  45.         jmp        .1
  46. .2:        ; 显示完毕

  47. ......
  48.        
复制代码
例子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、如果以上都不对的话,那想请教该如何理解段界限的检测?

论坛徽章:
0
2 [报告]
发表于 2011-08-15 12:34 |只看该作者
回复 1# shellmic


    顶
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP