The entire contents of this archive (source code to patch, utilities, various kerneldefs.inc files)
are Copyright Paul Bartholomew.
PATCHCODE_VERSION equ 2
%include "kerneldefs.inc"
%include "patchseg.inc"
CODE_SIZE equ 0x8000
HIGH_LOW_DIFF equ (HIGHCODE_BASE - LOWCODE_BASE)
PATCH_MAGIC_ID equ 0xcafebabe
DEF_PARTMETHOD_ONLY_STANDARD_PARTITIONS equ 0
DEF_PARTMETHOD_PART6_REST_OF_DRIVE equ 1
DEF_PARTMETHOD_PART6_UNDER_137GB_PART7_REST_OF_DRIVE equ 2
DEF_PARTMETHOD_PART6_UNDER_137GB_NO_PART7 equ 3
BITS 32
cpu 586
segment code
org HIGHCODE_BASE
; ofs=00000000
HIGHCODE_magic_id:
dd PATCH_MAGIC_ID
HIGHCODE_version_id:
dd PATCHCODE_VERSION
HIGHCODE_def_partition_method:
; db DEF_PARTMETHOD_PART6_REST_OF_DRIVE
db DEF_PARTMETHOD_PART6_UNDER_137GB_PART7_REST_OF_DRIVE
HIGHCODE_ignore_HD_part_table:
db 0
;more flag bytes
times 2 db 0
HIGHCODE_partition_table_offset:
dd (HIGHCODE_Partition_table - HIGHCODE_BASE)
times 48 db 0
; jump table
; ofs=00000040
HIGHCODE_DiscardINITSection_hook:
jmp HIGHCODE_DiscardINITSection_hook_handler
; ofs=00000045
HIGHCODE_DiskCreate__getsize_hook:
jmp HIGHCODE_DiskCreate__getsize_hook_handler
; ofs=0000004a
HIGHCODE_PartitionCreate_hook:
jmp HIGHCODE_PartitionCreate_hook_handler
; ofs=0000004f
HIGHCODE_IDESetupReadWrite_hook:
jmp HIGHCODE_IDESetupReadWrite_hook_handler
; ofs=00000054
HIGHCODE_IDESetupVerify_hook:
jmp HIGHCODE_IDESetupVerify_hook_handler
; ofs=00000059
HIGHCODE_DiskCreate__finalize_hook:
jmp HIGHCODE_DiskCreate__finalize_hook_handler
; ofs=0000005E
HIGHCODE_DiskIoControl_hook:
jmp HIGHCODE_DiskIoControl_hook_handler
align 256
db 'LBA48 support by Paul Bartholomew (oz_paulb) ',13,10
db 'Copyright (c) 2003 - Released under GNU Public License',13,10
db 0
align 64
XBOX_SWAPPART1_LBA_START equ 0x400
XBOX_SWAPPART_LBA_SIZE equ 0x177000
XBOX_SWAPPART2_LBA_START equ (XBOX_SWAPPART1_LBA_START + XBOX_SWAPPART_LBA_SIZE)
XBOX_SWAPPART3_LBA_START equ (XBOX_SWAPPART2_LBA_START + XBOX_SWAPPART_LBA_SIZE)
XBOX_SYSPART_LBA_START equ (XBOX_SWAPPART3_LBA_START + XBOX_SWAPPART_LBA_SIZE)
XBOX_SYSPART_LBA_SIZE equ 0xfa000
XBOX_MUSICPART_LBA_START equ (XBOX_SYSPART_LBA_START + XBOX_SYSPART_LBA_SIZE)
XBOX_MUSICPART_LBA_SIZE equ 0x9896b0
XBOX_STANDARD_MAX_LBA equ (XBOX_MUSICPART_LBA_START + XBOX_MUSICPART_LBA_SIZE)
%macro PT_ENTRY 5
db %1;partition name
dd %2;partition flags
dd %3;partition LBA start
dd %4;partition LBA size
dd %5;reserved
%endmacro
_PE_OFS__part_name equ (0)
_PE_OFS__part_flags equ (16)
PE_PARTFLAGS_IN_USE equ 0x80000000
_PE_OFS__part_lba_start equ (20)
_PE_OFS__part_lba_size equ (24)
_PE_OFS__part_reserved equ (28)
_PE_SIZ__part_entry equ (32)
MAX_PARTITIONS equ 14
HIGHCODE_Partition_table:
HIGHCODE_Partition_table_hdr:
db '****PARTINFO****'
PARTITION_MAGIC_LEN equ ($-HIGHCODE_Partition_table_hdr)
times 32 db 0; reserved
_PT_OFS__part_entries equ ($-HIGHCODE_Partition_table)
PT_ENTRY 'XBOX MUSIC ',PE_PARTFLAGS_IN_USE,XBOX_MUSICPART_LBA_START,XBOX_MUSICPART_LBA_SIZE,0
PT_ENTRY 'XBOX SYSTEM ',PE_PARTFLAGS_IN_USE,XBOX_SYSPART_LBA_START,XBOX_SYSPART_LBA_SIZE,0
PT_ENTRY 'XBOX GAME SWAP 1',PE_PARTFLAGS_IN_USE,XBOX_SWAPPART1_LBA_START,XBOX_SWAPPART_LBA_SIZE,0
PT_ENTRY 'XBOX GAME SWAP 2',PE_PARTFLAGS_IN_USE,XBOX_SWAPPART2_LBA_START,XBOX_SWAPPART_LBA_SIZE,0
PT_ENTRY 'XBOX GAME SWAP 3',PE_PARTFLAGS_IN_USE,XBOX_SWAPPART3_LBA_START,XBOX_SWAPPART_LBA_SIZE,0
HIGHCODE_Partition_table_first_available:
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PT_ENTRY ' ',0,0,0,0
PARTITION_TABLE_SIZE equ ($-HIGHCODE_Partition_table)
times 0x90 db 0; reserved
align 64
HIGHCODE_DiscardINITSection_hook_handler:
xor eax,eax
mov dword [LOWCODE_BASE],eax; clear 'magic' at destination
mov esi, HIGHCODE_BASE+4
mov edi, LOWCODE_BASE+4
mov ecx, (CODE_SIZE/4)-1
rep movsd ; copy all but 'magic'
mov eax,dword [HIGHCODE_BASE]
mov dword [LOWCODE_BASE],eax; copy 'magic' last
jmp (LOWCODE_DiscardINITSection_hook_continue - HIGH_LOW_DIFF)
align 16
LOWCODE_DiscardINITSection_hook_continue:
call FUNCADDR_DoDiscardINITSection+HIGH_LOW_DIFF
jmp ADDR_DiscardINITSection_hook_continue+HIGH_LOW_DIFF
align 64
BP_OFS_IDENTIFY_DEVICE_STRUCT equ (0-0x228)
ID_OFS__CMD_SET_SUPPORTED equ (83*2)
BITMASK__CMD_SET_HAS_LBA48 equ (1<<10)
ID_OFS__TOTAL_USER_SECTORS_LBA28 equ (60*2)
ID_OFS__TOTAL_USER_SECTORS_LBA48_LOW equ (100*2)
ID_OFS__TOTAL_USER_SECTORS_LBA48_HIGH equ (102*2)
HIGHCODE_DiskCreate__getsize_hook_handler:
push ebx
push ecx
push edx
mov eax,[ebp+BP_OFS_IDENTIFY_DEVICE_STRUCT+ID_OFS__CMD_SET_SUPPORTED]
and eax, BITMASK__CMD_SET_HAS_LBA48
jnz short .drive_supports_lba48
.no_lba48_support:
mov eax,[ebp+BP_OFS_IDENTIFY_DEVICE_STRUCT+ID_OFS__TOTAL_USER_SECTORS_LBA28]
jmp short .have_total_sectors
.drive_supports_lba48:
mov eax,[ebp+BP_OFS_IDENTIFY_DEVICE_STRUCT+ID_OFS__TOTAL_USER_SECTORS_LBA48_HIGH]
test eax,eax
jnz short .drive_is_huge__limit_to_32bits
mov eax,[ebp+BP_OFS_IDENTIFY_DEVICE_STRUCT+ID_OFS__TOTAL_USER_SECTORS_LBA48_LOW]
jmp short .have_total_sectors
.drive_is_huge__limit_to_32bits:
xor eax,eax; FIXME: should be 33 c0, generates 31 c0 (OK?)
dec eax
.have_total_sectors
mov edx,eax ;edx holds total drive sectors
cmp eax,XBOX_STANDARD_MAX_LBA
ja .try_extra_partitions
.j_skip_extra_partitions
jmp .skip_extra_partitions
.try_extra_partitions
cmp byte [HIGHCODE_def_partition_method],DEF_PARTMETHOD_ONLY_STANDARD_PARTITIONS
jz short .j_skip_extra_partitions
sub eax,XBOX_STANDARD_MAX_LBA;eax now free space at end of drive
mov ebx,eax ;ebx holds part6 size (default to all free space)
xor ecx,ecx ;ecx holds part7 size (default to zero)
cmp edx,0x0fffffff ;if drive isn't > 137gb, just create part6
jbe .create_partitions
.drive_larger_than_137gb:
cmp byte [HIGHCODE_def_partition_method],DEF_PARTMETHOD_PART6_REST_OF_DRIVE
jz .create_partitions
mov eax,0x0fffffff
sub eax,XBOX_STANDARD_MAX_LBA
mov ebx,eax ;ebx holds part6 size (rest of space before 137gb)
cmp byte [HIGHCODE_def_partition_method],DEF_PARTMETHOD_PART6_UNDER_137GB_NO_PART7
jz .create_partitions
mov eax,edx ;edx holds total drive sectors
sub eax,XBOX_STANDARD_MAX_LBA;eax now free space at end of drive
sub eax,ebx ;subtract space used for part6
mov ecx,eax ;ecx holds part7 size
.create_partitions
.drive_less_or_equal_to_137gb:
;ebx = part6 size
;ecx = part7 size
;edx = total drive sectors
mov eax,XBOX_STANDARD_MAX_LBA
mov [HIGHCODE_Partition_table_first_available+(0*_PE_SIZ__part_entry)+_PE_OFS__part_lba_start],eax
mov dword [HIGHCODE_Partition_table_first_available+(0*_PE_SIZ__part_entry)+_PE_OFS__part_lba_size],ebx
mov eax,'DRIV'
mov [HIGHCODE_Partition_table_first_available+(0*_PE_SIZ__part_entry)+_PE_OFS__part_name],eax
mov eax,'E F:'
mov [HIGHCODE_Partition_table_first_available+(0*_PE_SIZ__part_entry)+_PE_OFS__part_name+4],eax
mov eax,' '
mov [HIGHCODE_Partition_table_first_available+(0*_PE_SIZ__part_entry)+_PE_OFS__part_name+8],eax
mov eax,' '
mov [HIGHCODE_Partition_table_first_available+(0*_PE_SIZ__part_entry)+_PE_OFS__part_name+12],eax
mov eax,PE_PARTFLAGS_IN_USE
mov [HIGHCODE_Partition_table_first_available+(0*_PE_SIZ__part_entry)+_PE_OFS__part_flags],eax
test ecx,ecx
jz .partitions_created
mov eax,XBOX_STANDARD_MAX_LBA
add eax,ebx
mov [HIGHCODE_Partition_table_first_available+(1*_PE_SIZ__part_entry)+_PE_OFS__part_lba_start],eax
mov dword [HIGHCODE_Partition_table_first_available+(1*_PE_SIZ__part_entry)+_PE_OFS__part_lba_size],ecx
mov eax,'DRIV'
mov [HIGHCODE_Partition_table_first_available+(1*_PE_SIZ__part_entry)+_PE_OFS__part_name],eax
mov eax,'E P:'
mov [HIGHCODE_Partition_table_first_available+(1*_PE_SIZ__part_entry)+_PE_OFS__part_name+4],eax
mov eax,' '
mov [HIGHCODE_Partition_table_first_available+(1*_PE_SIZ__part_entry)+_PE_OFS__part_name+8],eax
mov eax,' '
mov [HIGHCODE_Partition_table_first_available+(1*_PE_SIZ__part_entry)+_PE_OFS__part_name+12],eax
mov eax,PE_PARTFLAGS_IN_USE
mov [HIGHCODE_Partition_table_first_available+(1*_PE_SIZ__part_entry)+_PE_OFS__part_flags],eax
.partitions_created:
.skip_extra_partitions
.partitions_done
mov eax,edx
pop edx
pop ecx
pop ebx
jmp ADDR_DiskCreate__getsize_hook_continue
align 64
BP_OFS_PARTITION_SIZE_IN_BYTES_LOW equ (0-0x20)
BP_OFS_PARTITION_SIZE_IN_BYTES_HIGH equ (0-0x1c)
HIGHCODE_PartitionCreate_hook_handler:
push edi
push esi
push ebx
push ecx
push edx
mov edi,0
mov esi,HIGHCODE_Partition_table-HIGH_LOW_DIFF
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .common
.we_are_highcode:
mov edi,1
mov esi,HIGHCODE_Partition_table
.common
test ebx,ebx
jz short .exit_failure
cmp ebx,MAX_PARTITIONS
ja short .exit_failure
add esi,_PT_OFS__part_entries
mov eax,ebx
dec eax
mov ecx,_PE_SIZ__part_entry
mul ecx
add esi,eax
mov eax,dword [esi+_PE_OFS__part_flags]
and eax,PE_PARTFLAGS_IN_USE
test eax,eax
jz short .exit_failure
mov eax,dword [esi+_PE_OFS__part_lba_size]
mov ecx,512
mul ecx
mov [ebp+BP_OFS_PARTITION_SIZE_IN_BYTES_LOW],eax
mov [ebp+BP_OFS_PARTITION_SIZE_IN_BYTES_HIGH],edx
mov eax,dword [esi+_PE_OFS__part_lba_start]
.exit_ok:
pop edx
pop ecx
pop ebx
pop esi
%if PartitionCreate_return_in_ecx > 0
mov ecx,eax
%endif
test edi,edi
jz short .exit_ok_lowcode
.exit_ok_highcode:
pop edi
jmp ADDR_PartitionCreate_hook_continue
.exit_ok_lowcode:
pop edi
jmp ADDR_PartitionCreate_hook_continue+HIGH_LOW_DIFF
.exit_failure:
pop edx
pop ecx
pop ebx
pop esi
mov eax,0xc0000034
test edi,edi
jz short .exit_failure_lowcode
.exit_failure_highcode:
jmp ADDR_PartitionCreate_hook_continue_err
.exit_failure_lowcode:
jmp ADDR_PartitionCreate_hook_continue_err+HIGH_LOW_DIFF
IDE_REG_SEC_COUNT equ 0x1f2
IDE_REG_LBA_LOW equ 0x1f3
IDE_REG_LBA_MID equ 0x1f4
IDE_REG_LBA_HIGH equ 0x1f5
IDE_REG_DEVICE equ 0x1f6
IDE_REG_COMMAND equ 0x1f7
IDE_CMD_READ_DMA equ 0xc8
IDE_CMD_READ_DMA_EXT equ 0x25
IDE_CMD_WRITE_DMA equ 0xca
IDE_CMD_WRITE_DMA_EXT equ 0x35
IDE_CMD_READ_VERIFY_SECTORS equ 0x40
IDE_CMD_READ_VERIFY_SECTORS_EXT equ 0x42
IO_BUSMASTER_REG equ 0xff60
IO_BUSMASTER_CMD_READ equ 0x09
IO_BUSMASTER_CMD_WRITE equ 0x01
IRQL_VALUE_RET equ 2
ESI_OFS_READ_OR_WRITE_FLAG equ 0
RWFLAG_IS_READ equ 2
ESI_OFS_NUM_BYTES equ 4
ESI_OFS_LBA equ 12
ESI_OFS_LBA_LOW equ (ESI_OFS_LBA+0)
ESI_OFS_LBA_MID equ (ESI_OFS_LBA+1)
ESI_OFS_LBA_HIGH equ (ESI_OFS_LBA+2)
ESI_OFS_LBA_XHIGH equ (ESI_OFS_LBA+3)
align 64
HIGHCODE_IDESetupReadWrite_hook_handler:
push eax
push ebx
push edx
push esi
push edi
mov eax,edi;byte count
shr eax,9;convert to sector count
mov edi,eax
mov eax,dword [VARADDR_TotalHardDriveSectors]
and eax,0xf0000000
test eax,eax
jz .is_lba28
mov eax,edi;num sectors
add eax,dword [esi+ESI_OFS_LBA]
and eax,0xf0000000
test eax,eax
jz short .is_lba28
.is_lba48:
mov dx,IDE_REG_SEC_COUNT
mov eax,edi
xchg ah,al
out dx,al ;COUNTREG (15:

= high(sector count)
xchg ah,al
out dx,al ;COUNTREG (7:0) = low(sector count)
mov dx,IDE_REG_LBA_LOW
mov al,byte [esi+ESI_OFS_LBA_XHIGH]
out dx,al ;LBAREG (31:24) = LBA (31:24)
mov al,byte [esi+ESI_OFS_LBA_LOW]
out dx,al ;LBAREG (7:0) = LBA (7:0)
mov dx,IDE_REG_LBA_MID
xor al,al
out dx,al ;LBAREG (39:32) = 0
mov al,byte [esi+ESI_OFS_LBA_MID]
out dx,al ;LBAREG (15:

= LBA (15:

mov dx,IDE_REG_LBA_HIGH
xor al,al
out dx,al ;LBAREG (47:40) = 0
mov al,byte [esi+ESI_OFS_LBA_HIGH]
out dx,al ;LBAREG (23:16) = LBA (23:16)
mov al,0x40
mov dx,IDE_REG_DEVICE
out dx,al
cmp byte [esi+ESI_OFS_READ_OR_WRITE_FLAG],RWFLAG_IS_READ
jnz short .is_write_lba48
.is_read_lba48:
mov al,IDE_CMD_READ_DMA_EXT
mov cl,IO_BUSMASTER_CMD_READ
jmp short .write_ide_rw_command
.is_write_lba48:
mov al,IDE_CMD_WRITE_DMA_EXT
mov cl,IO_BUSMASTER_CMD_WRITE
jmp short .write_ide_rw_command
.is_lba28:
mov eax,edi
mov dx,IDE_REG_SEC_COUNT
out dx,al
mov al,byte [esi+ESI_OFS_LBA_LOW]
mov dx,IDE_REG_LBA_LOW
out dx,al
mov al,byte [esi+ESI_OFS_LBA_MID]
mov dx,IDE_REG_LBA_MID
out dx,al
mov al,byte [esi+ESI_OFS_LBA_HIGH]
mov dx,IDE_REG_LBA_HIGH
out dx,al
mov al,byte [esi+ESI_OFS_LBA_XHIGH]
and al,0x0f
or al,0xe0
mov dx,IDE_REG_DEVICE
out dx,al
cmp byte [esi+ESI_OFS_READ_OR_WRITE_FLAG],RWFLAG_IS_READ
jnz short .is_write_lba28
.is_read_lba28:
mov al,IDE_CMD_READ_DMA
mov cl,IO_BUSMASTER_CMD_READ
jmp short .write_ide_rw_command
.is_write_lba28:
mov al,IDE_CMD_WRITE_DMA
mov cl,IO_BUSMASTER_CMD_WRITE
.write_ide_rw_command
mov dx,IDE_REG_COMMAND
out dx,al
mov al,cl
mov dx,IO_BUSMASTER_REG
out dx,al
pop edi
pop esi
pop edx
pop ebx
pop eax
pop edi;calling code pushed these, so pop them
pop esi
.exit:
mov cl,IRQL_VALUE_RET
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .exit_lowcode
.exit_highcode:
jmp ADDR_IDESetupReadWrite_hook_continue
.exit_lowcode:
jmp ADDR_IDESetupReadWrite_hook_continue+HIGH_LOW_DIFF
align 64
HIGHCODE_IDESetupVerify_hook_handler:
push eax
push ebx
push edx
push esi
push edi
mov eax,[esi+ESI_OFS_NUM_BYTES]
shr eax,9;convert to sector count
mov edi,eax
mov eax,dword [VARADDR_TotalHardDriveSectors]
and eax,0xf0000000
test eax,eax
jz .is_lba28
mov eax,edi;num sectors
add eax,dword [esi+ESI_OFS_LBA]
and eax,0xf0000000
test eax,eax
jz short .is_lba28
.is_lba48:
mov dx,IDE_REG_SEC_COUNT
mov eax,edi
xchg ah,al
out dx,al ;COUNTREG (15:

= high(sector count)
xchg ah,al
out dx,al ;COUNTREG (7:0) = low(sector count)
mov dx,IDE_REG_LBA_LOW
mov al,byte [esi+ESI_OFS_LBA_XHIGH]
out dx,al ;LBAREG (31:24) = LBA (31:24)
mov al,byte [esi+ESI_OFS_LBA_LOW]
out dx,al ;LBAREG (7:0) = LBA (7:0)
mov dx,IDE_REG_LBA_MID
xor al,al
out dx,al ;LBAREG (39:32) = 0
mov al,byte [esi+ESI_OFS_LBA_MID]
out dx,al ;LBAREG (15:

= LBA (15:

mov dx,IDE_REG_LBA_HIGH
xor al,al
out dx,al ;LBAREG (47:40) = 0
mov al,byte [esi+ESI_OFS_LBA_HIGH]
out dx,al ;LBAREG (23:16) = LBA (23:16)
mov al,0x40
mov dx,IDE_REG_DEVICE
out dx,al
mov al,IDE_CMD_READ_VERIFY_SECTORS_EXT
jmp short .write_ide_command
.is_lba28:
mov eax,edi
mov dx,IDE_REG_SEC_COUNT
out dx,al
mov al,byte [esi+ESI_OFS_LBA_LOW]
mov dx,IDE_REG_LBA_LOW
out dx,al
mov al,byte [esi+ESI_OFS_LBA_MID]
mov dx,IDE_REG_LBA_MID
out dx,al
mov al,byte [esi+ESI_OFS_LBA_HIGH]
mov dx,IDE_REG_LBA_HIGH
out dx,al
mov al,byte [esi+ESI_OFS_LBA_XHIGH]
and al,0x0f
or al,0xe0
mov dx,IDE_REG_DEVICE
out dx,al
mov al,IDE_CMD_READ_VERIFY_SECTORS
.write_ide_command
mov dx,IDE_REG_COMMAND
out dx,al
pop edi
pop esi
pop edx
pop ebx
pop eax
.exit:
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .exit_lowcode
.exit_highcode:
jmp ADDR_IDESetupVerify_hook_continue
.exit_lowcode:
jmp ADDR_IDESetupVerify_hook_continue+HIGH_LOW_DIFF
align 64
HIGHCODE_DiskCreate__finalize_hook_handler:
call FUNCADDR_IncrementBootCounter
cmp byte [HIGHCODE_ignore_HD_part_table],0
jz short .read_partition_table
jmp .exit
.read_partition_table
call HIGHCODE_read_partition_sector
test eax,eax
jnz short .exit
mov esi,HIGHCODE_Partition_table_hdr
mov edi,HIGHCODE_partition_iobuf
mov ecx,(PARTITION_MAGIC_LEN/4)
repe cmpsd
jnz short .exit
mov esi,HIGHCODE_partition_iobuf
mov edi,HIGHCODE_Partition_table_hdr
mov ecx,PARTITION_TABLE_SIZE
rep movsb
.exit
mov edi,HIGHCODE_partition_iobuf
mov ecx,(512/4)
xor eax,eax
rep stosd
jmp ADDR_DiskCreate__finalize_hook_continue
;typedef struct tagANSI_STRING {
; USHORT Length;
; USHORT MaximumLength;
; PCHAR Buffer;
;} ANSI_STRING;
struc ANSI_STRING
.Length resw 1
.MaximumLength resw 1
.Buffer resd 1
.Size:
endstruc
;typedef struct tagOBJECT_ATTRIBUTES {
; HANDLE RootDirectory;
; ANSI_STRING *ObjectName;
; ULONG Attributes;
;} OBJECT_ATTRIBUTES;
struc OBJECT_ATTRIBUTES
.RootDirectory resd 1
.ObjectName resd 1
.Attributes resd 1
.Size:
endstruc
;typedef struct tagIO_STATUS_BLOCK {
; union {
; unsigned int Status;
; PVOID Pointer;
; } u1;
; ULONG_PTR Information;
;} IO_STATUS_BLOCK;
struc IO_STATUS_BLOCK
.u1 resd 1
.Information resd 1
.Size:
endstruc
struc HANDLE
.Handle resd 1
.Size:
endstruc
struc LARGE_INTEGER
.QuadPart resd 2
.Size:
endstruc
HIGHCODE_read_partition_sector:
.var_handle equ (0-HANDLE.Size)
.var_byte_offset equ (.var_handle-LARGE_INTEGER.Size)
.var_io_stat_block equ (.var_byte_offset-IO_STATUS_BLOCK.Size)
.var_obj_attr equ (.var_io_stat_block-OBJECT_ATTRIBUTES.Size)
.var_a_path equ (.var_obj_attr-ANSI_STRING.Size)
.stack_adjust equ .var_a_path
push ebp
mov ebp,esp
add esp,.stack_adjust
; RtlInitAnsiString(&a_path, "\\Device\\Harddisk0\\partition0");
push .raw_partition_path
lea eax,[ebp+.var_a_path]
push eax
call FUNCADDR_RtlInitAnsiString
; obj_attr.RootDirectory = 0;
xor eax,eax
mov [ebp+.var_obj_attr+OBJECT_ATTRIBUTES.RootDirectory],eax
; obj_attr.ObjectName = &a_path;
lea eax,[ebp+.var_a_path]
mov [ebp+.var_obj_attr+OBJECT_ATTRIBUTES.ObjectName],eax
; obj_attr.Attributes = 0x40;
mov dword [ebp+.var_obj_attr+OBJECT_ATTRIBUTES.Attributes],0x40
; NtOpenFile(&handle, 0x80100000, &obj_attr, &io_stat_block, 3, 0x10);
push 0x10
push 3
lea eax,[ebp+.var_io_stat_block]
push eax
lea eax,[ebp+.var_obj_attr]
push eax
push 0x80100000
lea eax,[ebp+.var_handle]
push eax
call FUNCADDR_NtOpenFile
cmp eax,0
jl .j_exit_error
jmp short .continue
.j_exit_error:
jmp .exit_error
.continue:
; byte_offset.QuadPart = 0;
mov dword [ebp+.var_byte_offset+LARGE_INTEGER.QuadPart],0
mov dword [ebp+.var_byte_offset+LARGE_INTEGER.QuadPart+4],0
; NtReadFile(handle, 0, 0, 0, &io_stat_block, (PVOID)part_buf, sizeof(part_buf), &byte_offset);
lea eax,[ebp+.var_byte_offset]
push eax
push 0x200
mov eax,HIGHCODE_partition_iobuf
push eax
lea eax,[ebp+.var_io_stat_block]
push eax
push 0
push 0
push 0
mov eax,[ebp+.var_handle]
push eax
call FUNCADDR_NtReadFile
cmp eax,0
jl short .exit_error_close
; NtClose(handle);
mov eax,[ebp+.var_handle]
push eax
call FUNCADDR_NtClose
cmp eax,0
jl short .exit_error
jmp short .exit_ok
.exit_error_close
mov eax,[ebp+.var_handle]
push eax
call FUNCADDR_NtClose
.exit_error:
mov eax,-1
jmp short .exit
.exit_ok:
xor eax,eax
.exit:
leave
ret 0
.raw_partition_path db '\Device\Harddisk0\partition0',0
align 64
HIGHCODE_partition_iobuf: times 512 db 0
BP_OFS_IOCTL_ARG_DEVICE equ 8
BP_OFS_IOCTL_ARG_PACKET equ 0x0c
IOCTL_CMD_DO_START_IO equ 0x4d028
IOCTL_CMD_GET_DRIVE_GEOMETRY equ 0x70000
IOCTL_CMD_DO_VERIFY equ 0x70014
IOCTL_CMD_GET_PARTITION_INFO equ 0x74004
IOCTL_CMD_LBA48_ACCESS equ 0xcafebabe
IOCTL_LBA48_SUBCMD_GET_INFO equ 0x0
IOCTL_ARG_OFS_CMD_PACKET equ 0x5c
IOCTL_ARG_OFS_OUT_PTR equ 0x30
IOCTL_ARG_OFS_OUT_ACTUAL equ 0x14
IOCTL_CMD_OFS_COMMAND equ 0x10
IOCTL_CMD_OFS_OUT_BUFLEN equ 0x4
IOCTL_CMD_OFS_IN_BUFLEN equ 0x0c
IOCTL_CMD_OFS_IN_PTR equ 0x8
align 64
HIGHCODE_DiskIoControl_hook_handler:
push ebp
mov ebp,esp
push esi
;
;when we get here:
;[ebp+BP_OFS_IOCTL_ARG_DEVICE] device struct?
;[ebp+BP_OFS_IOCTL_ARG_PACKET] ioctl arg struct
;
mov esi,[ebp+BP_OFS_IOCTL_ARG_PACKET]
mov eax,[esi+IOCTL_ARG_OFS_CMD_PACKET]
mov ecx,[eax+IOCTL_CMD_OFS_COMMAND]
push edi
cmp ecx,IOCTL_CMD_LBA48_ACCESS
jnz short .standard_ioctl_code
jmp .got_my_ioctl_code
.standard_ioctl_code:
sub ecx,IOCTL_CMD_DO_START_IO
jz short .handle_start_io
sub ecx,(IOCTL_CMD_GET_DRIVE_GEOMETRY-IOCTL_CMD_DO_START_IO)
jz short .handle_get_drive_geometry
sub ecx,(IOCTL_CMD_DO_VERIFY-IOCTL_CMD_GET_DRIVE_GEOMETRY)
jz short .handle_do_verify
sub ecx,(IOCTL_CMD_GET_PARTITION_INFO-IOCTL_CMD_DO_VERIFY)
jnz short .unknown_ioctl_code
jmp .handle_get_partition_info
.unknown_ioctl_code:
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .unknown_ioctl_code_lowcode
.unknown_ioctl_code_highcode:
jmp ADDR_DiskIoControl__unknown_ioctl_code
.unknown_ioctl_code_lowcode:
jmp ADDR_DiskIoControl__unknown_ioctl_code+HIGH_LOW_DIFF
.handle_start_io:
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .handle_start_io_lowcode
.handle_start_io_highcode:
jmp ADDR_DiskIoControl__do_start_io
.handle_start_io_lowcode:
jmp ADDR_DiskIoControl__do_start_io+HIGH_LOW_DIFF
.handle_get_drive_geometry:
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .handle_get_drive_geometry_lowcode
.handle_get_drive_geometry_highcode:
jmp ADDR_DiskIoControl__get_drive_geometry
.handle_get_drive_geometry_lowcode:
jmp ADDR_DiskIoControl__get_drive_geometry+HIGH_LOW_DIFF
.handle_do_verify:
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .handle_do_verify_lowcode
.handle_do_verify_highcode:
jmp ADDR_DiskIoControl__do_verify
.handle_do_verify_lowcode:
jmp ADDR_DiskIoControl__do_verify+HIGH_LOW_DIFF
.handle_get_partition_info:
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .handle_get_partition_info_lowcode
.handle_get_partition_info_highcode:
jmp ADDR_DiskIoControl__get_partition_info
.handle_get_partition_info_lowcode:
jmp ADDR_DiskIoControl__get_partition_info+HIGH_LOW_DIFF
.got_my_ioctl_code:
;
;when we get here:
;[ebp+BP_OFS_IOCTL_ARG_DEVICE] device struct?
;[ebp+BP_OFS_IOCTL_ARG_PACKET] ioctl arg struct
;[ioctl struct+0x5c] ioctl transfer packet (in data/len, out data/len, command)
;
push esi
push edi
mov eax,[ebp+BP_OFS_IOCTL_ARG_PACKET]
mov esi,[eax+IOCTL_ARG_OFS_CMD_PACKET]
cmp dword [esi+IOCTL_CMD_OFS_IN_BUFLEN],4
jnb short .inbuf_big_enough
mov eax,0xc0000004;input length wrong
jmp short .exit
.inbuf_big_enough:
cmp dword [esi+IOCTL_CMD_OFS_OUT_BUFLEN],28
jnb short .outbuf_big_enough
mov eax,0xc0000023;buffer too small
jmp short .exit
.outbuf_big_enough:
mov edi,[esi+IOCTL_CMD_OFS_IN_PTR]
cmp dword [edi],IOCTL_LBA48_SUBCMD_GET_INFO
jz short .get_info_cmd
mov eax,0xc0000010;invalid request
jmp short .exit
.get_info_cmd:
mov edi,[eax+IOCTL_ARG_OFS_OUT_PTR]
mov dword [edi],0xcafebabe
mov dword [edi+4],0xbabeface
mov dword [edi+8],PATCHCODE_VERSION
mov dword [edi+12],LOWCODE_BASE
mov dword [edi+16],HIGHCODE_BASE
mov dword [edi+20],PATCHSEG_SIZE
mov dword [edi+24],(HIGHCODE_Partition_table-HIGHCODE_BASE)
mov dword [eax+IOCTL_ARG_OFS_OUT_ACTUAL],28
xor eax,eax
.exit:
pop edi
pop esi
mov edi,eax
cmp dword [HIGHCODE_magic_id-HIGH_LOW_DIFF],PATCH_MAGIC_ID
jz short .exit_lowcode
.exit_highcode:
jmp ADDR_DiskIoControl__return
.exit_lowcode:
jmp ADDR_DiskIoControl__return+HIGH_LOW_DIFF