保护操作系统(4)

This commit is contained in:
Yourtion
2016-05-04 18:57:39 +08:00
parent 4241eb28d8
commit e846dbd700
12 changed files with 98 additions and 244 deletions

View File

@@ -68,7 +68,7 @@ haribote.sys : asmhead.bin bootpack.hrb Makefile
copy /B asmhead.bin+bootpack.hrb haribote.sys
crack1.bim : crack1.obj Makefile
$(OBJ2BIM) @$(RULEFILE) out:crack1.bim map:crack1.map crack1.obj
$(OBJ2BIM) @$(RULEFILE) out:crack1.bim map:crack1.map crack1.obj a_nask.obj
crack1.hrb : crack1.bim Makefile
$(BIM2HRB) crack1.bim crack1.hrb 0
@@ -90,7 +90,7 @@ haribote.img : ipl10.bin haribote.sys Makefile \
copy from:crack1.hrb to:@: \
copy from:crack2.hrb to:@: \
imgout:haribote.img
# 其他指令
%.gas : %.c bootpack.h Makefile

View File

@@ -1,7 +1,8 @@
void api_putchar(int c);
void api_end(void);
void HariMain(void)
{
api_putchar('A');
return;
api_end();
}

View File

@@ -4,6 +4,7 @@
[FILE "a_nask.nas"] ; 源文件名信息
GLOBAL _api_putchar
GLOBAL _api_end
[SECTION .text]
@@ -12,3 +13,6 @@ _api_putchar: ; void api_putchar(int c);
MOV AL,[ESP+4] ; c
INT 0x40
RET
_api_end: ; void api_end(void);
MOV EDX,4
INT 0x40

View File

@@ -33,7 +33,7 @@ unsigned int memtest_sub(unsigned int start, unsigned int end);
void farjmp(int eip, int cs);
void farcall(int eip, int cs);
void asm_hrb_api(void);
void start_app(int eip, int cs, int esp, int ds);
void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
/* fifo.c */
struct FIFO32 {
@@ -247,8 +247,8 @@ void cmd_cls(struct CONSOLE *cons);
void cmd_dir(struct CONSOLE *cons);
void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline);
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline);
void hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax);
int inthandler0d(int *esp);
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax);
int *inthandler0d(int *esp);
/* file.c */
struct FILEINFO {

View File

@@ -237,7 +237,6 @@ void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline)
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
struct FILEINFO *finfo = file_search(cmdline + 5, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
char *p;
int i;
if (finfo != 0) {
/*找到文件的情况*/
p = (char *) memman_alloc_4k(memman, finfo->size);
@@ -258,6 +257,7 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
struct FILEINFO *finfo;
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
char name[18], *p, *q;
struct TASK *task = task_now();
int i;
/*根据命令行生成文件名*/
@@ -287,8 +287,8 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
q = (char *) memman_alloc_4k(memman, 64 * 1024);
*((int *) 0xfe8) = (int) p;
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER);
set_segmdesc(gdt + 1004, 64 * 1024 - 1, (int) q, AR_DATA32_RW);
set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60);
set_segmdesc(gdt + 1004, 64 * 1024 - 1, (int) q, AR_DATA32_RW + 0x60);
if (finfo->size >= 8 && strncmp(p + 4, "Hari", 4) == 0) {
p[0] = 0xe8;
p[1] = 0x16;
@@ -297,7 +297,7 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
p[4] = 0x00;
p[5] = 0xcb;
}
start_app(0, 1003 * 8, 64 * 1024, 1004 * 8);
start_app(0, 1003 * 8, 64 * 1024, 1004 * 8, &(task->tss.esp0));
memman_free_4k(memman, (int) p, finfo->size);
memman_free_4k(memman, (int) q, 64 * 1024);
cons_newline(cons);
@@ -307,9 +307,10 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
return 0;
}
void hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
{
int cs_base = *((int *) 0xfe8);
struct TASK *task = task_now();
struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
if (edx == 1) {
cons_putchar(cons, eax & 0xff, 1);
@@ -317,13 +318,16 @@ void hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int
cons_putstr0(cons, (char *) ebx + cs_base);
} else if (edx == 3) {
cons_putstr1(cons, (char *) ebx + cs_base, ecx);
} else if (edx == 4) {
return &(task->tss.esp0);
}
return;
return 0;
}
int inthandler0d(int *esp)
int *inthandler0d(int *esp)
{
struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
cons_putstr0(cons, "¥nINT 0D :¥n General Protected Exception.¥n");
return 1; /*强制结束程序*/
struct TASK *task = task_now();
cons_putstr0(cons, "\nINT 0D :\n General Protected Exception.\n");
return &(task->tss.esp0); /*强制结束程序*/
}

View File

@@ -1,5 +1,7 @@
void api_end(void);
void HariMain(void)
{
*((char *) 0x00102600) = 0;
return;
}
api_end();
}

View File

@@ -3,4 +3,5 @@
MOV EAX,1*8 ; OS用的段号
MOV DS,AX ; 将其存入DS
MOV BYTE [0x102600],0
RETF
MOV EDX,4
INT 0x40

View File

@@ -28,7 +28,7 @@ void init_gdtidt(void)
set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x40, (int) asm_hrb_api, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x40, (int) asm_hrb_api, 2 * 8, AR_INTGATE32 + 0x60);
return;
}

View File

@@ -10,6 +10,7 @@ putloop:
ADD ECX,1
JMP putloop
fin:
RETF
MOV EDX,4
INT 0x40
msg:
DB "hello",0

View File

@@ -3,6 +3,7 @@
MOV EDX,2
MOV EBX,msg
INT 0x40
RETF
MOV EDX,4
INT 0x40
msg:
DB "hello",0

View File

@@ -1,4 +1,5 @@
void api_putchar(int c);
void api_end(void);
void HariMain(void)
{
@@ -7,5 +8,5 @@ void HariMain(void)
api_putchar('l');
api_putchar('l');
api_putchar('o');
return;
api_end();
}

View File

@@ -118,77 +118,29 @@ _asm_inthandler20:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler20
ADD ESP,8
MOV EAX,ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler20
POP EAX
POPAD
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler20
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
POP DS
POP ES
IRETD
_asm_inthandler21:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler21
ADD ESP,8
POPAD
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler21
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
@@ -198,37 +150,13 @@ _asm_inthandler27:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler27
ADD ESP,8
POPAD
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX ],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler27
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
@@ -238,38 +166,13 @@ _asm_inthandler2c:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app
; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler2c
ADD ESP,8
POPAD
POP DS
POP ES
IRETD
.from_app:
; 当应用程序活动时发生中断
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存中断时的SS
MOV [ECX ],ESP ; 保存中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
CALL _inthandler2c
POP ECX
POP EAX
MOV SS,AX ; 将SS设回应用程序用
MOV ESP,ECX ; 将ESP设回应用程序用
POPAD
POP DS
POP ES
@@ -280,61 +183,20 @@ _asm_inthandler0d:
PUSH ES
PUSH DS
PUSHAD
MOV AX,SS
CMP AX,1*8
JNE .from_app
; 当操作系统活动时产生中断的情况和之前差不多
MOV EAX,ESP
PUSH SS ; 保存中断时的SS
PUSH EAX ; 保存中断时的ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler0d
ADD ESP,8
POPAD
POP DS
POP ES
ADD ESP,4 ; 在INT 0x0d中需要这句
IRETD
.from_app:
; 当应用程序活动时产生中断
CLI
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统的ESP
ADD ECX,-8
MOV [ECX+4],SS ; 保存产生中断时的SS
MOV [ECX ],ESP ; 保存产生中断时的ESP
MOV SS,AX
MOV ES,AX
MOV ESP,ECX
STI
CALL _inthandler0d
CLI
CMP EAX,0
JNE .kill
POP ECX
CMP EAX,0
JNE end_app
POP EAX
MOV SS,AX ; 将SS恢复为应用程序用
MOV ESP,ECX ; 将ESP恢复为应用程序用
POPAD
POP DS
POP ES
ADD ESP,4 ; INT 0x0d需要这句
IRETD
.kill:
; 将应用程序强制结束
MOV EAX,1*8 ; 操作系统用的DS/SS
MOV ES,AX
MOV SS,AX
MOV DS,AX
MOV FS,AX
MOV GS,AX
MOV ESP,[0xfe4] ; 强制返回到start_app时的ESP
STI ; 切换完成后恢复中断请求
POPAD ; 恢复事先保存的寄存器值
RET
_memtest_sub: ; unsigned int memtest_sub(unsigned int start, unsigned int end)
PUSH EDI ; 由于还要使用EBX, ESI, EDI
@@ -370,78 +232,55 @@ mts_fin:
RET
_farjmp: ; void farjmp(int eip, int cs);
JMP FAR [ESP+4] ; eip, cs
JMP FAR [ESP+4] ; eip, cs
RET
_start_app: ; void start_app(int eip, int cs, int esp, int ds);
PUSHAD ; 将32位寄存器的值全部保存起来
MOV EAX,[ESP+36] ; 应用程序用EIP
MOV ECX,[ESP+40] ; 应用程序用CS
MOV EDX,[ESP+44] ; 应用程序用ESP
MOV EBX,[ESP+48] ; 应用程序用DS/SS
MOV [0xfe4],ESP ; 操作系统用ESP
CLI ; 在切换过程中禁止中断请求
MOV ES,BX
MOV SS,BX
MOV DS,BX
MOV FS,BX
MOV GS,BX
MOV ESP,EDX
STI ; 切换完成后恢复中断请求
PUSH ECX ; 用于far-CALL的PUSH(cs)
PUSH EAX ; 用于far-CALL的PUSH(eip)
CALL FAR [ESP] ; 调用应用程序 ; 应用程序结束后返回此处
MOV EAX,1*8 ; 操作系统用DS/SS
CLI ; 再次进行切换,禁止中断请求
MOV ES,AX
MOV SS,AX
MOV DS,AX
MOV FS,AX
MOV GS,AX
MOV ESP,[0xfe4]
STI ; 切换完成后恢复中断请求
POPAD ; 恢复之前保存的寄存器值
_farcall: ; void farcall(int eip, int cs);
CALL FAR [ESP+4] ; eip, cs
RET
_asm_hrb_api:
; 为方便起见从开头就禁止中断请求
PUSH DS
PUSH ES
PUSHAD ; 用于保存的PUSH
MOV EAX,1*8
MOV DS,AX ; 先仅将DS设定为操作系统用
MOV ECX,[0xfe4] ; 操作系统ESP
ADD ECX,-40
MOV [ECX+32],ESP ; 保存应用程序的ESP
MOV [ECX+36],SS ; 保存应用程序的SS
; 将PUSHAD后的值复制到系统栈
MOV EDX,[ESP ]
MOV EBX,[ESP+ 4]
MOV [ECX ],EDX ; 复制传递给hrb_api
MOV [ECX+ 4],EBX ; 复制传递给hrb_api
MOV EDX,[ESP+ 8]
MOV EBX,[ESP+12]
MOV [ECX+ 8],EDX ; 复制传递给hrb_api
MOV [ECX+12],EBX ; 复制传递给hrb_api
MOV EDX,[ESP+16]
MOV EBX,[ESP+20]
MOV [ECX+16],EDX ; 复制传递给hrb_api
MOV [ECX+20],EBX ; 复制传递给hrb_api
MOV EDX,[ESP+24]
MOV EBX,[ESP+28]
MOV [ECX+24],EDX ; 复制传递给hrb_api
MOV [ECX+28],EBX ; 复制传递给hrb_api
MOV ES,AX ; 将剩余的段寄存器也设为操作系统用
MOV SS,AX
MOV ESP,ECX
STI ; 恢复中断请求
CALL _hrb_api
MOV ECX,[ESP+32] ; 取出应用程序的ESP
MOV EAX,[ESP+36] ; 取出应用程序的SS
CLI
MOV SS,AX
MOV ESP,ECX
STI
PUSH DS
PUSH ES
PUSHAD ; 用于保存的PUSH
PUSHAD ; 用于向hrb_api传值的PUSH
MOV AX,SS
MOV DS,AX ; 操作系统用段地址存入DS和ES
MOV ES,AX
CALL _hrb_api
CMP EAX,0 ; 当EAX不为0时程序结束
JNE end_app
ADD ESP,32
POPAD
POP ES
POP DS
IRETD ; 这个命令会自动执行STI
POP ES
POP DS
IRETD
end_app:
; EAX为tss.esp0的地址
MOV ESP,[EAX]
POPAD
RET ; 返回cmd_app
_start_app: ; void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
PUSHAD ; 将32位寄存器的值全部保存起来
MOV EAX,[ESP+36] ; 应用程序用EIP
MOV ECX,[ESP+40] ; 应用程序用CS
MOV EDX,[ESP+44] ; 应用程序用ESP
MOV EBX,[ESP+48] ; 应用程序用DS/SS
MOV EBP,[ESP+52] ; tss.esp0的地址
MOV [EBP ],ESP ; 保存操作系统用ESP
MOV [EBP+4],SS ; 保存操作系统用SS
MOV ES,BX
MOV DS,BX
MOV FS,BX
MOV GS,BX
; 下面调整栈以免用RETF跳转到应用程序
OR ECX,3 ; 将应用程序用段号和3进行OR运算
OR EBX,3 ; 将应用程序用段号和3进行OR运算
PUSH EBX ; 应用程序的SS
PUSH EDX ; 应用程序的ESP
PUSH ECX ; 应用程序的CS
PUSH EAX ; 应用程序的EIP
RETF
; 应用程序结束后不会回到这里