1 保护操作系统(5)(harib19a)

大家早上好。

在昨天的最后我们成功干掉了crack2.hrb,今天我们要尝试一下更厉害的攻击手段。所以说,从现在开始又要打开坏人模式了哟,嘿嘿嘿。

■■■■■

虽然把操作系统的段地址存入DS这一招现在已经不能用了,不过我可不会善罢甘休的。我要想个更厉害的招数,把使用“纸娃娃系统”的人推进恐怖的深渊,哈哈哈哈!

在操作系统管理的内存空间里搞破坏是行不通了,这次算你厉害,不过我还可以在定时器上动动手脚。这样一来,光标闪烁就会变得异常缓慢,任务切换的速度也会变慢,一定很不爽吧。嗯,光想想就觉得很有趣啊,嘿嘿嘿。

本次的crack3.nas

  1. [INSTRSET "i486p"]
  2. [BITS 32]
  3. MOV AL,0x34
  4. OUT 0x43,AL
  5. MOV AL,0xff
  6. OUT 0x40,AL
  7. MOV AL,0xff
  8. OUT 0x40,AL
  9. ; 上述代码的功能与下面代码相当
  10. ; io_out8(PIT_CTRL, 0x34);
  11. ; io_out8(PIT_CNT0, 0xff);
  12. ; io_out8(PIT_CNT0, 0xff);
  13. MOV EDX,4
  14. INT 0x40

好,完成了!赶紧“make run”,然后输入“crack3”,口中念念有词道:“可恶的‘纸娃娃系统’,吃我这招!”然后按下回车键。

1 保护操作系统(5)(harib19a) - 图1

可是失败了……

哎呀,有两下子嘛!可恶!

当以应用程序模式运行时,执行IN指令和OUT指令都会产生一般保护异常。当然,通过修改CPU设置,可以允许应用程序使用IN指令和OUT指令,不过这样大家会担心留下bug而遭到恶意攻击。

■■■■■

我还没输呢,这点挫折我可不会善罢甘休!既然如此,我就给你执行CLI然后再HLT,这样一来电脑就死机了。由于不再产生定时器中断,任务切换也会停止,键盘和鼠标中断也停止响应,除了按下机箱上的Reset按钮以外没有别的办法了。我真是个天才,哈哈哈哈!

本次的crack4.nas

  1. [INSTRSET "i486p"]
  2. [BITS 32]
  3. CLI
  4. fin:
  5. HLT
  6. JMP fin

这次一定要成功,“make run”!

1 保护操作系统(5)(harib19a) - 图2

又失败了……

又产生了异常,为什么啊!

当以应用程序模式运行时,执行CLI、STI和HLT这些指令都会产生异常。因为中断应该是由操作系统来管理的,应用程序不可以随便进行控制。不能执行HLT的话,应用程序就没办法省电了,不过一般情况下,这应该通过调用任务休眠API来实现,而不能由应用程序自己来执行HLT。此外,在多任务下,调用休眠API还可以让系统将CPU时间分配给其他任务。

连CLI也不让我执行吗?怎么会有这种事!这样的话不就干不成坏事了吗?难道只能缴械投降了?

哦哦,想起来了!操作系统里面不是有一个用来CLI的函数嘛,far-CALL这个函数不就行了吗?这样一来“纸娃娃系统”应该就会死机了。应该CALL哪个地址呢?只要有map文件就可以轻松找到了。

嗯嗯,map文件中有这样一行:

  1. 0x00000AC1 : _io_cli

我就来far-CALL这个地址吧,哈哈!

本次的crack5.nas

  1. [INSTRSET "i486p"]
  2. [BITS 32]
  3. CALL 2*8:0xac1
  4. MOV EDX,4
  5. INT 0x40

嘿嘿,准备接招吧,“make run”!

1 保护操作系统(5)(harib19a) - 图3

还是失败了……

又产生异常了!到底为啥呀!能不能让我赢一次啊!可恶!

如果应用程序可以CALL任意地址的话,像这样的恶作剧就可以成功了,因此CPU规定除了设置好的地址以外,禁止应用程序CALL其他的地址。因此,“纸娃娃系统”中应用程序要调用操作系统只能采用INT 0x40的方法。

■■■■■

于是坏人只好失望地洗洗睡了(笑)。3天后……

有了!这次应该能行,我怎么早没想到这个办法呢?哈哈,这次绝对可以成功!

既然应用程序只能调用API,那么把API修改一下不就行了吗?

本次的console.c节选

  1. int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
  2. {
  3. int cs_base = *((int *) 0xfe8);
  4. struct TASK *task = task_now();
  5. struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
  6. if (edx == 1) {
  7. cons_putchar(cons, eax & 0xff, 1);
  8. } else if (edx == 2) {
  9. cons_putstr0(cons, (char *) ebx + cs_base);
  10. } else if (edx == 3) {
  11. cons_putstr1(cons, (char *) ebx + cs_base, ecx);
  12. } else if (edx == 4) {
  13. return &(task->tss.esp0);
  14. } else if (edx == 123456789) { /*这里!*/
  15. *((char *) 0x00102600) = 0; /*这里!*/
  16. }
  17. return 0;
  18. }

嘿嘿嘿,改好了,然后只要写这样一个应用程序就行了。

本次的crack6.nas

  1. [INSTRSET "i486p"]
  2. [BITS 32]
  3. MOV EDX,123456789
  4. INT 0x40
  5. MOV EDX,4
  6. INT 0x40

好啦!准备接招吧,“make run”!

1 保护操作系统(5)(harib19a) - 图4

没有异常……

没有产生异常!不过到底成功了没有呢?dir一下看看……成功了,消失了耶!这次我赢了,哈哈!

如果操作系统内部存在这种蠢到作茧自缚的API,那么再优秀的CPU也对此无能为力,操作系统只能束手就擒。即使操作系统原本没有这样的API,如果像这次一样被篡改的话,也有可能被植入后门。

要防止这种问题的发生,我们只能 “不安装不可靠的操作系统”了。如果大家都能遵守这条原则,就不会因为随意下载应用程序而弄坏电脑了——当然,如果操作系统本身就破绽百出的话就另当别论了。

这次的crack6.hrb其实只能在使用 “改版纸娃娃系统”的人身上发挥效果。如果对方不安装“改版纸娃娃系统”的话,即便运行了这个应用程序也不会发生任何问题。因此,就目前而言,这个应用程序的受害者就只有这个坏人自己而已,从这个角度来说,他“赢”得还真是空虚啊。

■■■■■

现在坏人已经走了,接下来我们继续做系统吧。