osloader!AEOpen函数分析之osloader!HardDiskPartitionOpen和osloader!BiosDiskRead

第一部分:

ARC_STATUS

BiosPartitionOpen(

IN PCHAR OpenPath,

IN OPEN_MODE OpenMode,

OUT PULONG FileId

)

{

//

// Find the partition number to open

//

if (FwGetPathMnemonicKey(OpenPath,"partition",&Key)) {

BiosPartitionClose(DiskFileId);

return(EBADF);

}

dv

Key = 1

//

// Before we open the partition, we need to find an available

// file descriptor.

//

*FileId=2;

while (BlFileTable[*FileId].Flags.Open != 0) {

*FileId += 1;

if (*FileId == BL_FILE_TABLE_SIZE) {

return(ENOENT);

}

}

kd> dv

OpenPath = 0x00000001 "--- memory read error at address 0x00000001 ---"

OpenMode = ArcOpenReadOnly (0n0)

FileId = 0x00060ecc

kd> dx -r1 ((osloader!unsigned long *)0x60ecc)

((osloader!unsigned long *)0x60ecc) : 0x60ecc : 0x3 [Type: unsigned long *]

0x3 [Type: unsigned long]

//

// We found an entry we can use, so mark it as open.

//

BlFileTable[*FileId].Flags.Open = 1;

BlFileTable[*FileId].DeviceEntryTable=&BiosPartitionEntryTable;

kd> x osloader!BiosPartitionEntryTable

0044621c osloader!BiosPartitionEntryTable = struct _BL_DEVICE_ENTRY_TABLE

kd> dx -r1 (*((osloader!_BL_DEVICE_ENTRY_TABLE *)0x44621c))

(*((osloader!_BL_DEVICE_ENTRY_TABLE *)0x44621c)) [Type: _BL_DEVICE_ENTRY_TABLE]

+0x000\] Close : 0x414d4b \[Type: unsigned long (\*)(unsigned long)

+0x004\] Mount : 0x406a56 \[Type: unsigned long (\*)(char \*,_MOUNT_OPERATION)

+0x008\] Open : 0x416019 \[Type: unsigned long (\*)(char \*,_OPEN_MODE,unsigned long \*)

+0x00c\] Read : 0x414d86 \[Type: unsigned long (\*)(unsigned long,void \*,unsigned long,unsigned long \*)

+0x010\] GetReadStatus : 0x406a56 \[Type: unsigned long (\*)(unsigned long)

+0x014\] Seek : 0x414dfb \[Type: unsigned long (\*)(unsigned long,_LARGE_INTEGER \*,_SEEK_MODE)

+0x018\] Write : 0x414e58 \[Type: unsigned long (\*)(unsigned long,void \*,unsigned long,unsigned long \*)

+0x01c\] GetFileInformation : 0x415f1b \[Type: unsigned long (\*)(unsigned long,_FILE_INFORMATION \*)

+0x020\] SetFileInformation : 0x406a56 \[Type: unsigned long (\*)(unsigned long,unsigned long,unsigned long)

+0x024\] Rename : 0x406a56 \[Type: unsigned long (\*)(unsigned long,char \*)

+0x028\] GetDirectoryEntry : 0x406a56 \[Type: unsigned long (\*)(unsigned long,_DIRECTORY_ENTRY \*,unsigned long,unsigned long \*)

+0x02c\] BootFsInfo : 0x0 \[Type: _BOOTFS_INFO \*

kd> u 406a56

osloader!BlArcNotYetImplemented [d:\srv03rtm\base\boot\lib\i386\arcemul.c @ 813]:

00406a56 55 push ebp

00406a57 8bec mov ebp,esp

00406a59 ff7508 push dword ptr [ebp+8]

00406a5c 68e8c74300 push offset osloader!`string' (0043c7e8)

00406a61 e869eeffff call osloader!BlPrint (004058cf)

00406a66 59 pop ecx

00406a67 59 pop ecx

00406a68 6a07 push 7

尚未实施;未实现;

kd> x osloader!BlFileTable

00479a00 osloader!BlFileTable = struct _BL_FILE_TABLE [48]

kd> dx -r1 (*((osloader!_BL_FILE_TABLE (*)[48])0x479a00))

(*((osloader!_BL_FILE_TABLE (*)[48])0x479a00)) [Type: _BL_FILE_TABLE [48]]

0\] \[Type: _BL_FILE_TABLE

1\] \[Type: _BL_FILE_TABLE

2\] \[Type: _BL_FILE_TABLE

3\] \[Type: _BL_FILE_TABLE

kd> dx -r1 (*((osloader!_BL_FILE_TABLE *)0x479b38))

(*((osloader!_BL_FILE_TABLE *)0x479b38)) [Type: _BL_FILE_TABLE]

+0x000\] Flags \[Type: _BL_FILE_FLAGS

+0x004\] DeviceId : 0x0 \[Type: unsigned long

+0x008\] Position : {0} \[Type: _LARGE_INTEGER

+0x010\] StructureContext : 0x0 \[Type: void \*

+0x014\] DeviceEntryTable : 0x44621c \[Type: _BL_DEVICE_ENTRY_TABLE \*\] //DeviceEntryTable : 0x44621c \[+0x018\] FileNameLength : 0x0 \[Type: unsigned char

+0x019\] FileName : "" \[Type: char \[32\]

+0x040\] u \[Type: __unnamed

kd> x osloader!BiosPartitionEntryTable

0044621c osloader!BiosPartitionEntryTable = struct _BL_DEVICE_ENTRY_TABLE

第二部分:

kd> p

osloader!BiosPartitionOpen+0x1fa:

00416213 e8c40bffff call osloader!HardDiskPartitionOpen (00406ddc)

kd> t

osloader!HardDiskPartitionOpen:

00406ddc 55 push ebp

kd> kc

00 osloader!HardDiskPartitionOpen

01 osloader!BiosPartitionOpen

02 osloader!AEOpen

03 osloader!BlGetActivePartition

04 osloader!NtProcessStartup

WARNING: Frame IP not in any known module. Following frames may be wrong.

05 0x0

06 0x0

07 osloader!`string'

08 0x0

kd> dv

FileId = 3

DiskId = 2

PartitionNumber = 0x00 ''

kd> dx -r1 ((osloader!_BL_DEVICE_ENTRY_TABLE *)0x44624c)

((osloader!_BL_DEVICE_ENTRY_TABLE *)0x44624c) : 0x44624c [Type: _BL_DEVICE_ENTRY_TABLE *]

+0x000\] Close : 0x414d0c \[Type: unsigned long (\*)(unsigned long)

+0x004\] Mount : 0x406a56 \[Type: unsigned long (\*)(char \*,_MOUNT_OPERATION)

+0x008\] Open : 0x415526 \[Type: unsigned long (\*)(char \*,_OPEN_MODE,unsigned long \*)

+0x00c\] Read : 0x415edd \[Type: unsigned long (\*)(unsigned long,void \*,unsigned long,unsigned long \*)

+0x010\] GetReadStatus : 0x406a56 \[Type: unsigned long (\*)(unsigned long)

+0x014\] Seek : 0x414dfb \[Type: unsigned long (\*)(unsigned long,_LARGE_INTEGER \*,_SEEK_MODE)

+0x018\] Write : 0x415798 \[Type: unsigned long (\*)(unsigned long,void \*,unsigned long,unsigned long \*)

+0x01c\] GetFileInformation : 0x415f70 \[Type: unsigned long (\*)(unsigned long,_FILE_INFORMATION \*)

+0x020\] SetFileInformation : 0x406a56 \[Type: unsigned long (\*)(unsigned long,unsigned long,unsigned long)

+0x024\] Rename : 0x406a56 \[Type: unsigned long (\*)(unsigned long,char \*)

+0x028\] GetDirectoryEntry : 0x406a56 \[Type: unsigned long (\*)(unsigned long,_DIRECTORY_ENTRY \*,unsigned long,unsigned long \*)

+0x02c\] BootFsInfo : 0x0 \[Type: _BOOTFS_INFO \*

kd> u 414dfb

osloader!BiosPartitionSeek [d:\srv03rtm\base\boot\lib\i386\biosdrv.c @ 548]:

00414dfb 55 push ebp

00414dfc 8bec mov ebp,esp

00414dfe 8b4510 mov eax,dword ptr [ebp+10h]

00414e01 83e800 sub eax,0

00414e04 7432 je osloader!BiosPartitionSeek+0x3d (00414e38)

00414e06 48 dec eax

00414e07 7414 je osloader!BiosPartitionSeek+0x22 (00414e1d)

00414e09 ff7510 push dword ptr [ebp+10h]

ULONG PartitionOffset=0;

dv

PartitionOffset = 0

kd> p

osloader!HardDiskPartitionOpen+0x5e:

00406e3a ff5014 call dword ptr [eax+14h]

kd> r

eax=0044624c ebx=00000200 ecx=00060bd0 edx=00000000 esi=00000138 edi=00479ae4

eip=00406e3a esp=000609b4 ebp=00060be4 iopl=0 nv up di pl nz na pe nc

cs=0008 ss=0010 ds=0010 es=0010 fs=0030 gs=0000 efl=00000006

osloader!HardDiskPartitionOpen+0x5e:

00406e3a ff5014 call dword ptr [eax+14h] ds:0010:00446260={osloader!BiosPartitionSeek (00414dfb)}

第三部分:

kd> r

eax=0044624c ebx=00000200 ecx=00060bd0 edx=00000000 esi=00000138 edi=00479ae4

eip=00406e3a esp=000609b4 ebp=00060be4 iopl=0 nv up di pl nz na pe nc

cs=0008 ss=0010 ds=0010 es=0010 fs=0030 gs=0000 efl=00000006

osloader!HardDiskPartitionOpen+0x5e:

00406e3a ff5014 call dword ptr [eax+14h] ds:0010:00446260={osloader!BiosPartitionSeek (00414dfb)}

kd> t

osloader!BiosPartitionSeek:

00414dfb 55 push ebp

kd> kc

00 osloader!BiosPartitionSeek

01 osloader!HardDiskPartitionOpen

02 osloader!BiosPartitionOpen

03 osloader!AEOpen

04 osloader!BlGetActivePartition

05 osloader!NtProcessStartup

WARNING: Frame IP not in any known module. Following frames may be wrong.

06 0x0

07 0x0

08 osloader!`string'

09 0x0

ARC_STATUS

BiosPartitionSeek (

IN ULONG FileId,

IN PLARGE_INTEGER Offset,

IN SEEK_MODE SeekMode

)

{

switch (SeekMode) {

case SeekAbsolute:

BlFileTable[FileId].Position = *Offset;

break;

case SeekRelative:

BlFileTable[FileId].Position.QuadPart += Offset->QuadPart;

break;

default:

#if DBG

BlPrint("SeekMode %lx not supported\n",SeekMode);

#endif

return(EACCES);

}

第四部分:

kd> dx -r1 (*((osloader!_BL_FILE_TABLE *)0x479ad0))

(*((osloader!_BL_FILE_TABLE *)0x479ad0)) [Type: _BL_FILE_TABLE]

+0x000\] Flags \[Type: _BL_FILE_FLAGS

+0x004\] DeviceId : 0x0 \[Type: unsigned long

+0x008\] Position : {0} \[Type: _LARGE_INTEGER

+0x010\] StructureContext : 0x0 \[Type: void \*

+0x014\] DeviceEntryTable : 0x44624c \[Type: _BL_DEVICE_ENTRY_TABLE \*

+0x018\] FileNameLength : 0x0 \[Type: unsigned char

+0x019\] FileName : "" \[Type: char \[32\]

+0x040\] u \[Type: __unnamed

Status = (BlFileTable[DiskId].DeviceEntryTable->Read)(DiskId,

DataBuffer,

SECTOR_SIZE,

&Count );

kd> p

osloader!HardDiskPartitionOpen+0x7a:

00406e56 ff500c call dword ptr [eax+0Ch]

kd> r

eax=0044624c ebx=00000200 ecx=000609cc edx=00000000 esi=00000138 edi=00479ae4

eip=00406e56 esp=000609b0 ebp=00060be4 iopl=0 nv up di pl zr na pe nc

cs=0008 ss=0010 ds=0010 es=0010 fs=0030 gs=0000 efl=00000046

osloader!HardDiskPartitionOpen+0x7a:

00406e56 ff500c call dword ptr [eax+0Ch] ds:0010:00446258={osloader!BiosDiskRead (00415edd)}

第五部分:

ARC_STATUS

BiosDiskRead(

IN ULONG FileId,

OUT PVOID Buffer,

IN ULONG Length,

OUT PULONG Count

)

{

USHORT PhysicalSectors;

PhysicalSectors = SECTOR_SIZE;

return(pBiosDiskReadWorker(FileId,Buffer,Length,Count,PhysicalSectors,FALSE));

}

kd> t

osloader!BiosDiskRead:

00415edd 55 push ebp

kd> dv

FileId = 2

Buffer = 0x000609cc

Length = 0x200

Count = 0x00060bcc

kd> kc

00 osloader!BiosDiskRead

01 osloader!HardDiskPartitionOpen

02 osloader!BiosPartitionOpen

03 osloader!AEOpen

04 osloader!BlGetActivePartition

05 osloader!NtProcessStartup

WARNING: Frame IP not in any known module. Following frames may be wrong.

06 0x0

07 0x0

08 osloader!`string'

09 0x0

第六部分:

kd> p

osloader!BiosDiskRead+0x16:

00415ef3 e8bcfbffff call osloader!pBiosDiskReadWorker (00415ab4)

kd> t

osloader!pBiosDiskReadWorker:

00415ab4 55 push ebp

kd> kc

00 osloader!pBiosDiskReadWorker

01 osloader!BiosDiskRead

02 osloader!HardDiskPartitionOpen

03 osloader!BiosPartitionOpen

04 osloader!AEOpen

05 osloader!BlGetActivePartition

06 osloader!NtProcessStartup

WARNING: Frame IP not in any known module. Following frames may be wrong.

07 0x0

08 0x0

09 osloader!`string'

0a 0x0

kd> dv

FileId = 2

Buffer = 0x000609cc

Length = 0x200

Count = 0x00060bcc

SectorSize = 0x200

xInt13 = 0x00 ''

kd> x osloader!FwLastSectorCache

00446eb0 osloader!FwLastSectorCache = struct _BL_LAST_SECTOR_CACHE

kd> dx -r1 (*((osloader!_BL_LAST_SECTOR_CACHE *)0x446eb0))

(*((osloader!_BL_LAST_SECTOR_CACHE *)0x446eb0)) [Type: _BL_LAST_SECTOR_CACHE]

+0x000\] Initialized : 0x0 \[Type: unsigned char

+0x001\] Valid : 0x0 \[Type: unsigned char

+0x004\] DeviceId : 0x0 \[Type: unsigned long

+0x008\] SectorNumber : 0x0 \[Type: unsigned __int64

+0x010\] Data : 0x0 \[Type: unsigned char \*

//

// Initialize the last sector cache if it has not been

// initialized.

//

if (!FwLastSectorCache.Initialized) {

FwLastSectorCache.Data =

FwAllocatePool(BL_LAST_SECTOR_CACHE_MAX_SIZE);

if (FwLastSectorCache.Data) {

FwLastSectorCache.Initialized = TRUE;

}

}

kd> x osloader!FwLastSectorCache

00446eb0 osloader!FwLastSectorCache = struct _BL_LAST_SECTOR_CACHE

kd> dx -r1 (*((osloader!_BL_LAST_SECTOR_CACHE *)0x446eb0))

(*((osloader!_BL_LAST_SECTOR_CACHE *)0x446eb0)) [Type: _BL_LAST_SECTOR_CACHE]

+0x000\] Initialized : 0x1 \[Type: unsigned char

+0x001\] Valid : 0x0 \[Type: unsigned char

+0x004\] DeviceId : 0x0 \[Type: unsigned long

+0x008\] SectorNumber : 0x0 \[Type: unsigned __int64

+0x010\] Data : 0x48a000 : 0x0 \[Type: unsigned char \*

//

// Gather disk stats. 搜集磁盘状态,就是上面的osloader!BiosDiskOpen之后存储在BlFileTable[FileId]的信息

//

SectorsPerTrack = BlFileTable[FileId].u.DriveContext.Sectors;

Heads = BlFileTable[FileId].u.DriveContext.Heads;

Cylinders = BlFileTable[FileId].u.DriveContext.Cylinders;

AllowXInt13 = BlFileTable[FileId].u.DriveContext.xInt13;

Int13Unit = BlFileTable[FileId].u.DriveContext.Drive;

dv

Heads = 0xff

Cylinders = 0x3ff

SectorsPerTrack = 0x3f '?'

AllowXInt13 = 0x01 ''

参考BlFileTable[2]:

kd> dx -r1 (*((osloader!_DRIVE_CONTEXT *)0x479b10))

(*((osloader!_DRIVE_CONTEXT *)0x479b10)) [Type: _DRIVE_CONTEXT]

+0x000\] IsCd : 0x0 \[Type: unsigned char

+0x001\] Drive : 0x80 \[Type: unsigned char

+0x002\] Sectors : 0x3f \[Type: unsigned char

+0x004\] Cylinders : 0x3ff \[Type: unsigned short

+0x006\] Heads : 0xff \[Type: unsigned short

+0x008\] xInt13 : 0x1 \[Type: unsigned char

参考BlFileTable[2]:

HeadSector = BlFileTable[FileId].Position.QuadPart / SectorSize;

HeadOffset = (ULONG)(BlFileTable[FileId].Position.QuadPart % SectorSize);

TailSector = (BlFileTable[FileId].Position.QuadPart + Length - 1) / SectorSize;

TailByteCount = (ULONG)((BlFileTable[FileId].Position.QuadPart + Length - 1) % SectorSize);

TailByteCount ++;

if (((ULONG_PTR) pDestInUserBuffer + NumBytesToTransfer < BIOSDISK_1MB) &&

(((ULONG_PTR) pDestInUserBuffer & BIOSDISK_64KB_MASK) ==

(((ULONG_PTR) pDestInUserBuffer + NumBytesToTransfer) & BIOSDISK_64KB_MASK)) &&

((pEndOfUserBuffer - pDestInUserBuffer) >= (LONG) NumBytesToTransfer)) {

pTransferDest = pDestInUserBuffer;

}

kd> dv pTransferDest

pTransferDest = 0x000609cc "???"

第七部分:

//

// Perform the read.

//

if(xInt13) {

Status = ReadExtendedPhysicalSectors(Int13Unit,

CurrentSector,

SectorsToTransfer,

pTransferDest);

} else {

Status = ReadPhysicalSectors(Int13Unit,

CurrentSector,

SectorsToTransfer,

pTransferDest,

SectorsPerTrack,

Heads,

Cylinders,

AllowXInt13);

}

kd> dv xInt13

xInt13 = 0x00 ''

+0x008\] xInt13 : 0x1 \[Type: unsigned char

kd> p

osloader!pBiosDiskReadWorker+0x26b:

00415d1f ff75e4 push dword ptr [ebp-1Ch]

kd> p

osloader!pBiosDiskReadWorker+0x26e:

00415d22 e8997f0000 call osloader!XferPhysicalDiskSectors (0041dcc0)

kd> x osloader!XferPhysicalDiskSectors

0041dcc0 osloader!XferPhysicalDiskSectors (unsigned char, unsigned int64, unsigned char, unsigned char *, unsigned char, unsigned short, unsigned short, unsigned char, unsigned char)

kd> u 41dcc0

osloader!XferPhysicalDiskSectors [d:\srv03rtm\base\boot\lib\i386\machine.c @ 171]:

0041dcc0 55 push ebp

0041dcc1 8bec mov ebp,esp

0041dcc3 83ec10 sub esp,10h

0041dcc6 0fb64514 movzx eax,byte ptr [ebp+14h]

0041dcca c1e009 shl eax,9

0041dccd 034518 add eax,dword ptr [ebp+18h]

0041dcd0 3d00001000 cmp eax,100000h

0041dcd5 7608 jbe osloader!XferPhysicalDiskSectors+0x1f (0041dcdf)

kd> kc 8

00 osloader!XferPhysicalDiskSectors

01 osloader!pBiosDiskReadWorker

02 osloader!BiosDiskRead

03 osloader!HardDiskPartitionOpen

04 osloader!BiosPartitionOpen

05 osloader!AEOpen

06 osloader!BlGetActivePartition

07 osloader!NtProcessStartup

//

// Figure out CHS values. Note that we use a ULONGLONG for the cylinder,

// because it could overflow 1023 if the start sector is large.

//

SectorsPerCylinder = SectorsPerTrack * Heads;

cylinder = (ULONG)(StartSector / SectorsPerCylinder);

r = StartSector % SectorsPerCylinder;

head = (USHORT)(r / SectorsPerTrack);

sector = (UCHAR)(r % SectorsPerTrack) + 1;

kd> dv

Int13UnitNumber = 0x80 ''

StartSector = 0

SectorCount = 0x01 ''

Buffer = 0x000609cc "???"

SectorsPerTrack = 0x3f '?'

Heads = 0xff

Cylinders = 0x3ff

AllowExtendedInt13 = 0x01 ''

Write = 0x00 ''

sector = 0x3f '?'

s = 0xffffff01

第八部分:

D:\srv03rtm\base\boot/inc/bldrx86.h:251:#define GET_SECTOR (*ExternalServicesTable->DiskIOSystem)

//

// OK, xfer the sectors via conventional int13.

//

retry = (Int13UnitNumber < 128) ? 3 : 1;

do {

s = GET_SECTOR(

(UCHAR)(Write ? 3 : 2), // int13 function number

Int13UnitNumber,

head,

(USHORT)cylinder, // we know it's 0-1023

sector,

SectorCount,

Buffer

);

kd> p

osloader!XferPhysicalDiskSectors+0x131:

0041ddf1 ff5004 call dword ptr [eax+4]

kd> r

eax=000244ec ebx=00000002 ecx=00000001 edx=00000000 esi=00000001 edi=00000000

eip=0041ddf1 esp=000608b0 ebp=000608e8 iopl=0 nv up di pl nz na po nc

cs=0008 ss=0010 ds=0010 es=0010 fs=0030 gs=0000 efl=00000002

osloader!XferPhysicalDiskSectors+0x131:

0041ddf1 ff5004 call dword ptr [eax+4] ds:0010:000244f0=00022e6c

参考:

kd> dx -r1 ((osloader!_EXTERNAL_SERVICES_TABLE *)0x244ec)

((osloader!_EXTERNAL_SERVICES_TABLE *)0x244ec) : 0x244ec [Type: _EXTERNAL_SERVICES_TABLE *]

+0x000\] RebootProcessor : 0x22e60 \[Type: void (__cdecl\*)()

+0x004\] DiskIOSystem : 0x22e6c \[Type: long (__cdecl\*)(unsigned char,unsigned char,unsigned short,unsigned short,unsigned char,unsigned char,unsigned char \*)\]//DiskIOSystem : 0x22e6c \[+0x008\] GetKey : 0x22e84 \[Type: unsigned long (__cdecl\*)()

+0x00c\] GetCounter : 0x22e90 \[Type: unsigned long (__cdecl\*)()

+0x010\] Reboot : 0x22e9c \[Type: void (__cdecl\*)(unsigned long)

+0x014\] DetectHardware : 0x22ec0 \[Type: void (__cdecl\*)(unsigned long,unsigned long,void \*,unsigned long \*,char \*,unsigned long)

+0x018\] HardwareCursor : 0x22ea8 \[Type: void (__cdecl\*)(unsigned long,unsigned long)

+0x01c\] GetDateTime : 0x22eb4 \[Type: void (__cdecl\*)(unsigned long \*,unsigned long \*)

+0x020\] ComPort : 0x22ecc \[Type: void (__cdecl\*)(long,unsigned long,unsigned char)

+0x024\] GetStallCount : 0x22ed8 \[Type: unsigned long (__cdecl\*)()

+0x028\] InitializeDisplayForNt : 0x22ee4 \[Type: void (__cdecl\*)()

+0x02c\] GetMemoryDescriptor : 0x22ef0 \[Type: void (__cdecl\*)()

+0x030\] GetEddsSector : 0x22e78 \[Type: long (__cdecl\*)(unsigned char,unsigned long,unsigned long,unsigned short,unsigned char \*,unsigned char)

+0x034\] GetElToritoStatus : 0x22efc \[Type: long (__cdecl\*)(unsigned char \*,unsigned char)

+0x038\] GetExtendedInt13Params : 0x22f08 \[Type: unsigned char (__cdecl\*)(unsigned char \*,unsigned char)

+0x03c\] NetPcRomServices : 0x0 \[Type: unsigned short (__cdecl\*)(unsigned long,void \*)

+0x040\] ApmAttemptReconnect : 0x22f14 \[Type: void (__cdecl\*)()

+0x044\] BiosRedirectService : 0x0 \[Type: unsigned long (__cdecl\*)(unsigned long)

参考: