IOPM(I/O Permission Bitmap) 조작하기

Ring3에서 입/출력 포트의 직접적인 제어를 하기 위해서 아래의 두가지 방법이 사용된다.

1. 디바이스 드라이버 제작, IOCTL을 가지고 명령 수행.
2. 특정 입/출력 포트에 접근할 특정 태스크(프로세스)를 위해서 입/출력 퍼미션 비트맵
   (I/O Permission Bitmap)을 수정하여 직접 접근.

보호모드에서는 두가지를 여부를 보고 입/출력 포트에 접근하도록 하는데, 하나는 EFLAGS
레지스터의 IOPL(I/O Privilege Level)이고, 나머지 하나는 TSS(Task State Segment)에
있는 입/출력 권한 비트맵(IOPM)이다.

예를들어, 입/출력 instruction이 실행되면, 프로세서는 먼저 태스크가 해당 포트에 대한
특권이 있는지 IOPL을 통해 확인하고, 특권이 있으면 명령을 실행한다. 그런데 특권이 없는
경우에는 TSS에 있는 IOPM을 검사한다.

IOPM은 말그대로 비트맵이고, 하나의 비트가 하나의 입/출력 주소를 나타낸다. 그래서
특정 포트에 대한 비트가 Set(1)되어 있으면 Privileged Instruction Exception을 일으키고
Clear(0)되어 있으면 명령을 수행한다. 물론 이렇게 동작하기 때문에 태스트당 하나의
IOPM이 존재함을 알 수 있다. 그럼 어떻게 이 IOPM이란 녀석을 조작할 수 있을까??

IOPM을 조작하기 위해서는 일단 커널에서 동작하는 드라이버가 하나 필요하겠다.
이 녀석은 몇가지 undocumented API를 통해서 IOPM을 조작하는 일을 수행할 것이다.
우선 특정한 프로세스에 대한 정보를 얻기 위해서 EPROCESS 구조체의 포인터를 얻는
PsLookupProcessByProcessId(IN ULONG uIProcId, OUT struct _EPROCESS **pEProcess);
를 사용한다. 포인터를 얻었다면 이제 Ke386Brother API를 통해서 직접 IOPM을 조작할 수
있다.

void Ke386SetIoAccessMap(int, IOPM *);
void Ke386QueryIoAccessMap(int, IOPM *);
void Ke386IoSetAccessProcess(PEPROCESS, int);


먼저, Ke386SetIoAccessMap()은 TSS에 지정된 IOPM을 복사하는 역할을 한다.
그리고 Ke386QueryIoAccessMap()는 TSS로부터 IOPM을 읽어오는 역할을 한다.
IOPM은 8192바이트의 배열로, 1비트가 하나의 어드레스이므로 최대 64K만큼의 접근
가능 여부를 표시할 수 있다. IOPM이 TSS에 복사된 후에는 Ke386IoSetAccessProcess
를 호출하여 EPROCESS내부의 IOPM offest 포인터가 새롭게 복사한 IOPM을 가리키도록
해줘야 한다. 두번째 파라메터에 0을 넘기면 포인터를 제거하고 1을 넘기면 설정된다.

참고 : http://www.freewebs.com/four-f/KmdTut/kmd03.html

by nerd | 2007/04/19 11:29 | Drivers | 트랙백(1) | 덧글(0)


트랙백 주소 : http://nerd.egloos.com/tb/3123602
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from at 2014/03/11 00:42

제목 : http://helenmccrory.org/
line5...more

:         :

:

비공개 덧글

◀ 이전 페이지다음 페이지 ▶