; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; Description: Heroic attempt to disassemble the Windows 95 Boot Sector. ; Date: 16. Aug. 1998 ; Author: Mr. X ; Email: unknown ; Comment: This boot code is messy. ; Status: PART I, II and III are now pretty much done. ; Important: "SHLD EDX,EAX,16" This is a Microsoft Patent. ; Also take a look at the "list near EOF" ; ; ---> CUT HERE IF YOU LIKE TO LISTEN TO ME <--- ; ; This file will assemble into a fully functional (I hope) Win95B boot code. ; ; tasm win95 /m ; tlink win95,win95.bin /t ; ; Ask someone for the proper dropper code... ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ; AFTER DISASSEMBLY I have this impression: ; ; This is what Bill Gates said... when Win95 was going to be released: ; ; "Gates: OK, then we're ready to press the CD's and start shipping out ; this new load of shit, but of course nobody will notice... harr harr. ; Employee: Hey, Mr. Gates what about the Boot Sector?? We haven't ; written the FAT32 support routines there yet... ; Gates: Ah, that's right... anybody?? We have just 45 minutes... ; Employee #2: Well, I think I can hack some shit together... ; Gates: Fine, go for it... remember you have only 44 minutes... ; Employee #2: I think I can do it. ; Gates: Fine, then I'll just go home... We've made it!!" ; ; FUNNY? ; ; There is some really strange code in this boot record.... ; ; I bet Bill Gates hired some crazy mother fucker to write this shit. ; It seems like he had really tried to make the code fit within one sector. ; But when it didn't hid just decided to use three instead... ; ; This is a typical microsoft solution, they mix stupid 8086 code... with ; cheap solutions and then suddenly they use 386 code... ; ; And then there is the new FAT32 data structures where they have moved ; the volume label, FileSystem ID and serial number down to make room for ; some extended FAT32 variables... it sucks. Why not rearange the whole ; structure... An OS would not try to interpret the shit anyway, because ; the Partitioni Table SYSID has changed with FAT32. ; ; As I said... crazy mother fucker... ; ; Well, well... here's some of the stuff... with a mix of mine and sourcer's ; comments... ; ; Another thing about TASM, which I use, of course I didn't buy it... I'm ; have a shareware version on a 30 year trial period. ; ; Back to what I was about to say again... When I use the brXXXX variables ; in indexing with BP, TASM generates 16-bit offset in operands even when ; they are less than 128... the Win95 code uses byte offsets (I'm not sure ; if I'm expressing myself clear here). When I changed the code from: ; ; mov AX,[bp+brHPC] to mov AX,[bp+128], TASM did use the byte offset form... ; This made my code a little less readable... but the comments should give ; you an idea of what data is being accessed. ; ; Basically this boot sector code is 32 bit extension for a 16 bit patch to ; an 8 bit boot sector originally coded for a 4 bit microprocessor, written ; by a 2 bit company, that can't stand 1 bit of competition. ; ; ---> CUT HERE IF YOU DOES NOT LIKE TO LISTEN TO ME <--- .386C CODE SEGMENT USE16 ASSUME CS:CODE, DS:CODE, SS:NOTHING ; BOOT RECORD - PART I - MAIN BOOT SECTOR CODE ; Just so I've said it - ASM opcodes are only readable when capitalized, Win95b PROC FAR JMP SkipData ; 0000h brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ SkipData: ; Set up stack 8 bytes below us, do you know why??? MOV SP,7C00H - 8 ; Point DS:SI to INT 1E - DISKETTE PARAMS structure... LDS SI,DWORD PTR SS:[BP] PUSHDS MOV DI,522H MOV SS:[BP],DI ; setup our INT 1E ; copy 11 bytes from old diskette parameter table into MOV CL,11 MOV BP,7C00H ; point BP to start of us MOV BYTE PTR [DI-2],0FH ; modify head settle time MOV AX,SS:[BP+18H] MOV [DI-7],AL ; modify sectors per track ; compare drive number with 0... CMP SS:[BP+40H],CL ; Boot from diskette? MOV AX,CX ; AX=CX=0 MOV BX,0700H ; Use 0000:0700 for sector CALL ReadSector ; load Master Boot Record SUB BX,58 ; BX = 08C6h (700h - 3Ah) MOV DL,[BX-4] ; Put System ID in DL JNZ NotOurs ; Jump if not our entry ; If system ID or "partition type", is 0Ch or 0Eh, ReadSector OR DL,2 ; set bit 1, to allow for MOV SS:[BP+2],DL ; set brINT13Flag ; FAT32 - Is sector per FAT zero? CMP WORD PTR SS:[BP+16H],0 ; Put number of hidden sectors in DX:AX MOV AX,WORD PTR SS:[BP+1CH] MOV CX,3 ; Boot Record is 3 sectors... ; Start loading reminder of Boot Record for FAT32 JNZ Skipper ; AX wrap-around? CALL ReadSectorX ; Read Sector MOV AL,0F8H ; what's this???? DECDI MOV AX,SS:[BP+32H] ; get backup boot sector MOV CX,3 ; if 3 is higher than MOV SI,SS:[BP+0EH] ; SI = # of reserved sectors SUB SI,CX ; get number reserved sectors ; add number of hidden sectors to DX:AX ADD AX,WORD PTR SS:[BP+1CH] JMP LoadIt JMP GOFAT32 CBW TESTAL,AL CMP AL,-1 MOV AH,0EH ; TTY write character JMP NextChar ; repeat write... POP SI ; restore the stack... why??? INT 19H ; BIOS bootstrap loader... Win95b ENDP ;========================================================================== ReadSector PROC NEAR INC CX ; increase SECTOR COUNT rsReadMore: MOV SI,SP ; save stack pointer PUSHA ; Save "all" registers CMP BYTE PTR SS:[BP+2],0EH ; Use INT13 extensions? MOV AH,42H ; Do ext INT13 READ DIV WORD PTR SS:[BP+18H] ; div LBA_HI by sectors/track XCHG CX,AX ; save result in CX and put DIV WORD PTR SS:[BP+18H] ; divide reminder and LBA_LO INC DX ; make sector 1-based XCHG CX,DX ; save it in CX and get the DIV WORD PTR SS:[BP+1AH] ; divide this new result by MOV DH,DL ; save Head of CHS in DH MOV CH,AL ; save LO cylinder in CH ROR AH,2 ; rotate AH to make bits 8-9 MOV AX,201H ; setup for READ - 1 sector POPA ; Restore "all" registers ; the entry code pushed 12h bytes on the stack... LEASP,[SI+10H]; Load effective addr ; Now, SI should contain 0001h POPSI ; was there an error from INT13? JC RSDone INC AX ; increment LBA sector num INC DX ; yes raise high word too DEC CX ; decrement SECTOR COUNT ReadSector ENDP ;============================================================================ ErrMsg1 DB 03H ; Skip counter for message1 DB 13,10,'Ugyldig systemdisk ',-1 ;============================================================================ DB 0,0 ; Padding? ; ROOT file names to search for...? IO_SYS DB 'IO SYS' DB 7EH,1,0 ; What is this? WINBOOT_SYS DB 'WINBOOT SYS' ; When is this used? DB 0,0 ; Padding? ; DB480 DUP (0) ; FSINFO information... DB 'rrAa' ; FAT32 FSINFO Signature brFreeClusters DD 56990 ; I have 233431040 bytes free! DW ? ; word padding DW 0AA55H ; 2nd Boot Signature ; calculate total size of FAT area MOVZX EAX,BYTE PTR SS:[BP+10H] ; number of FATs ; add hidden sectors ADD EAX,SS:[BP+1CH] ; add reserved sectors MOVZX EDX,WORD PTR SS:[BP+0EH] XOR CX,CX ; clear CX for some reason... ; EAX will now point to the start of the data area (cluster 2) MOV SS:[BP-4],EAX ; Save another value to... This one is checked by GetFAT32Sector MOV DWORD PTR SS:[BP-8],0FFFFFFFFH ; Oh... at Microsoft they take no chances... disable INTs again! CLI ; load Root Start Cluster in EAX MOV EAX,SS:[BP+2CH] ; Is it cluster 2? CMP EAX,2 ; Is it an EOF marker or something above? CMP EAX,0FFFFFF8H ; Put upper 16-bits of cluster number into DX?? SHLD EDX,EAX,16 STI ; Puh. Safe again. CLI ; Eh? ; clear upper 16-bits of cluster number, and of course move up the SHL EAX,16 ; shift lower 16-bits of cluster number back down, and at the same SHRD EAX,EDX,16 ; make cluster number 0-based... "the way it's supposed to be" SUB EAX,2 ; put Sectors Per Cluster in EBX MOVZX EBX,BYTE PTR SS:[BP+0DH] ; save it in SI too! Yippi MOV SI,BX ; calculate relative sector of first part of root... right? MUL EBX ; add the "start of data area" value we saved below us! ADD EAX,SS:[BP-4] ; Maybe now, some shitter is trying to make DX:AX what EAX is?? SHLD EDX,EAX,10H STI; Enable interrupts ; Use 0070:0000 as a directory buffer... ; read 1 sector MOV CX,1 CALL ReadSectorX ; this shit should be pretty MOV CL,11 ; the stupid CP/M filenames MOV SI,OFFSET IO_SYS + 7C00H REPE CMPSB ; Is it IO.SYS? POPSI JZ FoundOS ; Yeah... ADD DI,CX ; add what's left after CMPSB ; Yeah, yeah, anyway... point to the next dir entry... CMP DI,BX ; are there any more sectors in this cluster??? DECSI POP AX ; restore cluster number ; Get FAT value... "GetFAT32value" will compare the value with CALL GetFAT32value ; if not end of root... go to GetRootCluster.. EndOfRoot: ; EOF/BAD cluster...
; SI would be set to DirEntry[14H] - starting cluster (HI) MOV SI,[DI+09H] ; copy FAT32 starting cluster upper 16-bits to AX MOV AX,SI CLI; Disable interrupts ; shift cluster high into upper half of EAX and store lower half SHL EAX,10H ; cluster out of range?? CMP EAX,2 ; clusters start with 2 CMP EAX,0FFFFFF8H ; cluster 0FFFFFF8 is EOF DEC EAX ; make it 0-based... ; Multiply cluster number with "sectors per cluster" MOVZX ECX,BYTE PTR SS:[BP+0DH] ; Add the "start of data area" value that was saved back there... ADD EAX,SS:[BP-4] ; And for the N'th time, make DX:AX same as EAX - sector number. SHLD EDX,EAX,10H STI ; aha... MOV BX,0700H ; IO.SYS loads here! PUSH BX JC ShowErrMsg2 ; error...???
; Is there a Mark Zibikowski in the room? CMP WORD PTR [BX],'ZM' ; EXE signature... ; Is there a Barabara Jones in the room? CMP WORD PTR DS:[0200H][BX],'JB' ; IO.SYS signature? ; The above shit appear in the IO.SYS file at offsets 0 and 200h ;========================================================================== GetFAT32value PROC NEAR ADD AX,AX ; Multiply DX:AX by 4, ; DX:AX is passed on as the FAT offset to lookup... CALL GetFAT32Sector ; read FAT sector ; the correct sector is returned... with DI as index...?? CLI MOV EAX,ES:[BX+DI] ; EAX = cluster value ; mask of top 4 bits of because Microsoft say it's reserved. AND EAX,0FFFFFFFH ; Make DX:AX the cluster number too... SHLD EDX,EAX,16 ; EAX[HI] into EDX[LO] ; Check for EOF/BAD CMP EAX,0FFFFFF8H ; Is it the EOF marker? STI ; return with ZF=1 if the GetFAT32value ENDP ;========================================================================== ; On entry DX:AX is the FAT offset in bytes... GetFAT32Sector PROC NEAR ; When this is called 0070:0200 seems to be the buffer in ES:BX MOV DI,7E00H CLI; Disable interrupts ; make EAX the sector number again... move DX into top of EAX... SHL EAX,16 ; move bytes per sector into ECX MOVZX ECX,WORD PTR SS:[BP+0BH] ; divide EDX:EAX by BPS... EAX = sector, EDX = offset in sector... XOR EDX,EDX ; Check FAT sector number agains... saved value on stack... CMP EAX,SS:[BP-8] ; If sector is <> from -1, save this sector at 0000:7BF8 MOV SS:[BP-8],EAX ; add hidden sectors... ADD EAX,SS:[BP+1CH] ; add reserved sectors too... MOVZX ECX,WORD PTR SS:[BP+0EH] ; get FAT32 flags into EBX MOVZX EBX,WORD PTR SS:[BP+28H] ; keep "Active FAT" bits 0-3 AND BX,0FH ; If zero, we're at the correct FAT JZ CorrectFAT ; compare active FAT with number of FATs... CMP BL,SS:[BP+10H] ; save FAT sector in ECX MOV ECX,EAX ; Put sectors per fat in EAX MOV EAX,SS:[BP+24H] ; Multiply active FAT number with sectors per FAT MUL EBX ; Add to first FAT sector number we already had... ADD EAX,ECX ; NOW, EAX contains the correct FAT sector number. POP DX ; And for the N'th time, make DX:AX same as EAX - sector number. SHLD EDX,EAX,16 STI; Enable interrupts MOV BX,DI ; read FAT sector into ; They sucker who wrote this could have saved 1 byte by MOV CX,1 ; 1 sector POP DX JC ShowErrMsg2 GetFAT32Sector ENDP ; Properly align the sector's boot signature at the end of ORG 512 * 3 - 2 DW 0AA55H ; 3rd Boot Signature CODE ENDS END ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
Windows 95 Boot Sector
最新推荐文章于 2024-10-04 10:45:54 发布