Windows 에서 BOOL 형 과 BOOLEAN 형은 TRUE, FALSE를 구별하는 변수의 타입으로 사용되지만 서로 약간의 차이점이 존재합니다.
그것은 아래와 같이 선언됨에 따라서 BOOLEAN 으로 선언한 변수의 크기는 1바이트이며, BOOL 은 4바이트(32bit 시스템에서) 인 점입니다.
typedef int BOOL
일반적으로 프로그래밍을 할 경우에, 이 둘을 별로 구별하지 않고 사용하게 되는데요. 하지만 후킹(함수 포인터 변경 방식)을 하는 경우 원본 함수를 호출하려 할때 정확하지 않은 함수 인자를(즉, 사이즈가 다른) 사용하면 때때로 에러(ERROR_INVALID_PARAMETER)로 리턴 되는 경우가 있어 주의가 필요합니다.
특히, Windows 의 Undocument API 를 후킹하고자 할 때는 함수 프로토타입을 알수가 없어서 정확한 함수 인자를 알기가 어렵습니다.
이러한 Undocument API 함수의 프로토타입은 http://undocumented.ntinternals.net/ 와 Windows NT/2000 NATIVE API Reference 책을 참조하는게 보통입니다.
하지만 오늘 위 두 곳에서 정의한 함수 프로토타입이 틀릴 수도 있으므로 주의가 필요함을 알았습니다.
1. 우선 아래와 같은 함수를 확인하실 수 있습니다.
NtCreateNamedPipeFile(OUT PHANDLE NamedPipeFileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN BOOLEAN WriteModeMessage,
IN BOOLEAN ReadModeMessage,
IN BOOLEAN NonBlocking,
IN ULONG MaxInstances,
IN ULONG InBufferSize,
IN ULONG OutBufferSize,
IN PLARGE_INTEGER DefaultTimeOut );
실제로 그런지 확인해 보겠습니다.
2. XP 에서 NtCreateNamedPipeFIle 의 SDT 의 인덱스는 2C 입니다.
ntdll!NtCreateNamedPipeFile:
7c93d715 b82c000000 mov eax,2Ch
7c93d71a ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0
300)
7c93d71f ff12 call dword ptr [edx]
7c93d721 c23800 ret 38h
3. SDT(Service Descriptor Table)은 아래와 같이 4개의 멤버를 가지고 있습니다.
(2) CounterTable Address
(3) Service Limit
(4) System Service Parameter Table Address
4. 아래와 같이 SDT 에서 System Service Parameter Table Address 가 있는 위치를 확인합니다. 흠.. 0x80519fc4 네요
80563500 804e68b0 00000000 0000011c 80519fc4
80563510 00000000 00000000 00000000 00000000
80563520 00000000 00000000 00000000 00000000
80563530 00000000 00000000 00000000 00000000
80563540 00000002 00002710 bf80c227 00000000
80563550 badefa80 f753d4a0 8a96b0f0 80711040
80563560 00000000 00000000 ffeced30 ffffffff
80563570 e0d48b70 01c883c9 00000000 00000000
5. 각 함수의 인자 값을 확인해면 아래와 같습니다.
80519fc4 18 20 2c 2c 40 2c 40 44-0c 08 18 18 08 04 04 0c . ,,@,@D……..
80519fd4 10 18 08 08 0c 04 08 08-04 04 0c 08 0c 04 04 20 ……………
80519fe4 08 10 0c 14 0c 2c 10 0c-0c 1c 20 10 38 10 14 20 …..,…. .8..
80519ff4 24 24 1c 14 10 20 10 34-14 08 0c 08 04 04 04 04 $$… .4……..
8051a004 0c 08 28 04 1c 18 08 18-0c 18 08 18 0c 08 0c 04 ..(………….
8051a014 10 00 0c 10 28 08 08 10-1c 04 08 0c 04 10 08 00 ….(………..
8051a024 08 04 08 0c 28 08 04 10-04 04 0c 0c 28 04 24 28 ….(…….(.$(
8051a034 30 0c 0c 0c 18 0c 0c 0c-0c 30 10 0c 10 0c 0c 0c 0……..0……
즉, 함수 선언에 있는 것처럼 인자의 총 합이 47바이트(4Byte * 11 + 1Byte * 3) 가 아니라 56 바이트(통상 4Byte * 14) 이어야 합니다.
즉, BOOLEAN 형의 인자 세개가 잘못 된 것이며, 4Byte 타입으로 선언해야 합니다.
이러한 함수를 몇개 더 확인해 본 결과, 함수 선언중 BOOLEAN 인자로 되어 있는것은 전부 이렇게 인자 바이트 합이 일치하지 않았으며, BOOLEAN 타입을 4Byte 타입으로 바꾸어서(ULONG) 계산하면 일치함을 확인했습니다.
또한 이렇게 수정한 결과 후킹후 원본 함수 호출 시 ERROR_INVALID_PARAMETER 가 발생하지 않음을 확인했습니다.
위 내용에 대해서 2000 SP4, XP SP2 에 환경에서 확인해 보았습니다.