⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 用ntldr加载进dos.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 3 页
字号:
;    找到我们的LCN,清除堆栈返回.
        pop ebx
    pop ebx
    pop ebx
    ret
MftLcn20:
;    在这个文件记录里不能找到VCN,在下一个....
    pop ecx                     ;ecx=剩余文件记录号....当前...
    pop eax                     ;eax->当前FRS
    pop edx                     ;edx=VCN
    add eax,BytesPerFrs         ;eax->下一个文件记录
    loop MftLcn10
;    没找到
    xor eax, eax
    ret
ComputeMftLcn endp
;*********************************************************
;ReadNonresidentAttribute:读来自非常驻属性的簇
;入口:                    eax=要读的开始VCN
;                         ebx=属性
;                         ecx=要读的簇数
;                         es:edi=缓冲
ReadNonresidentAttribute proc
    push es
    push ds
    pushad
    cmp byte ptr [ebx+08h], 01h
    je ReadNR10                 ;是非常驻属性
    jmp ErrorExit
ReadNR10:
    cmp ecx, 00000000
    jne ReadNR20
;    没有要读的簇号.返回.
    popad
    pop ds
    pop es
    ret
ReadNR20:
    push ebx
    push eax                    ;当前VCN
    push ecx
    push edi
    push es
    call ComputeLcn             ;eax=要读的LCN,ecx=运行长度
    mov edx, ecx                ;edx=剩余的长度
    pop es
    pop edi
    pop ecx
    cmp ecx, edx
    jnl ReadNR30
    mov edx, ecx                ;运行长度高于剩余的.只读剩余的

ReadNR30:
    call ReadClusters
    sub ecx, edx                ;减去剩余的簇
    mov ebx, edx
    mov eax, edx                ;eax=剩余的簇
    movzx edx, SectorsPerCluster
    mul edx
    movzx edx, BytesPerSector
    mul edx                     ;eax=要读的字节
    add edi, eax                ;修改缓冲以备读下一个
    pop eax
    add eax, ebx                ;修改要的VCN
    pop ebx                     ;ebx=属性
    jmp ReadNR10
ReadNonresidentAttribute endp
;************************************************************
;ReadWholeAttribute:  读一个属性列表
;入口:                ebx->属性   es:edi=缓冲
ReadWholeAttribute proc
    cmp byte ptr [ebx+08h], 00 ;常驻属性
    jne rwa10
    push es
    push ds
    pushad
    lea edx, dword ptr [ebx+10h] ;edx->常驻属性信息
    mov ecx, dword ptr [edx]    ;ecx = bytes in value
    mov esi, ebx                ;esi->属性
    add si, word ptr [edx+04h]  ;esi->属性值
    repz movsb
    popad
    pop ds
    pop es
    ret

rwa10:
;    这是个非常驻属性调用ReadNonresidentAttribute VCN0
    lea edx, dword ptr [ebx+10h];edx->非常驻属性信息
    mov ecx, dword ptr [edx+08h];ecx = HighestVcn
    inc ecx                     ;ecx=在属性的簇
    sub eax, eax                ;eax=开始VCN
    call ReadNonresidentAttribute
    ret
ReadWholeAttribute endp
;*********************************************************
;SearchAttrList:  搜索FRS属性链表,........
;入口:            ecx=类型代码  eax=FRS头
;出口:            eax=FRN文件记录号(0为失败)
SearchAttrList proc
    push ecx
    mov ebx, 00000020h          ;$ATTRIBUTE_LIST
    mov ecx, 00000000           ;属性名长度
    mov edx, 00000000           ;属性名
    call LocateAttributeRecord
    or eax, eax
    je SearchAttrList$NotFoundIndex1
;    读属性链表.eax->属性链表属性
    mov ebx, eax
    push ds
    pop es
    mov edi, AttrList           ;ds:edi->属性链表缓冲
    call ReadWholeAttribute
    push ds
    pop es
    mov ebx, AttrList           ;es:ebx->开始属性链表入口
    pop ecx
SearchAttrList$LookingForIndex:
    cmp es:[bx], ecx            ;.ATTRLIST_TypeCode
    je SearchAttrList$FoundIndex
    cmp dword ptr es:[bx], 0FFFFFFFFh
    je SearchAttrList$NotFoundIndex2
    cmp word ptr es:[bx+04h], 0000
    je SearchAttrList$NotFoundIndex2

    movzx eax, word ptr es:[bx+04h]
    add bx, ax
    mov ax, bx
    and ax, 8000h
    je SearchAttrList$LookingForIndex
;    下一个32k段.....
    mov ax, es
    add ax, 0800h
    mov es, ax
    and bx, 7FFFh
    jmp SearchAttrList$LookingForIndex


SearchAttrList$FoundIndex:
;    找到索引,返回FRN
    mov eax, es:[bx+10h]
    ret
SearchAttrList$NotFoundIndex1:
    pop ecx
SearchAttrList$NotFoundIndex2:
    xor eax, eax
    ret
SearchAttrList endp
;*****************************************************
;UpcaseName:   转换所有名字为大写
;入口:         esi->名字    ecx->名字长度
UpcaseName proc
    or ecx, ecx
    jne UN5
    ret
UN5:
    push ecx
    push esi
UN10:
    cmp word ptr [esi], 0061h;如果它小于'a'
    jl UN20
    cmp word ptr [esi], 007Ah;如果高于'z'
    jg UN20
    sub word ptr [esi], 0020h;转换小写字符
UN20:
    add esi, 00000002h       ;移到下一个unicode字符
    loop UN10 
    pop esi
    pop ecx
    ret
UpcaseName endp
;**********************************************************
;VcnFromMappingPair:   
;入口:                ebx->映射字节
;出口:                ecx->VCN来自映射
VcnFromMappingPair proc
    sub ecx, ecx
    mov cl, byte ptr [ebx]          ;ecx=字节数
    and cl, 0Fh                     ;ecx=v
    cmp ecx, 00000000
    jne VFMP5
    sub ecx, ecx
    ret

VFMP5:

    push ebx
    push edx
    add ebx, ecx                    ;ebx->压缩的vcn前个字节
    movsx edx, byte ptr [ebx]
    dec ecx
    dec ebx
VFMP10:
    cmp ecx, 00000000
    je VFMP20
    shl edx, 08h
    mov dl, byte ptr [ebx]
    dec ebx
    dec ecx
    jmp VFMP10


VFMP20:
    mov ecx, edx
    pop edx
    pop ebx
    ret
VcnFromMappingPair endp
;****************************************************************
;SetupMft:   读MFT文件记录段(MFT FRS)到内存
SetupMft proc
    push es
    push ds
    pushad
    mov eax, 00000001
    mov SegmentsInMft,eax
    mov eax, MftFrs
    add eax, BytesPerFrs
    mov NextBuffer,eax
;    读FRS 0 到第一个MFT FRS缓冲,请务必解决更新序列列阵

    mov eax, MftStartLcn
    movzx ebx, SectorsPerCluster
    mul ebx                         ;eax= MFT开始扇区
    mov SectorBase,eax
    mov eax, SectorsPerFrs
    mov SectorCount,ax
    mov ebx, MftFrs
    push ds
    pop es
    call DoRead
    movzx edi, bx                    ;es:edi = 缓冲
    call MultiSectorFixup
;      确定是否MFT有一个属性链表属性
    mov eax, MftFrs
    mov ebx, 00000020h               ;$ATTRIBUTE_LIST
    mov ecx, 00000000
    mov edx, 00000000
    call LocateAttributeRecord
    or eax, eax
    je SetupMft99                    ;没有属性链表,完成安装
;    读属性链表,eax->属性链表属性
    mov ebx, eax
    push ds
    pop es
    mov edi, AttrList                ;ds:edi->属性链表缓冲
    call ReadWholeAttribute
    mov ebx, AttrList                ;第一个属性链入口
;    现在搜索属性链$DATA属性.ebx->属性链表入口.
SetupMft10:
    cmp dword ptr [bx], 00000080h    ;.ATTRLIST_TypeCode, $DATA
    je SetupMft20
    add bx, [bx+04h]                 ;.ATTRLIST_Length
    jmp SetupMft10


SetupMft20:
;......................


    cmp dword ptr [bx], 00000080h
    je SetupMft99
    push ebx
    mov eax, [ebx+10h]               ;***.ATTRLIST_SegmentReference.REF_LowPart
    mov edi, NextBuffer
    push  ds
    pop  es                          
    call ReadFrs
    pop ebx
;      调整NextBuffer and SegmentsInMft以备下一个属性.....
       mov  eax, BytesPerFrs
       add  NextBuffer, eax
       inc  SegmentsInMft

;      到下一个属性链表入口
       add     bx, [ebx+04h]             ;***.ATTRLIST_Length
       jmp     SetupMft20

SetupMft99:
    popad
    pop ds
    pop es
    ret
SetupMft endp
;*******************************************************************************
;DoRead:   从SectorBase开始的LBA扇区,读SectorCount个扇区到ES:EBX处.使用扩展
;          int13h操作一次最多读(1000h-BytesPerSector)/BytesPerSector个扇区.
;          物理地址=段地址*16+偏移,段地址=物理地址/16,偏移=物理地址 MOD 16
;          注意:要求设置的缓冲区地址低4位为零.以下只用了段地址=物理地址/16.
DoRead proc
    push ds
        pushad
    push cs
    pop  ds
    mov   si,offset DAP             ;ds:si=缓冲区首址
    mov   eax,SectorBase
    add   eax,HiddenSectors
    mov   [si+8],eax                ;设置操作开始LBA
    xor   eax,eax
    mov   ax,es                     ;eax=段地址
    shl   eax,4                     ;eax=eax*10h
    add   eax,ebx                   ;eax=缓冲区物理地址
    mov   bx,SectorCount            
DR10:
    push  eax                       ;保存当前物理地址
    shr   eax,4                     ;eax=段地址    
    mov   word ptr [si+4],0         ;设置缓冲区偏移
    mov   [si+6],ax                 ;设置缓冲区段址
    mov   eax,10000h                ;eax=64KB,edx(0~10000h)
    movzx ecx,BytesPerSector        ;一个扇区字节.
    sub   eax,ecx                   ;防止操作到段边界处.
    mov   edi,eax                   ;edi=该段分块
    xor   edx,edx
    div   ecx                       ;64KB段:一次最多扇区数. 

        cmp   ax,bx                     ;实际操作扇区数按64K段分.
        jg    DR20
    mov   [si+2],ax
    mov   ah,42h
        mov   dl,DriveNumber
    int   13h
;    处理到下一个读缓冲区,把SectorCount*BytesPerSector.
;    按64kb-BytesPerSector进行分块读.防止int13边界出错.
    pop   eax                       ;eax=当前物理地址
    add   eax,edi                   ;eax=下一个64k分块
    sub   bx,[si+2]                 ;bx=剩余扇区数
    movzx ecx,word ptr [si+2]
    add  [si+8],ecx                 ;下一个64kB分块开始LBA
    jmp  DR10
DR20:
    pop  eax
    mov  [si+2],bx
    mov  ah,42h
        mov  dl,DriveNumber
    int  13h
;    读完成退出.
    popad
    pop ds
    ret
dap     db 10h,00,14 dup(0)             ;定义扩展读要用的参数.
DoRead endp
;****************************************************************************
;********************************************************************
;HardDiskImageVirtualFloppy: 将硬盘的软盘镜像文件.虚拟成A盘.
;入口:        ebp=软盘镜像文件在硬盘的开始LBA
HardDiskImageVirtualFloppy proc
jmp Install                     ;跳到安装程序
;BiosInt13h服务程序....
INT13Handler:
  cmp dl,0                      ;不是读软盘?
  jz FloppyR                    
  jmp dword ptr cs:[200h]
FloppyR:
  pushad
  push ds
  cmp ah,42h                    ;是LBA方式读
  jz LBARead
  cmp ah,02                     ;是CHS方式读
  jnz Exit

  push cs
  pop  ds
  mov  si,210h                  ;ds:si->磁盘数据包
  mov [si+2],al                 ;要读的扇区数
  mov [si+4],bx                 ;缓冲区偏移值
  mov [si+6],es                 ;缓冲区段地址
  mov [si+8],cl
  and dword ptr [si+8],3fh      ;要读的扇区号
  dec byte ptr [si+8]           ;S-1
  mov ax,cs:[18h]               ;PS每磁道扇区数
  mul dh                        ;dh要读的磁头号
  add [si+8],ax                 ;+H*PS
  xchg ch,cl
  shr ch,6                      ;cx要读的磁道号
  mov ax,cs:[18h]               ;PS每磁道扇区数
  mul cx                        ;C*PS                      
  mov bx,cs:[1ah]               ;磁头数
  mul bx                        ;PH每柱面磁道数
  add [si+8],ax                 ;+C*PH*PS
LBARead:
  mov eax,cs:[204h]             ;镜像文件开始扇区编号
  add [si+8],eax                ;得到读软盘在硬盘LBA
  mov ah,42h                    ;用扩展int13读硬盘
  mov dl,80h                    ;读硬盘(C)镜像文件
Exit:
  pushf
  call dword ptr cs:[200h]
  pop ds
  popad 
  iret
;*****************************************************
;安装硬盘的软盘镜像文件,虚拟成A盘的int13h服务程序
Install:
    push es
    push ds
    pushad
    cli                        ;有些操作要求关中断.
;    分配高端内存以便我们的int13h服务程序驻留..
    xor ax,ax
    mov ds,ax
    mov ax,ds:[413h]
    dec ax
    mov ds:[413h],ax           ;ax=可用内存(单位KB)
    shl eax,0ah                ;eax=eax*1024
    shr eax,4                  ;eax=eax/16
;*************************************************
;    将我们的int13h服务将程序复制到分配的内存
    mov es,ax                  ;es:0->分配高端内存
    push cs
    pop ds
    mov di,230h                ;es:di->我们的int13h程序
    mov si,offset INT13Handler
    mov cx,offset Install-offset INT13Handler
    cld
    repz movsb                 
;    读取软盘镜像第一个扇区到此,以取得BPB
    mov si,offset HDIVFdap
    mov [si+6],es              ;es:0
    mov [si+8],ebp             ;镜像文件开始LBA
    mov ah,42h
    mov dl,DriveNumber
    int 13h
;    设置参数int13服务程序要的参数及..
    xor ax,ax
    mov ds,ax
    mov eax,ds:[4ch]           ;保存旧的int13h服务程序
    mov es:[200h],eax          ;es:200h旧的int13h服务程序
    mov es:[204h],ebp          ;es:200h镜像文件开始LBA
    mov word ptr es:[210h],10h ;es:210h->扩展int13h参数包
    mov ds:[4ch],230h
    mov ds:[4eh],es            ;设置int13h为我们的程序
;*******************************************************
    sti                        ;最后开中断
    popad
    pop ds
    pop es
    ret
HDIVFdap   db 10h,00,01,00,00,00,10 dup(0)
HardDiskImageVirtualFloppy endp
;***************************************************************************
NTFSDOSAPI endp
;********************************************************************************
;********************************************************************************
    org 2000h                 ;所有的代码结束最小长度2000h
;********************************************************************************
CodeEnd:
Start           ENDP
CSEG            ENDS                           
                END     Start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -