当前位置: 首页 > news >正文

nt!IoSynchronousPageWrite函数分析之atapi!IdeReadWrite----非常重要


第一部分:预分析

1: kd> g
Breakpoint 7 hit
atapi!IdeReadWrite:
f729cb2a 55              push    ebp
1: kd> kc
 #
00 atapi!IdeReadWrite
01 atapi!IdeSendCommand
02 atapi!AtapiStartIo
03 atapi!IdeStartIoSynchronized
04 nt!KeSynchronizeExecution
05 atapi!IdePortAllocateAccessToken
06 PCIIDEX!BmReceiveScatterGatherList
07 hal!HalBuildScatterGatherList
08 hal!HalGetScatterGatherList
09 PCIIDEX!BmSetup
0a atapi!IdePortStartIo
0b nt!IoStartPacket
0c atapi!IdePortDispatch
0d nt!IofCallDriver
0e CLASSPNP!SubmitTransferPacket
0f CLASSPNP!ServiceTransferRequest
10 CLASSPNP!ClassReadWrite
11 nt!IofCallDriver
12 PartMgr!PmReadWrite
13 nt!IofCallDriver
14 ftdisk!FtDiskReadWrite
15 nt!IofCallDriver
16 volsnap!VolSnapWrite
17 nt!IofCallDriver
18 Ntfs!NtfsSingleAsync
19 Ntfs!NtfsNonCachedIo
1a Ntfs!NtfsCommonWrite
1b Ntfs!NtfsFsdWrite
1c nt!IofCallDriver
1d nt!IoSynchronousPageWrite
1e nt!MiFlushSectionInternal
1f nt!MmFlushSection
20 nt!CcFlushCache
21 Ntfs!LfsFlushLfcb
22 Ntfs!LfsFlushToLsnPriv
23 Ntfs!LfsWriteLfsRestart
24 Ntfs!LfsWriteRestartArea
25 Ntfs!NtfsCheckpointVolume
26 Ntfs!NtfsCheckpointAllVolumes
27 nt!ExpWorkerThread
28 nt!PspSystemThreadStartup
29 nt!KiThreadStartup


1: kd> dt HW_DEVICE_EXTENSION 0x895e98a8
atapi!HW_DEVICE_EXTENSION
   +0x000 CurrentSrb       : 0x898f9d7c _SCSI_REQUEST_BLOCK
   +0x004 BaseIoAddress1   : _IDE_REGISTERS_1
   +0x028 BaseIoAddress2   : _IDE_REGISTERS_2
   +0x034 BaseIoAddress1Length : 8
   +0x038 BaseIoAddress2Length : 1
   +0x03c MaxIdeDevice     : 2
   +0x040 MaxIdeTargetId   : 2
   +0x044 CurrentIdeDevice : 0
   +0x048 MoreWait         : 0
   +0x04c NoRetry          : 0
   +0x050 NumberOfCylinders : [4] 0x4443
   +0x060 NumberOfHeads    : [4] 0xf
   +0x070 SectorsPerTrack  : [4] 0x3f
   +0x080 InterruptMode    : 1
   +0x084 DataBuffer       : 0x894ef000  "FILE0"
   +0x088 BytesLeft        : 0
   +0x08c ErrorCount       : 0
   +0x090 TimeoutCount     : [4] 0
   +0x0a0 LastLun          : [4] 0
   +0x0b0 DeviceFlags      : [4] 0x30e01
   +0x0c0 MaximumBlockXfer : [4]  "@"
   +0x0c4 ExpectingInterrupt : 0 ''
   +0x0c5 DMAInProgress    : 0 ''
   +0x0c6 scsi2atapi       : 0 ''
   +0x0c7 RDP              : 0 ''
   +0x0c8 DriverMustPoll   : 0 ''
   +0x0c9 PrimaryAddress   : 0x1 ''
   +0x0ca SecondaryAddress : 0 ''
   +0x0cb NoPioSetTransferMode : 0 ''
   +0x0cc OriginalCdb      : [16]  ""
   +0x0dc SmartCommand     : 0 ''
   +0x0dd ReturningMediaStatus : 0 ''
   +0x0de IdentifyData     : [4] _IDENTIFY_DATA
   +0x8e0 BusMasterInterface : _PCIIDE_BUSMASTER_INTERFACE
   +0x928 DeviceParameters : [4] _DEVICE_PARAMETERS
   +0xa18 ResetState       : RESET_STATE
1: kd> dx -id 0,0,899a2278 -r1 (*((atapi!_IDE_REGISTERS_1 *)0x895e98ac))
(*((atapi!_IDE_REGISTERS_1 *)0x895e98ac))                 [Type: _IDE_REGISTERS_1]
    [+0x000] RegistersBaseAddress : 0x1f0 : Unable to read memory at Address 0x1f0 [Type: unsigned char *]
    [+0x004] Data             : 0x1f0 : Unable to read memory at Address 0x1f0 [Type: unsigned short *]
    [+0x008] Error            : 0x1f1 : Unable to read memory at Address 0x1f1 [Type: unsigned char *]
    [+0x00c] BlockCount       : 0x1f2 : Unable to read memory at Address 0x1f2 [Type: unsigned char *]
    [+0x010] BlockNumber      : 0x1f3 : Unable to read memory at Address 0x1f3 [Type: unsigned char *]
    [+0x014] CylinderLow      : 0x1f4 : Unable to read memory at Address 0x1f4 [Type: unsigned char *]
    [+0x018] CylinderHigh     : 0x1f5 : Unable to read memory at Address 0x1f5 [Type: unsigned char *]
    [+0x01c] DriveSelect      : 0x1f6 : Unable to read memory at Address 0x1f6 [Type: unsigned char *]
    [+0x020] Command          : 0x1f7 : Unable to read memory at Address 0x1f7 [Type: unsigned char *]

1: kd> dx -r1 ((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)
((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)                 : 0x898f9d7c [Type: _SCSI_REQUEST_BLOCK *]
    [+0x000] Length           : 0x40 [Type: unsigned short]
    [+0x002] Function         : 0x0 [Type: unsigned char]
    [+0x003] SrbStatus        : 0x0 [Type: unsigned char]
    [+0x004] ScsiStatus       : 0x0 [Type: unsigned char]
    [+0x005] PathId           : 0x0 [Type: unsigned char]
    [+0x006] TargetId         : 0x0 [Type: unsigned char]
    [+0x007] Lun              : 0x0 [Type: unsigned char]
    [+0x008] QueueTag         : 0x0 [Type: unsigned char]
    [+0x009] QueueAction      : 0x20 [Type: unsigned char]
    [+0x00a] CdbLength        : 0xa [Type: unsigned char]
    [+0x00b] SenseInfoBufferLength : 0x12 [Type: unsigned char]
    [+0x00c] SrbFlags         : 0x40210180 [Type: unsigned long]
    [+0x010] DataTransferLength : 0x2000 [Type: unsigned long]
    [+0x014] TimeOutValue     : 0xa [Type: unsigned long]
    [+0x018] DataBuffer       : 0x89537000 [Type: void *]
    [+0x01c] SenseInfoBuffer  : 0x898f9d68 [Type: void *]
    [+0x020] NextSrb          : 0x0 [Type: _SCSI_REQUEST_BLOCK *]
    [+0x024] OriginalRequest  : 0x898f9b38 [Type: void *]
    [+0x028] SrbExtension     : 0x2 [Type: void *]
    [+0x02c] InternalStatus   : 0x5e3c57 [Type: unsigned long]
    [+0x02c] QueueSortKey     : 0x5e3c57 [Type: unsigned long]
    [+0x030] Cdb              [Type: unsigned char [16]]


1: kd> db 0x89537000
89537000  52 43 52 44 28 00 09 00-1a 0b 0f 08 00 00 00 00  RCRD(...........
89537010  01 00 00 00 02 00 01 00-d0 08 00 00 00 00 00 00  ................
89537020  0f 0b 0f 08 00 00 00 00-dc 0e db 01 00 00 00 00  ................
89537030  00 00 01 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
89537040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
89537050  0a 0a 0f 08 00 00 00 00-eb 09 0f 08 00 00 00 00  ................
89537060  eb 09 0f 08 00 00 00 00-98 00 00 00 00 00 00 00  ................
89537070  01 00 00 00 18 00 00 00-00 00 00 00 00 00 00 00  ................
1: kd> dd 0x89537000
89537000  44524352 00090028 080f0b1a 00000000
89537010  00000001 00010002 000008d0 00000000
89537020  080f0b0f 00000000 01db0edc 00000000
89537030  00010000 00000000 00000000 00000000
89537040  00000000 00000000 00000000 00000000
89537050  080f0a0a 00000000 080f09eb 00000000
89537060  080f09eb 00000000 00000098 00000000
89537070  00000001 00000018 00000000 00000000
1: kd> dd c2c45000
c2c45000  44524352 00090028 080f0b1a 00000000
c2c45010  00000001 00010002 000008d0 00000000
c2c45020  080f0b0f 00000000 00000edc 00000000
c2c45030  00000000 00000000 00000000 00000000
c2c45040  00000000 00000000 00000000 00000000
c2c45050  080f0a0a 00000000 080f09eb 00000000
c2c45060  080f09eb 00000000 00000098 00000000
c2c45070  00000001 00000018 00000000 00000000

1: kd> dd 0x89538000
89538000  44524352 00090028 080f0c44 00000000
89538010  00000001 00020002 00000220 00000000
89538020  080f0c0c 00000000 00240edd 00000000
89538030  00000000 0000000c 00000000 00000000
89538040  00000000 00000000 00000000 00000000
89538050  00000000 00000000 00000000 00000000
89538060  080f0c0c 00000000 080f0b1a 00000000
89538070  080f0b1a 00000000 00000190 00000000
1: kd> dd c2c46000
c2c46000  44524352 00090028 080f0c44 00000000
c2c46010  00000001 00020002 00000220 00000000
c2c46020  080f0c0c 00000000 00000edd 00000000
c2c46030  00000000 00000000 00000000 00000000
c2c46040  00000000 00000000 00000000 00000000
c2c46050  00000000 00000000 00000000 00000000
c2c46060  080f0c0c 00000000 080f0b1a 00000000
c2c46070  080f0b1a 00000000 00000190 00000000


    [+0x010] DataTransferLength : 0x2000 [Type: unsigned long]
    [+0x014] TimeOutValue     : 0xa [Type: unsigned long]
    [+0x018] DataBuffer       : 0x89537000 [Type: void *]


    //
    // Set data buffer pointer and words left.
    //

    deviceExtension->DataBuffer = (PUCHAR)Srb->DataBuffer;
    deviceExtension->BytesLeft = Srb->DataTransferLength;

第二部分:


    //
    // Select device 0 or 1.
    //
    SelectIdeDevice(baseIoAddress1, Srb->TargetId, 0);


1: kd> p
atapi!IdeReadWrite+0x20:
f729cb4a 50              push    eax
1: kd> p
atapi!IdeReadWrite+0x21:
f729cb4b ff7620          push    dword ptr [esi+20h]
1: kd> p
atapi!IdeReadWrite+0x24:
f729cb4e ffd3            call    ebx
1: kd> r
eax=000000a0 ebx=804f4d68 ecx=00000000 edx=00000001 esi=895e98a8 edi=898f9d7c
eip=f729cb4e esp=f78d1bd8 ebp=f78d1bf4 iopl=0         nv up ei ng nz na pe cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000287
atapi!IdeReadWrite+0x24:
f729cb4e ffd3            call    ebx {hal!WRITE_PORT_UCHAR (804f4d68)}


cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port    01f6            [+0x01c] DriveSelect      : 0x1f6 :
        mov     al,[esp+8]              ; (al) = Value    a0
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR


1: kd> p
eax=000000a0 ebx=804f4d68 ecx=00000000 edx=000001f6 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei ng nz na pe cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000287
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


#define SelectIdeDevice(BaseIoAddress, deviceNumber, additional) {\
    SelectIdeLine(BaseIoAddress, (deviceNumber) >>1);\
    WRITE_PORT_UCHAR ((BaseIoAddress)->DriveSelect, (UCHAR)((((deviceNumber) & 0x1) << 4) | 0xA0 | additional));\
    }


    //
    // Select device 0 or 1.
    //
    SelectIdeDevice(baseIoAddress1, Srb->TargetId, 0);

[+0x006] TargetId         : 0x0 [Type: unsigned char]

如果是[+0x006] TargetId         : 0x1 [Type: unsigned char],则
10000
0x10

0x10 | 0xA0= |0xB0


第三部分:


    GetStatus(baseIoAddress1, statusByte2);


cPublicProc _READ_PORT_UCHAR ,1
cPublicFpo 1, 0

        xor     eax, eax        ; Eliminate partial stall on return to caller

        mov     edx,[esp+4]             ; (dx) = Port    1f7     [+0x020] Command          : 0x1f7
        in      al,dx                00
        stdRET    _READ_PORT_UCHAR

stdENDP _READ_PORT_UCHAR


1: kd> p
eax=00000000 ebx=804f4d68 ecx=00000000 edx=000001f7 esi=895e98a8 edi=898f9d7c
eip=804f4d06 esp=f78d1bd8 ebp=f78d1bf4 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
hal!READ_PORT_UCHAR+0x6:
804f4d06 ec              in      al,dx
1: kd> p
eax=00000050 ebx=804f4d68 ecx=00000000 edx=000001f7 esi=895e98a8 edi=898f9d7c
eip=804f4d07 esp=f78d1bd8 ebp=f78d1bf4 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
hal!READ_PORT_UCHAR+0x7:
804f4d07 c20400          ret     4

eax=00000050    #define IDE_STATUS_IDLE              0x50


//
// IDE status definitions
//
#define IDE_STATUS_ERROR             0x01
#define IDE_STATUS_INDEX             0x02
#define IDE_STATUS_CORRECTED_ERROR   0x04
#define IDE_STATUS_DRQ               0x08
#define IDE_STATUS_DSC               0x10
#define IDE_STATUS_DRDY              0x40
#define IDE_STATUS_IDLE              0x50
#define IDE_STATUS_BUSY              0x80


    if (statusByte2 & IDE_STATUS_BUSY) {
        DebugPrint((DBG_CRASHDUMP | DBG_READ_WRITE,
                    "IdeReadWrite: Returning BUSY status\n"));
        return SRB_STATUS_BUSY;
    }


第四部分:

    //
    // Set data buffer pointer and words left.
    //

    deviceExtension->DataBuffer = (PUCHAR)Srb->DataBuffer;
    deviceExtension->BytesLeft = Srb->DataTransferLength;

   +0x084 DataBuffer       : 0x89537000  "RCRD("
   +0x088 BytesLeft        : 0x2000

第五部分:


1: kd> ?(0x2000 + 0x1FF)/0x200
Evaluate expression: 16 = 00000010


    //                                                         
    // Set up sector count register. Round up to next block.
    //
    IdePortOutPortByte (
                       baseIoAddress1->BlockCount,
                       (UCHAR)((Srb->DataTransferLength + 0x1FF) / 0x200));

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port        [+0x00c] BlockCount       : 0x1f2 :
        mov     al,[esp+8]              ; (al) = Value        10
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=00000010 ebx=804f4d68 ecx=00000000 edx=000001f2 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na po cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000203
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第六部分:

    //
    // Get starting sector number from CDB.
    //

    startingSector = ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte3 |        0x57
                     ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte2 << 8 |        0x3c00
                     ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 |        0x5e0000
                     ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24;


  +0x000 CDB10            : _CDB10
      +0x000 OperationCode    : 0x2a '*'
      +0x001 RelativeAddress  : 0y0
      +0x001 Reserved1        : 0y00
      +0x001 ForceUnitAccess  : 0y1
      +0x001 DisablePageOut   : 0y0
      +0x001 LogicalUnitNumber : 0y000
      +0x002 LogicalBlockByte0 : 0 ''
      +0x003 LogicalBlockByte1 : 0x5e '^'
      +0x004 LogicalBlockByte2 : 0x3c '<'
      +0x005 LogicalBlockByte3 : 0x57 'W'
      +0x006 Reserved2        : 0 ''
      +0x007 TransferBlocksMsb : 0 ''
      +0x008 TransferBlocksLsb : 0x10 ''
      +0x009 Control          : 0 ''

0x5e3c57

1: kd> p
atapi!IdeReadWrite+0xb7:
f729cbe1 50              push    eax
1: kd> p
atapi!IdeReadWrite+0xb8:
f729cbe2 682eca29f7      push    offset atapi!IdeReadWriteExt+0x35e (f729ca2e)
1: kd> r
eax=005e3c57

第七部分:


   if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_LBA) {


1: kd> dt HW_DEVICE_EXTENSION 0x895e98a8

   +0x0b0 DeviceFlags      : [4] 0x30e01
1: kd> dx -id 0,0,899a2278 -r1 (*((atapi!unsigned long (*)[4])0x895e9958))
(*((atapi!unsigned long (*)[4])0x895e9958))                 [Type: unsigned long [4]]
    [0]              : 0x30e01 [Type: unsigned long]
    [1]              : 0x0 [Type: unsigned long]
    [2]              : 0x0 [Type: unsigned long]
    [3]              : 0x0 [Type: unsigned long]

1: kd> db 0x895e98a8+0x0b0
895e9958  01 0e 03 00 00 00 00 00-00 00 00 00 00 00 00 00  ................


#define DFLAGS_LBA                   (1 << 10)   // support LBA addressing


 100 0000 0000

0x400


1110 0000 0001


第八部分:

    if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_LBA) {

        SelectIdeDevice(baseIoAddress1,
                        Srb->TargetId,
                        (IDE_LBA_MODE | ((startingSector & 0x0f000000) >> 24)));

        IdePortOutPortByte (
                           baseIoAddress1->BlockNumber,
                           (UCHAR) ((startingSector & 0x000000ff) >> 0));
        IdePortOutPortByte (
                           baseIoAddress1->CylinderLow,
                           (UCHAR) ((startingSector & 0x0000ff00) >> 8));

        IdePortOutPortByte (
                           baseIoAddress1->CylinderHigh,
                           (UCHAR) ((startingSector & 0x00ff0000) >> 16));


#define IDE_LBA_MODE                                    (1 << 6)

100    0000
0x40


005e3c57 & 0x0f000000

        SelectIdeDevice(baseIoAddress1,
                        Srb->TargetId,
                        (IDE_LBA_MODE | ((startingSector & 0x0f000000) >> 24)));

0x40
0x0| 0xA0 |0x40=0xe0

#define SelectIdeDevice(BaseIoAddress, deviceNumber, additional) {\
    SelectIdeLine(BaseIoAddress, (deviceNumber) >>1);\
    WRITE_PORT_UCHAR ((BaseIoAddress)->DriveSelect, (UCHAR)((((deviceNumber) & 0x1) << 4) | 0xA0 | additional));\
    }

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port    01f6
        mov     al,[esp+8]              ; (al) = Value    e0
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=800000e0 ebx=804f4d68 ecx=000000e0 edx=000001f6 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000282
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第九部分:

 [+0x010] BlockNumber      : 0x1f3 : Unable to read memory at Address 0x1f3 [Type: unsigned char *]
    [+0x014] CylinderLow      : 0x1f4 : Unable to read memory at Address 0x1f4 [Type: unsigned char *]
    [+0x018] CylinderHigh     : 0x1f5 : Unable to read memory at Address 0x1f5 [Type: unsigned char *]


        IdePortOutPortByte (
                           baseIoAddress1->BlockNumber,                 [+0x010] BlockNumber      : 0x1f3
                           (UCHAR) ((startingSector & 0x000000ff) >> 0));        0x57

005e3c57& 0x000000ff=0x57

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port
        mov     al,[esp+8]              ; (al) = Value
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR


1: kd> p
eax=80000057 ebx=804f4d68 ecx=000000e0 edx=000001f3 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000282
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第十部分:

        IdePortOutPortByte (
                           baseIoAddress1->CylinderLow,            [+0x014] CylinderLow      : 0x1f4
                           (UCHAR) ((startingSector & 0x0000ff00) >> 8));    3c

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port        01f4
        mov     al,[esp+8]              ; (al) = Value        3c
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=00005e3c ebx=804f4d68 ecx=000000e0 edx=000001f4 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000206
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第十一部分:


        IdePortOutPortByte (
                           baseIoAddress1->CylinderHigh,            [+0x018] CylinderHigh     : 0x1f5
                           (UCHAR) ((startingSector & 0x00ff0000) >> 16));    5e
    
cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port            01f5
        mov     al,[esp+8]              ; (al) = Value            5e
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=0000005e ebx=804f4d68 ecx=000000e0 edx=000001f5 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000202
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第十二部分:

//
// SRB Flag Bits
//

#define SRB_FLAGS_QUEUE_ACTION_ENABLE       0x00000002
#define SRB_FLAGS_DISABLE_DISCONNECT        0x00000004
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER    0x00000008

#define SRB_FLAGS_BYPASS_FROZEN_QUEUE       0x00000010
#define SRB_FLAGS_DISABLE_AUTOSENSE         0x00000020
#define SRB_FLAGS_DATA_IN                   0x00000040
#define SRB_FLAGS_DATA_OUT                  0x00000080            #define SRB_FLAGS_DATA_OUT         
#define SRB_FLAGS_NO_DATA_TRANSFER          0x00000000
#define SRB_FLAGS_UNSPECIFIED_DIRECTION      (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)

#define SRB_FLAGS_NO_QUEUE_FREEZE           0x00000100            #define SRB_FLAGS_NO_QUEUE_FREEZE
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE      0x00000200
#define SRB_FLAGS_FREE_SENSE_BUFFER         0x00000400

#define SRB_FLAGS_IS_ACTIVE                 0x00010000            #define SRB_FLAGS_IS_ACTIVE
#define SRB_FLAGS_ALLOCATED_FROM_ZONE       0x00020000
#define SRB_FLAGS_SGLIST_FROM_POOL          0x00040000
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE       0x00080000

#define SRB_FLAGS_NO_KEEP_AWAKE             0x00100000
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE    0x00200000        #define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
#define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT  0x00400000
#define SRB_FLAGS_DONT_START_NEXT_PACKET    0x00800000

#define SRB_FLAGS_PORT_DRIVER_RESERVED      0x0F000000
#define SRB_FLAGS_CLASS_DRIVER_RESERVED     0xF0000000

    //
    // Check if write request.
    //

    if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) {        //不是读操作,是写操作


1: kd> dx -r1 ((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)
((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)                 : 0x898f9d7c [Type: _SCSI_REQUEST_BLOCK *]
    [+0x000] Length           : 0x40 [Type: unsigned short]
    [+0x002] Function         : 0x0 [Type: unsigned char]
    [+0x003] SrbStatus        : 0x0 [Type: unsigned char]
    [+0x004] ScsiStatus       : 0x0 [Type: unsigned char]
    [+0x005] PathId           : 0x0 [Type: unsigned char]
    [+0x006] TargetId         : 0x0 [Type: unsigned char]
    [+0x007] Lun              : 0x0 [Type: unsigned char]
    [+0x008] QueueTag         : 0x0 [Type: unsigned char]
    [+0x009] QueueAction      : 0x20 [Type: unsigned char]
    [+0x00a] CdbLength        : 0xa [Type: unsigned char]
    [+0x00b] SenseInfoBufferLength : 0x12 [Type: unsigned char]
    [+0x00c] SrbFlags         : 0x40210180 [Type: unsigned long]        #define SRB_FLAGS_DATA_OUT                  0x00000080

第十三部分:


    } else {


        //
        // Send write command.
        //
        if (SRB_USES_DMA(Srb)) {        //符合条件:    [+0x028] SrbExtension     : 0x2 [Type: void *]

            IdePortOutPortByte (
                               baseIoAddress1->Command,
                               IDE_COMMAND_WRITE_DMA);


#define SRB_USES_DMA(Srb)               (((ULONG_PTR)Srb->SrbExtension) & 2)


    [+0x028] SrbExtension     : 0x2 [Type: void *]

#define IDE_COMMAND_WRITE_DMA                   0xCA

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port        01f7
        mov     al,[esp+8]              ; (al) = Value        ca
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=000000ca ebx=804f4d68 ecx=000000e0 edx=000001f7 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000202
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al

http://www.lryc.cn/news/576575.html

相关文章:

  • 视频序列中的帧间匹配技术 FrameMatcher 详解
  • 智能制造——56页2025 智慧工厂解决方案【附全文阅读】
  • zookeeper Curator(3):Watch事件监听
  • 从单体架构到微服务:微服务架构演进与实践
  • 从台式电脑硬件架构看前后端分离开发模式
  • Spring Boot 3 多数据源改造全流程:Druid、HikariCP 与 dynamic-datasource 实战总结
  • 内网横向-工作流
  • 典型工程应用三
  • [rootme:ctf all the day]Ubuntu 8.04week wp
  • python 项目利用uv管理python包依赖
  • phpstudy 可以按照mysql 数据库
  • cf 禁止http/1.0和http/1.1的访问 是否会更安全?
  • 《自动控制原理 》- 第 1 章 自动控制的基本原理与方式
  • Confluence-测试用例执行规范
  • srs-gb28181 与 SRS 5.0 对 GB28181 国标支持
  • Learning to Prompt for Continual Learning
  • python基础21(2025.6.28)_全栈爬取_车168以及诗词名句案例
  • AUTOSAR图解==>AUTOSAR_AP_EXP_SOVD
  • Linux快速查找文件
  • JVM 之双亲委派机制与打破双亲委派
  • 【安卓Sensor框架-2】应用注册Sensor 流程
  • Everything
  • 深入解析 Electron 核心模块:构建跨平台桌面应用的关键
  • day45 Tensor board使用介绍
  • 【Bluedroid】蓝牙启动之BTM_reset_complete源码解析
  • 虚拟 DOM 与 Diff 算法
  • c++学习(五、函数高级)
  • 【AI智能体】Dify 核心组件从使用到实战操作详解
  • 设计模式-代理模式、装饰者模式
  • 【Java--SQL】${}与#{}区别和危害