Skip to content

Malware University

Class is in Session

  • About
    • Privacy Policy
  • Contact
  • Resources

Tag: bootsector

TDL4 IDAPython Decryptor

Posted on September 14, 2021 - September 14, 2021 by admin

This is a script used to unpack a hidden area of the bootsector after a TDL4 infection. This is classic code but still useful is anyone needs it. Written by your humble admin many years ago.

import idaapi

# Simulate C-style for() loop.
def cfor(first, test, update):
    while test(first):
        yield first
        first = update(first)


# Bit-shifting operations.
#def ROR(x, n, bits = 32):
#    mask = (2L**n) - 1
#    mask_bits = x & mask
#    return (x >> n) | (mask_bits << (bits - n))

#def ROL(x, n, bits = 32):
#    return ROR(x, bits - n, bits)
def ROR(byte, count):
    while count > 0:
        byte = (byte >> 1 | byte << 7) & 0xFF
        count -= 1
    return byte


if __name__ == "__main__":
    print "TDL4 Decrypt"
    print "A script to unpack the contents hidden on the bootsector of a TDL4 infected host"
    print ""
    
    encryptedBytes = [None] * 311
    
    rorCount = 311  # 0x137 (CX)
    count = 0
    # target starts at 0x62A in memory
    for i in cfor(int('0x2A', 16), lambda i : i < (311 + i), lambda i : i + 1):
        cryptedByte = idaapi.get_byte(i)
        print "Byte[" + hex(i) + "]:    " + hex(cryptedByte)
        idaapi.patch_byte(i, ROR(cryptedByte, rorCount - count))
        count += 1
        if count == 311:
            break
Posted in UtilitiesTagged bootsector, decryptor, ida pro, idapython, malware, tdl4, windowsLeave a comment

Windows XP SP3 Bootsector Analysis: Part 2

Posted on September 14, 2021 - September 14, 2021 by admin

These are notes made while disassembling the Windows XP Service Pack 3 bootsector (x86 real mode) code.

; This is the "Volume Boot Record".
; Also called "Windows bootstrap loader"/"Windows partition boot sector"
; The section before this is the MBR of the hard disk, next is NTLDR.


.686p
.mmx
.model flat

; Segment type:	Pure code
BOOT_SECTOR segment byte public	'CODE' use16
assume cs:BOOT_SECTOR
;org 7C00h
assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing

; =============== S U B	R O U T	I N E =======================================

; DL = 0x82
; drive	number on Bochs	XP
; Attributes: noreturn

public start
start proc far				; CODE XREF: debug002:20101J
					; DATA XREF: BOOT_SECTOR:7CDEo
jmp	short near ptr sub_7C54	; jump over BPB to beginning of code
start endp

; ---------------------------------------------------------------------------
db 90h
db 4Eh,	54h					; 8-byte OEM ID or System Name ("NTFS    ")
db 46h
db 53h
db 20h
db 20h,	20h, 20h, 
; Start of NTFS BPB (Bios Parameter Block) (size 54h inclusive)
; REMEMBER THIS IS A MEMORY SNAPSHOT, THUS VALUES ARE IN LITTLE ENDIAN, whereas on disk 
; it's big endian
dw 0002h,					; Sector Size (in bytes) (512)
db 8,						; Sectors per Cluster
							; Number of sectors per allocation unit.
							; 512 * 8 = 4096 (4kb cluster size)
							; value is 4 if partition < 2GB
byte_7C0E dw 0000			; DATA XREF: sub_7C54+18w
							; Reserved Sectors (on disk)
							; After loading into memory:
							;	stores number of sectors of Boot Record read into memory
							;	begins with value of 0x10 (16) and counts down to zero
dword_7C10 dd 0				; DATA XREF: BOOT_SECTOR:loc_7CCBr
byte_7C14 db 0				; DATA XREF: sub_7CAA+18w
					; BOOT_SECTOR:7CEBr ...
db 0F8h 					; "Fixed Disk" Media Descriptor ID
dw 0000 					; Must be set to zero for NTFS volumes
							; Originally for FAT 12/16 "Sectors per FAT" value
dw 3F00h 					; Sectors per track (0x3F)
dw 0FF00h					; Number of Heads (sides) (0xFF)	
dword_7C1C dd 3Fh			; DATA XREF: BOOT_SECTOR:7CCFr
							; stored 3F 00 00 00 in memory
							; number of "Hidden (Reserved) Sectors" (cylinder = head = 0)
							; count of hidden sectors preceding partition that contains this volume
dword_7C20 dd 0				; DATA XREF: sub_7C54+51w
							; on disk:
							; 	not used in NTFS
							; 	Total Number of Sectors (FAT32)
							; in memory:
							;	stores Total Number of Sectors in the partition we're trying to boot
					; BOOT_SECTOR:7CD4r
byte_7C24 db 80h			; DATA XREF: sub_7C7Br	sub_7CAA+5r ...
							; First byte of four byte sequence indicates Drive Number (0x80)
							; NTFS OS always fills these bytes with "80 00 80 00"
			db 0
			db 80h
			db 0
db 89h						; Total Sectors (in the Volume)
db B6h						; 00000000007FB689 (long long word)
db 7Fh						; 1 sector less than total number to account for NTFS "Backup Sector"
db 0						; "Backup Sector" not considered part of NTFS volume
db 0
db 0
db 0
db 0
							; end of Total Sectors
	db 0					; Starting Cluster Number (for $MFT file in this partition)
	db 0					; 0000000000040000 (long long word)
	db 4
	db 0
	db 0
	db 0
	db 0
	db 0
							; end of Starting Cluster Number
db 68h						; Starting Cluster Number (for $MFTMirror file in this partition)
db 0FBh						; 000000000007FB68 (long long word)
db 7
db 0
db 0
db 0
db 0
db 0
							; end of Starting Cluster Number
db 0F6h						; Clusters (or bytes) per File Record Segment (FRS)
							; signed byte (-10 -> 1024 bytes)
							; Can be negative when cluster size (8) > MFT File Record Size
							; From MS:
							; "If this number is positive (up to 0x7F), it represents Clusters 
							; per MFT record. 
							; If the number is negative (0x80 to 0xFF), the size of the File Record 
							; is 2 raised to the absolute value of this number."
							; 2 ^ (|-10|) = 2 ^ 10 = 1024 bytes
db 0, 0, 0					; Unused by NTFS (3 bytes)
db 1						; Clusters per Index Buffer
							; signed byte
							; Size of each index buffer, used to allocate space for NTFS structures
							; such as directories
db 0, 0, 0					; Unused by NTFS (3 bytes)
db 0B8h, 0F8h, 0FBh			; NTFS Volume Serial Number
db 0B4h, 1Ah, 0FCh, 0B4h, 0D8h	; [B4 FB] F8 B8 
								; D8 [B4 FC] 1A (long long word)
								; the [] are different than thestarman's
dd 0						; Unused by NTFS

; =============== S U B	R O U T	I N E =======================================

; Attributes: noreturn

sub_7C54 proc far			; CODE XREF: startj

; FUNCTION CHUNK AT 026A SIZE 00000199 BYTES
; FUNCTION CHUNK AT 7C81 SIZE 00000029 BYTES

cli							; disable maskable interrupts
xor	ax, ax					; AX = 0
mov	ss, ax					; SS = 0
assume es:debug002, ss:debug002, ds:debug002 ; inaccurate and wtf is assume?
mov	sp, 7C00h				; SP = 0x7C00
sti							; enable interrupts
mov	ax, 7C0h				; AX = 0x07C0
mov	ds, ax					; DS = 0x07C0
assume ds:nothing
call	sub_7C7B			; drive	number (80)
							; stores total sectors of boot partition in BPB offset 20h
mov	ax, 0D00h				; 0000:7C65, AX = 0x0D00
mov	es, ax					; ES = 0x0D00
assume es:nothing
xor	bx, bx					; BX = 0
mov	byte ptr ds:0Eh, 10h	; *(BYTE *)07C0:000E (0x7C0E) = 0x10
call	loc_7CC7			; reads all boot sectors in memory beginning at 0D00:0000 and ending
							; at 0F00:0000
; ---------------------------------------------------------------------------
push	0D00h
push	26Ah
retf						; returns to 0D00:026A or 0xD26A
sub_7C54 endp ;	sp-analysis failed


; =============== S U B	R O U T	I N E =======================================

; drive	number (80)
; sub_7C7B is _CalculateTotalSectorsBootPartition
; Calculates total sectors in the boot partition using only CHS
sub_7C7B proc near			; CODE XREF: sub_7C54+Ep
mov	dl, ds:24h				; 07C0:0024 = 0x80 (DX = 0x0180)
							; DS:0000 is pointer to start of BPB
							; 0x80 is the first hard drive (offset 24h of BPB)
mov	ah, 8					; AX = 0x08C0
sub_7C7B endp ;	sp-analysis failed
; START	OF FUNCTION CHUNK FOR sub_7C54
int	13h				; DISK - DISK -	GET CURRENT DRIVE PARAMETERS (XT,AT,XT286,CONV,PS)
					; DL = drive number
					; Return: CF set on error, AH =	status code (0), BL	= drive	type (0)
					; DL = number of consecutive drives on the system (1)
					; DH = maximum head number (0xFE)
					; ES:DI -> drive parameter [ EB 52 90 4E 54 46 53 20 20 20 20 ]
					;		Disk Base Table
					; CX = 0x09BF
					; CH = low 8 bits of maximum cylinder number
					; CL (bits 7 - 6) = high 2 bits of maximum cylinder number
					; CL (bits 5 - 0) = maximum sector number
					; Returns CF = 0
jnb	short loc_7C8A	; jump if successful
mov	cx, 0FFFFh		; Not successful?  Set CX = 0xFFFF and DH = 0xFF
mov	dh, cl			; Results in count of 0x00FC0000 or 16515072 sectors being placed into
					; [0000:7C20] and following

loc_7C8A:				; CODE XREF: sub_7C54+2Fj
movzx	eax, dh		; EAX = 0x000000FE
inc	ax				; AX = 0x00FF (total heads)
movzx	edx, cl		; EDX = 0x000000BF (maximum sector number)
and	dl, 3Fh			; DX = 0x003F (0x3F is maximum number of heads)
mul	dx				; head number *	max number of sectors
					; 0x3F * 0xFF
					; DX = 0
					; AX = 0x3EC1
xchg	cl, ch		; CH = 0xBF
					; CL = 0x09 (low 8 bits of maximum cylinder number)
shr	ch, 6			; CX = 0x0209 (shift bits 7-6 of CH next to CL)
					; CX now equals the maximum cylinder number
inc	cx				; CX = 0x020A (total cylinders)
movzx	ecx, cx		; ECX = 0x0000020A
mul	ecx				; 20A *	3EC1
					; EDX = 0
					; EAX = 0x007FF58A (total number of sectors)
mov	ds:20h,	eax		; 07C0:0020 (7C20) = 8A F5 7F 00 (little endian)
					; stores total number of sectors in offset 20h of BPB
retn				; returns to 7C65 (07C0:0065)
; END OF FUNCTION CHUNK	FOR sub_7C54

; =============== S U B	R O U T	I N E =======================================

; sub_7CAA is _TestInt13Extensions
sub_7CAA proc near			; CODE XREF: BOOT_SECTOR:7CF4p
mov	ah, 41h			; function 0x41
mov	bx, 55AAh		; has to be 0x55AA for function
mov	dl, ds:24h
int	13h				; DISK - Check for INT 13h Extensions
					; BX = 55AAh, DL = drive number
					; Return: CF set if not	supported
					; AH = extensions version
					; BX = AA55h
					; CX = Interface support bit map
jb	short locret_7CC6 ; jump if failed
cmp	bx, 0AA55h
jnz	short locret_7CC6 ; jump if failed
test	cl, 1
jz	short locret_7CC6 ; test if "Device Access using the packet structure"
inc	byte ptr ds:14h	  ; increase high-byte of small sectors count for FAT12/16

locret_7CC6:				; CODE XREF: sub_7CAA+Bj sub_7CAA+11j	...
retn
sub_7CAA endp

; ---------------------------------------------------------------------------

; loc_7CC7 is _ReadAllBootSectors
; stores all boot sectors (16) into memory at 0D00:000
loc_7CC7:				; CODE XREF: sub_7C54+1Dp
pushad					; save all (double) general-purpose registers
push	ds				; *SP = 0x07C0 (pointer to BPB offset 0)
push	es				; *SP = 0x0D00 (pointer to RAM location)

loc_7CCB:				; CODE XREF: BOOT_SECTOR:7D58j
mov	eax, ds:10h			; EAX = 0x00000000 (for NTFS, always 0)
add	eax, ds:1Ch			; EAX = 0x0000003F (number of "Hidden Sectors")
cmp	eax, ds:20h			; 0x3F < 0x7FF58A (Logical Block Addressing)
						; This is making sure we have at least a full "track" (63 sectors).
						; We can't have more "Hidden Sectors" than the total number of sectors!
jb	loc_7D17			; jump on success
push	ds
push	large (offset start - offset start) ; DMA page register	74LS612:
					; Channel 7 (address bits 17-23)
push	eax
push	es
push	bx
push	large 10010h			; DMA page register 74LS612:
					; Channel 7 (address bits 17-23)
cmp	byte ptr ds:14h, 0	; Not used on NTFS/FAT32 (0), 
						; but it's the high-byte of the "small sectors count" for FAT12/16
jnz	loc_7D00
call	sub_7CAA		; check for extended Int13 code
cmp	byte ptr ds:14h, 0

loc_7CFC:
jz	loc_7D61			; jumps if extensions are NOT installed ("A disk read error")

loc_7D00:				; CODE XREF: BOOT_SECTOR:7CF0j
mov	ah, 42h	; 'B'
mov	dl, ds:24h
push	ss
pop	ds
assume ds:debug002
mov	si, sp
int	13h				; DISK - IBM/MS	Extension - EXTENDED READ (DL -	drive, DS:SI - disk address packet)
pop	eax
pop	bx
pop	es
assume es:nothing
pop	eax
pop	eax
pop	ds
assume ds:nothing
jmp	short loc_7D44
; ---------------------------------------------------------------------------

; This function will read in the first 16 sectors of the primary drive into RAM starting
; at 0D00:0000 to 0F00:0000 (exclusive).
; I believe what is read is the "Initial Program Loader."
; loc_7D17 is _ReadFirstSectorOfSecondHead
loc_7D17:				; CODE XREF: BOOT_SECTOR:7CD9j
xor	edx, edx			; EDX = 0
movzx	ecx, word ptr ds:18h	; ECX = 0x0000003F (sectors per track) offset 18h from BPB
div	ecx					; 0x3F (sectors per track) / 0x3F (number of "hidden sectors")
						; DX = 0x0000
						; AX = 0x0001
inc	dl					; DX = 0x0001
mov	cl, dl				; CX = 0x0001
mov	edx, eax			; EDX = 0x00000001
shr	edx, 10h			; EDX = 0x00000000 (align remainder on 512 boundary)
div	word ptr ds:1Ah		; 0x00FF (number of heads/sides) / 0x01
						; 1000000000b = 512 = 0x200
						; DX = 0x0001
						; AX = 0x0000 ?
xchg	dl, dh			; DH = 0x01 (head = 0x1)
						; DL = 0x00 (drive 0)
mov	dl, ds:24h			; DX = 0x0180 (80 is drive number)
mov	ch, al				; CX = 0x0001 (track = 0, sector = 1)
shl	ah, 6				; AX = 0
						; calculates the cube of AH, assuming AH <= 2 (10b)
or	cl, ah				; sets CL only if it is 1 (which it is)
mov	ax, 201h			; AX = 0x0201 (AH = function, AL = sectors to read)
int	13h				; DISK - READ SECTORS INTO MEMORY
					; AL = number of sectors to read (max 512 bytes (0x200)), CH = track, CL = sector
					; DH = head, DL	= drive, ES:BX -> buffer to fill (0D00:0000) (D000)
					; Return: CF set on error, AH =	status (0),	AL = number of sectors read (1)
					; Returns CF = 0

loc_7D44:				; CODE XREF: BOOT_SECTOR:7D15j
jb	loc_7D61		; jump if failed ("A disk read error")
mov	ax, es			; AX = 0x0D00
add	ax, 20h	; ' '	; AX = 0x0D20
					; adds 0x200 (512) bytes to (0D00:0000) or (0xD000) offset
mov	es, ax			; ES = 0x0D20	(0D20:xxxx) or (0xD200)
assume es:nothing
inc	dword ptr ds:10h; *(DWORD* ) 07C0:0010 (0x7C10) = 0x1
					; Field that apparently is used to count how many sectors were read
					; BPB offset 10h
dec	word ptr ds:0Eh ; *(WORD* ) 07C0:000E (0x7C0E) = 0x000F
					; BPB offset 0Eh is count of how many sectors are left to read
					; AF = 1, PF = 1
jnz	loc_7CCB		; jumps if 0x7C0E is not zero (now)
					; loops for 16 (0x10) times
pop	es				; restore original ES (0D00)
assume es:nothing
pop	ds				; restore original DS (07C0), wasn't modified
popad				; restore all (double) registers
retn				; return to 0000:7C74 (assuming everything just worked)
; ---------------------------------------------------------------------------

; loc_7D61 is _SomethingFailedRtn
loc_7D61:				; CODE XREF: BOOT_SECTOR:loc_7CFCj
					; BOOT_SECTOR:loc_7D44j
mov	al, ds:1F8h		; pointer value for message area ("A disk read error occurred")
call	sub_7D70
; ---------------------------------------------------------------------------
mov	al, ds:1FBh
call	sub_7D70
; ---------------------------------------------------------------------------
db 0FBh
; ---------------------------------------------------------------------------

loc_7D6E:				; CODE XREF: BOOT_SECTOR:loc_7D6Ej
jmp	short loc_7D6E		; endless loop

; =============== S U B	R O U T	I N E =======================================

; Attributes: noreturn

sub_7D70 proc near			; CODE XREF: BOOT_SECTOR:7D64p
					; BOOT_SECTOR:7D6Ap
mov	ah, 1

lodsb					; CODE XREF: BOOT_SECTOR:7D80j
cmp	al, 0				; check for NULL byte
jz	short locret_7D82	; jump if done printing message
mov	ah, 0Eh				; teletype output, one char at a time
mov	bx, 7
int	10h				; - VIDEO - WRITE CHARACTER AND	ADVANCE	CURSOR (TTY WRITE)
					; AL = character, BH = display page (alpha modes)
					; BL = foreground color	(graphics modes)
jmp	short loc_7D74		; continue printing while character exists
; ---------------------------------------------------------------------------

locret_7D82:				; CODE XREF: BOOT_SECTOR:7D77j
retn
; ---------------------------------------------------------------------------
aADiskReadErrorOccurred	db 0Dh,0Ah
db 'A disk read error occurred',0
aNtldrIsMissing	db 0Dh,0Ah
db 'NTLDR is missing',0
db 0Dh,	0Ah, 4Eh, 54h, 4Ch
dd 69205244h				; disk signature
aSCompressed db	's compressed',0
aPressCtrlAltDelToResta	db 0Dh,0Ah
db 'Press Ctrl+Alt+Del to restart',0Dh,0Ah,0
align 8
byte_7DF0 db 0,	0, 0, 0, 0, 0, 0, 0, 83h, 0A0h,	0B3h, 0C9h, 0, 0
word_7DFE dw 0AA55h			; DATA XREF: sub_61B:loc_681r
BOOT_SECTOR ends

; ===========================================================================

; Segment type:	Pure data
; Segment permissions: Read/Write
debug002 segment byte public 'DATA' use16
assume cs:debug002
;org 7E00h

; =============== S U B	R O U T	I N E =======================================

; F000:FFF0
; First	instruction on all BIOS	chips.
; Hard coded into all processors.
; Attributes: thunk

PowerOnResetVector proc	near
jmp	far ptr	loc_FE05B
PowerOnResetVector endp

; ---------------------------------------------------------------------------
db  30h	; 0
db  38h	; 8
db  2Fh	; /
db  32h	; 2
db  31h	; 1
db  2Fh	; /
db  31h	; 1
db  32h	; 2
db    0
db 0FCh	; �
db  80h	; �
BIOS ends

; ===========================================================================


Posted in Code AnalysisTagged bootsector, real mode, sp3, windows, windows xp, x86Leave a comment

Windows XP SP3 Bootsector Analysis: Part 1

Posted on September 14, 2021 - September 14, 2021 by admin

These are notes made while disassembling the Windows XP Service Pack 3 bootsector (x86 real mode) code.




; File Name   :	C:\Users\anonymous\Documents\windows_xpsp3_bootsector.img
; Format      :	Binary file
; Base Address:	0000h Range: 0000h - 0200h Loaded length: 0200h

		.686p
		.mmx
		.model flat

; ===========================================================================

; Segment type:	Pure code
seg000		segment	byte public 'CODE' use16
		assume cs:seg000
		assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing

; =============== S U B	R O U T	I N E =======================================


; ORIGin is 0x7C00
sub_0		proc far
		xor	ax, ax			; AX = 0
		mov	ss, ax			; SS = 0
		mov	sp, 7C00h		; SP = 0x7C00
		sti					; enable interrupts
		push	ax			; *SP = 0
		pop	es				; ES = *SP
		push	ax			; *SP = 0
		pop	ds				; DS = *SP
		cld					; clear direction (left to right)
		mov	si, 7C1Bh	; for (int i = 0; i < 0x1E5; i++)
					;    *((BYTE* ) 0x061B)	= *((BYTE* ) &0x7C1B);
		mov	di, 61Bh
		push	ax			; puts value of zero on top of stack
		push	di			; *SP = 0x061B
		mov	cx, 1E5h		; CX = 0x1E5 (number of elements to copy)
		rep movsb			; copy byte by byte
		retf				; 0000:061B
sub_0		endp


; =============== S U B	R O U T	I N E =======================================
; THIS CODE IS COPIED TO 0x061B FOR 0x1E5 BYTES (see above)
; This area is 0000:061B to 0000:0800 in RAM

sub_1B		proc far
		mov	bp, 7BEh		; BP points to partition table
		mov	cl, 4			; sets counter to 4 (max number active partitions)

; loc_20 is _FindActivePartition
loc_20:					; CODE XREF: sub_1B+Fj
		cmp	[bp+0],	ch		; *(BP + 0) = 0x80 (drive number)
		jl	short loc_2E	; jumps ((signed int)(0x0 - 0x80) < 0)
		jnz	short loc_3A	; jump if Active flag was negative (0xF0 to 0xFF, inclusive)
		add	bp, 10h			; only gets here if Active flag was zero (0x00)
		loop	loc_20		; loop a maximum of four times, trying to find active partition
							; reboot/pause if active partition not found after four attempts
		int	18h		; TRANSFER TO ROM BASIC
					; causes transfer to ROM-based BASIC (IBM-PC)
					; often	reboots	a compatible; often has	no effect at all

; loc_2E is _SuccessFoundActivePartition
loc_2E:					; CODE XREF: sub_1B+8j
		mov	si, bp		; if we made it here, we found the partition

loc_30:					; CODE XREF: sub_1B+1Dj
		add	si, 10h		; point to next partition entry
		dec	cx			; decrease counter
		jz	short loc_4F; jump if parsed all four partition table entries
		cmp	[si], ch	; check to see if active flag in next entry is NULL
		jz	short loc_30; check next partition entry, if we have any left (four possible)

; loc_3A is _PrintInvalidPartitionTable
loc_3A:					; CODE XREF: sub_1B+Aj
		mov	al, ds:7B5h	; AL = *(0x07B5) [2C] 

loc_3D:					; CODE XREF: sub_1B+4Ej sub_1B+64j ...
		mov	ah, 7		; AH = 0x07
		mov	si, ax		; DATA XREF: sub_1B+30r (0x072C)
						; 0x072C = "Invalid partition table"

; loc_41 is _LoadNextErrorChar
loc_41:					; CODE XREF: sub_1B+32j
		lodsb			; load character at ((BYTE* ) 0x072C++)

; loc_42 is _PrintErrorThenInfiniteLoop
loc_42:					; CODE XREF: sub_1B+29j
		cmp	al, 0		; until the byte is NULL (infinite loop!)
		jz	short loc_42
		mov	bx, 7		; BX = 0x7
		mov	ah, 0Eh		; AH = 0xE
		int	10h		; DATA XREF: sub_9B+8r	sub_9B+3Br ...
					; - VIDEO - WRITE CHARACTER AND	ADVANCE	CURSOR (TTY WRITE)
					; AL = character, BH = display page (alpha modes)
					; BL = foreground color	(graphics modes)
		jmp	short loc_41; load next character
; ---------------------------------------------------------------------------
; loc_4F is _PartitionTableParsed
loc_4F:					; CODE XREF: sub_1B+19j
		mov	[bp+10h], cl; set next partition entry to inactive (why?)
		call	sub_9B
		jnb	short loc_81

loc_57:					; CODE XREF: sub_1B+72j
		inc	byte ptr [bp+10h]
		cmp	byte ptr [bp+4], 0Bh
		jz	short loc_6B

loc_60:					; DATA XREF: sub_1B+11r
		cmp	byte ptr [bp+4], 0Ch
		jz	short loc_6B
		mov	al, ds:7B6h
		jnz	short loc_3D

loc_6B:					; CODE XREF: sub_1B+43j sub_1B+49j
		add	byte ptr [bp+2], 6
		add	word ptr [bp+8], 6
		adc	word ptr [bp+0Ah], 0
		call	sub_9B
		jnb	short loc_81
		mov	al, ds:7B6h
		jmp	short loc_3D
; ---------------------------------------------------------------------------
; loc_81 is _CheckPartitionMagic
loc_81:					; CODE XREF: sub_1B+3Aj sub_1B+5Fj
		cmp	word ptr ds:7DFEh, 0AA55h
		jz	short loc_94
		cmp	byte ptr [bp+10h], 0
		jz	short loc_57
		mov	al, ds:7B7h
		jmp	short loc_3D
; ---------------------------------------------------------------------------
; loc_94 is _LegitimatePartitionMagic
loc_94:					; CODE XREF: sub_1B+6Cj
		mov	di, sp		; DI = 0x7C00
		push	ds		; *(SP) = 0
		push	di		; *(SP) = 0x7C00
		mov	si, bp		; SI = 0x07BE (pointer to partition table entry)
		retf			; returns to 0000:7C00
						; END OF CURRENT ANALYSIS
						; GO TO PART 2 !!!!!!!!!!!!!!!!
						; GO TO PART 2 !!!!!!!!!!!!!!!!
						; GO TO PART 2 !!!!!!!!!!!!!!!!
						
						
						
						
						
						
						
sub_1B		endp ; sp-analysis failed


; =============== S U B	R O U T	I N E =======================================


sub_9B		proc near		; CODE XREF: sub_1B+37p sub_1B+5Cp
		mov	di, 5	; DI = 5 (write drive parameter to 0000:0005)
		mov	dl, [bp+0]	; DL = drive number (0x80)
		mov	ah, 8
		int	13h		; DISK - DISK -	GET CURRENT DRIVE PARAMETERS (XT,AT,XT286,CONV,PS)
					; DL = drive number (0x80)
					; Return: CF set on error, AH =	status code (0x8), BL = drive type (0)
					; DL = number of consecutive drives (0x1)
					; DH = maximum value for head number (0xFE), ES:DI -> drive parameter (0000:0005)
					; 0000:0005 points to Disk Base Table (http://stanislavs.org/helppc/dbt.html)
					;	value is : 0xFF 0x00 0xF0 0x53 0xFF 0x00 0xF0 0x53 0xFF 0x00 0xF0
					; returns CF = 0
		jb	short loc_CA	; jumps if failed
		mov	al, cl			; AL = 0xBF
		and	al, 3Fh			; AL = 0x3F	(why?)
		cbw					; AX = 0x003F
		mov	bl, dh			; BL = 0xFE
		mov	bh, ah			; BH = 0
		inc	bx				; BX = 0x00FF
		mul	bx				; 0xFF * 0x3F = 0x3EC1
							; AX = 0x3EC1
		mov	dx, cx			; DX = 0x09BF
		xchg	dl, dh		; DL = 0x09
							; DH = 0xBF
		mov	cl, 6			; CX = 0x0906
		shr	dh, cl			; DX = 0x0209
		inc	dx				; DX = 0x020A
		mul	dx				; 0x020A * 0x3EC1 = 0x7FF58A (Logical Block Addressing)
							; DX = 0x7F
							; AX = 0xF58A
		cmp	[bp+0Ah], dx	; 0 < 0x7F
		ja	short loc_E6	; definitely not
		jb	short loc_CA	; yes
		cmp	[bp+8],	ax		; 0x003F < 0xF58A (doesn't get here normally)
		jnb	short loc_E6	; jumps if something is messed up? has to check for INT 13 extensions

; loc_CA is _GetCurrentDriveParametersError
loc_CA:					; CODE XREF: sub_9B+Aj	sub_9B+28j ...
		mov	ax, 201h		; AX = 0x0201
		mov	bx, 7C00h		; BX = 0x7C00
		mov	cx, [bp+2]		; CX = 0x00 (track) 01 (sector)
		mov	dx, [bp+0]		; DX = 0x01 (head) 80 (drive)
		int	13h		; DISK - READ SECTORS INTO MEMORY
					; AL = number of sectors to read, CH = track, CL = sector
					; DH = head, DL	= drive, ES:BX -> buffer to fill (0000:7C00)
					; Return: CF set on error, AH =	status,	AL = number of sectors read
					; Returns CF = 0
		jnb	short locret_12B	; jumps on successful read (ours)
		dec	di
		jz	short locret_12B
		xor	ah, ah
		mov	dl, [bp+0]
		int	13h		; DISK - RESET DISK SYSTEM
					; DL = drive (if bit 7 is set both hard	disks and floppy disks reset)
		jmp	short loc_CA
; ---------------------------------------------------------------------------

loc_E6:					; CODE XREF: sub_9B+26j sub_9B+2Dj
		mov	dl, [bp+0]
		pusha
		mov	bx, 55AAh
		mov	ah, 41h	; 'A'
		int	13h		; DISK - Check for INT 13h Extensions
					; BX = 55AAh, DL = drive number
					; Return: CF set if not	supported
					; AH = extensions version
					; BX = AA55h
					; CX = Interface support bit map
		jb	short loc_129
		cmp	bx, 0AA55h
		jnz	short loc_129
		test	cl, 1
		jz	short loc_129
		popa

loc_FF:					; CODE XREF: sub_9B+8Cj
		pusha
		push	0
		push	0
		push	word ptr [bp+0Ah]
		push	word ptr [bp+8]
		push	0
		push	7C00h
		push	1
		push	10h
		mov	ah, 42h	; 'B'
		mov	si, sp
		int	13h		; DISK - IBM/MS	Extension - EXTENDED READ (DL -	drive, DS:SI - disk address packet)
		popa
		popa
		jnb	short locret_12B
		dec	di
		jz	short locret_12B
		xor	ah, ah
		mov	dl, [bp+0]
		int	13h		; DISK - RESET DISK SYSTEM
					; DL = drive (if bit 7 is set both hard	disks and floppy disks reset)
		jmp	short loc_FF
; ---------------------------------------------------------------------------

loc_129:				; CODE XREF: sub_9B+56j sub_9B+5Cj ...
		popa
		stc

locret_12B:				; CODE XREF: sub_9B+3Dj sub_9B+40j ...
		retn			; returns to 0000:0655 (loc_55)
sub_9B		endp

; ---------------------------------------------------------------------------
		db  49h	; I
		db  6Eh	; n
		db  76h	; v
		db  61h	; a
		db  6Ch	; l
		db  69h	; i
		db  64h	; d
		db  20h
		db  70h	; p
		db  61h	; a
		db  72h	; r
		db  74h	; t
		db  69h	; i
		db  74h	; t
		db  69h	; i
		db  6Fh	; o
		db  6Eh	; n
		db  20h
		db  74h	; t
		db  61h	; a
		db  62h	; b
		db  6Ch	; l
		db  65h	; e
		db    0
		db  45h	; E
		db  72h	; r
		db  72h	; r
		db  6Fh	; o
		db  72h	; r
		db  20h
		db  6Ch	; l
		db  6Fh	; o
		db  61h	; a
		db  64h	; d
		db  69h	; i
		db  6Eh	; n
		db  67h	; g
		db  20h
		db  6Fh	; o
		db  70h	; p
		db  65h	; e
		db  72h	; r
		db  61h	; a
		db  74h	; t
		db  69h	; i
		db  6Eh	; n
		db  67h	; g
		db  20h
		db  73h	; s
		db  79h	; y
		db  73h	; s
		db  74h	; t
		db  65h	; e
		db  6Dh	; m
		db    0
		db  4Dh	; M
		db  69h	; i
		db  73h	; s
		db  73h	; s
		db  69h	; i
		db  6Eh	; n
		db  67h	; g
		db  20h
		db  6Fh	; o
		db  70h	; p
		db  65h	; e
		db  72h	; r
		db  61h	; a
		db  74h	; t
		db  69h	; i
		db  6Eh	; n
		db  67h	; g
		db  20h
		db  73h	; s
		db  79h	; y
		db  73h	; s
		db  74h	; t
		db  65h	; e
		db  6Dh	; m
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db  2Ch	; ,
		db  44h	; D
		db  63h	; c
		db 0AAh	; �
		db  0Ah
		db 0AAh	; �
		db  0Ah
		db    0
		db    0
		db  80h	; �
		db    1
		db    1
		db    0
		db    7
		db 0FEh	; �
		db 0FFh
		db 0FFh
		db  3Fh	; ?
		db    0
		db    0
		db    0
		db 0D9h	; �
		db 0A6h	; �
		db  3Fh	; ?
		db    1
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db    0
		db  55h	; U
		db 0AAh	; �
seg000		ends


		end
Posted in Code AnalysisTagged bootsector, real mode, sp3, windows, windows xp, x86Leave a comment

Recent Posts

  • Manual Scraping
  • Nitter Replacement
  • MFA Abuse in Splunk
  • Virtualbox Automation
  • Repository Poisoning

Recent Comments

    Archives

    • August 2024
    • July 2023
    • August 2022
    • March 2022
    • November 2021
    • October 2021
    • September 2021
    • August 2021
    • July 2021
    • June 2021
    • February 2021
    • December 2020
    • October 2020
    • September 2020
    • April 2020
    • March 2020
    • January 2020
    • July 2019
    • June 2019

    Categories

    • Campaign Analysis
    • Campaign Management
    • Code Analysis
    • Current Events
    • Malware Development
    • Techniques
    • Uncategorized
    • Utilities

    Meta

    • Log in
    • Entries feed
    • Comments feed
    • WordPress.org
    Proudly powered by WordPress | Theme: micro, developed by DevriX.