最后可用的。不过进了win98找不到它,不能被系统使用。 |
本帖最后由 窄口牛 于 2023-10-6 14:42 编辑 又测试了,win98可以识别非--top的盘;xp安装svbus驱动,可以识别大的--top的盘,大盘作为(可能是因为镜像是img非ima)fd,无法工作,必须是hd才行。 今天又鼓捣了一上午结果一致。 |
谢谢分享 |
前面的帖子,是说可以参考 Z0MBiE 的代码,利用 DPMI 的漏洞获取 ring0 权限从而进入 long 模式,实现高位内存的访问。 如果不利用漏洞,而是想办法给 Win9x 的 VMM(虚拟机管理器,或虚拟机监控器)打补丁,让它能够访问高位内存,那就更好。当然了,这就相当于写一个 VxD 驱动程序了,甚至比写 VxD 还要难,因为我们无法获得 VMM 的源代码,只能靠反汇编。为 VMM 打补丁就是给它增加一个 int 功能调用,类似于 int15h/87h,但能够访问 4G 以上的高位内存。然后让 grub4dos 的 int13 handler 调用它即可。 能够运行 win98 的硬件,已经消失殆尽了。所以,以上提到的这些代码和方法,也都没什么实际价值。它仅有的价值,大概也只是作为教学的材料,用来练习 intel cpu 的汇编指令。一个有漏洞的 Win98,也不可能成为人们普遍采纳的、主流的操作系统。就是说,在未来,整个 Win98 系统,主要的用途,大概也只是作为一个 intel CPU 指令集的实验教材。前面提到的这些方法,如果你通过学习,能够成功实现,那么,你对于 intel 指令集的学习(就好比说,这是一道闯关题),就算是过关了。 |
谢谢分享 |
本帖最后由 不点 于 2023-10-14 12:30 编辑 理解、分析一下 Z0MBiE 的从 VM86 模式获取 ring0 权限的代码。文件名是 V86_2_R0.ASM。 以下是源代码,并附上我的注解。 ; V86 -> RING0 (从 VM86 模式进入 ring0) ; this program should be executed under Win95/98 ; developed under win98 程序应在 Win95/98 下运行;是在 Win98 下开发的。 ; 1. start in V86, exec int3 ; 2. go to PROT16/RING3 using DPMI, exec int3 ; 3. go to PROT32/RING0 using DPMI/IDT hack, exec int3 ; 4. back to DOS 第一步,从 VM86 模式启动,执行 int3 指令 第二步,用 DPMI 进入 16 位保护模式,ring3,执行 int3 指令 第三步,用 DPMI 并对 IDT 进行 hack,进入32位保护模式,ring0,执行 int3 指令 第四步,返回 DOS 这些 int3 指令,不起实质性作用,只是为了调试的时候,能够在此处中断。 ; (c) Z0MBiE/29A -- March 22, 1999 model tiny (tiny 的意思就是要生成 .com 程序) p386 locals __ jumps codeseg org 100h start: mov ax, 1600h ; windows running? int 2fh cmp al, 4 ; win95/98 ? jne __exit 若不是 win9x,退出 int 3 ; V86 lea sp, endofstack ; set own stack 设置自己的堆栈 mov ah, 4ah ; resize our memory block mov bx, memory 调整内存块大小 int 21h 以上代码不是实质性的,仅仅是减少本程序对内存的过多占用,因为 .com 程序默认占用 64K,有点多。 mov ax, 1687h ; DPMI - installation check int 2fh 检查是否存在 DPMI or ax, ax jnz __exit 若不存在 DPMI,退出 ; ES:DI = DPMI mode-switch entry point ; SI=memory(in par.) needed for DPMI private data push es ; init DPMI initproc push di pop dpmicall 保存DPMI模式切换子程序入口 mov ah, 48h ; allocate memory mov bx, si ; for DPMI private data int 21h 为 DPMI 所需私有数据分配内存 jc __exit mov es, ax 保存分配到的内存段值到ES 这额外的私有数据,有点讨厌。.com 程序运行在 DOS 下,当然可以调用 DOS 来分配内存。 然而我们假如只是在 int13 的 handler 里面运行,此时还能调用 DOS 来分配内存吗? 这是个疑问。就算能调用,将来在 int13 handler 结束时,还得记住要释放内存。 所以,安全起见,我们应该设法避免调用 DOS API 来分配内存。 xor ax, ax ; flags: bit0=0 -> 16-bit program call dpmicall 调用模式切换子程序 jc __exit ; now in protected mode (16-bit, ring3) 此时已进入 16 位保护模式,ring3 权限。 int 3 ; PROT16/R3 sidt idtr ; read IDTR (读 “中断描述符表” 寄存器) 只有进入保护模式之后,DPMI 才会为保护模式代码生成 IDT。 这可能就是为什么需要进入保护模式的原因。 mov ax, 6 ; save (get&push) ES.base mov bx, es 获取ES段的基地址 int 31h push cx 将 ES 基地址保存在堆栈上 push dx mov ax, 7 ; set ES.base mov bx, es 设置 ES 段的基地址...... push idtr_base ; CX:DX=newnase=IDTR.base (此处 newnase 是打字错误,应为 newbase) pop dx ......为中断描述符表的基地址 pop cx int 31h 把 ES 指向中断描述符表,目的就是要修改中断描述符表。 ring3 程序可以修改中断描述符表,并进入 ring0,这应该属于 DPMI 的一个漏洞。 ; by default ES points to PSP and ES.limit is 0FFh, ; so we can increase it a little w/o problems DPMI 在默认时设置 ES 指向 PSP,段限是 0FFh(其实就是通常所说的 100h)。 所以我们可以把段限增大一点,没问题。 段限其实准备增大到中断描述符表的长度,也就是 2K。 ; DPMI host is big madafucka, it dont allows you to set selectorlimit >= 2GB 去它大爷的,DPMI 服务端真该死,它不允许你设置段限为 2GB 或更多。 那就设置段限为 2K 吧,反正也够用了。 mov ax, 8 ; set ES.limit mov bx, es mov cx, 0 ; CX:DX=newlimit=maxIDTlimit mov dx, 256*8-1 (这就是 2K) int 31h mov ax, 0006h ; get CS.base into CX:DX mov bx, cs int 31h 获取 CS 基地址 add dx, offset __ring0 ;calc lin. addr of __ring0 adc cx, 0 ; [BUGFIX] was: dx push cx push dx pop ebp __ring0 的线性地址放在 ebp 中 xchg bp, es:[0] ; INT00 <--> __ring0 rol ebp, 16 xchg bp, es:[6] 修改中断描述符表的int 00表项,使其指向 __ring0 xor dx, dx xor cx, cx 除以零,故意制造故障或异常 div cx ; call INT 00 除以零以后,会跳到 __ring0 处,执行 32 位保护模式的 ring0 代码(异常处理代码)。 异常处理结束后,回到这里继续运行。由于异常处理用 iret 结束,所以, 此时已经回到 16 位保护模式,ring3 权限了。 xchg bp, es:[6] ; INT00 <--> __ring0 rol ebp, 16 xchg bp, es:[0] 恢复中断描述符表原来的int00指针 mov ax, 7 ; restore(pop&set) ES.base mov bx, es 恢复 ES 原来的基地址 pop dx pop cx int 31h ES 段限不必恢复,大一点没关系。 __exit: mov ax, 4c00h ; exit int 21h 在 DPMI 的保护模式下,可以直接执行 int21h/4C00h,退出DOS。 我们在 int13 handler 里面,当然不可以这么做。 在 int13 handler 里面,此时我们必须做一个额外的工作。 我们需要从 16 位保护模式切换到 VM86 模式, 这是因为 int13 handler 本来就运行在 VM86 模式。 如果继续保持 16 位保护模式的话, 在 int13 handler 的处理全部完成、准备最后执行 iret 返回到调用者的时候,就完蛋了。 我们可以通过调用 int31h/AX=301h 来切换到 VM86 模式。这个调用的名称是: Call Real Mode Procedure With Far Return Frame。参见 ; DOS PROTECTED MODE INTERFACE(DPMI) SPECIFICATION Version 1.0 ; March 12, 1991 ; Application Program Interface (API) for Protected Mode DOS Applications ; © Copyright The DPMI Committee, 1989-1991. ; All rights reserved. ; http://www.sudleyplace.com/dpmione/dpmispec1.0.pdf 调用之后,我们不要用 RETF 指令返回到保护模式。因为我们的目的只是进入 VM86 模式而已。 既然访问高位内存的工作已经完成, 此刻我们需要跳转到(或返回到) int13 handler 的某个合适的地方,这样就平滑过渡到了原来的流程,继续运行。 __ring0: int 3 ; PROT32/R0 inc cx ; inc ecx (!) 这条指令让 CX 不再是 0,保证 “除以零” 这个故障不会反复发生,而只发生一次。 这是因为,新型 CPU 把 “除以零” 作为故障,而故障的处理程序在 iret 结束后, 会再次跳到(返回到)出现故障的这条指令,重复执行一次。 也就是说,如果此时 CX 仍然是零,那么,故障将再次触发, 这样,就会无限循环,死机。 我们的 ring0 代码,应该插入这里。 此刻处于 32 位保护模式,ring0 权限。 我们的 ring0 代码需要进入 long 模式, 访问 4G 以上高位内存中的扇区数据, 然后再回到 32 位保护模式。 iret 这条 iret 会返回到先前的 16 位保护模式(ring3)代码中。 ; --------------------------------------------------------------------------- dpmicall dd ? idtr label fword idtr_limit dw ? idtr_base dd ? even db 1024 dup (?) endofstack: memory equ ($-start+256+15)/16 end start |
dayeye 发表于 2023-10-11 22:45 大内存补丁后就能了。系统内认到3.5g,实际可能会用的就2g。 |
看到有人继续关注,本帖就稍稍深入一步,谈谈 win98 下访问 --top 内存盘的技术可行性。纯粹是空谈,不再实干。因为空谈容易,实干难。 我们知道,著名的 CIH 病毒的作者就是一个高手。他能够在 Win98 之下获取 CPU 最高权限( ring 0 权限),从而不受任何约束地执行自己的代码。这个获取 ring 0 权限的代码,我估计现在还能够从网上找到。除此之外,网上还能找到另外一个牛人,名叫 Z0MBiE,他有个主页: https://z0mbie.dreamhosters.com/ 里面有很多代码和文章。有人把他的代码和文章收集起来,保存在这里: https://github.com/lwerdna/z0mbie.host.sk 他能用多种方法从 win98 获取 ring0 权限。 我们利用这个技术,就可以让 grub.exe 从 win98 下运行,进入实模式,然后再执行 grub4dos 的其他命令。 如果说在 win98 之下运行 grub.exe 的意义不大的话,那么,下面这个应该算是有实在意义的:获取 ring 0 权限后,磁盘仿真代码能够顺利读取(或写入)4G 以上的高位内存,这样,--top 的问题就解决了。 |
本帖最后由 dayeye 于 2023-10-11 23:04 编辑 ACER 4750G,10G内存,实机安装win98。map --mem --top 的2375M的fd盘可以格式化完成使用。格式化时间很长,拷贝文件时很不稳定,反复报错。 我觉得不稳定报错的原因可能是我的win98系统本就没安装好,缺少大堆驱动,能打开而已。 小的fd小到只有4k,格式化为720k-3.5'软盘可以使用。2375M-fd部分想分开成一个fd+一个hd没有成功。 其他试用结果与楼主结果基本一致。 4096M以后的--TOP盘fd/hd都无法使用。4096以内hd完好使用。 实机在1G内存时安装成功。2G及以上内存时不能自行引导启动。 |
sunsea 发表于 2023-10-10 08:22 模式切换,确实不好。但这是历史造成的。如果执意要跟历史割裂开来,那当然就不需要模式切换了,只需要新的 CPU 指令集、新的架构、新的功能就行了。 ARM 和龙芯,都属于新的架构。龙芯不太了解,暂且不说。但 ARM 就不是取代 x86 的气势。 看看传统电脑的设计:主板 ROM 提供服务 ==> DOS 操作系统 ==> 应用程序。 有了主板提供的基本输入输出系统,操作系统的设计就很简单、很精炼。 多级设计,才能达到精炼。就像飞船登月,需要多级火箭。每一级都是对后续(下一级)的支撑。 ARM 电脑缺乏这个具有统一规范的基本输入输出系统。操作系统启动后,直接操纵硬件。这么一来,操作系统就需要各种各样的驱动程序,体积就十分庞大。Windows 也是这样,不再利用 BIOS,而是直接操纵硬件。 其实 Windows 也可以建立一套适用于 Windows 的新型 BIOS 规范,让主板制造商(以及其它硬件设备制造商)遵守,这样,就不需要五花八门的驱动程序了,只调用主板提供的服务就行。可是,Windows 此时已经没有动力干这个事了。这是因为,Windows 正在努力把系统体积变大,而不是变小。体积越大,控制力越强。操作系统越臃肿就越符合操作系统开发商的利益。 对于操作系统的学习者来说,当然操作系统越精炼、越简单,就越好。这刚好跟开发商的想法相反。开发商的操作系统,目的是让你变傻,然后方便收钱。而学生则是想学会、掌握这门技术的。开发商不怕普通用户学会技术,因为普通用户根本就不去学。开发商害怕竞争对手掌握了它的技术。所以,开发商需要保护自己。怎样才能保护自己?就是采用封闭策略。已有的规范,要破坏掉。为什么?因为这些规范已经被竞争对手掌握,自己无法在技术上占据压倒优势。为什么不再推出新的 BIOS?因为新的 BIOS 规范一旦推出,迟早也还是要被竞争对手掌握。在开发商看来,没有规范最好了,所有的硬件都由操作系统来处理,别人难以掌握,这就提高了门槛,挡住了竞争者。 这就明白了,今后再也不会有 BIOS 了。任何商家都不会推出类似 BIOS 这种规范了。商家要提高门槛,就必须这么做。 虽然 BIOS 已经差不多算是死干净了,但假如还有人由于某种特殊的原因而想念 BIOS,他就会觉得历史上曾经出现的 BIOS 十分珍贵。一个东西,再也找不着了,那么,物以稀为贵,他有可能把它当作贵重的文物保存起来(虽然可能只是保存在自己的脑海里)。那些不学技术的普通人,当然不可能把这当成宝贝。 |
不点 发表于 2023-10-8 23:09 应该是这样的。Win98的系统调用就是这么个半吊子的东西。保护模式不保护模式,实模式不实模式,非要从32位进入这么一个东西再跑回来,所以98比纯保护模式的NT不稳定的多。 |
xp也有搞得,之前把win8的驱动移植到xp,现在把win7的也移植了,只要还能装win7的现代机器,都可以跑xp啦。 大部分是手机回复,只有电脑回复才比较容易设置大字体。 |
窄口牛 发表于 2023-10-10 00:11 呵呵,干脆让微软放出 win98 源代码,就省事了。 难道说,这帮人还要把 win98 的内核翻个底朝天?那得多费劲啊? reactOS 就够费劲的,现在还有 “掏空” win98 的。 我想,这帮人可能是想练手、提高个人技能,以反汇编和破解为乐趣。 要掏空 XP 可能很难。所以,他们要拿 win98 来练手。 还有一个重要的原因,win98 与实模式 DOS 搭配良好,其后的 Windows 都开始逐步抛弃 DOS 了。 商家抛弃 DOS 之后,这些高手们觉得失去了自由。他们想找回自由。 因此,Win98 是个最好的 “切入点”。 还有一点,我想说。IBM 个人电脑的普及,是一个巨大的事件。DOS 里面的 debug,是编程者的最大福音,没有之一。debug 是有史以来最好的程序。没有 debug,你的电脑知识就只能停留在应用层面,不可能深入一步。debug 与其他编译器、调试器的不同之处在于,它是轻量级的。它运行在 DOS 下,而 DOS 本身也是轻量级的。在 debug 中,每一条 CPU 指令,你都可以尝试运行。那种轻易就能够获得的 “控制感”,能够让你确实感受到乐趣。否则,如果一开始都很难,那么大多数人都将失去耐心,逃之夭夭了。debug 能够让一个普通爱好者快速切入电脑的内部工作流程当中,不需要专门的培训。 干掉 DOS,就没有了 debug,那么,要想进入电脑内层,就提高了门槛。普通爱好者就不要再想了。 电脑刚开始普及的时候,商家需要有人对电脑内幕感兴趣。但是,后来感兴趣的人多了,反而对商家不利。此时,商家需要提高门槛,让一般人不能切入系统内层,这样就保护了商家的利益。 debug 和 DOS 的 .com 程序格式,是一个精粹。.com 程序不拖泥带水,一开始就是 cpu 指令,没有复杂的结构。最短的 .com 程序,可以只有一个字节,只放置一条 ret 指令(这是个单字节指令)就行了。Linux 之下没有类似这种的 “无结构” 可执行文件格式,而是复杂的 ELF 格式。而且,进入 Linux 之后,调试器本身也处于保护模式,而不是实模式。要想切换到实模式,还颇为困难。因此,要想学习 CPU 知识,通过 DOS 下实模式的 debug 来学习,是最好的途径,没有之一。 ARM 之下没有实模式和保护模式的区分。但要命的是,ARM 之下连统一的 BIOS 都没有。没有类似 DOS 的轻量级操作系统。DOS 之所以轻量,是因为 BIOS 提供了很多服务。DOS 只需调用这些服务即可。而 DOS 下运行 debug,理论上就可以控制所有的方面了。ARM 有 Linux 和 gdb,但 Linux 也缺乏类似于 .com 格式的可执行文件,而 ELF 格式比较复杂,不利于初学者、门外汉快速切入。 |
好建议 |
窄口牛 发表于 2023-10-9 07:30 Microsoft WINDOWS 98 (SE) unofficial support site http://windows98.xf.cz/ 牛B plus!牛B 确实牛B,但我的理解力还跟不上,理解不动。微软扔掉的、而且封杀了多年的东西,还能捡起来? 不过,那东西倒是也有优点。其一,精简、轻量。其二,不含网络后门,不会从网上控制你。 |
现在都 2023 年了,还有人在 Linux 下用 DOSbox 运行 win98: Run Windows 98 in Vanilla DOSBox https://leo3418.github.io/2023/01/03/windows-98-in-vanilla-dosbox.html |
2011yaya2007777 发表于 2023-10-9 07:16 在g4d下可以看到,打开,说明不是grub4dos的锅了,只能在win98里解决这个问题。 九八方面 http://windows98.xf.cz/这个网站可以关注一下,我就是在玩这些东西,不过有些还没玩到位。 |
这个 --top 的问题貌似是无法解决的 我觉得不点分析的很到位。我看了一下asm.S文档,前辈们有以下2段注释: /* But Win9x may expect additional data after SafeMBRHook structure. //但在Win9x可能期望SafeMBRHook结构后的附加数据。 * This is undocumented, and mysterious. If this area is not what //这是无证,而神秘。如果这方面是不是有什么Win9x的预期,Win9x的可能挂起。 * Win9x expected, Win9x could hang. */ # win9x vm86-mode int15/ah=87h will also fail in accessing more than 4G //Win9x vm86模式int15/ah=87h访问超过4G内存失败。 # memory. Hope someone would develop a driver for win9x in the future. //希望有人会发展为未来的Win9x驱动程序。 |
又找到一个网站,目前能够正常访问: https://www.dewassoc.com/windows-95-98-and-nt-setup-switches/ 它介绍了 win98 setup.exe 安装时的一些选项,包括未公开的(秘密)选项。对于玩 win98 的人来说,这应该也是有用的。 |
不点 发表于 2023-10-9 06:36 嗯,dosbox,pcem,都可以模拟win98.,win2000打游戏。 |
找到一些相关的技术,说不定以后有人找到这里了,他就能用得着。 https://dosbox-x.com/wiki/Guide%3AInstalling-Windows-98 这个网页居然说可以从 DOSbox-X 下安装、运行 Win98。我记得以前在 DOSbox 之下是不能运行 win98 的。所以,这个 DOSbox-X 是个突破。 可惜,我这里无法访问 dosbox-x.com 这个网站,猜测可能是被墙了吧。 |
这个 --top 的问题貌似是无法解决的。我猜,real-mode mapper 里面的 real-mode,并非真的是指 real-mode,而很可能是表示 “16 位模式” 或者 vm86 模式。也就是说,grub4dos 的实模式代码在 win98 环境是失效的。grub4dos 在 win98 的 vm86 模式下,是通过调用 bios 的 int15 / 87h 来实现 4G 以内的内存块移动(可以理解为内存块读写)。而 int15/87h 不支持对 4G 以上的内存块进行操作(幸运的是 4G 以内的低位内存,能够完美支持)。看来,要想实现 --top 内存盘的访问,还真是需要有人为 win98 写一个(类似于 svbus 的)驱动程序。前面已经说了,这希望太渺茫了,那就当做一个美丽的梦想吧。 |
窄口牛 发表于 2023-10-7 13:34 好的,明白了。大的 bug 是没有的。但可能存在小 bug,那就是,grub4dos 对于高位内存的处理(代码层面),不能适应 win98 环境。猜测很可能需要改进代码。 |
窄口牛 发表于 2023-10-7 07:15 你报告得很详细。有两种可能:其一,grub4dos 的实模式仿真代码,可能有 bug。其二,win98 系统的 realmode mapper 可能由于某种原因(可能存在内存冲突之类的原因),不能与 grub4dos 的实模式高位内存处理代码协同工作。 我想了解,在进入 win98 之前,也就是在 grub4dos 环境下,或者从 grub4dos 直接启动一个 DOS 系统,这样能否访问 --top 内存盘中的文件?这个问题很重要。如果能访问,那就说明是 win98 与 grub4dos 的高位内存处理代码有冲突。如果 dos 和 grub4dos 下也不能正常访问 --top 虚拟出来的软盘,那问题就大了,属于巨大 bug。 |
不点 发表于 2023-10-6 16:28 嗯,能懂你的意思。 |
窄口牛 发表于 2023-10-5 10:39 你修改帖子之后,我猜到问题在什么地方了。你试图把含有分区表的 img 仿真成软盘 fd0,这肯定不行。你需要的是一个不含 mbr 磁道,只有分区(卷)的 img,这才可以仿真为软盘。 |
本帖最后由 不点 于 2023-10-6 16:18 编辑 XP 之下,是使用 svbus 之类的驱动,而不是使用 grub4dos 的实模式代码。两者是完全不一样的。 所以,仍然有可能是 grub4dos 的实模式磁盘仿真代码出了 bug,虽然可能性不大。 还有一个可能性就是,你的 img 本身有问题,导致 win98 不能挂载它的文件系统。 可以试试一个 1.44M 的软盘,用 map --top --mem 加载为虚拟软盘 (fd0),看看进入 win98 之后是否能看到软盘。 如果成功,就说明 grub4dos 的代码是正常的、没问题的。 |
应该不是grub4dos的问题,因为在XP里没问题。 |
Powered by Discuz! X3.3
© 2001-2017 Comsenz Inc.