- [Duke's Virus Labs #9] - [Page 24] -

אַ     樮 ⥬ Windows95/98/NT
(c) by SMT/SMF

      䠪஢  windows ⥬  ,  䥩
אַ 㯠    㬥஢.  訫 ᯮ  ஡.
 ⮣ 뫨 ᬮ७ ᪮쪮 ⨫⮪ (symantec᪨  
sysinternal).
    ਬ   ਢ  C,   祭  ७  asm.

     ᫥ ,  95-  NT   ᮢ襭 ࠧ묨
ᯮᮡ.  NT  祭 :
   HANDLE hDisk = CreateFile("\\\\.\\C:",
          GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_READ | FILE_SHARE_WRITE,
          NULL, OPEN_EXISTING, 0, NULL);
    ⮫쪮  䫠 GENERIC_WRITE    ⮫쪮 ᫨ 
짮⥫, ⨢襣 ,  ᮮ⢥騥 ਢ.   -
 account 襣   㡥    ணࠬ...
       쭮 :
1. ⥭/ numsectors ᥪ஢, 稭  startsector:
     SetFilePointer(hDisk, startsector*512, NULL, FILE_BEGIN);
    筮, ᫨  让 ( 4gb),  ਤ :
     __int64 i = startsector * 512;
     unsigned high = i >> 32;
     SetFilePointer(hDisk, (unsigned)i, &high, FILE_BEGIN);
     ᮡ⢥ ⥭/:
     ReadFile/WriteFile(hDisk, buffer, 512*numsectors, &dummy, NULL);
2. ⮬  ᤥ CloseHandle(hDisk)

 ᬮਬ,   ᤥ  95-.

     95-   ⠪ . -,   ⠪ 뢠 
஢. -, ਤ
   VxD,  ,  , ᪥⪨ ࠡ뢠 ᮢᥬ  ⠪
 ⨪, ..   直 ࠣ   1 ࠧ  ࠧ 
஢ 0  ⥬ ᯮ  int 13. 㤮⢮ ⮨  ⮬, 
㦭 뢠   ᥪ  ஦/ᥪ ( int 13 
㬥஢). ,  ᭨,  䫮   ⠪ ,
   ⢥묨 ᪠ -  㤥 ࠢ쭮.
    ⠪: 0 -  ;  ᪥     䠩.
   ᪥  饭  ᥣ  ⠪ 䠩 (  swap),
  室 ⮫쪮  ᪥. 1 -   אַ 㯠,
  㣨 ਫ  ᬮ  lock1,    
ࠧ ;  - த ।⢠ ࠧ . 2 - 
ᥡ 㣨 ਫ   ᪠,   . 3 - 㣨 
ਮ⠭  ⪥ ⥭-,      ,
 㣮.

     ᤥ. ஥ vxd:
   HANDLE hDevice = CreateFile("\\\\.\\vwin32", 0,0,0,0,
              FILE_FLAG_DELETE_ON_CLOSE,0);
    㠫쭮 ன⢮ 㫨 int 21 ax=4400/4401, int 21 ax=730x,
int 13, int 25  int 26,    ,  ᯥ譮 ᯮ짮
dos-ᠬ.   control-:

#define VWIN32_DIOC_DOS_DRIVEINFO (6)
#define VWIN32_DIOC_DOS_INT13 (4)
#define VWIN32_DIOC_DOS_INT25 (2)
#define VWIN32_DIOC_DOS_INT26 (3)
#define VWIN32_DIOC_DOS_IOCTL (1)

 ⢥ IOBUF 㦭 । 祭 ॣ஢:
typedef struct _DIOC_REGISTERS {
    unsigned reg_EBX, reg_EDX, reg_ECX, reg_EAX, reg_ESI, reg_EDI, reg_Flags;
} DIOC_REGISTERS;


   ० ᥣ  㦭  . ࠧ ⠪  ᤥ  㤠,
.. ஢   3 ࠧ , ⥯  ᢮ ஢
㯠 (t , !).
    ᮮ⢥ 㭪:

char lock(char drvNUM, DWORD level, DWORD lockflags) {
    DIOC_REGISTERS buf = { 0 };
    unsigned r;
    unsigned s = (level << 8) | drvNUM;
    unsigned d = LOWORD(lockflags);
    unsigned i = 0x48;

    buf.reg_ECX = (i << 8) | 0x4A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = s;
    buf.reg_EDX = d;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf,
                          0x1c, &buf, 0x1c, &level, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;

    i = 8;
    buf.reg_ECX = (i << 8) | 0x4A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = s;
    buf.reg_EDX = d;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf, 0x1c,
          &buf, 0x1c, &level, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;
    return 0;
}

T  lockflags:
Ŀ
 祭 lockflags   ஢ ஢ 1  ஢ 2    ஢ 3 
͵
             0           W- M+ R+           W- M+ R+     W- M- R-  
Ĵ
             1           W- M- R+           W- M- R+     W- M- R-  
Ĵ
             2           W+ M+ R+           W- M+ R+     W- M- R-  
Ĵ
             3           W+ M+ R+           W- M- R+     W- M- R-  

  W+  => 㣨   
     R+  => 㣨   
     M+  => 㣨   ᮧ  filemapping'
     W-, R-, M-  => ᮮ⢥⢥  

    ⥭ ᥪ஢  㦭 맢 㭪 lock() 2 ࠧ:
lock(drvNUM, 1, 1); lock(drvNUM, 2, 0),    - 3:
lock(drvNUM, 1, 1); lock(drvNUM, 2, 0); lock(drvNUM, 3, 0);
    drvNUM -  ᪠, ᫨ , 稭  1, ..
A: -> 1, B: -> 2, C: -> 3  ..
      㭪樨 ⥭-:

char ReadSectors(char drvNUM, unsigned sector,
                     unsigned short num, void *buffer) {
  DIOC_REGISTERS buf = { 0 };
  unsigned r;
  #pragma pack(1)
  struct { unsigned v4; short v8; void *va; } st = { 0 };
  #pragma pack()

  st.v4 = sector;
  st.v8 = num;
  st.va = buffer;
  buf.reg_EAX = 0x7305;
  buf.reg_ECX = 0xFFFFFFFF;
  buf.reg_EDX = drvNUM;
  buf.reg_EBX = (unsigned)&st;
  r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_DRIVEINFO, &buf, 0x1c, &buf,
                         0x1c, (unsigned*)&num, 0);
  return (r && !(buf.reg_Flags & 1));
}

char WriteSectors(char drvNUM, unsigned sector, unsigned short num,
                      void *buffer, unsigned xx) {
  DIOC_REGISTERS buf = { 0 };
  unsigned r;
  #pragma pack(1)
  struct { unsigned v4; short v8; void *va; } st = { 0 };
  #pragma pack()

  st.v4 = sector;
  st.v8 = num;
  st.va = buffer;
  buf.reg_ESI = xx | 1;
  buf.reg_EAX = 0x7305;
  buf.reg_ECX = 0xFFFFFFFF;
  buf.reg_EDX = drvNUM;
  buf.reg_EBX = (unsigned)&st;
  r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_DRIVEINFO, &buf, 0x1c,
                           &buf, 0x1c, (unsigned*)&num, 0);
  return (r && !(buf.reg_Flags & 1));
}

     । ࠬ஢,  饬-, 祢,  ᪫祭
"xx"  㭪樨 WriteSectors().   xx=0x6000  .
    ⠫ ⮫쪮 ࠧ஢   㧨 vxd:

char unlock(char drvNUM) {
    DIOC_REGISTERS buf = { 0 };
    unsigned r, xx;
    unsigned i = 0x48;

    buf.reg_ECX = (i << 8) | 0x6A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = drvNUM;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf, 0x1c,
                         &buf, 0x1c, &xx, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;

    i = 8;
    buf.reg_ECX = (i << 8) | 0x6A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = drvNUM;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf,
                                 0x1c, &buf, 0x1c, &xx, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;
    return 0;
}

   unlock() 㦭 맢 ⮫쪮 ࠧ, ᪮쪮  맢 lock().
     㦭 맢 CloseHandle(hDevice).

    ᮡ⢥,  . 祬    ?    
樨,     dir-ᮢ. ࠢ, ᫥ , 
 FAT, FAT32  NTFS  ᪠  ᮢᥬ ,   㦥  
஡.   ᠬ ᭮ - 訥 ਧ  boot-ᥪ.
   ਬ  ਫ  ୠ ਢ ᮫쭠 ண, 
⠥   boot-ᥪ.   ᫥騬 ࠧ:
       direct d:
           -  boot  ᪠ d:  䠩 oldboot.bin
       direct d: myboot.bin
           -  ,    ।饬 砥,   boot 512-
             䠩 myboot.bin
P.S.    ࠡ⠥, ᫨  windows  1080,  ᫨ 
windows98.   <= 1080 祣    (   ⠪ ॢ
   ஢),     㤥 ࠡᯮᮡ...

===== Cut =====
#include <windows.h>
#include <stdio.h>

typedef struct _DIOC_REGISTERS {
    unsigned reg_EBX, reg_EDX, reg_ECX, reg_EAX, reg_ESI, reg_EDI, reg_Flags;
} DIOC_REGISTERS;

#define VWIN32_DIOC_DOS_DRIVEINFO (6)
#define VWIN32_DIOC_DOS_INT13 (4)
#define VWIN32_DIOC_DOS_INT25 (2)
#define VWIN32_DIOC_DOS_INT26 (3)
#define VWIN32_DIOC_DOS_IOCTL (1)

HANDLE hDevice;
char boot = 0;
#define BUFSIZE 512
char oldboot[BUFSIZE], newboot[BUFSIZE];

char lock(char drvNUM, DWORD level, DWORD lockflags) {
    DIOC_REGISTERS buf = { 0 };
    unsigned r;
    unsigned s = (level << 8) | drvNUM;
    unsigned d = LOWORD(lockflags);
    unsigned i = 0x48;

    buf.reg_ECX = (i << 8) | 0x4A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = s;
    buf.reg_EDX = d;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf,
                          0x1c, &buf, 0x1c, &level, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;

    i = 8;
    buf.reg_ECX = (i << 8) | 0x4A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = s;
    buf.reg_EDX = d;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf, 0x1c,
          &buf, 0x1c, &level, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;
    return 0;
}

char unlock(char drvNUM) {
    DIOC_REGISTERS buf = { 0 };
    unsigned r, xx;
    unsigned i = 0x48;

    buf.reg_ECX = (i << 8) | 0x6A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = drvNUM;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf, 0x1c,
                         &buf, 0x1c, &xx, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;

    i = 8;
    buf.reg_ECX = (i << 8) | 0x6A;
    buf.reg_EAX = 0x440d;
    buf.reg_EBX = drvNUM;
    r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, &buf,
                                 0x1c, &buf, 0x1c, &xx, 0);
    if (r && !(buf.reg_Flags & 1)) return 1;
    return 0;
}

char ReadSectors(char drvNUM, unsigned sector,
                     unsigned short num, void *buffer) {
  DIOC_REGISTERS buf = { 0 };
  unsigned r;
  #pragma pack(1)
  struct { unsigned v4; short v8; void *va; } st = { 0 };
  #pragma pack()

  st.v4 = sector;
  st.v8 = num;
  st.va = buffer;
  buf.reg_EAX = 0x7305;
  buf.reg_ECX = 0xFFFFFFFF;
  buf.reg_EDX = drvNUM;
  buf.reg_EBX = (unsigned)&st;
  r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_DRIVEINFO, &buf, 0x1c, &buf,
                         0x1c, (unsigned*)&num, 0);
  return (r && !(buf.reg_Flags & 1));
}

char WriteSectors(char drvNUM, unsigned sector, unsigned short num,
                      void *buffer, unsigned xx) {
  DIOC_REGISTERS buf = { 0 };
  unsigned r;
  #pragma pack(1)
  struct { unsigned v4; short v8; void *va; } st = { 0 };
  #pragma pack()

  st.v4 = sector;
  st.v8 = num;
  st.va = buffer;
  buf.reg_ESI = xx | 1;
  buf.reg_EAX = 0x7305;
  buf.reg_ECX = 0xFFFFFFFF;
  buf.reg_EDX = drvNUM;
  buf.reg_EBX = (unsigned)&st;
  r = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_DRIVEINFO, &buf, 0x1c,
                           &buf, 0x1c, (unsigned*)&num, 0);
  return (r && !(buf.reg_Flags & 1));
}

void __cdecl main(int argc, char **argv) {
    char root[] = "x:\\", type, drive, drvNUM;
    FILE *ff;

    if (argc < 2) {
        printf("read/write boot sector via direct disk access\n"
               " Usage: direct d: [newsector.bin]");
        return;
    }
    if (argc == 3) {
        boot = 1;
        ff = fopen(argv[2], "rb");
        if (!ff) {
            printf("can't read %s", argv[2]);
            return;
        }
        fread(newboot, 1, BUFSIZE, ff);
        fclose(ff);
    }
    drive = *(argv[1]);
    *root = drive;
    if ((type = GetDriveType(root)) != DRIVE_REMOVABLE && type != DRIVE_FIXED) {
        printf("wrong disk %c:! Only floppy and HDD are supported!", drive);
        return;
    }
    if (!(GetVersion() & 0x80000000)) { // windows NT
        char root1[] = "\\\\.\\x:";
        HANDLE file; unsigned len, flag;
        root1[4] = drive;
        flag = boot ? GENERIC_WRITE : 0;
        file = CreateFile(root1, GENERIC_READ | flag,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 NULL, OPEN_EXISTING, 0, NULL);
        if (file == INVALID_HANDLE_VALUE) {
            printf("no access to drive %c: Contact your system administrator", drive);
            return;
        }
        ReadFile(file, oldboot, BUFSIZE, &len, NULL);
        SetFilePointer(file, 0, NULL, FILE_BEGIN);
        if (boot) WriteFile(file, newboot, BUFSIZE, &len, NULL);
        CloseHandle(file);

        ff = fopen("oldboot.bin", "wb");
        fwrite(oldboot, 1, BUFSIZE, ff);
        fclose(ff);

        return;
    }
    // now fuck with 95/98
    hDevice = CreateFile("\\\\.\\vwin32", 0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0);
    if (hDevice == INVALID_HANDLE_VALUE) {
        printf("can't open device");
        return;
    }
    drvNUM = toupper(drive) - 'A' + 1;
    if (!lock(drvNUM, 1, 1)) {
        printf("can't lock drive");
        return;
    }
    if (!lock(drvNUM, 2, 0)) {
        unlock(drvNUM);
        printf("can't lock drive for reading");
        return;
    }
    if (!ReadSectors(drvNUM, 0, 1, oldboot)) {
        unlock(drvNUM);
        printf("can't read sector");
        return;
    }
    if (boot) {
        if (!lock(drvNUM, 3, 0)) {
            unlock(drvNUM);
            unlock(drvNUM);
            printf("can't lock drive for writing");
            return;
        }
        if (!WriteSectors(drvNUM, 0, 1, newboot, 0x6000))
            printf("can't write sector");
        unlock(drvNUM);
    }
    unlock(drvNUM);
    unlock(drvNUM);
    CloseHandle(hDevice);

    ff = fopen("oldboot.bin", "wb");
    fwrite(oldboot, 1, BUFSIZE, ff);
    fclose(ff);
}
===== Cut =====
