심플스 - 프로그램과 책 이야기로 가득한 곳, (Simples.Kr)

  


   심플스 배너



 

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////

// Windows Vista 64Bit 미만에 운영체제에서 ( Windows XP 64Bit, Windows 2003 Server 64Bit )
// 32Bit 프로세스에서 IOCTL_SCSI_PASS_THROUGH_DIRECT 를 내릴 때 DeviceIoControl이 실패하게 되는데 이러한 문제점을
// 하드코딩하여 수정하는 코드입니다.
//
// 정확하게 말하자면 실패 위치는.. WinDbg로 디버깅을 하면서 차례대로 내려갔을 때..
//
// fffffadf`f543f48c e80ffaffff      call    SCSIPORT!SpHandleIoctlScsiPassThrough (fffffadf`f543eea0)
//
// SCSIPORT!SpHandleIoctlScsiPassThrough:
// fffffadf`f543eea0 4883ec28        sub     rsp,28h
// fffffadf`f543eea4 48895c2438      mov     qword ptr [rsp+38h],rbx
// fffffadf`f543eea9 4889742440      mov     qword ptr [rsp+40h],rsi
// fffffadf`f543eeae 488bf1          mov     rsi,rcx
// fffffadf`f543eeb1 488b4940        mov     rcx,qword ptr [rcx+40h]
// fffffadf`f543eeb5 48897c2448      mov     qword ptr [rsp+48h],rdi
// fffffadf`f543eeba 488bfa          mov     rdi,rdx
// fffffadf`f543eebd e84e0b0000      call    SCSIPORT!SpSendPassThrough (fffffadf`f543fa10) <= 에러 발생위치
//
// fffffadf`f543fae2 e869720000      call    SCSIPORT!PortSendPassThrough (fffffadf`f5446d50) < = 여기서 에러남
//
// fffffadf`f5446e8a e8a1000000      call    SCSIPORT!PortPassThroughInitialize (fffffadf`f5446f30) <= 여기서 에러남
//
// SCSIPORT!PortPassThroughInitialize 함수내부에서
// fffffadf`f5447151 3b4d08          cmp     ecx,dword ptr [rbp+8] ss:0018:fffffadf`f6ea0b6c=00000001
// 다음과 같이 값을 비교하게 되는데 dword ptr [rbp+8] ss:0018:fffffadf`f6ea0b6c 에 값이 0x01이어서 조건문에 의해 에러가 발생하게 됩니다.
//
// 클론시디에 경우에는
/*
.text:0000000000011CC7                 call    sub_16200
.text:0000000000011CCC                 lea     rcx, [rsp+1D8h+var_158]
.text:0000000000011CD4                 mov     [rsp+1D8h+var_158], r12d
.text:0000000000011CDC                 call    cs:RtlGetVersion <= 버전을 비교하는 함수를 호출..
.text:0000000000011CE2                 cmp     eax, r15d
.text:0000000000011CE5                 jl      short loc_11CF1
.text:0000000000011CE7                 cmp     [rsp+1D8h+var_154], 6 <= 6이라는 값을 비교하는걸 보니 dwMajorVersion와 비교할 가능성이 매우 높습니다.
.text:0000000000011CEF                 jnb     short loc_11D0D // 부호 없는 데이터, 작지 않을 때
.text:0000000000011CF1
.text:0000000000011CF1 loc_11CF1:                              ; CODE XREF: HwFindAdapter+F1j <= 작으면 이곳이 호출됩니다.
.text:0000000000011CF1                 mov     rax, [rbx+148h]
.text:0000000000011CF8                 mov     cs:qword_1A230, rax
.text:0000000000011CFF                 lea     rax, SetHalGetAdapter <= 그리고 SetHalGetAdapter 에 주소를 넣습니다.
.text:0000000000011D06                 mov     [rbx+148h], rax
.text:0000000000011D0D loc_11D0D:                              ; CODE XREF: HwFindAdapter+FBj
.text:0000000000011D0D                 mov     eax, cs:dword_1A238
.text:0000000000011D13                 mov     [rsi+17F8h], eax

*/
// 위에 코드가 실행 된 후에 HalGetAdapter 함수를 SCSIPort 내부에서 클론시디 드라이버에 있는 HalGetAdapter를 호출하게 되는데 어떻게 해서 그렇게 했는지 모르겠습니다.
// 중요한것은 저렇게 루틴을 탔을 경우에만 IOCTL_SCSI_PASS_THROUGH_DIRECT가 전송이 되고 그렇지 않으면 전송이 되지 않습니다.
//
// dword ptr [rbp+8] ss:0018:fffffadf`f6ea0b6c <= 해당 주소를 조사한 결과
// (UCHAR *)(g_pDriverObject->DeviceObject->DeviceExtension) + 0x3EC 위치에 값이 있었습니다.
// 비교는 ecx 레지스터와 비교를 하게 되므로 32Bit 값일것입니다.
//
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////

#define HACK_IOCTL_SCSI_PASS_THROUGH_DIRECT_OFFSET 0x3EC

PVOID g_HackDeviceExtensionPointer = NULL;

VOID Hack64BitIOCTL_SCSI_PASS_THROUGH_DIRECT()
{
    if (g_HackDeviceExtensionPointer != NULL)
    {
        KdPrint(("H.A.C.K IOCTL_SCSI_PASS_THROUGH_DIRECT\n"));
        *(DWORD *)(((UCHAR *)g_HackDeviceExtensionPointer + HACK_IOCTL_SCSI_PASS_THROUGH_DIRECT_OFFSET)) = 0x00000011;
    }
}

VOID InitHack64BitIOCTL_SCSI_PASS_THROUGH_DIRECT(PDRIVER_OBJECT pDriverObject)
{
    NTSTATUS ntStatus;
    RTL_OSVERSIONINFOW rtlOsVersionInfoW;

    ntStatus = RtlGetVersion(&rtlOsVersionInfoW);
    if (NT_SUCCESS(ntStatus) == TRUE)
    {
        if (rtlOsVersionInfoW.dwMajorVersion < 6)
        {
            g_HackDeviceExtensionPointer = pDriverObject->DeviceObject->DeviceExtension;
        }
    }
    else
    {
        NOTHING
    }
}


InitHack64BitIOCTL_SCSI_PASS_THROUGH_DIRECT 함수에 인자 pDriverObject는 DriverEntry에서 받은 DriverObject를 넣으면 되며, HwFindAdapter에서 호출되어야 합니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수
» Windows Research SCSI Miniport - IOCTL_SCSI_PASS_THROUGH_DIRECT ( ... [레벨:6]lain 2011-06-11 3649
161 Windows Research 커널레벨에서 IAT Hook [레벨:6]lain 2011-06-11 4348
160 Windows Research DEVICE_OBJECT에 대한 보안 디스크립터 변경 [레벨:6]lain 2011-06-11 3167
159 Windows Research IE Cache 경로 변경하기 [레벨:6]lain 2011-06-09 3292
158 Windows Research 32Bit 윈도우즈에서 실제 물리메모리크기 얻어오기 [레벨:6]lain 2011-06-09 3431
157 Windows Research VMWare 탐지 기법 우회 - 2 [2] [레벨:6]lain 2011-04-04 8850
156 Linux Tip 우분투에 IRC서버 설치후 닉네임 길이와 동접자 조절. [1] [레벨:0]오랑캐꽃 2010-11-26 5829
155 Linux Tip VirtualBox에 우분투 설치 후에 내부 네트워크 접속 설정하기 file [레벨:8]esniper 2010-09-10 12222
154 Linux Tip VirtualBox에서 오른쪽 CTRL키 사용하기(VitualBox 호스트키) file [2] [레벨:8]esniper 2010-09-10 6057
153 Linux Tip 우분투 설치 후 putty에서 한글 안 깨지도록 설정하기 file [레벨:8]esniper 2010-09-10 6366
152 Linux Tip 우분투 ssh or mysql 서버 접속지연이 있는 경우 해결책 [레벨:8]esniper 2010-09-10 6244
151 문서자료 고품질의 무료 아이콘들 [3] [레벨:8]esniper 2010-09-08 7439
150 Windows Research Sysinternals - Filemon source code file [5] [레벨:6]lain 2010-09-04 5818
149 Windows Research Sysinternals - Regmon source code file [1] [레벨:6]lain 2010-09-04 5492
148 Windows Research PostQueuedCompletionStatus 함수에 실패 여부도 고려해야 할까... [레벨:6]lain 2010-09-04 4678
147 Windows Research SetEvent 함수는 언제 실패할까? [레벨:6]lain 2010-09-04 5491
146 Windows Research 커널모드 드라이버에서 사용하는 시간관련 매크로 [레벨:6]lain 2010-09-04 4443
145 Windows Research 화면캡쳐방지는 어떻게 구현될까? [3] [레벨:6]lain 2010-09-04 8658
144 Windows Research IRP Completion Hook file [레벨:6]lain 2010-09-04 3992
143 Windows Research IRP Hook [레벨:6]lain 2010-09-04 4195

  • 이용약관
  • 개인정보취급방침
  • 사이트맵