无忧启动论坛

标题: 关于KonBoot加载的疑问,感谢不点大大提示,我想了个办法,求鉴定! [打印本页]

作者: zyphio    时间: 2015-3-7 17:34
标题: 关于KonBoot加载的疑问,感谢不点大大提示,我想了个办法,求鉴定!
本帖最后由 zyphio 于 2015-3-23 09:00 编辑

今天重新看了一下不点大大21#楼的想法,结合C大大前几天回答我关于find命令应用的疑问,我突然有了新的点子,重新写了此菜单,虽无什么复杂技术,但精妙之处有二,一是尽量完美的解决Konboot加载交换hd的的问题,二来保证只从grldr所在“设备”(即使是不同分区)上读取外置菜单和Konboot镜像等文件,同时兼容UD!

grldr内置菜单:

  1. errorcheck off
  2. set /A firstbd=*0x82a0
  3. configfile /boot/menu.lst
  4. if "%firstbd%"=="0x23" && set /A firstbd=*0x82b9&0xff
  5. find --set-root /boot/menu.lst checkrange %firstbd% read 0x82a0 && configfile /boot/menu.lst
  6. echo Can't find the configuration file form the first boot device.
  7. pause Press any key to continue...
  8. errorcheck on
复制代码


menu.lst外置菜单:

  1. title KonBoot
  2.         map --unmap=0:255
  3.         map --rehook
  4.         find --set-root /boot/konboot.img checkrange %firstbd% read 0x82a0
  5.         map --mem /boot/konboot.img (fd0)
  6.         map --hook
  7.         if "%firstbd%"=="0x23" && set /A firstbd=*0x82b9&0xff
  8.         if "%firstbd%"=="0x80" && map (hd0) (hd1) && map (hd1) (hd0) && map --rehook
  9.         chainloader (fd0)+1
  10.         rootnoverify (fd0)

  11. title Windows Version 5 PE (32bit)
  12.         map --unmap=0:255
  13.         map --rehook
  14.         find --set-root /boot/win5pe32.iso checkrange %firstbd% read 0x82a0
  15.         map --mem /boot/win5pe32.iso (0xff)
  16.         map --hook
  17.         chainloader (0xff)
  18.         rootnoverify (0xff)

  19. title DiskGenius (DOS)
  20.         map --unmap=0:255
  21.         map --rehook
  22.         find --set-root /boot/dgdos.img checkrange %firstbd% read 0x82a0
  23.         map --mem /boot/dgdos.img (fd0)
  24.         map --hook
  25.         chainloader (fd0)+1
  26.         rootnoverify (fd0)
复制代码


———————————我是朴素的分割线————————————

感谢不点大大前面的解释,6楼的问题,我想到一个解决办法,可避免U盘被认为非h类设备时还交换 (hd0) (hd1)的问题,思路和菜单如下,求高手们鉴定:

1.konboot.img在U盘上(可能存在以c、u、f、h类分区中);
2.通过find找到konboot.img,把其所在设备分区设置为根设备,并加载konboot.img到(fd0);
3.用if句,判断根设备第一分区的类型,如果是h类成立,那说明U盘被BIOS认为是h类设备,占用了(hd0),那主机的物理硬盘在(hd1);
4.用map把(hd1)与(hd0)互换,保证(fd0)中的konboot接下将引导的(hd0)是主机的物理硬盘!

title KonBoot
        find --set-root /konboot.img
        map --mem /konboot.img (fd0)
        if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)
        map --hook
        chainloader (fd0)+1
        rootnoverify (fd0)

经测,UD启动,跳转到hd0上第二个主分区/konboot.img,根设备为(hd0,1)时,上述if语句有效,成功利konboot以任意密码进入(hd1)上的Win7!

谢谢不点大大在11楼的提示,我在想,不管UD宿主盘是什么,可以肯定搜索到的konboot.img所在的U盘是h类设备,那不就不管三七二十一,交换(hd0)和(hd1)了,死机或失败了再调整,甚至得拔插硬件了,毕竟konboot可支持Windows、Linux、MAC且认准了(hd0),专门在grub4dos里检测哪个hd上是否有Konboot支持的这些系统可能比较麻烦吧。

感谢23楼 chiannet解决根设备是UD的菜单:

title KonBoot 2.1 绕过密码
        map --mem ()/BOOT/IMGS/KON.IMG (fd0)
        if "%@root%"=="(ud)" && calc *0x82A0=*0x82b9&0xff
        if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)
        map --rehook
        chainloader (fd0)+1
        rootnoverify (fd0)

———————————以下最早提问的内容————————————


GRUB4DOS加载KonBoot镜像时菜单命令我一直写成这样:

title Kon-Boot
        map --mem /konboot.img (fd0)
        map (hd0) (hd1)
        map (hd1) (hd0)
        map --hook
        chainloader (fd0)+1
        rootnoverify (fd0)

一直可成功应用KonBoot啊,

后来看到官方的USB引导默认写成:

title Kon-Boot
        map --mem /konboot.img (fd0)
        map --hook
        chainloader (fd0)+1
        map (hd1) (hd0)
        map --hook
        rootnoverify (fd0)

1.map --hook后立即从fd0进行chainloader,后面的map会不会在某些情况下无效?
2.为什么官方的菜单要用两次map --hook,这样兼容性更好么?
3.上面两种命令顺序对比,哪种更规范?逻辑更合理?
4.在map --hook之前,map --mem是否已经把镜像加载进内存了?

我在想,grub4dos的对命令的处理原理是不是这样的:

如命令行状态一样,每个菜单的几条命令录入后形成一种“配置”状态,再使用map --hook、boot这类执行命令,让这种已通过命令定义好的“配置”状态生效,不是所有命令录入后不一定是实时生效的对吧?
作者: 不点    时间: 2015-3-7 21:43
本帖最后由 不点 于 2015-3-7 22:15 编辑

顺序好像没有太大影响,因为所涉及到的虚拟盘没有互相覆盖的情况。

chainloader (fd0)+1 这条命令需要在某个 map --hook 之后才行,否则虚拟盘 (fd0)就不存在,无法执行 chainloader (fd0)+1 命令。

此例中,可以只用一条 map --hook,但正如刚才所说,chainloader 命令需要放在 map --hook 之后。

两种菜单的效果也有不同。第一个菜单,创建了两个虚拟硬盘 (hd0)和 (hd1),实际上是交换了两个硬盘。

第二个菜单只创建了一个虚拟硬盘 (hd0),它覆盖掉了原来的真实硬盘 (hd0)。仿真生效以后,(hd0)将代表原来的真实硬盘 (hd1),而原来的真实硬盘 (hd0)将无法访问了。


至于说哪个更好,我分辨不出来。感觉似乎都可以达到目的。

其他一些基本问题,可以搜教程,一般都会有讲解。

补充:这两个菜单都有一个共同的毛病。它们都只能适用于当 bios 把 u 盘当作硬盘 (hd0)的情形。如果 bios 把 u 盘识别为软盘 (fd0),那么,由于真实的 (hd0)是本地硬盘,它被 map (hd1) (hd0) 命令覆盖掉了。因此,仿真生效以后,konboot 将无法找到本地硬盘。konboot 所找到的 (hd0)其实是原来的 (hd1)。如果系统中不存在 (hd1),则 konboot 有可能死机。回忆一下:对于那些 buggy 的 bios,如果你尝试访问不存在的设备,它就会死机。
作者: zyphio    时间: 2015-3-7 22:40
谢谢不点大大回复得这么详细!完全明白了!但不点大大有更好的建议或办法么?
作者: 不点    时间: 2015-3-8 09:38
zyphio 发表于 2015-3-7 22:40
谢谢不点大大回复得这么详细!完全明白了!但不点大大有更好的建议或办法么?


我曾经是开发者,但不是应用者,我对于 grub4dos 的应用,没有经验。尤其是到了后来,我身体不行了,因此,逐步放弃了开发,甚至也放弃了对新功能的了解和掌握。比如说,chenall 为 grub4dos 添加了变量的功能,也添加了批处理功能,这我都不曾应用过。

以下是仅仅凭借我以前所掌握的知识,使用较旧的功能,来试图满足你的要求。其实方法有很多,只要能够确定并区分出启动盘究竟是软盘还是硬盘,即可达到目的。当启动盘是软盘时,本地硬盘是 hd0,就不要动它了。当启动盘是 hd0 时,则需要把本地硬盘 hd1 仿真为虚拟硬盘 hd0。这算是一个总思路吧。刚才说了,下面只是一种具体的实现方法,其他方法也有很多种。

        map --mem /konboot.img (fd0) 这条命令把启动盘上的 /konboot.img 文件仿真为 fd0。此时,我们不管、也不知道启动盘究竟是 fd0 还是 hd0。
        map --hook 这条命令让仿真生效,因此,如果启动盘是 fd0,则真实的启动盘 fd0 将无法访问了,只有虚拟的软盘 fd0 才能被访问到。反之,如果启动盘是 hd0,则 hd0 仍可访问,它仍旧是启动盘。
        chainloader (fd0)+1 不管三七二十一,现在先加载虚拟软盘的第一扇区到 0000:7C00 处,准备启动它。
        ls /konboot.img && map (hd0) (hd1)
        ls /konboot.img && map (hd1) (hd0)
        ls /konboot.img && map --hook
ls 列出当前盘上的 /konboot.img 文件,如果能列出,则表明当前盘是 hd0, 即,它未被虚拟盘 fd0 覆盖掉。此时,执行交换 hd0 和 hd1 的命令,目的是保证本地硬盘 hd1 成为虚拟的 hd0, 让 konboot 软件能够正常操作本地硬盘, 而不是误把真实的 hd0 ( 它是 usb 启动盘 ) 当作本地硬盘。
反之,当 ls 列不出 /konboot.img 时,这表明启动盘是 fd0, 它已经被虚拟盘 fd0 覆盖掉了,所以找不到原来的 fd0 上的 /konboot.img 文件了。此时,本地硬盘是 hd0, 无需执行、也不应该再执行多余的交换硬盘的步骤。
        rootnoverify (fd0) 这条命令是为 boot 命令服务的。boot 命令会把当前 root 盘的盘号赋值给 DL 寄存器,并把控制权交给位于 0000:7C00 的启动代码。
        boot 既然一切准备就绪,现在可以启动了。
作者: zyphio    时间: 2015-3-8 11:36
本帖最后由 zyphio 于 2015-3-8 12:09 编辑
不点 发表于 2015-3-8 09:38
我曾经是开发者,但不是应用者,我对于 grub4dos 的应用,没有经验。尤其是到了后来,我身体不行了,因 ...


不管不点大大您还有没有在开发,您曾经的贡献和创造,以及无私的互联网分享精神,我们都不会忘记,你对我这种菜鸟提的弱智问题都回答得如此尽心尽责,说明你的心思还是没有离开,这更让我由衷的佩服和感谢,先祝您身体健康,生活愉快!

我再研究研究,也就是把菜单改成这样:

title Kon-Boot
        find --set-root /konboot.img
        map --mem /konboot.img (fd0)
        map --hook
        chainloader (fd0)+1
        ls /konboot.img && map (hd0) (hd1)
        ls /konboot.img && map (hd1) (hd0)
        ls /konboot.img && map --hook
        rootnoverify (fd0)

就可以了么?

我实际工作也中极少要用到komboot,如遇到特殊情况,我就手工录入命令一种一种情况去尝试就行了,再次谢谢您。
作者: 不点    时间: 2015-3-8 13:10
zyphio 发表于 2015-3-8 11:36
不管不点大大您还有没有在开发,您曾经的贡献和创造,以及无私的互联网分享精神,我们都不会忘记,你对 ...

我前一个帖子所写的,就是一个完整的菜单内容。你又加上 find 命令,那就变味了。

不过,我的菜单也有局限性。我没考虑usb 为 ud 启动的情况。

假如你是从 ud 启动,你需要写个专门针对 ud 的菜单。

你可以参考 0pe 里面的菜单。或者向经常使用 ud 的人请教。


作者: zyphio    时间: 2015-3-8 14:26
不点 发表于 2015-3-8 13:10
我前一个帖子所写的,就是一个完整的菜单内容。你又加上 find 命令,那就变味了。

不过,我的菜单也有 ...

谢谢老大!
作者: saiz    时间: 2015-3-8 18:33
我是搭配RUN的 swap功能使用
title Kon-Boot v2.4 \n Windows 8/8.1 online account authorization bypass!
map --mem /ISO/konboot24.img (fd0)
command RUN --swap-ext --end exit
chainloader (fd0)+1
rootnoverify (fd0)

作者: zyphio    时间: 2015-3-8 22:47
saiz 发表于 2015-3-8 18:33
我是搭配RUN的 swap功能使用

谢谢支持!

我现在想能否通过grub4dos自身的功能判断hd0是不是带有系统的硬盘!
作者: zyphio    时间: 2015-3-9 00:20
本帖最后由 zyphio 于 2015-3-9 00:22 编辑

感谢不点大大前面的解释,6楼的问题,我想到一个解决办法,可避免U盘被认为非h类设备时还交换 (hd0) (hd1)的问题,思路和菜单如下,求高手们鉴定:

1.konboot.img在U盘上(可能存在以c、u、f、h类分区中);
2.通过find找到konboot.img,把其所在设备分区设置为根设备,并加载konboot.img到(fd0);
3.用if句,判断根设备第一分区的类型,如果是h类成立,那说明U盘被BIOS认为是h类设备,占用了(hd0),那主机的物理硬盘在(hd1);
4.用map把(hd1)与(hd0)互换,保证(fd0)中的konboot接下将引导的(hd0)是主机的物理硬盘!

title KonBoot
        find --set-root /konboot.img
        map --mem /konboot.img (fd0)
        if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)
        map --hook
        chainloader (fd0)+1
        rootnoverify (fd0)

求高手们鉴定:
1.此思路可行否?
2.if语句写法没错吧?

PS:当然如果插入多个U盘、硬盘或BIOS启动顺序原因,启动时主机物理硬盘默认不是(hd1)那就没办法了,也不考虑了,毕竟谁也无法保证主机物理硬盘里一定有konboot支持的系统嘛!
作者: 不点    时间: 2015-3-9 00:42
最难对付的是 ud 启动。你只要能搞定 ud 启动,其他都容易了。

ud 启动时,当前 root 是 (ud)。假如你 find --set-root 得到的是 (ud),那是不是你的程序代码就一定要交换硬盘?因为你现在还不知道 ud 盘的宿主盘(或者叫做母盘)是不是 hd0。如果是的,你应该交换,如果不是,则不应该交换。
作者: zyphio    时间: 2015-3-9 09:56
本帖最后由 zyphio 于 2015-3-9 09:59 编辑
不点 发表于 2015-3-9 00:42
最难对付的是 ud 启动。你只要能搞定 ud 启动,其他都容易了。

ud 启动时,当前 root 是 (ud)。假如你 ...


谢谢不点大大在11楼的提示,我在想,不管UD宿主盘是什么,可以肯定搜索到的konboot.img所在的U盘是h类设备,那不就不管三七二十一,交换(hd0)和(hd1)了,死机或失败了再调整,甚至得拔插硬件了,毕竟konboot可支持Windows、Linux、MAC且认准了(hd0),专门在grub4dos里检测哪个hd上是否有Konboot支持的这些系统可能比较麻烦吧。
作者: 不点    时间: 2015-3-9 11:23
看不太懂你说的话。

假如你从 USB 启动了 ud,此时,又假定主板已经把 USB 当成了 fd0,那么,你交换 (hd0) 和 (hd1) 只会让 konboot 错把 (hd1) 当成 hd0,甚至会在去读 hd1 时发生死机。


作者: zyphio    时间: 2015-3-9 14:12
本帖最后由 zyphio 于 2015-3-9 16:18 编辑
不点 发表于 2015-3-9 11:23
看不太懂你说的话。

假如你从 USB 启动了 ud,此时,又假定主板已经把 USB 当成了 fd0,那么,你交换 (h ...


谢谢不点大大,哈,看来我的逻辑不行,表述也不行哈,原谅我哈。。

我是这样想的:

假如从U盘启动了ud,主板把U盘当做fd0,那konboot.img所在的fd0(或ud)被定义为根设备,那按if句的写法,根设备=="h"不成立(不是h类设备嘛),&&后面的map就不执行(也就不交换hd0和hd1了)。

作者: zyphio    时间: 2015-3-9 16:19
本帖最后由 zyphio 于 2015-3-9 17:17 编辑
不点 发表于 2015-3-9 11:23
看不太懂你说的话。

假如你从 USB 启动了 ud,此时,又假定主板已经把 USB 当成了 fd0,那么,你交换 (h ...


if "%@root%"=="(hd0)" && map (hd0) (hd1) && map (hd1) (hd0)

发现改成这样不行,"%@root%"结果是(hd0,1)


作者: 不点    时间: 2015-3-9 16:30
但假如你 find --set-root 的结果是 (ud),这就回到前面的话题了,那么,你又该如何?

ud 所在的宿主盘有可能是 fd0,也有可能是 hd0。

很简单,你可以试验一下,试试从 ud 启动后,%@root% 的值究竟是什么?

如果 %@root% 的值是 (ud),那么你的菜单根本就没解决问题。

如果 %@root% 的值是 (fd0) 或 (hd0) 或 (fd0,X) 或 (hd0,X) 之类的,那么你的菜单或许还能有点用。


作者: captain_g    时间: 2015-3-9 16:37
这个我可能插不上嘴。如果是UD启动,情况比较复杂一些。

举例

我有两个启动U盘,自制的UD三分区结构,一个U盘启动后用find查看得到的情况是:(ud),(hd0),(hd0,0)和(hd0,1);而另一个U盘启动后用find查看得到的情况却是:(ud),(hd0),(hd0,0)和(hd0,4)。
用ls查看(ud)和(hd0)的内容实际上是一样的。

在另外一台电脑上,情况又变成了另一则情形:(ud),(fd0),(fd0,0)和(fd0,1);(ud),(fd0),(fd0,0)和(fd0,4)。【一时记不清了,可能有错】。
用ls查看(ud)和(fd0)的内容实际上是一样的。

如果 (ud) = (hd0),你 map --mem /konboot.img (fd0) 并 map (hd0) (hd1) && map (hd1) (hd0)可能没问题,但
如果 (ud) = (fd0),你 map --mem /konboot.img (fd0) 并 map (hd0) (hd1) && map (hd1) (hd0),结果可能会意想不到吧!
作者: zyphio    时间: 2015-3-9 16:47
captain_g 发表于 2015-3-9 16:37
这个我可能插不上嘴。如果是UD启动,情况比较复杂一些。

举例

谢谢哈,您说的太对了!
这个应就是不点大大考虑的,所以,map交换(hd0)和(hd1)的前提是,konboot.img所在设备占用了(hd0),如果konboot.img在(hd1)、(hd2)、(fd0)等设备上,那完全没有map交换的必要了,听天由命让konboot引导(hd0)吧,成不成功那是另一回事了,这样好像没有完美解决的办法了,完全是 贝者 一把了!
作者: captain_g    时间: 2015-3-9 16:49
如果确实是UD启动的且konboot.img是放在UD中的,konboot.img 应该不可能在(hd2)上吧?
作者: captain_g    时间: 2015-3-9 17:06
如果你是制作自用的工具或是在特定的电脑上使用,总是可以找到成功的方法的。

但如果你做的工具是给别人或者是在不特定的机器上用的,就应该尽可能考虑得周详些,确保较高的成功率。

这是一个思路决定方法的问题。
作者: 不点    时间: 2015-3-9 18:24
本帖最后由 不点 于 2015-3-9 18:33 编辑

请 chenall、yaya 留意这个问题。

当 grldr 或 grub.exe 接管控制时,在 asm.S 的最开头,我设置了一个 WORD 变量,用来存放此刻的 DX 寄存器值。其目的是,在用户的系统出问题时,这个域的值可以帮助开发者确定问题的根源。DX 寄存器保存的位置是内存地址 0x8206,覆盖掉 GNU GRUB 原来的(2字节的) stage2 version 域。这个 stage2 version 域本身还是有用的,它好像在某种情况下被 grub4dos 用来作为合法 grub.exe 格式或合法 grldr 格式的判断标准。但是,那只是静态的判断,也就是说,只是用于判断 grldr 和 grub.exe 的文件格式,而在 grldr 或 grub.exe 接管控制以后,那个位于内存 0x8206 的 stage2 version 域,已经完全不起作用了。所以,我就把它用作 DX 的备份空间。

在 ud 启动的情形,应该把 ud 的宿主盘的盘号放在位于 0x8206 的字节当中(也就是相应于 DL 的位置;也可以同时把 0x8207 处的字节修改为 0xFF,即相应于 DH 的位置,代表分区号),这个工作我没有做。chenall、yaya 可以考虑把这个弄一下。如果照这样弄好了,那么可以公开这个字节的意义,即,位于 0x8206 的一个字节的值,代表着由 BIOS 或者由 boot sector 传来的真实盘号。(然而在 grub.exe 启动的情形,这个 DX 值是没有什么意义的,所以,这也是个毛病。)

由于当前 root 盘和 boot_drive 都已经被初始化为同一个值,所以,在 ud 启动的情形,用户无法直接得到 BIOS 所传递的盘号,只能通过 fb_status 变量间接得到,这不利于让用户的菜单编程简单化。所以,这个问题需要权衡。

初步考虑,有以下几个办法:

1、正如刚才所说,可以把 ud 的宿主盘盘号记录在 0x8206 的字节上。它的毛病是,此字节并非总是代表 BIOS 的启动盘盘号。

2、创建一个新的变量,用来保存经由 fb_status 修正后的 boot_drive 值。

3、干脆就根据 fb_status 直接修改 boot_drive 的值,让 ud 启动后的当前 root 为 (ud),而 boot_drive 和 install_partition 变量的值分别修正为真实的  BIOS 启动盘盘号和 0xFFFFFF(即分区号为 0xFF,代表着从 MBR 开始的整个盘)。如果最终确定真的要这么修改的话,可以在 init_bios_info() 函数中进行修改。假如我们暂时不考虑经由 DOS 或 Linux 来 “第二启动” grub.exe 的情况,那么,这个 boot_drive 的值就差不多可以说是完全准确的了,它完全反映了 BIOS 所传递的真实启动盘盘号(它有可能是 pd,也有可能是 cd,也有可能是 fd0 以及 hd0,其实大致也只有这几种情况)。那么用户也就可以方便地用它来确定 BIOS 是否把 USB 当作硬盘 hd0 了。

目前我倾向于采用上述第三种方案。由于 ud 本身的特殊性,我觉得这个方案是比较合理的。但这会不会带来某些兼容性问题?它会带来多大的好处和坏处?都需要你们来评估。请 chenall 你们来权衡和决定。



作者: zyphio    时间: 2015-3-9 20:23
不点 发表于 2015-3-9 18:24
请 chenall、yaya 留意这个问题。

当 grldr 或 grub.exe 接管控制时,在 asm.S 的最开头,我设置了一个  ...

看来已个问题有解了。感谢各位大大!
作者: chiannet    时间: 2015-3-9 20:29
本帖最后由 chiannet 于 2015-3-9 20:34 编辑
  1. title KonBoot 2.1 绕过密码
  2. map --mem ()/BOOT/IMGS/KON.IMG (fd0)
  3. if "%@root%"=="(ud)" && calc *0x82A0=*0x82b9&0xff
  4. if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)
  5. map --rehook
  6. chainloader (fd0)+1
  7. rootnoverify (fd0)
复制代码



捣鼓成这样可否?
作者: 不点    时间: 2015-3-9 21:37
chiannet 发表于 2015-3-9 20:29
捣鼓成这样可否?

貌似不错。至于说可靠与否,由熟悉的人来鉴定。

但这个写法,仍然太复杂,技术性太强。需要有个简单的处理方案,也就是说,有必要讨论 grub4dos 的改进方案。

既然说到了改进,那就顺便说说我的另外一个改进建议。

那就是稍稍改进一下 boot 命令,让它带一个设备参数,目的就是为引导扇区传递 DL 寄存器的值。用法大致如下:

boot [ device ]

例如:boot (hd0) 相当于执行 rootnoverify (hd0) 和 boot 两条命令。这样大家就可以简化某些菜单程序了。


作者: zyphio    时间: 2015-3-9 22:08
chiannet 发表于 2015-3-9 20:29
捣鼓成这样可否?

哈,怎么看着那么熟悉啊,if句是grldr默认载入菜单的方式,求高手大大们解释一下含义,我们菜鸟可以学习学习!
作者: zyphio    时间: 2015-3-9 22:11
不点 发表于 2015-3-9 21:37
貌似不错。至于说可靠与否,由熟悉的人来鉴定。

但这个写法,仍然太复杂,技术性太强。需要有个简单的 ...

哇吓,boot [device],这样大好!
记得几年前就问过不点大大关于boot的用法,当时就觉得boot命令,放在菜单最后面有和没一个样,有点浪费了这个易记的好单词啊!
作者: zyphio    时间: 2015-3-9 22:38
本帖最后由 zyphio 于 2015-3-9 23:53 编辑
不点 发表于 2015-3-9 16:30
但假如你 find --set-root 的结果是 (ud),这就回到前面的话题了,那么,你又该如何?

ud 所在的宿主盘 ...


是这样的,我忘记说了,我的U盘用的是我自己想出来的制作方案:

UD(U盘最前面16384个扇区,含fbinst引导扇区、UD主数据区,不含UD扩展数据区,主数据区仅有grldr)
+
exFAT(主分区,U盘主要存储数据区,用于日常存储超过4GB的文件,激活)
+
FAT16(主分区,类似U+V2的高端隐藏,内含各引导文件和镜像,以及UEFI启动的文件)

http://bbs.wuyou.net/forum.php?m ... p;extra=#pid3055441

我用这个方案解决了几起纯UD启动加载扩展数据区的文件失败或扩展数据区读写慢的问题,还同时以最小成本,集UD的万能启动、UEFI启动、大文件存储于一身。虽失去的是UD的相对于常规分区软件的隐藏性,但好在高端隐藏在一定程度上弥补了这个遗憾。

话说回来,在我这个方案下,Konboot.img是在高端隐藏分区,find后根设备要么是h类,要么是f类,不会是ud。所以回避了这如果根设备是ud的问题,还好23楼chiannet的 if "%@root%"=="(ud)" && calc *0x82A0=*0x82b9&0xff解决根设备是ud的问题,再次感谢!
作者: captain_g    时间: 2015-3-10 13:15
单硬盘,ud优盘启动,ud为hd0或fd0时,均测试成功加载konboot.img后进入硬盘系统!
(2014-11-11的0.46a)

konboot.img 在ud区中 的菜单是:

title KonBoot2.4绕过登录密码
map --mem ()/boot/konboot.img (fd0)
if "%@root%"=="(ud)" && calc *0x82a0=*0x82b9&0xff
if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)
map --rehook
chainloader (fd0)+1
rootnoverify (fd0)

konboot.img 在非ud区中 的菜单是:

title KonBoot2.4绕过登录密码
find --set-root /konboot.img
map --mem /konboot.img (fd0)
if "%@root%"=="(ud)" && calc *0x82a0=*0x82b9&0xff
if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)
map --rehook
chainloader (fd0)+1
rootnoverify (fd0)
作者: captain_g    时间: 2015-3-10 13:17
我在命令环境下手动输入
if "%@root%"=="(ud)" && calc *0x82a0=*0x82b9&0xff
后,再用
echo "%@root:~1,1%"
看到的是
"u"
在ud是hd0的情况下,为什么也成功进了硬盘呢?
难道是因为konboot.img?
或者说无需交换(hd0)和(hd1)?
作者: zyphio    时间: 2015-3-10 13:58
本帖最后由 zyphio 于 2015-3-10 13:59 编辑
captain_g 发表于 2015-3-10 13:17
我在命令环境下手动输入
if "%@root%"=="(ud)" && calc *0x82a0=*0x82b9&0xff
后,再用


我的理解是:

不用管konboot.img在不是ud或非ud区,先执行:
find --set-root /任意位置/konboot.img
此时root设备有可能是u\h\f等类型

执行:
if "%@root%"=="(ud)" && calc *0x82a0=*0x82b9&0xff,
即当上一步得到的root设备是ud(u类型),那么就把*0x82A0处(root设备)赋值为*0x82b9处的高位(指boot设备对吧?),

此时root设备有可能是h\f等类型了,接着执行:
if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)
即如果root设备是h类的,则交换(hd0)和(hd1),如是f等其他类型的则不交换。
最后chainloader加载konboot,konboot将默认引导(hd0)。
作者: captain_g    时间: 2015-3-10 15:05
我的意思是:
1、U盘启动后root肯定是ud(未用过find --set-root等);
2、konboot.img在ud区(无需用find --set-root等);
3、在确定u盘是hd0的情况下(启动时按c后用find查看的);
4、执行if "%@root%"=="(ud)" && calc *0x82a0=*0x82b9&0xff后;
5、实际上查看到的是"%@root:~1,1%"=="u",并不是=="h";
6、也即:if "%@root:~1,1%"=="h" && map (hd0) (hd1) && map (hd1) (hd0)这句应该不会执行,(hd0) (hd1)并没有交换;
7、问题来了:为什么最终进的是硬盘而不是U盘?

是我理解不透或错了?还是手工输入与在菜单中使用那两行有可能会出现不同结果?还是那两行有潜在问题,成功有偶然因素?

本人小白,没用过这样复杂且深的方法,尝试一下,想了解透一点而已。

G4D的帮助文档中说这一句:if "%@root%"=="(ud)" && calc *0x82a0=*0x82b9&0xff 的作用是:如果当前ROOT是(ud),设置当前磁盘为(ud)所在磁盘,比如(fd0)或(hd0),

也就是说在ud启动的情况下,这时,"%@root:~1,1%"应是"h" 或 "f"
作者: zyphio    时间: 2015-3-10 16:28
本帖最后由 zyphio 于 2015-3-10 16:38 编辑
captain_g 发表于 2015-3-10 15:05
我的意思是:
1、U盘启动后root肯定是ud(未用过find --set-root等);
2、konboot.img在ud区(无需用fin ...


我也小白啊,确实你的思路没错,确实存在这个有趣的问题。

不过发现我自己的理解居然与G4D帮助文档里对第一个if句的解释是一样的(哈,我之前没看过这帮助哩)。

但有一点,root设备和boot设备不是一回事!不点大大前面提到改进就是想确保boot设备可被用户容易且准确识别好管理。

我都是把konboot.img外置到U盘常规分区上的,再find这img后root不会是u类,可能会是h\f\c等类型,实际上查看到的是"%@root:~1,1%"确实为"h"类,map交换有生效;。

谢谢哦,晚上再研究研究。




作者: captain_g    时间: 2015-3-11 12:42
chiannet 发表于 2015-3-9 20:29
捣鼓成这样可否?

我捣鼓成下面这样,测试均成功(UD启动后U盘被识别为hd0或fd0)!

title  KonBoot2.4绕过登录密码
map --mem ()/boot/konboot.img (fd0)
if "%@root%"=="(ud)" && set /a xyz=*0x82b9&0xff
if %xyz%==128 && map (hd0) (hd1) && map (hd1) (hd0)
map --rehook
chainloader (fd0)+1
rootnoverify (fd0)

或者

title  KonBoot2.4绕过登录密码
map --mem ()/boot/konboot.img (fd0)
if "%@root%"=="(ud)" && set /a xyz=*0x82b8&0xff00
if %xyz%==32768 && map (hd0) (hd1) && map (hd1) (hd0)
map --rehook
chainloader (fd0)+1
rootnoverify (fd0)

你的也是成功的,改动的出发点见#29、31。
作者: zyphio    时间: 2015-3-11 15:05
本帖最后由 zyphio 于 2015-3-11 15:13 编辑
captain_g 发表于 2015-3-11 12:42
我捣鼓成下面这样,测试均成功(UD启动后U盘被识别为hd0或fd0)!

title  KonBoot2.4绕过登录密码


发现之前一直在绕弯路,总把问题复杂化:

本意——

只要确认是从这个设备上启动Konboot,要被Konboot引导的Win/linux/MAC OS在另一个硬盘上,而这个启动设备占用了(hd0),就交换(hd0)和(hd1)。

那么——

1.不用管启动盘是什么硬件设备,无论U盘、USB/eSATA移动硬盘、光盘、ZIP驱等。
2.不用管启动后或者find后,root是什么,是ud也好,是fd0也行,是常规的分区也罢。
3.直接检查启动Konboot的设备所在的驱动器是不是被BIOS认为(hd0),一行命令去确认就行了,是的话,就交换(hd0)和(hd1)后听天由命去:

title KonBoot
        find --set-root /konboot.img
        map --mem /konboot.img (fd0)
        checkrange 0x80 calc *0x82b9&0xff && map (hd0) (hd1) && map (hd1) (hd0)
        map --hook
        chainloader (fd0)+1
        rootnoverify (fd0)

这样少事也好理解,求高手鉴定。

作者: 不点    时间: 2015-3-11 15:23
zyphio 发表于 2015-3-11 15:05
发现之前一直在绕弯路,总把问题复杂化:

本意——

你好像掉进漩涡了——开个玩笑。

82b9 处是 fb_status 的一个字节。假如不是从 ud 启动,这里的字节都是 00,无意义。

因此,假如不是从 ud 启动,你就不该访问这里的字节。


作者: captain_g    时间: 2015-3-11 15:34
zyphio 发表于 2015-3-11 15:05
发现之前一直在绕弯路,总把问题复杂化:

本意——

checkrange 0x80 calc *0x82b9&0xff && map (hd0) (hd1) && map (hd1) (hd0)

这一句在UD优盘启动的情况下,可能没问题,*0x82b9与0xff按位与运算后得到可能是0x80或0x0;

如果是普通U启的情况,0x82b9的右两位,很可能不是80,即*0x82b9与0xff按位与运算后可能经常得不到0x80!而这时0x8280和0x82a0却是80!

在这种情况下,可能应该使用 checkrange 0x80 read 0x8280 && ...

或者

checkrange 0x80 read 0x82a0 && ...
作者: zyphio    时间: 2015-3-11 15:46
captain_g 发表于 2015-3-11 15:34
checkrange 0x80 calc *0x82b9&0xff && map (hd0) (hd1) && map (hd1) (hd0)

这一句在UD优盘启动的情 ...

哦,原来这样,那就再加这句在后面:
checkrange 0x80 calc *0x8280&0xff && map (hd0) (hd1) && map (hd1) (hd0)

有可能*0x82b9与*x8280或*0x82b0后来两位同时是80的情况么?即不点大大#21楼提到的,用户不容易准确得BIOS层面的启动盘盘号。
作者: captain_g    时间: 2015-3-11 16:06
我在真机上试了,如果是普通U启(无UD、未量产、未分区),在命令环境下:
read 0x8280 或 read 0x82a0,它们的value都是0x80(当然也可能是0x0吧),
我不知道这个有没有普遍性,道理只能由 不点 来解释了。
也就是说没必要再做*0x8280&0xff运算了,不如直接:
checkrange 0x80 read 0x8280 && map (hd0) (hd1) && map (hd1) (hd0)(没试过,初学不知语法对不对)
作者: zyphio    时间: 2015-3-11 16:09
不点 发表于 2015-3-11 15:23
你好像掉进漩涡了——开个玩笑。

82b9 处是 fb_status 的一个字节。假如不是从 ud 启动,这里的字节都 ...

谢谢老大,我只是一直在思考你24#说的,写法能不能好理解一些,好像还是不行,还是得像您#21楼说的那样,等用户可以方便通过某个命令得知BIOS真实启动设备再说了。
作者: zyphio    时间: 2015-3-11 16:15
captain_g 发表于 2015-3-11 16:06
我在真机上试了,如果是普通U启(无UD、未量产、未分区),在命令环境下:
read 0x8280 或 read 0x82a0, ...

试过直接检测0x8280,但宿主为hd0的ud启动后,这个的值是0x23,即还是ud,所以这个判断不会交换(hd0)(hd1),达不到效果。
作者: zyphio    时间: 2015-3-11 16:30
本帖最后由 zyphio 于 2015-3-11 16:57 编辑
captain_g 发表于 2015-3-11 12:42
我捣鼓成下面这样,测试均成功(UD启动后U盘被识别为hd0或fd0)!

title  KonBoot2.4绕过登录密码


刚虚拟机下试了,才突然发现,这样有一个问题,从U盘常规分区下启动,U被识别为(hd0)了,但第一个if句没生效,xyz变量没赋值,第二个if也无法生效,这样根本没交换(hd0)和(hd1)。

结合chreckrange命令,我改成这样:

title KonBoot
        find --set-root /konboot.img
        map --mem /konboot.img (fd0)
        if "%@root%"=="(ud)" && calc *0x82A0=*0x82b9&0xff
        checkrange 0x80 read 0x82a0 && map (hd0) (hd1) && map (hd1) (hd0)
        map --hook
        chainloader (fd0)+1
        rootnoverify (fd0

这样,konboot.img在U盘上——
若是ud启动,则if句把root设备定义为ud的宿主设备,检测root设备是否是(hd0);
如果不是ud启动,if句没生效,直接检测root设备是否是(hd0)。

至少比前面直接检测root设备是否是h类更细颗粒化一些。

作者: captain_g    时间: 2015-3-11 17:02
刚刚我又手工重试了一下#23楼chiannet的菜单,没有再现我在#29和#31楼提到现象,原因可能是我昨天手动输入有误。

那几句与grldr本身内置的菜单命令相仿,内置的菜单命令已经过无数人这么久的使用,应该是没有问题的。

总结:UD U启的菜单命令 与 普通U盘 U起的菜单,是很难做到一单通用的,应该根据不同的情况分别拟写,以确保正确、成功。

还有,我在#33楼提供的菜单示例,只能用于UD U启方式。如果要用在普通U盘 U起的情况下使用,应做修改(可参见#36、#38楼)。
作者: zyphio    时间: 2015-3-11 17:04
zyphio 发表于 2015-3-11 16:30
刚虚拟机下试了,才突然发现,这样有一个问题,从U盘常规分区下启动,U被识别为(hd0)了,但第一个if句 ...


另外,改成0x8280更符合逻辑一些,因为万一konboot.img在别的盘呢。

我们知道从U盘(可能是常规分区、UD分区)启动,0x8280才是boot device,即是U盘,可能被BIOS识别为ud、fd、hd、cd等。

假如,是从U盘常规分区启动后,我从内置硬盘(hd1)的任意分区找到konboot.img,载入,0x82A0处root device已经变了,成了内置硬盘(hd0),如果用082a0的值去检测,就无map交换了!

所以,上面我再修改为:

title KonBoot
        find --set-root /konboot.img
        map --mem /konboot.img (fd0)
        if "%@root%"=="(ud)" && calc *0x8280=*0x82b9&0xff
        checkrange 0x80 read 0x8280 && map (hd0) (hd1) && map (hd1) (hd0)
        map --hook
        chainloader (fd0)+1
        rootnoverify (fd0)
作者: zyphio    时间: 2015-3-11 17:06
captain_g 发表于 2015-3-11 17:02
刚刚我又手工重试了一下#23楼chiannet的菜单,没有再现我在#29和#31楼提到现象,原因可能是我昨天手动输入 ...


我曾经也认为可能是你录入手误,但想想也有万一,看来我们都得仔细点,请帮我鉴定一下43#的想法,可以么?
作者: captain_g    时间: 2015-3-11 17:07
zyphio 发表于 2015-3-11 17:06
我曾经也认为可能是你录入手误,但想想也有万一,看来我们都得仔细点,请帮我鉴定一下43#的想法,可以 ...

注意啊!
G4D帮助文档中说:
使用 boot 或 configfile 命令会改变启动设备(即0x8280的值)。
作者: zyphio    时间: 2015-3-11 17:13
captain_g 发表于 2015-3-11 17:07
注意啊!
G4D帮助文档中说:
使用 boot 或 configfile 命令会改变启动设备(即0x8280的值)。

所以,这适用于开机后没执行过boot,还有配置文件在U盘上的情况。

小白滴偶,能否把你说的G4D帮助文档给个链接我看看?
作者: zyphio    时间: 2015-3-11 17:33
captain_g 发表于 2015-3-11 17:07
注意啊!
G4D帮助文档中说:
使用 boot 或 configfile 命令会改变启动设备(即0x8280的值)。

其实仔细想想,无法回避一切可能,即使是使用0x80A0的值,也容易遇到find、root等命令的修改啊

结合chreckrange命令,我最新改成这样,一来至少比之前直接检测root设备是否是h类更细颗粒化一些,二来适应从U盘UD分区或常规分区启动,三来支持从其他设备载入konboot.img(只要相对路径正确)。

使用0x8280位置的前提启动后没有执行过针对其他驱动器的boot或configfile命令。

title KonBoot
        if "%@root%"=="(ud)" && calc *0x8280=*0x82b9&0xff
        checkrange 0x80 read 0x8280 && map (hd0) (hd1) && map (hd1) (hd0)
        find --set-root /konboot.img
        map --mem /konboot.img (fd0)
        map --hook
        chainloader (fd0)+1
        rootnoverify (fd0)
作者: 不点    时间: 2015-3-11 17:49
如果不是 ud 启动,那当然比较容易做了。此处我就不想再重复说了。

关键就是 ud 启动时,用户不能方便地获得原始的 bios 启动盘盘号(00h 或 80h),所以,才有这样一些问题的出现。虽然说用一条菜单语句可以完成这个检测,但是,这个方法不容易被初次接触的人理解和掌握。所以,我觉得这有改进的余地。改进的目的是让 grub4dos 的用户更容易理解和掌握。

对于开发者来说,可以仔细研究这个问题能否改进以及如何改进。

对于用户来讲,假如开发者由于某种原因(或者某种权衡)没能采取任何改进措施,那么用户应该学习有关 ud 的一些知识,理解那些变量的意义,写好自己的菜单。

另外,有些用户其实是可以避免使用 ud 的。zyphio 曾经谈到,他自己使用 ud,只在 ud 区放置一个 grldr 文件,其他文件都在可见区。一句话,zyphio 不需要 ud 的隐藏功能。既然如此,我觉得 zyphio 可以用我去年开发的 multimbr 来代替 ud,这样就不会出现上述所讨论的那些与 ud 有关的问题了。


作者: zyphio    时间: 2015-3-11 18:56
不点 发表于 2015-3-11 17:49
如果不是 ud 启动,那当然比较容易做了。此处我就不想再重复说了。

关键就是 ud 启动时,用户不能方便地 ...

谢谢不点大大,我确实太小白了,菜鸟一个,纯纠结啊。。哈。。。

我觉得启动盘首要因素是兼容性,其次才是安全、功能、效率等,那multimbr?!是不是类似fbinst引导扇区的功能?搜索了一圈没找到,望大大能提供个下载链接与帮助文档,我想好好学习一下。
作者: zyphio    时间: 2015-3-11 20:02
不点 发表于 2015-3-11 17:49
如果不是 ud 启动,那当然比较容易做了。此处我就不想再重复说了。

关键就是 ud 启动时,用户不能方便地 ...

找不到啊,求multimbr,thanx
作者: 不点    时间: 2015-3-11 20:08
zyphio 发表于 2015-3-11 18:56
谢谢不点大大,我确实太小白了,菜鸟一个,纯纠结啊。。哈。。。

我觉得启动盘首要因素是兼容性,其次 ...


http://bbs.wuyou.net/forum.php?mod=viewthread&tid=320244


作者: captain_g    时间: 2015-3-11 20:30
zyphio 发表于 2015-3-11 17:13
所以,这适用于开机后没执行过boot,还有配置文件在U盘上的情况。

小白滴偶,能否把你说的G4D帮助文档 ...

http://bbs.wuyou.net/forum.php?m ... &extra=page%3D1
作者: captain_g    时间: 2015-3-11 21:06
zyphio 发表于 2015-3-11 17:33
其实仔细想想,无法回避一切可能,即使是使用0x80A0的值,也容易遇到find、root等命令的修改啊

结合ch ...

如果是【UD U启】,还是建议你按#23、#28楼的示例来拟制菜单。
菜单内置到UD中的GRLDR中或放置中UD中。
强力建议你将konboot.img放在UD区中,lzma压缩后也就 几K 到 十几K,可以避免搜索。
这个比较可靠,因为 0x82b9、0x82b8 的值好像不随 root, find --set-root, boot, configfile 操作而改变。

当然了,在实际使用中,如果你需要使用 konboot.img 去绕过登录密码,估计也不会跑一大圈才来。

我以前使用简单笨拙的方法,写了两个菜单选项,一个针对U盘为 hd0 的情形,另一个针对为 fd0 的情形。在前一个中用fallback指向后一个,如果失败则自动切换到后一个。如果不怕死循环,就在后一个中再用fallback指向前一个,操作时随便按那一个!
作者: zyphio    时间: 2015-3-11 21:18
captain_g 发表于 2015-3-11 21:06
如果是【UD U启】,还是建议你按#23、#28楼的示例来拟制菜单。
菜单内置到UD中的GRLDR中或放置中UD中。
...

好的,谢谢你哈,我也研究研究。
作者: zyphio    时间: 2015-3-11 21:19
captain_g 发表于 2015-3-11 20:30
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=185938&extra=page%3D1

呃,好久前就有下载了,没仔细去学习,我X。。
作者: zyphio    时间: 2015-3-11 21:20
不点 发表于 2015-3-11 20:08
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=320244

谢谢不点大大,喜欢算扇区,我去研究研究
作者: zyphio    时间: 2015-3-22 18:59
本帖最后由 zyphio 于 2015-3-23 09:00 编辑

今天重新看了一下不点大大21#楼的想法,结合C大大前几天回答我关于find命令应用的疑问,我突然有了新的点子,重新写了此菜单,虽无什么复杂技术,但精妙之处有二,一是尽量完美的解决Konboot加载交换hd的的问题,二来保证只从grldr所在“设备”(即使是不同分区)上读取外置菜单和Konboot镜像等文件,同时兼容UD!

grldr内置菜单:

  1. errorcheck off
  2. set /A firstbd=*0x82a0
  3. configfile /boot/menu.lst
  4. if "%firstbd%"=="0x23" && set /A firstbd=*0x82b9&0xff
  5. find --set-root /boot/menu.lst checkrange %firstbd% read 0x82a0 && configfile /boot/menu.lst
  6. echo Can't find the configuration file form the first boot device.
  7. pause Press any key to continue...
  8. errorcheck on
复制代码


menu.lst外置菜单:

  1. title KonBoot
  2.         map --unmap=0:255
  3.         map --rehook
  4.         find --set-root /boot/konboot.img checkrange %firstbd% read 0x82a0
  5.         map --mem /boot/konboot.img (fd0)
  6.         map --hook
  7.         if "%firstbd%"=="0x23" && set /A firstbd=*0x82b9&0xff
  8.         if "%firstbd%"=="0x80" && map (hd0) (hd1) && map (hd1) (hd0) && map --rehook
  9.         chainloader (fd0)+1
  10.         rootnoverify (fd0)

  11. title Windows Version 5 PE (32bit)
  12.         map --unmap=0:255
  13.         map --rehook
  14.         find --set-root /boot/win5pe32.iso checkrange %firstbd% read 0x82a0
  15.         map --mem /boot/win5pe32.iso (0xff)
  16.         map --hook
  17.         chainloader (0xff)
  18.         rootnoverify (0xff)

  19. title DiskGenius (DOS)
  20.         map --unmap=0:255
  21.         map --rehook
  22.         find --set-root /boot/dgdos.img checkrange %firstbd% read 0x82a0
  23.         map --mem /boot/dgdos.img (fd0)
  24.         map --hook
  25.         chainloader (fd0)+1
  26.         rootnoverify (fd0)
复制代码





欢迎光临 无忧启动论坛 (http://wuyou.net/) Powered by Discuz! X3.3