diff --git a/21_day/Makefile b/21_day/Makefile index 6c408b7..13e8023 100644 --- a/21_day/Makefile +++ b/21_day/Makefile @@ -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 diff --git a/21_day/a.c b/21_day/a.c index 0afb794..a6668af 100644 --- a/21_day/a.c +++ b/21_day/a.c @@ -1,7 +1,8 @@ void api_putchar(int c); +void api_end(void); void HariMain(void) { api_putchar('A'); - return; + api_end(); } diff --git a/21_day/a_nask.nas b/21_day/a_nask.nas index 68f3c03..28b00f5 100644 --- a/21_day/a_nask.nas +++ b/21_day/a_nask.nas @@ -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 diff --git a/21_day/bootpack.h b/21_day/bootpack.h index b5ae31d..8322e34 100644 --- a/21_day/bootpack.h +++ b/21_day/bootpack.h @@ -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 { diff --git a/21_day/console.c b/21_day/console.c index 1cf569c..c2f8619 100644 --- a/21_day/console.c +++ b/21_day/console.c @@ -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); /*强制结束程序*/ } diff --git a/21_day/crack1.c b/21_day/crack1.c index 1ac44f7..d74acf3 100644 --- a/21_day/crack1.c +++ b/21_day/crack1.c @@ -1,5 +1,7 @@ +void api_end(void); + void HariMain(void) { *((char *) 0x00102600) = 0; - return; -} \ No newline at end of file + api_end(); +} diff --git a/21_day/crack2.nas b/21_day/crack2.nas index f9b467c..73a9fb0 100644 --- a/21_day/crack2.nas +++ b/21_day/crack2.nas @@ -3,4 +3,5 @@ MOV EAX,1*8 ; OS用的段号 MOV DS,AX ; 将其存入DS MOV BYTE [0x102600],0 - RETF + MOV EDX,4 + INT 0x40 diff --git a/21_day/dsctbl.c b/21_day/dsctbl.c index e5d7a40..cdcee71 100644 --- a/21_day/dsctbl.c +++ b/21_day/dsctbl.c @@ -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; } diff --git a/21_day/hello.nas b/21_day/hello.nas index 029ed22..b4e9576 100644 --- a/21_day/hello.nas +++ b/21_day/hello.nas @@ -10,6 +10,7 @@ putloop: ADD ECX,1 JMP putloop fin: - RETF + MOV EDX,4 + INT 0x40 msg: DB "hello",0 diff --git a/21_day/hello2.nas b/21_day/hello2.nas index 3550694..5e1e58c 100644 --- a/21_day/hello2.nas +++ b/21_day/hello2.nas @@ -3,6 +3,7 @@ MOV EDX,2 MOV EBX,msg INT 0x40 - RETF + MOV EDX,4 + INT 0x40 msg: DB "hello",0 diff --git a/21_day/hello3.c b/21_day/hello3.c index 17a53ad..97d3236 100644 --- a/21_day/hello3.c +++ b/21_day/hello3.c @@ -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(); } diff --git a/21_day/naskfunc.nas b/21_day/naskfunc.nas index cc59a61..35950c7 100644 --- a/21_day/naskfunc.nas +++ b/21_day/naskfunc.nas @@ -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 - 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设回应用程序用 + MOV EAX,ESP + PUSH EAX + MOV AX,SS + MOV DS,AX + MOV ES,AX + CALL _inthandler20 + POP EAX 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 +; 应用程序结束后不会回到这里