|
我看<<加密与解密(2)>>
我买过两本书:首先是风飘雪的,对刚入门的cracker 能激发兴趣,也比较详细,实例也多,不过设及的方面不太多,且书中有些错误没有更正。有些问题含糊不清,但还是一本不错的书,主要是由浅到深能激发学者的信心,这就够了。再后,我买了第二本这方面书:由本论坛打造的由段刚编的第二版书,涉及的方面虽多,可许多只是谈到高潮时卡喳而止。让我们有点被半途抛弃的感觉,希望编者能把读者当作自己的学生一样,循序渐进。比如书中关于某些脱壳时,只是单一的upx最多,而其它的壳机理和脱壳过程并不多。我的愿望是希望作者能带着读者,慢慢前进。同时插入少量激发读者的文章。 |
|
两篇关于汇编方面的文章
fly大哥 ,谢谢你的关心,由于时间的限制,我只有回复和贴贴子,如果你有时间或愿意的话,请帮忙把它上精华,谢谢!。另外,如果你愿意的话,我把我的小小软件通过qq传给你,你作个ftp或http让大家下载共享。谢谢!qq:122253385 |
|
版主,哪里有光盘可以下载?
哈哈,我买了 这本书,不错 |
|
两篇关于汇编方面的文章
以上几篇算我对此论坛的支持而而作点小奉献,有些摘自微软内部资料!本人酷爱汇编,为了纪念江民先生的逻辑锁亲自作了一个一键恢复分区表的软盘上的程序,有兴趣小试一翻,这也是我研究和破解还原卡自己用的软件,由于受上传文件大小限制,不便上传,我把它传给fly兄,让他帮忙开个页面下载,也可向QQ :122253385索取。dsxu8@sina.com |
|
两篇关于汇编方面的文章
扩展int13h调用详解 第一部分 简 介 一. 硬盘结构简介 1. 硬盘参数释疑 到目前为止, 人们常说的硬盘参数还是古老的 CHS (Cylinder/ Head/Sector)参数. 那么为什么要使用这些参数, 它们的意义是什么? 它们的取值范围是什么? 很久以前, 硬盘的容量还非常小的时候, 人们采用与软盘类似的结 构生产硬盘. 也就是硬盘盘片的每一条磁道都具有相同的扇区数. 由此 产生了所谓的3D参数 (Disk Geometry). 既磁头数(Heads), 柱面数 (Cylinders), 扇区数(Sectors),以及相应的寻址方式. 其中: 磁头数(Heads) 表示硬盘总共有几个磁头,也就是有几面盘片, 最大 为 255 (用 8 个二进制位存储); 柱面数(Cylinders) 表示硬盘每一面盘片上有几条磁道, 最大为 1023 (用 10 个二进制位存储); 扇区数(Sectors) 表示每一条磁道上有几个扇区, 最大为 63 (用 6 个二进制位存储). 每个扇区一般是 512个字节, 理论上讲这不是必须的, 但好象没有取 别的值的. 所以磁盘最大容量为: 255 * 1023 * 63 * 512 / 1048576 = 8024 MB ( 1M = 1048576 Bytes ) 或硬盘厂商常用的单位: 255 * 1023 * 63 * 512 / 1000000 = 8414 MB ( 1M = 1000000 Bytes ) 在 CHS 寻址方式中, 磁头, 柱面, 扇区的取值范围分别为 0 到 Heads - 1, 0 到 Cylinders - 1, 1 到 Sectors (注意是从 1 开始). 2. 基本 Int 13H 调用简介 BIOS Int 13H 调用是 BIOS 提供的磁盘基本输入输出中断调用, 它可以 完成磁盘(包括硬盘和软盘)的复位, 读写, 校验, 定位, 诊断, 格式化等功能. 它使用的就是 CHS 寻址方式, 因此最大识能访问 8 GB 左右的硬盘 ( 本文中 如不作特殊说明, 均以 1M = 1048576 字节为单位). 3. 现代硬盘结构简介 在老式硬盘中, 由于每个磁道的扇区数相等, 所以外道的记录密度要远低 于内道, 因此会浪费很多磁盘空间 (与软盘一样). 为了解决这一问题, 进一 步提高硬盘容量, 人们改用等密度结构生产硬盘. 也就是说, 外圈磁道的扇区 比内圈磁道多. 采用这种结构后, 硬盘不再具有实际的3D参数, 寻址方式也改 为线性寻址, 即以扇区为单位进行寻址. 为了与使用3D寻址的老软件兼容 (如使用BIOS Int13H接口的软件), 在硬 盘控制器内部安装了一个地址翻译器, 由它负责将老式3D参数翻译成新的线性 参数. 这也是为什么现在硬盘的3D参数可以有多种选择的原因 (不同的工作模 式, 对应不同的3D参数, 如 LBA, LARGE, NORMAL). 4. 扩展 Int 13H 简介 虽然现代硬盘都已经采用了线性寻址, 但是由于基本 Int 13H 的制约, 使 用 BIOS Int 13H 接口的程序, 如 DOS 等还只能访问 8 G 以内的硬盘空间. 为了打破这一限制, Microsoft 等几家公司制定了扩展 Int 13H 标准 (Extended Int13H), 采用线性寻址方式存取硬盘, 所以突破了 8 G 的限制, 而且还加入了对可拆卸介质 (如活动硬盘) 的支持. 二. Boot Sector 结构简介 1. Boot Sector 的组成 Boot Sector 也就是硬盘的第一个扇区, 它由 MBR (Master Boot Record), DPT (Disk Partition Table) 和 Boot Record ID 三部分组成. MBR 又称作主引导记录占用 Boot Sector 的前 446 个字节 ( 0 to 0x1BD ), 存放系统主引导程序 (它负责从活动分区中装载并运行系统引导程序). DPT 即主分区表占用 64 个字节 (0x1BE to 0x1FD), 记录了磁盘的基本分区 信息. 主分区表分为四个分区项, 每项 16 字节, 分别记录了每个主分区的信息 (因此最多可以有四个主分区). Boot Record ID 即引导区标记占用两个字节 (0x1FE and 0x1FF), 对于合法 引导区, 它等于 0xAA55, 这是判别引导区是否合法的标志. Boot Sector 的具体结构如下图所示 (参见 NightOwl 大侠的文章): 0000 |------------------------------------------------| | | | | | Master Boot Record | | | | | | 主引导记录(446字节) | | | | | | | 01BD | | 01BE |------------------------------------------------| | | 01CD | 分区信息 1(16字节) | 01CE |------------------------------------------------| | | 01DD | 分区信息 2(16字节) | 01DE |------------------------------------------------| | | 01ED | 分区信息 3(16字节) | 01EE |------------------------------------------------| | | 01FD | 分区信息 4(16字节) | |------------------------------------------------| | 01FE | 01FF | | 55 | AA | |------------------------------------------------| 2. 分区表结构简介 分区表由四个分区项构成, 每一项的结构如下: BYTE State : 分区状态, 0 = 未激活, 0x80 = 激活 (注意此项) BYTE StartHead : 分区起始磁头号 WORD StartSC : 分区起始扇区和柱面号, 底字节的低6位为扇区号, 高2位为柱面号的第 9,10 位, 高字节为柱面号的低 8 位 BYTE Type : 分区类型, 如 0x0B = FAT32, 0x83 = Linux 等, 00 表示此项未用 BYTE EndHead : 分区结束磁头号 WORD EndSC : 分区结束扇区和柱面号, 定义同前 DWORD Relative : 在线性寻址方式下的分区相对扇区地址 (对于基本分区即为绝对地址) DWORD Sectors : 分区大小 (总扇区数) 注意: 在 DOS / Windows 系统下, 基本分区必须以柱面为单位划分 ( Sectors * Heads 个扇区), 如对于 CHS 为 764/255/63 的硬盘, 分区的 最小尺寸为 255 * 63 * 512 / 1048576 = 7.844 MB. 3. 扩展分区简介 由于主分区表中只能分四个分区, 无法满足需求, 因此设计了一种扩展 分区格式. 基本上说, 扩展分区的信息是以链表形式存放的, 但也有一些特 别的地方. 首先, 主分区表中要有一个基本扩展分区项, 所有扩展分区都隶属于它, 也就是说其他所有扩展分区的空间都必须包括在这个基本扩展分区中. 对于 DOS / Windows 来说, 扩展分区的类型为 0x05或0x0F(>8GB). 除基本扩展分区以外的其他所有扩展分区则以链表的形式级联存放, 后 一个扩展分区的数据项记录在前一个扩展分区的分区表中, 但两个扩展分区 的空间并不重叠. 扩展分区类似于一个完整的硬盘, 必须进一步分区才能使用. 但每个扩 展分区中只能存在一个其他分区. 此分区在 DOS/Windows 环境中即为逻辑盘. 因此每一个扩展分区的分区表 (同样存储在扩展分区的第一个扇区中)中最多 只能有两个分区数据项(包括下一个扩展分区的数据项). 扩展分区和逻辑盘的示意图如下: |-----------------------| -------- | 主扩展分区(/dev/hda2) | ^ |-----------------------| | | 扩 展 | 分区项 1 |--\ | | |------------| | | | 分区表 | 分区项 2 |--+--\ | |-----------------------| | | | | | | | | | 逻辑盘 1 (/dev/hda5) |<-/ | | | | | | |-----------------------| | 主 | 扩展分区 2 |<----/ |-----------------------| 扩 | 扩 展 | 分区项 1 |--\ | |------------| | 展 | 分区表 | 分区项 2 |--+--\ |-----------------------| | | 分 | | | | | 逻辑盘 2 (/dev/hda6) |<-/ | 区 | | | | |-----------------------| | | | 扩展分区 3 |<----/ | |-----------------------| | | 扩 展 | 分区项 1 |--\ | | |------------| | | | 分区表 | | | | |-----------------------| | | | | | | | 逻辑盘 3 (/dev/hda7) |<-/ | | | | |-----------------------| --------- 三. 系统启动过程简介 系统启动过程主要由一下几步组成(以硬盘启动为例): 1. 开机 :-) 2. BIOS 加电自检 ( Power On Self Test -- POST ) 内存地址为 0ffff:0000 3. 将硬盘第一个扇区 (0头0道1扇区, 也就是Boot Sector) 读入内存地址 0000:7c00 处. 4. 检查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于 则转去尝试其他启动介质, 如果没有其他启动介质则显示 "No ROM BASIC" 然后死机. 5. 跳转到 0000:7c00 处执行 MBR 中的程序. 6. MBR 首先将自己复制到 0000:0600 处, 然后继续执行. 7. 在主分区表中搜索标志为活动的分区. 如果发现没有活动 分区或有不止一个活动分区, 则转停止. 8. 将活动分区的第一个扇区读入内存地址 0000:7c00 处. 9. 检查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于则 显示 "Missing Operating System" 然后停止, 或尝试 软盘启动. 10. 跳转到 0000:7c00 处继续执行特定系统的启动程序. 11. 启动系统 ... 以上步骤中 2,3,4,5 步是由 BIOS 的引导程序完成. 6,7,8,9,10 步由MBR中的引导程序完成. 一般多系统引导程序 (如 SmartFDISK, BootStar, PQBoot 等) 都是将标准主引导记录替换成自己的引导程序, 在运行系统启动程序 之前让用户选择要启动的分区. 而某些系统自带的多系统引导程序 (如 lilo, NT Loader 等) 则可以将自己的引导程序放在系统所处分区的第一个扇区中, 在 Linux 中即为 SuperBlock (其实 SuperBlock 是两个扇区). 注: 以上各步骤中使用的是标准 MBR, 其他多系统引导程序的引导 过程与此不同. 第二部分 技术资料 第一章 扩展 Int13H 技术资料 一. 简介 设计扩展 Int13H 接口的目的是为了扩展 BIOS 的功能, 使其支持 多于1024柱面的硬盘, 以及可移动介质的琐定, 解锁及弹出等功能. 二. 数据结构 1. 数据类型约定 BYTE 1 字节整型 ( 8 位 ) WORD 2 字节整型 ( 16 位 ) DWORD 4 字节整型 ( 32 位 ) QWORD 8 字节整型 ( 64 位 ) 2. 磁盘地址数据包 Disk Address Packet (DAP) DAP 是基于绝对扇区地址的, 因此利用 DAP, Int13H 可以轻松地逾 越 1024 柱面的限制, 因为它根本就不需要 CHS 的概念. DAP 的结构如下: struct DiskAddressPacket { BYTE PacketSize; // 数据包尺寸: //(固定值,恒等于16,即10H,指本结构所占用的存储空间) BYTE Reserved; // ==0 WORD BlockCount; // 要传输的数据块个数(以扇区为单位) DWORD BufferAddr; // 传输缓冲地址(segment:offset) QWORD BlockNum; // 磁盘起始绝对块地址 }; PacketSize 保存了 DAP 结构的尺寸, 以便将来对其进行扩充. 在 目前使用的扩展 Int13H 版本中 PacketSize 恒等于 16. 如果它小于 16, 扩展 Int13H 将返回错误码( AH=01, CF=1 ). BlockCount 对于输入来说是需要传输的数据块总数, 对于输出来说 是实际传输的数据块个数. BlockCount = 0 表示不传输任何数据块. BufferAddr 是传输数据缓冲区的 32 位地址 (段地址:偏移量). 数据 缓冲区必须位于常规内存以内(1M). BlockNum 表示的是从磁盘开始算起的绝对块地址(以扇区为单位), 与分区无关. 第一个块地址为 0. 一般来说, BlockNum 与 CHS 地址的关系 是: BlockNum = (cylinder * NumberOfHeads + head) * SectorsPerTrack + sector - 1; 其中 cylinder, head, sector 是 CHS 地址, NumberOfHeads 是磁盘 的磁头数, SectorsPerTrack 是磁盘每磁道的扇区数. 也就是说 BlockNum 是沿着 扇区->磁道->柱面 的顺序记数的. 这一顺 序是由磁盘控制器虚拟的, 磁盘表面数据块的实际排列顺序可能与此不同 (如为了提高磁盘速度而设置的间隔因子将会打乱扇区的排列顺序). 3. 驱动器参数数据包 Drive Parameters Packet 驱动器参数数据包是在扩展 Int13H 的取得驱动器参数子功能调用中 使用的数据包. 格式如下: struct DriveParametersPacket { WORD InfoSize; // 数据包尺寸: //(固定值,等于26,即1AH,指本结构所占用的存储空间) WORD Flags; // 信息标志 DWORD Cylinders; // 磁盘柱面数 DWORD Heads; // 磁盘磁头数 DWORD SectorsPerTrack; // 每磁道扇区数 QWORD Sectors; // 磁盘总扇区数 WORD SectorSize; // 扇区尺寸 (以字节为单位) }; 信息标志用于返回磁盘的附加信息, 每一位的定义如下: 0 位: 0 = 可能发生 DMA 边界错误 1 = DMA 边界错误将被透明处理 如果这位置 1, 表示 BIOS 将自动处理 DMA 边界错误, 也就是说 错误代码 09H 永远也不会出现. 1 位: 0 = 未提供 CHS 信息 1 = CHS 信息合法 如果块设备的传统 CHS 几何信息不适当的话, 该位将置 0. 2 位: 0 = 驱动器不可移动 1 = 驱动器可移动 3 位: 表示该驱动器是否支持写入时校验. 4 位: 0 = 驱动器不具备介质更换检测线 1 = 驱动器具备介质更换检测线 5 位: 0 = 驱动器不可锁定 1 = 驱动器可以锁定 要存取驱动器号大于 0x80 的可移动驱动器, 该位必须置 1 (某些驱动器号为 0 到 0x7F 的设备也需要置位) 6 位: 0 = CHS 值是当前存储介质的值 (仅对于可移动介质), 如果 驱动器中有存储介质, CHS 值将被返回. 1 = CHS 值是驱动器支持的最大值 (此时驱动器中没有介质). 7 - 15 位: 保留, 必须置 0. 三. 接口规范 1. 寄存器约定 在扩展 Int13H 调用中一般使用如下寄存器约定: ds:si ==> 磁盘地址数据包( disk address packet ) dl ==> 驱动器号 ah ==> 功能代码 / 返回码 在基本 Int13H 调用中, 0 - 0x7F 之间的驱动器号代表可移动驱动器 0x80 - 0xFF 之间的驱动器号代表固定驱动器. 但在扩展 Int13H 调用中 0x80 - 0xFF 之间还包括一些新出现的可移动驱动器, 比如活动硬盘等. 这些驱动器支持先进的锁定,解锁等功能. ah 返回的错误码除了标准 Int13H 调用规定的基本错误码以外,又增加 了以下错误码: B0h 驱动器中的介质未被锁定 B1h 驱动器中的介质已经锁定 B2h 介质是可移动的 B3h 介质正在被使用 B4h 锁定记数溢出 B5h 合法的弹出请求失败 2. API 子集介绍 1.x 版的扩展 Int13H 调用中规定了两个主要的 API 子集. 第一个子集提供了访问大硬盘所必须的功能, 包括 检查扩展 In13H 是否存在( 41h ), 扩展读( 42h ), 扩展写( 43h ), 校验扇区( 44h ), 扩展定位( 47h ) 和 取得驱动器参数( 48h ). 第二个子集提供了对软件控制驱动器锁定和弹出的支持, 包括 检查扩展 Int13H 是否存在( 41h ), 锁定/解锁驱动器( 45h ), 弹出驱动器( 46h ), 取得驱动器参数( 48h ), 取得扩展驱动器改变状态( 49h ), int 15h. 如果使用了调用规范中不支持的功能, BIOS 将返回错误码 ah = 01h, CF = 1. 3. API 详解 1) 检验扩展功能是否存在 入口: AH = 41h BX = 55AAh DL = 驱动器号 返回: CF = 0 AH = 扩展功能的主版本号 AL = 内部使用 BX = AA55h CX = API 子集支持位图 CF = 1 AH = 错误码 01h, 无效命令 这个调用检验对特定的驱动器是否存在扩展功能. 如果进位标志置 1 则此驱动器不支持扩展功能. 如果进位标志为 0, 同时 BX = AA55h, 则 存在扩展功能. 此时 CX 的 0 位表示是否支持第一个子集, 1位表示是否 支持第二个子集. 对于 1.x 版的扩展 Int13H 来说, 主版本号 AH = 1. AL 是副版本号, 但这仅限于 BIOS 内部使用, 任何软件不得检查 AL 的值. 2) 扩展读 入口: AH = 42h DL = 驱动器号 DS:DI = 磁盘地址数据包(Disk Address Packet) 返回: CF = 0, AH = 0 成功 CF = 1, AH = 错误码 这个调用将磁盘上的数据读入内存. 如果出现错误, DAP 的 BlockCount 项中则记录了出错前实际读取的数据块个数. 3) 扩展写 入口: AH = 43h AL 0 位 = 0 关闭写校验 1 打开写校验 1 - 7 位保留, 置 0 DL = 驱动器号 DS:DI = 磁盘地址数据包(DAP) 返回: CF = 0, AH = 0 成功 CF = 1, AH = 错误码 这个调用将内存中的数据写入磁盘. 如果打开了写校验选项, 但 BIOS 不支持, 则会返回错误码 AH = 01h, CF = 1. 功能 48h 可以检测BIOS是否 支持写校验. 如果出现错误, DAP 的 BlockCount 项中则记录了出错前实际写入的数 据块个数. 4) 校验扇区 入口: AH = 44h DL = 驱动器号 DS:DI = 磁盘地址数据包(Disk Address Packet) 返回: CF = 0, AH = 0 成功 CF = 1, AH = 错误码 这个调用校验磁盘数据, 但并不将数据读入内存.如果出现错误, DAP 的 BlockCount 项中则记录了出错前实际校验的数据块个数. 5) 锁定/解锁驱动器 入口: AH = 45h AL = 0 锁定驱动器 = 1 驱动器解锁 = 02 返回锁定/解锁状态 = 03h-FFh - 保留 DL = 驱动器号 返回: CF = 0, AH = 0 成功 CF = 1, AH = 错误码 这个调用用来缩定指定驱动器中的介质. 所有标号大于等于 0x80 的可移动驱动器必须支持这个功能. 如果 在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用, 将 会成功返回. 驱动器必须支持最大255次锁定, 在所有锁定被解锁之前, 不能在物理上 将驱动器解锁. 解锁一个未锁定的驱动器,将返回错误码 AH= B0h. 如果锁定一 个已锁定了255次的驱动器, 将返回错误码 AH = B4h. 锁定一个没有介质的驱动器是合法的. 6) 弹出可移动驱动器中的介质 入口: AH = 46h AL = 0 保留 DL = 驱动器号 返回: CF = 0, AH = 0 成功 CF = 1, AH = 错误码 这个调用用来弹出指定的可移动驱动器中的介质. 所有标号大于等于 0x80 的可移动驱动器必须支持这个功能. 如果 在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用, 将 会返回错误码 AH = B2h (介质不可移动). 如果试图弹出一个被锁定的介质 将返回错误码 AH = B1h (介质被锁定). 如果试图弹出一个没有介质的驱动器, 则返回错误码 Ah = 31h (驱动器 中没有介质). 如果试图弹出一个未锁定的可移动驱动器中的介质, Int13h会调用 Int15h (AH = 52h) 来检查弹出请求能否执行. 如果弹出请求被拒绝则返回错误码(同 Int15h). 如果弹出请求被接受,但出现了其他错误, 则返回错误码 AH = B5h. 7) 扩展定位 入口: AH = 47h DL = 驱动器号 DS:DI = 磁盘地址数据包(Disk Address Packet) 返回: CF = 0, AH = 0 成功 CF = 1, AH = 错误码 这个调用将磁头定位到指定扇区. 8) 取得驱动器参数 入口: AH = 48h DL = 驱动器号 DS:DI = 返回数据缓冲区地址 返回: CF = 0, AH = 0 成功 DS:DI 驱动器参数数据包地址, (参见前面的文章) CF = 1, AH = 错误码 这个调用返回指定驱动器的参数. 9) 取得扩展驱动器介质更换检测线状态 入口: AH = 49h DL = 驱动器号 返回: CF = 0, AH = 0 介质未更换 CF = 1, AH = 06h 介质可能已更换 这个调用返回指定驱动器的介质更换状态. 这个调用与 Int13h AH = 16h 子功能调用相同, 只是允许任何驱动器 标号. 如果对一台支持可移动介质功能子集的固定驱动器使用此功能,则永远 返回 CF = 0, AH = 0. 简单地将可移动介质锁定再解锁就可以激活检测线, 而无须真正更换介质. 10) Int 15h 可移动介质弹出支持 入口: AH = 52h DL = 驱动器号 返回: CF = 0, AH = 0 弹出请求可能可以执行 CF = 1, AH = 错误码 B1h 或 B3h 弹出请求不能执行 这个调用是由 Int13h AH=46h 弹出介质功能调用内部使用的. |
|
两篇关于汇编方面的文章
主引导记录包括代码、数据两部分。它在被BIOS中断Int19h装入内存后获得控制权。数据 ; 部分最重要的当然是分区表了!彻底熟悉主引导记录,可以帮助我们了解系统的引导过程, ; 处理因主引导记录损坏所造成的无法引导故障,消除引导型计算机病毒,更使我们能通过 ; 修改主引导记录完成我们希望的工作:如多重引导,系统加软锁等... ; ; BIOS中断总是把主引导记录所在扇区(硬盘的0头0道1扇区)的内容(包括代码和数据) ; 装入内存0000:7C00起始的区域,然后检验该扇区内容的最后两个字节是不是“AA55”, ; 如果不是,那么对不起,Int19h将不把控制权交给主引导记录;若是,则下面的主引导记录 ; 才能获得了控制权了(Int19通过跳转指令交转控制权): ; ; 二进制形式的主引导记录: 0000:0600 33 C0 8E D0 BC 00 7C FB-50 07 50 1F FC BE 1B 7C 3.....|.P.P....| 0000:0610 BF 1B 06 50 57 B9 E5 01-F3 A4 CB BE BE 07 B1 04 ...PW........... 0000:0620 38 2C 7C 09 75 15 83 C6-10 E2 F5 CD 18 8B 14 8B 8,|.u........... 0000:0630 EE 83 C6 10 49 74 16 38-2C 74 F6 BE 10 07 4E AC ....It.8,t....N. 0000:0640 3C 00 74 FA BB 07 00 B4-0E CD 10 EB F2 89 46 25 <.t...........F% 0000:0650 96 8A 46 04 B4 06 3C 0E-74 11 B4 0B 3C 0C 74 05 ..F...<.t...<.t. 0000:0660 3A C4 75 2B 40 C6 46 25-06 75 24 BB AA 55 50 B4 :.u+@.F%.u$..UP. 0000:0670 41 CD 13 58 72 16 81 FB-55 AA 75 10 F6 C1 01 74 A..Xr...U.u....t 0000:0680 0B 8A E0 88 56 24 C7 06-A1 06 EB 1E 88 66 04 BF ....V$.......f.. 0000:0690 0A 00 B8 01 02 8B DC 33-C9 83 FF 05 7F 03 8B 4E .......3.......N 0000:06A0 25 03 4E 02 CD 13 72 29-BE 2D 07 81 3E FE 7D 55 %.N...r).-..>.}U 0000:06B0 AA 74 5A 83 EF 05 7F DA-85 F6 75 83 BE 1A 07 EB .tZ.......u..... 0000:06C0 8A 98 91 52 99 03 46 08-13 56 0A E8 12 00 5A EB ...R..F..V....Z. 0000:06D0 D5 4F 74 E4 33 C0 CD 13-EB B8 00 00 80 49 12 00 .Ot.3........I.. 0000:06E0 56 33 F6 56 56 52 50 06-53 51 BE 10 00 56 8B F4 V3.VVRP.SQ...V.. 0000:06F0 50 52 B8 00 42 8A 56 24-CD 13 5A 58 64 10 72 PR..B.V$..ZX.d.r 0000:0700 0A 40 75 01 42 80 C7 02-E2 F7 F8 5E C3 EB 74 B7 .@u.B......^..t. 0000:0710 D6 C7 F8 B1 ED CE DE D0-A7 00 BC D3 D4 D8 B2 D9 ................ 0000:0720 D7 F7 CF B5 CD B3 CA B1-B3 F6 B4 ED 00 4D 69 73 .............Mis 0000:0730 73 69 6E 67 20 6F 70 65-72 61 74 69 6E 67 20 73 sing operating s 0000:0740 79 73 74 65 6D 00 00 00-00 00 00 00 00 00 00 00 ystem........... 0000:0750 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0760 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0770 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0780 00 00 00 8B FC 1E 57 8B-F5 CB 00 00 00 00 00 00 ......W......... 0000:0790 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:07A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:07B0 00 00 00 00 00 00 00 00-86 D8 00 00 00 00 80 01 ................ 0000:07C0 01 00 06 3F 3F FD 3F 00-00 00 41 A0 0F 00 00 00 ...??.?...A..... 0000:07D0 01 FE 05 3F FF FE 80 A0-0F 00 C0 4F 2F 00 00 00 ...?.......O/... 0000:07E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:07F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U. ; ; 反汇编结果 ; ; 0000:7C00~0000:7C1A:初始化各个段寄存器、堆栈指针,最后将主引导记录在内存中搬家,腾出其所占内 ; 存空间以供装入分区引导记录。 0000:7C00 33C0 XOR AX,AX ;AX寄存器清0 0000:7C02 8ED0 MOV SS,AX ;SS=0 0000:7C04 BC007C MOV SP,7C00 ;装填栈指针――SS:SP=0000:7C00 0000:7C07 FB STI ;开中断(装填栈指针时为避免硬件中断引起栈混乱应关中断) 0000:7C08 50 PUSH AX ; 0000:7C09 07 POP ES ;装填附加数据段寄存器ES=0 0000:7C0A 50 PUSH AX ; 0000:7C0B 1F POP DS ;装填数据段寄存器DS=0 0000:7C0C FC CLD ;规定其后的串操作为正向串操作 0000:7C0D BE1B7C MOV SI,7C1B ;源指针 0000:7C10 BF1B06 MOV DI,061B ;目的指针 0000:7C13 50 PUSH AX ; 0000:7C14 57 PUSH DI ;看看0000:7C1A――构造一个跳转 0000:7C15 B9E501 MOV CX,01E5 ; 0000:7C18 F3 REPZ ; 0000:7C19 A4 MOVSB ;0000:7C1B起始的CX字节传送至0000:061B起始的区域 0000:7C1A CB RETF ;跳转到0000:061B(这是一种技巧跳转) ; ; 为直观起见,下面的地址按实际运行时的地址给出。 ; 0000:061B~0000:062B:对分区表进行初步检验,一旦检测到某分区表项状态字节大于等于80h,就通过(当 ; 然,在此之前如果检测到某项分区表的状态字节小于80h,就转错误处理。当然,如果四个分区项的状态字节 ; 都为零,主引导记录就会调用BIOS-ROM的INT 18h,显示"PRESS A KEY TO REBOOT"信息等待你的操作。 0000:061B BEBE07 MOV SI,07BE ;SI指向第一个分区表项,这时CX=0 0000:061E B104 MOV CL,04 ;分区表共四个表项 0000:0620 382C CMP [SI],CH ; 0000:0622 7C09 JL 062D ;大于等于80h转[注意JL指令:(SF xor OF)=1则转] 0000:0624 7515 JNZ 063B ;不为0则[SI]一定小于80h,只能转错误处理了! 0000:0626 83C610 ADD SI,+10 ;为零则检查下一表项 0000:0629 E2F5 LOOP 0620 ;检查下一表项 0000:062B CD18 INT 18 ;四表项的状态字节都为0,则系统只好调用INT 18h了! ; ; 0000:062D~0000:0639:检查剩余的分区表项――状态字节必须为零,否则显示错误信息“分区表无效”然 ; 后当机!拜托,微软搞错没有,怎么用中文提示信息?真TM傻得可爱! ; 这里还有个小BUG,前面放行原则是只要状态字节大于等于80h,那么如果这个字节是诸如A0h、E5h之类数值 ; 呢?嘿嘿,这个引导记录统统认为是有效的可引导分区了! 0000:062D 8B14 MOV DX,[SI] ;为读分区引导记录做准备:磁头号→DH,驱动器号→DL 0000:062F 8BEE MOV BP,SI ;SI→BP,保存可引导分区表项的指针 ; 0000:0631 83C610 ADD SI,+10 ;其余的分区表项还要检查检查的 0000:0634 49 DEC CX ; 0000:0635 7416 JZ 064D ;CX=0则检查顺利通过,转继续 0000:0637 382C CMP [SI],CH ; 0000:0639 74F6 JZ 0631 ;为零,是合法表项,再查下一表项 ; ; 0000:063B~0000:064B:执行错误处理――报告错误信息后当机 0000:063B BE1007 MOV SI,0710 ;错误信息字符串偏移+1→SI 0000:063E 4E DEC SI ;SI-1→SI 0000:063F AC LODSB ;SI+1→SI 0000:0640 3C00 CMP AL,00 ; 0000:0642 74FA JZ 063E ;AL=0则表明一条错误信息显示完毕,系统陷入一个死循环 0000:0644 BB0700 MOV BX,0007 ;字符方式显示 0000:0647 B40E MOV AH,0E ; 0000:0649 CD10 INT 10 ;以写电传方式显示信息(只显示一个字符) 0000:064B EBF2 JMP 063F ;显示下一个字符,直到遇到提示信息结束为止 ; ; 0000:064D~0000:0662:判断可引导分区的分区类型,然后转相应处理程序。 0000:064D 894625 MOV [BP+25],AX ;BP=指向第一个可引导分区表项的指针,这时AX=0000h ;使用长度最短的指令将[BP+25]起始的两个单元清零 ;这两个单元将被用来存放中间变量 0000:0650 96 XCHG SI,AX ;此时SI清零的最佳指令选择(仅1字节),将服务于0000:06B8 0000:0651 8A4604 MOV AL,[BP+04] ;取分区类型(本例是“06”喽――FAT16主DOS分区) 0000:0654 B406 MOV AH,06 ;为扩展INT 13h无法使用做好更改分区类型的准备 0000:0656 3C0E CMP AL,0E ;0Eh:需要用扩展INT 13h访问的FAT16主DOS分区 0000:0658 7411 JZ 066B ;0Eh类型的分区转066Bh 0000:065A B40B MOV AH,0B ; 0000:065C 3C0C CMP AL,0C ;0Ch:需要用扩展INT 13h访问的FAT32分区 0000:065E 7405 JZ 0665 ;0Ch类型的分区转0665h先行预处理 0000:0660 3AC4 CMP AL,AH ;0Bh:用传统INT 13h就可以访问的FAT32分区 0000:0662 752B JNZ 068F ;其他类型的分区转068Fh ; ; 0000:0664~0000:06A1:根据分区类型和分区表表项内容进行读取分区引导记录前的处理工作 0000:0664 40 INC AX ;★★★0Bh类型的分区由此开始处理,此条指令用意是清ZF位 0000:0665 C6462506 MOV BYTE PTR [BP+25],06 ;★★★0Ch类型的分区由此开始处理 ;为什么取值06,一时没有自圆我说的解释,请耐心几天吧。 0000:0669 7524 JNZ 068F ;请注意上面指令对ZF位的影响:0Bh类型分区转,0Ch则不转 ; 0000:066B~0000:068C这段代码仅当分区类型是0Ch、0Eh才有获得执行的机会 0000:066B BBAA55 MOV BX,55AA ;★★★0Eh类型的分区由此开始处理 0000:066E 50 PUSH AX ; 0000:066F B441 MOV AH,41 ;扩展INT 13h功能,检测BIOS是否已经支持扩展INT13h 0000:0671 CD13 INT 13 ;入口参数:BX=55AAh,DL=驱动器号,AH=41h 0000:0673 58 POP AX ;执行完恢复AX为060Eh 0000:0674 7216 JB 068C ;不支持则转 0000:0676 81FB55AA CMP BX,AA55 ; 0000:067A 7510 JNZ 068C ;扩展INT13h不可用也转 0000:067C F6C101 TEST CL,01 ;测试扩展盘访问是否被支持 0000:067F 740B JZ 068C ;不支持还转 ; 因为扩展INT13h方式读盘与标准INT13h方式读盘有很大差别,所以0000:0686处指令修改其后的代码以保证按 ; 照扩展读方式读分区引导扇区时能正确跳转到相应的处理程序中。 0000:0681 8AE0 MOV AH,AL ;分区类型→AH 0000:0683 885624 MOV [BP+24],DL ;保存驱动器号→[BP+24] 0000:0686 C706A106EB1E MOV WORD PTR [06A1],1EEB ;修改0000:06A1处代码为"JMP 06C1" 0000:068C 886604 MOV [BP+04],AH ;注意:如果扩展INT13h不能使用则A改分区类型为06,但如果 ;扩展INT13h能使用,则仍保持原分区类型不变 0000:068F BF0A00 MOV DI,000A ;★★★其它类型分区由此开始处理。此条指令初始化计数器 0000:0692 B80102 MOV AX,0201 ;AH:读操作,AL:读取1个扇区的内容 0000:0695 8BDC MOV BX,SP ;SP=7C00→BX,指定分区引导记录装入内存的位置偏移 0000:0697 33C9 XOR CX,CX ;CX清零 0000:0699 83FF05 CMP DI,+05 ;注意5 0000:069C 7F03 JG 06A1 ;大于则转去读由分区表指定的分区引导扇区 0000:069E 8B4E25 MOV CX,[BP+25] ;小于则证明所读分区表指定的引导扇区无合法的引导记录, ;改按???再读,毕竟多一种选择多一次机会嘛!;) ; 以下标有①②者请注意它们的地址都是一样的,就是说实际运行中只可能是二者之一,但为了分析之方便,我 ; 把两者都列了出来以供对比,阅读时千万别看成是两条指令了啊! ①0000:06A1 034E02 ADD CX,[BP+02] ;获取分区引导扇区所在的柱面号和物理扇区号 ②0000:06A1 EB1E JMP 06C1 ;如果分区类型是0Ch、0Eh而且扩展读能使用则执行该指令 ; ; 0000:06A4:将可引导分区的分区引导记录装入内存指定区域 ; 入口参数:AH=功能号,02为读盘操作;AL=一次读取的扇区数 ; ES:BX=读入内存的起始地址 ; CH=10位柱面号的低8位;CL:高两位是10位柱面号的高两位,低6位是物理扇区号 ; DH=磁头号;DL=驱动器号,最高位(即位7)为0是软盘,为1是硬盘 0000:06A4 CD13 INT 13 ;读分区引导记录到0000:7C00起始的区域 ; ; 0000:06A6 7229 JB 06D1 ;不成功转 0000:06A8 BE2D07 MOV SI,072D ;错误信息字符串偏移→SI 0000:06AB 813EFE7D55AA CMP WORD PTR [7DFE],AA55 ;分区引导记录合法吗? 0000:06B1 745A JZ 070D ;合法则转(这是主引导记录唯一的正常出口) 0000:06B3 83EF05 SUB DI,+05 ;不合法则为换读其他扇区做准备 0000:06B6 7FDA JG 0692 ;只有一次换读扇区的机会! ; ; 0000:06B8~0000:06BF:错误预处理 0000:06B8 85F6 TEST SI,SI ;测试SI值是否为0,其意义在于确定该显示哪条信息 0000:06BA 7583 JNZ 063F ;不为0则转错误处理,显示“Missing operating system” 0000:06BC BE1A07 MOV SI,071A ;错误信息字符串偏移→SI 0000:06BF EB8A JMP 064B ;转错误处理,显示“加载操作系统时出错” ; ; 0000:06C1~0000:06CF:整理扩展读所需入口参数,然后调用扩展读子程序 ; 这段代码只有在以扩展读方式读取分区引导记录时才有机会获得执行 0000:06C1 98 CBW ;转换字节AL为字AX,执行后,AX中是一次要读的扇区数 0000:06C2 91 XCHG CX,AX ;AX→CX,CX→AX,执行后,CX中是一次要读的扇区数 0000:06C3 52 PUSH DX ; 0000:06C4 99 CWD ;将字AX转换为双字→DX,AX 0000:06C5 034608 ADD AX,[BP+08] ; 0000:06C8 13560A ADC DX,[BP+0A] ;执行后,DX:AX=LBA绝对物理扇区号 0000:06CB E81200 CALL 06E0 ;调用扩展读子程序 0000:06CE 5A POP DX ; 0000:06CF EBD5 JMP 06A6 ; ; ; 0000:06D1~0000:06D8分区引导记录装入失败时的处理 0000:06D1 4F DEC DI ;计数器减1 0000:06D2 74E4 JZ 06B8 ;五次读盘均未成功则转错误处理(注意这时SI=0) 0000:06D4 33C0 XOR AX,AX ;置功能号 0000:06D6 CD13 INT 13 ;复位磁盘系统 0000:06D8 EBB8 JMP 0692 ;再读 ; ; 0000:06DA 00 00 80 49 12 00 ...I.. ; ; 0000:06E0~0000:070C:使用扩展INT 13h功能读取分区引导记录的子程序 ; 调用时,SP=7BFE。这段程序利用压栈寄存器方式构造了一个磁盘地址包,请注意体会。另外,0000:06FC处 ; 的一条指令就释放了几乎全部由本段程序占用的栈空间,构思之巧妙,绝对需要我们学习! ; 所以,分析该段程序,一个重点应放在栈的变化上。 0000:06E0 56 PUSH SI ;保存SI――注意,这次压栈并不构造磁盘地址包 0000:06E1 33F6 XOR SI,SI ;清零 0000:06E3 56 PUSH SI ; 0000:06E4 56 PUSH SI ; 0000:06E5 52 PUSH DX ; 0000:06E6 50 PUSH AX ;以上四条指令压栈的是扇区LBA号码*2 0000:06E7 06 PUSH ES ;压栈内存目标缓冲区首址段址 0000:06E8 53 PUSH BX ;压栈内存目标缓冲区首址偏移 0000:06E9 51 PUSH CX ;压栈所读扇区数 0000:06EA BE1000 MOV SI,0010 ;注意SI的高8位对应着磁盘地址包的保留字节,必须为0 0000:06ED 56 PUSH SI ;压栈磁盘地址包包长,执行完本条指令一个包已经构造完毕 0000:06EE 8BF4 MOV SI,SP ;规定磁盘地址包偏移指针,这时SP=7BEA 0000:06F0 50 PUSH AX ;保存AX 0000:06F1 52 PUSH DX ;保存DX 0000:06F2 B80042 MOV AX,4200 ;置扩展读功能号 0000:06F5 8A5624 MOV DL,[BP+24] ;取驱动器号,参照0000:0683 ; 入口参数:AH=功能号,02为读盘操作;DL=驱动器号 ; DS:SI=16字节磁盘地址包――第0字节:包长度(固定为10h);第1字节:保留,必须为0; ; 第2、3字节:所读扇区数;第4~5字节:内存目标缓冲区首址偏移; ; 第6~7字节:内存目标缓冲区首址段址; 第8~15字节:扇区LBA号码 ; 出口参数:成功则AH=0;错误则AH=错误代码 0000:06F8 CD13 INT 13 ;执行扩展读操作 0000:06FA 5A POP DX ; 0000:06FB 58 POP AX ; 0000:06FC 8D6410 LEA SP,[SI+10] ;7BEA+10h=7BFA→SP(注意是取偏移而不是取单元内容) 0000:06FF 720A JB 070B ;扩展读不成功转 0000:0701 40 INC AX ; 0000:0702 7501 JNZ 0705 ; 0000:0704 42 INC DX ;AX加1溢出时(比如0FFFFh+1)DX才加1 0000:0705 80C702 ADD BH,02 ;调整BX,使偏移量增加512字节(刚好一扇区) 0000:0708 E2F7 LOOP 0701 ;0701~0708一段代码暂未明白其真实意图! 0000:070A F8 CLC ; 0000:070B 5E POP SI ; 0000:070C C3 RET ; ; ; 0000:070D:中继跳转 0000:070D EB74 JMP 0783 ; ; ; 070F~0745是错误信息!果然是中文Windows98生成的主引导记录,所以我要特别 ; “感谢”微软这个傻B,真难为它竟然用中文表述前两个信息!可惜真需显示的时 ; 候鬼才能看懂是什么呢!!!我K!――耍弄我们耶!? ; 070F~0718:“分区表无效”中文信息 ; 071A~072B:“加载操作系统时出错”中文信息 ; 072D~0744:“Missing operating system”英文信息 0000:070F B7 . 0000:0710 D6 C7 F8 B1 ED CE DE D0-A7 00 BC D3 D4 D8 B2 D9 ................ 0000:0720 D7 F7 CF B5 CD B3 CA B1-B3 F6 B4 ED 00 4D 69 73 .............Mis 0000:0730 73 69 6E 67 20 6F 70 65-72 61 74 69 6E 67 20 73 sing operating s 0000:0740 79 73 74 65 6D 00 00 00-00 00 00 00 00 00 00 00 system.......... 0000:0750 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0760 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0770 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:0780 00 00 00 ... ; ; 0000:0783~0000:0789:控制权移交 0000:0783 8BFC MOV DI,SP ; 0000:0785 1E PUSH DS ; 0000:0786 57 PUSH DI ;构造一个跳转地址 0000:0787 8BF5 MOV SI,BP ; 0000:0789 CB RETF ;交控制权给分区引导记录(0000:7C00) ; ; 0000:078A 00 00 00 00 00 00 ...... 0000:0790 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:07A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ ; ; 07B8~07BB四个字节的内容用于什么呢?(不同机器此四字节均不同) ; 07BE~07FD为分区表,内含四个分区表项(每表项10h字节) 0000:07B0 00 00 00 00 00 00 00 00-86 D8 00 00 00 00 80 01 ................ 0000:07C0 01 00 06 3F 3F FD 3F 00-00 00 41 A0 0F 00 00 00 ...??.?...A..... 0000:07D0 01 FE 05 3F FF FE 80 A0-0F 00 C0 4F 2F 00 00 00 ...?.......O/... 0000:07E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0000:07F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U. *1:因为物理扇区号总是从1排列而起 *2:由此可见,就是使用LBA扩展读的功能,主引导记录却限制了分区引导扇区必须在LBA绝对物理扇区 0FFFFFFFFh之前才有可能从该分区引导系统! |
|
xp下不能激活softice
虚拟机pc 或wm能装softice并运行吗?求教 |
|
|
|
请教各位,为什么xp下用ollydbgdump出来的文件入口处成了leave ,ret,而在98下dump出来的不同,xp下怎么修
谢谢老大,可同样的oep在98下却正常,为什么呢? |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值