;屏蔽所有可屏蔽中断-关掉所有8259中断
mov al,0xff ;mask all interrupts for now
out 0xA1,al
out 0x80,al ;Delay is needed after doing I/O
;mov al,0xFB ; mask all irq‘s but irq2 which
;out 0x21,al
;out 0x80,al ;Delay is needed after doing I/O
; 保证所有的协处理都被正确的Reset
xor ax, ax
out 0xf0,al
out 0x80,al ;Delay is needed after doing I/O
out 0xf1,al
out 0x80,al ;Delay is needed after doing I/O
;屏蔽所有可屏蔽中断-关掉所有8259中断
mov al,0xff ;mask all interrupts for now
out 0xA1,al
out 0x80,al ;Delay is needed after doing I/O
;mov al,0xFB ; mask all irq‘s but irq2 which
;out 0x21,al
;out 0x80,al ;Delay is needed after doing I/O
; 保证所有的协处理都被正确的Reset
xor ax, ax
out 0xf0,al
out 0x80,al ;Delay is needed after doing I/O
out 0xf1,al
out 0x80,al ;Delay is needed after doing I/O
;进入32位模式 ;//CR0寄存器的PE位
mov ax,1
LMSW ax
jmp dword CS_SELECTOR:kernel_start
dw 0
kernel_start: ;启动内核
db 0xB9,0x00,0x00,0x50,0x00,0x66,0xC7,0x01,0x89,0xC8,0xFF,0xE1
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
注意:
db 0xB9,0x00,0x00,0x50,0x00,0x66,0xC7,0x01,0x89,0xC8,0xFF,0xE1
其实就是跳入保护模式的32位汇编,如果用bin编译出来就有点乱套了
对应的代码就是
MOV ECX,500000
MOV WORD PTR DS:[ECX],0C889
JMP ECX
然后自以为就okay了,编译后并入img后,装入bochs进行调试,意外发生了,
当单步执行到MOV WORD PTR DS:[ECX],0C889,灾难发生了,bochs跳转到起始处
(0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b
也就是说咱们刚初生的系统夭折了,经过反复测试,一条条比对,测试,终于知道了隐藏在深处的原因,因为我们装入的段是代码段有可读和可执行的权限,我们需要写的权限,但没有,我们的第二个代码段有这个权限,这时猜测需要将数据段装入cs和ds段,装入后写完病毒,再将第一个有执行权限的代码段装入,就okay了,结果是猜测是完全正确的。
bochs命令行命令如下:
b 0x7c00
c
u 0x7c00 0x7c90
b 0x7c57
c
s
s
u 0x7c64 0x7c80
set cs=0x10
set ds=0x10
s
s
set cs=8
set ds=8
s
终于我们看见了我们之前写入的久违的病毒代码
(0) [0x00500000] 0008:0000000000500000 (unk. ctxt): mov eax, ecx ;
注意gdt第二条索引是0x10000,即16
okay,我们制作了病毒,并将其装入特定的大内存处,并跳转成功。
至于在程序中将代码段转换留给大家做练习。 未完待续
;屏蔽所有可屏蔽中断-关掉所有8259中断
mov al,0xff ;mask all interrupts for now
out 0xA1,al
out 0x80,al ;Delay is needed after doing I/O
;mov al,0xFB ; mask all irq‘s but irq2 which
;out 0x21,al
;out 0x80,al ;Delay is needed after doing I/O
; 保证所有的协处理都被正确的Reset
xor ax, ax
out 0xf0,al
out 0x80,al ;Delay is needed after doing I/O
out 0xf1,al
out 0x80,al ;Delay is needed after doing I/O
;进入32位模式 ;//CR0寄存器的PE位
mov ax,1
LMSW ax
jmp dword CS_SELECTOR:kernel_start
dw 0
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
kernel_start: ;占位符,会放置c语言编译后的代码
db 0
;屏蔽所有可屏蔽中断-关掉所有8259中断
mov al,0xff ;mask all interrupts for now
out 0xA1,al
out 0x80,al ;Delay is needed after doing I/O
;mov al,0xFB ; mask all irq‘s but irq2 which
;out 0x21,al
;out 0x80,al ;Delay is needed after doing I/O
; 保证所有的协处理都被正确的Reset
xor ax, ax
out 0xf0,al
out 0x80,al ;Delay is needed after doing I/O
out 0xf1,al
out 0x80,al ;Delay is needed after doing I/O
/* Light gray text on a black background. */
#define DEFAULT_TEXT_ATTR GFX_ATTR(GFX_LIGHT_GRAY, GFX_BLACK, GFX_STATIC)
/*
* Clears the screen.
*/
void gfx_cls(void)
{
int i;
for (i = 0; i < SCREEN_ROWS * SCREEN_COLS; i++) {
*(VIDEO + 2*i) = 0;
*(VIDEO + 2*i + 1) = DEFAULT_TEXT_ATTR;
}
}
/*
* Writes the specified character at the specified position.
* Does NOT handle scrolling.
* Does NOT move the cursor.
*/
void videomem_putchar(char c, int row, int col, uint8_t textattr)
{
int idx = 2 * (row * SCREEN_COLS + col);
*(VIDEO + idx) = c;
*(VIDEO + idx + 1) = textattr;
}
/*
* Writes the specified string starting at the specified position.
* The string must be NULL terminated.
* Does NOT handle scrolling.
* Does NOT move the cursor.
*/
void videomem_putstring(char *s, int row, int col, uint8_t textattr)
{
char c;
int i = row * SCREEN_COLS + col;
while ((c = *s++) != '\0')
{
if (i < 0 || i >= SCREEN_ROWS * SCREEN_COLS)
break;
*(VIDEO + 2*i) = c;
*(VIDEO + 2*i + 1) = textattr;
i++;
}
}