<보안 study>/리버싱

공유메모리 매핑

gosoeungduk 2023. 1. 4. 15:07
반응형

메모리 매핑

  • 작은 버퍼 대신 Page 단위로 큰 데이터를 빠르게 처리가능한 방식
  • 파일이 매핑된 가상메모리와 파일은 커널에 의해 동기화 되기 전까지는 불일치할 수도 있음.

공유 메모리 매핑 방식

  • 메모리 맵의 데이터를 변경하면, 그 즉시 커널에 의해 원본 파일과 데이터가 동기화되는 방식.
  • 프로세스간 메모리 공유에 특화된 방식이기 때문에 IPC 통신에서도 주로 쓰인다.

"ZwMapViewOfSection" 을 통한 공유 메모리 매핑 예제

// 물리 메모리를 사용하겠습니다. 선언.
UNICODE_STRING DestinationString;
RtlInitUnicodeString(&DestinationString, L"\\Device\\PhysicalMemory");
/* 중략 */
*a4 = 0;

// 얻어올 물리메모리 핸들에 대한 속성 지정
// 영구적, 객체이름 대소문자 구분 X, 커널 모드 핸들 O
OBJECT_ATTRIBUTES Object;
InitializeObjectAttributes(&Object, 
        &DestinationString, 
        OBJ_PERMANENT | OBJ_EXCLUSIVE 
        | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);


// 물리 메모리 영역에 대한 핸들을 a4 에 저장
v9 = ZwOpenSection(a4, 0xF001F, &ObjectAttributes);

DbgPrint("Opened section handle %p in driver\n", a4);

// 매핑된 가상메모리 주소를 BaseAddresss 에 보관 처리
ZwMapViewOfSection(*a4, -1, &BaseAddress, ~~, 0x204);

실제 매핑된 물리 메모리는 어떻게 참조하나?

  • 위 그림은 처음에 말한 공유 메모리 사용 시, IPC 가 이루어질 때 여러 프로세스가 메모리를 공유하는 경우를 가정한 것이다. (fork 된 프로세스라던지...)
  • 각 프로세스는 분명 다른 코드영역, 스택영역, 등의 가상 주소를 갖고 운용되는데 이런 경우는 같은 물리메모리를 가리키게 된다.
  • 이것은 Page Directory, Page Table 이라는 것 덕분인데, 그것에 대해 짤막하게 정리해본다.

페이징과 물리메모리

학교 운영체제 과목에서 배우는 내용. 우리가 평소에 보는 스택 주소, 코드영역 주소, 등등이 과연 실제 메모리에는 어떻게 대응이 되는 것일까?

32bit 기준으로 설명을 하자면, 원리는 다음과 같다.

 

우리가 흔히 보는 0x8041234 와 같은 주소는 위와 같이 10bit, 10bit, 12bit 로 각 역할에 따라 나눌 수 있다.

그리고 나눈 것들로 실제 물리 메모리(RAM) 에서의 위치를 포인팅 하게 되는데, 이에 대한 기준이 되는 것이 Page Directory Base(PDB) 이다.

 

해당 PDB 는 커널모드에서만 접근 가능한 컨트롤 레지스터 중에서도 CR3 레지스터에 담겨있는데, 이는 프로세스마다 각자 다른 Page Directory Base 주소 값을 갖고 운용된다.

 

그리고 실제 주소 찾기는 위와 같이 심플하게 나타낼 수 있다. 그림에 대한 설명은 아래와 같다.

  1. CR3 레지스터로 부터 프로세스의 Page Directory Base 주소를 가져옴.
  2. 가상 주소에서 얻은 Page Directory IndexPage Directory Base 주소를 더하여 프로세스의 Page Table Base 주소를 구해냄
  3. 가상 주소에서 얻은 Page Table Index 와 1 에서 구한 Page Table Base 주소를 더하여 Physical Memory Base 주소를 구해냄
  4. 가상 주소에서 얻은 Physical Offset 과 2 에서 구한 Physical Memory Base 주소를 더하여 실제 물리 주소를 구해냄.

정말 어려울게 없다. 이러한 전반적인 과정을 페이징이라고 통칭할 수 있으며, Windows 에서 DLL 을 공유메모리로 매핑하여 여러 프로세스가 사용하는 경우 페이징 단위로 쓰기(Copy on Write) 작업을 진행하는데에도 사용된다고 한다.

더 자세한 주소 구조(?) 구성(?) 은 복잡한 내용이 더 있으나 일단은 요까지 써본다. 끗.

반응형

'<보안 study> > 리버싱' 카테고리의 다른 글

[UE4] FNamePool 위치 식별  (3) 2023.05.23
MFC 프레임워크 기반 앱 시작지점  (0) 2023.01.06
Cracking Example  (1) 2022.11.21
자바 1.8.0 다운  (0) 2022.09.07
[iOS] iOS 어플 IDA로 원격 디버깅 하기  (1) 2022.05.20