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

📄 用ntldr加载进dos.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 3 页
字号:
    pop ecx
    ret
FindFile90:
;    文件没找到,失败回.
    pop ecx
    pop ecx
    xor eax,eax
    ret
FindFile endp
;******************************************************************************************
;IsBlockInUse:  索引分配块用来检查索引位图.
;入口:          eax=块号
IsBlockInUse proc
    push eax
    push ebx
    push ecx
    mov ebx, IndexBitmapBuffer
    mov ecx, eax
    shr eax, 03h                         ;eax=字节号
    and ecx, 00000007h                   ;ecx=在字节的位号
    add ebx, eax                         ;ebx -> byte to test
    mov eax, 00000001h
    shl eax, cl                          ;eax=mask
    test byte ptr [ebx], al
    je IBU10
    clc                                  ;Block is not in use.
    jmp IBU20
IBU10:
    stc                                  ; Block is in use.
IBU20:
    pop ecx
    pop ebx
    pop eax
    ret
IsBlockInUse endp
;*********************************************************************
;LcnFromMappingPair:    
;入口:                     ebx->映射字节数       
;出口:                     ecx->LCN来自映射
LcnFromMappingPair proc
    push ebx
    push edx
    sub edx, edx
    mov dl, byte ptr [ebx]              ;edx = count byte
    and edx, 0000000Fh                  ;edi = v
    sub ecx, ecx
    mov cl, byte ptr [ebx]
    shr cl, 04h                         ;ecx = l
    cmp ecx, 00000000
    jne LFMP5
    sub ecx, ecx
    pop edx
    pop ebx
    ret

LFMP5:

    add ebx, edx                        ;ebx->压缩的VCN前个字节
    add ebx, ecx                        ;ebx->LCN最字节
    movsx edx, byte ptr [ebx]
    dec ecx
    dec ebx
LFMP10:

    cmp ecx, 00000000
    je LFMP20
    shl edx, 08h
    mov dl, byte ptr [ebx]
    dec ebx
    dec ecx
    jmp LFMP10


LFMP20:

    mov ecx, edx
    pop edx
    pop ebx
    ret
LcnFromMappingPair endp
;********************************************************
;LoadIndexFrs:   根据索引类型代码定位并装入相应的FRS
;入口:           eax=索引类型代码    ecx->要装入的FRS缓冲
;出口:           eax->在FRS缓冲的偏移(为0失败)
LoadIndexFrs proc
    push ecx
    push eax
    mov eax, 00000005h            ;设置为根目录索引代码
    push ds
    pop es
    mov edi, ecx                  ;es:edi装入的缓冲
    call ReadFrs
    mov eax, ecx                  ;搜索到FRS
    pop ebx
    push ebx
    movzx ecx, index_name_length  ;属性名长度
    mov dx, offset index_name     ;mov edx,offset index_name
    call LocateAttributeRecord
    pop ebx
    pop ecx
    or eax, eax
    jne LoadIndexFrs$Exit         ;如果在目录找到,返回.
;    如果在当前FRS没有找到,则搜索属性列表.
    mov eax, ecx
    mov ecx, ebx
    push eax
    push ebx
    call SearchAttrList
    pop ebx
    pop edi
    or eax, eax
    je LoadIndexFrs$Exit
    push ds
    pop es
    call ReadFrs
    mov eax, edi
    movzx ecx, index_name_length
    mov dx, offset index_name     ;mov edx,offset index_name
    call LocateAttributeRecord
LoadIndexFrs$Exit:
    ret
LoadIndexFrs endp
;********************************************************************************
;LocateAttributeRecord: 查找一个属性在记录在一个FRS
;入口:                  eax->FRS               ebx=属性代码
;                       ecx=属性名长度         edx->属性名
;出口:                  eax->属性记录(0表示未找到)
LocateAttributeRecord proc
    add ax, word ptr [eax+14h]                   ;eax->下一个属性记录
lar10:
    cmp dword ptr [eax], 0FFFFFFFFh              ;属性记录结束
    je lar99
    cmp dword ptr [eax], ebx
    jne lar80                                    ;比较属性代码
    or ecx, ecx                                  ;属性名长度不为0时
    jne lar20
    cmp byte ptr [eax+09h], 00                   ;比较属性名长度
    jne lar80
    ret
lar20:
    cmp cl, byte ptr [eax+09h]
    jne lar80
    mov esi, eax
    add si, word ptr [eax+0Ah]                   ;esi->属性名保存缓冲
    call UpcaseName
    push ecx
    push ds
    pop es
    mov edi, edx
    repz cmpsw                                   ;比较属性名
    pop ecx
    jne lar80
    ret
lar80:
;    到下一个属性记录
    cmp dword ptr [eax+04h], 00000000
    je lar99                                     ;属性记录为0退出
    add eax, dword ptr [eax+04h]                 ;eax->下一个属性记录
    jmp lar10                                    ;继续查找
lar99:
;    未找到,失败返回
    sub eax, eax
    ret
LocateAttributeRecord endp
;********************************************************************
;LocateIndexEntry:   在一个文件名索引查找一个索引入口
;入口:               eax->索引头  ebx->要查找文件名 ecx=文件名长度
;出口:               eax->索引入口(为0失败)
LocateIndexEntry proc
    mov esi, ebx
    call UpcaseName
    add eax, dword ptr [eax]           ;eax->第一个索引入口
lie10:
    test word ptr [eax+0Ch], 0002h     ;索引入口结束
    jne lie99
    lea edx, dword ptr [eax+10h]       ;edx -> FILE_NAME属性值
    cmp cl, byte ptr [edx+40h]         ;比较文件名长度
    jne lie80
    lea esi, dword ptr [edx+42h]       ;esi->文件名缓冲
    call UpcaseName
    push ecx
    push ds
    pop es
    mov edi, ebx
    repz cmpsw                         ;比较文件名
    pop ecx
    jne lie80
    ret
lie80:

    cmp word ptr [eax+08h], 0000      ;入口长度为0退出
    je lie99
    add ax, word ptr [eax+08h]        ;eax->下一个入口
    jmp lie10                         ;继续查找
lie99:
;    没找到失败返回
    xor eax, eax
    ret
LocateIndexEntry endp
;*************************************************
;MultiSectorFixup:  修正读磁盘结构.....
;入口:              es:edi=缓冲
MultiSectorFixup proc
    push es
    push ds
    pushad
    movzx ebx, word ptr es:[edi+04h];ebx=更新偏移
    movzx ecx, word ptr es:[edi+06h];ecx=更新偏移
    or ecx, ecx
    je ErrorExit
    add ebx, edi
    add ebx, 00000002h
    add edi, 000001feh              ;SEQUENCE_NUMBER_STRIDE - 2
    dec ecx
MSF10:
    or ecx, ecx
    je MSF30
    mov ax, word ptr es:[ebx]
    mov word ptr es:[edi], ax
    add ebx, 00000002h
    add edi, 00000200h              ;SEQUENCE_NUMBER_STRIDE 
    dec ecx
    jmp MSF10

MSF30:

    popad
    pop ds
    pop es
    ret
MultiSectorFixup endp
;*************************************************************
;ReadClusters:  在磁盘读一个运行簇
;入口:          eax=要读的LCN    edx=要读的簇    es:edi->缓冲
;注意:          真正要读的开始扇区LBA)=SectorBase+HiddenSectors
ReadClusters proc
    push es
    push ds
    pushad
    mov ebx, edx
    movzx ecx, SectorsPerCluster
    mul ecx                     ;转换LCN到扇区编号
    mov SectorBase, eax         ;保存扇区编号(LBA)
    mov eax, ebx
    mul ecx
    mov SectorCount,ax          ;要读的扇区数
;    将es:edi参数转换成调用int13h时的es:ebx
    mov  ebx,edi
    call DoRead                 ;调用磁盘读
    popad
    pop ds
    pop es
    ret
ReadClusters endp
;**************************************************
;ReadFrs:  读一个FRS
;入口:     eax=FRS号   es:edi=缓冲
ReadFrs proc
    push es
    push ds
    pushad
    mul SectorsPerFrs ;eax=在MFT数据属性的扇区号
    mov ecx, SectorsPerFrs
    call   ReadMftSectors
    call   MultiSectorFixup
    popad
    pop ds
    pop es
    ret
ReadFrs endp
;*******************************************************************
;ReadIndexBlock:  在根目录读一个索引块
;入口:            eax=块号
ReadIndexBlock proc
    push es
    push ds
    pushad
    mul SectorsPerIndexBlock      ;eax=要读的第一个VBN
    mov ebx, IndexAllocation      ;ebx->$INDEX_ALLOCATION属性
    mov ecx, SectorsPerIndexBlock ;ecx=要读的扇区
    push ds
    pop es
    mov edi, IndexBlockBuffer     ;es:edi->索引块缓冲
    call ReadIndexBlockSectors
    call MultiSectorFixup
    popad
    pop ds
    pop es
    ret
ReadIndexBlock endp
;**********************************************************************
;ReadIndexBlockSectors: 读扇区来自一个索引分配属性
;入口:                  eax=要读的开始VBN
;                       ebx->属性
;                       ecx=要读的扇区数
;                       es:edi=缓冲
;注意:          真正要读的开始扇区LBA)=SectorBase+HiddenSectors
ReadIndexBlockSectors proc
    push es
    push ds
    pushad
    cmp byte ptr [ebx+08h], 01h  ;.ATTR_FormCode, NONRESIDENT_FORM
    je ReadIBS_10
;    这是个常驻属性
    jmp ErrorExit
ReadIBS_10:
    cmp ecx, 00000000
    jne ReadIBS_20
;    没有要读的,返回.
    popad
    pop ds
    pop es
    ret
ReadIBS_20:
    push ebx
    push eax                     ;当前VBN
    push ecx
    push edi
    push es
;    VBN转换到VCN:用VBN除以每簇扇区数  余数X
;    VCN转换到LCN:通过属性里面的映射
;    LCN转换到LBN:用LCN乘以每簇扇区数  加上X
;    VBN除以每簇扇区数,余数表示其余扇区在簇里
    push ecx                    ;保存剩余扇区数
    xor edx, edx
    movzx ecx, SectorsPerCluster;ecx=每簇扇区数
    div ecx                     ;eax=VCN
    push edx                    ;保存余数
    call ComputeLcn             ;获取VCN的LCN.返回eax=LCN ecx=剩余簇
    movzx ebx, SectorsPerCluster
    mul ebx                     ;eax=LBN簇
    pop edx
    add eax, edx
    push eax                    ;保存我们的LBN
    movzx eax, SectorsPerCluster
    mul ecx                     ;eax=在扇区的剩余运行长度
    mov edx, eax                ;剩余运行长度
    pop eax                     ;eax=LBN
    pop ecx                     ;要读的剩余扇区
    pop es
    pop edi
    pop ecx
    cmp ecx, edx
    jnl ReadIBS_30
;    运行长度高于剩余的.只读剩余
    mov edx, ecx
ReadIBS_30:

    mov SectorBase,eax
    mov SectorCount,dx
;    将es:edi参数转换成调用int13h时的es:ebx
    push ebx
    mov  ebx,edi
    call DoRead
    pop  ebx

    sub ecx, edx                 ;修正要读的剩余扇区
    mov ebx, edx
    mov eax, edx
    movzx edx, BytesPerSector
    mul edx
    add edi, eax                 ;修正缓冲以备下一个读的扇区
    pop eax
    add eax, ebx                 ;修正要读的VBN
    pop ebx
    jmp ReadIBS_10
ReadIndexBlockSectors endp
;***********************************************
;ReadMftSectors:   读扇区来自MFT
;入口:             eax=开始VBN  ecx=要读的扇区数
;                  es:edi=缓冲区
ReadMftSectors proc

    push es
    push ds
    pushad
RMS$Again:
    push eax                  ;保存开始VBN
    push ecx
    xor edx, edx
;    VBN除以SectorsPerCluster得到VCN
    movzx ebx, SectorsPerCluster
    div ebx                   ;eax=VCN
    push edx                  ;保存剩余的
    push edi
    call ComputeMftLcn        ;eax=LCN
    pop edi
    or eax, eax               ;LCN=0
    je ErrorExit
    movzx ebx, SectorsPerCluster
    mul ebx                   ;eax=开始LBN簇
    pop edx                   ;edx=剩余扇区
    add eax, edx              ;eax=LBN
    mov SectorBase,eax
    pop ecx                   ;要读的扇区数
    movzx ebx, SectorsPerCluster
    cmp ecx, ebx
    jle RMS10
    mov SectorCount,bx        ;这时读一个簇
    sub ecx, ebx              ;ecx=要读的剩余扇区数
    pop eax                   ;eax=VBN
    add eax, ebx              ;VBN+=要读的扇区数
    push eax                  ;保存下一个VBN
    push ecx                  ;剩余扇区数
    jmp RMS20
RMS10:

    pop eax                   ;eax=VBN
    add eax, ecx              ;VBN += sectors this read
    push eax
    mov SectorCount,cx
    mov ecx, 00000000
    push ecx                  ;保存剩余的
RMS20:
;    将es:edi参数转换成调用int13h时的es:ebx
    mov  ebx,edi
    call DoRead
    add edi, BytesPerCluster
    pop ecx
    pop eax
    cmp ecx, 00000000
    jg RMS$Again
    popad
    pop ds
    pop es
    ret
ReadMftSectors endp
;****************************************************************
;ComputeMftLcn:  算出MFT一个簇的LCN
;入口:           eax=VCN
;出口:           eax=LCN(0,失败)注意:与调试的win2k版本代码不同
ComputeMftLcn proc
    mov edx, eax
    mov ecx, SegmentsInMft        ;ecx=要搜索的文件记录号(FRS)
    mov eax, MftFrs               ;eax->要搜索的第一个FRS
MftLcn10:
    push edx
    push eax
    push ecx
    push edx
    mov ebx, 00000080h            ;$DATA
    mov ecx, 00000000
    mov edx, ecx
    call LocateAttributeRecord
;    eax->$DATA属性
    or eax, eax
    je ErrorExit                  ;这个文件记录里没有$DATA属性
    mov ebx, eax                  ;ebx->属性
    pop eax                       ;eax=VCN
    call ComputeLcn
    or eax, eax
    je MftLcn20

⌨️ 快捷键说明

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