본문 바로가기
System Hacking/해커스쿨 F.T.Z Hacking Zone

해커스쿨 F.T.Z Level 10

by En_Geon 2020. 2. 19.

level 10 로그인 후 hint를 본다.

 

level 10 hint

 

여기서는 공유메모리(Shared Memory)에 대해 알아야 한다.

공유메모리에 대해서는 yundream님의 블로그 공유메모리의 사용, 리눅스 시스템 프로그래밍 IPC를 참조하였다.

yundream님의 블로그에는 질 높은 좋은 글들이 많으니 한 번 둘러보는 것도 좋다.

 

 

공유메모리(Shared Memory)

 

보통 프로세스에서 사용되는 메모리 영역은 해당 프로세스만이 사용할 수 있다. 하지만 때때로 여러 개의 프로세스가 특정 메모리 영역을 사용했으면 하는 때가 있다. 이때 System V IPC 설비 중 하나인 "공유메모리"를 통해 사용할 수 있다.

 

System V IPC(Inter-Process Communication)에서 대표적으로 제공하는 설비의 형태는 Pipe, FIFO(First In First Out), Message Queue, Semaphore, Shared Memory, 파일 기반소켓(AF_UNIX) 등이 있다. IPC 설비는 아직 표준화되지 않아서 어떤 UNIX 시스템에서는 지원하지만 다른 UNIX 시스템에서는 지원하지 않는 것들이 많으며 모든 시스템에 공통으로 지원하는 것은 Pipe 정도가 유일하다.

 

데이터를 공유하는 방법에는 크게 두 가지가 있다. 통신을 이용해서 데이터를 주고받는 것과 데이터 자체를 공유하는 것이다. "pipe, named pipe, message queue"가 통신을 이용한 설비라면 "공유 메모리"가 데이터 자체를 공유하도록 지원하는 설비다.

 

프로세스는 자신만의 메모리 영역을 가지고 있다. 이 메모리 영역은 다른 프로세스가 접근해서 함부로 데이터를 읽거나 쓰지 못하도록 커널에 의해서 보호가 된다. 만약 다른 프로세스의 메모리 영역을 침범하려고 하면 커널은 침범 프로세스에 SIGSEGV 경고 신호를 보낸다.

 

공유 메모리는 프로세스 간 메모리 영역을 공유해서 사용할 수 있도록 허용한다. 프로세스가 공유 메모리 할당을 커널에 요청하면 커널은 해당 프로세스에 메모리 공간을 할당한다. 이후 어떤 프로세스든지 해당 메모리 영역에 접근할 수 있다.

공유 메모리는 중개자가 없이 곧바로 메모리에 접근할 수 있어서 다른 모든 IPC 중에서 가장 빠르게 작동한다.

 

공유메모리 공간은 커널이 관리한다. 그러므로 프로세스가 종료되면 반환되는 메모리 영역과는 달리 생성한 프로세스가 종료하더라도 공유 메모리는 그대로 남아있게 된다.

 

공유메모리 과정

 

  1. 공유 메모리 영역 생성 요청
  2. 공유 메모리를 자신의 프로세스에서 맵핑해서 사용할 수 있도록 요청
  3. 공유 메모리 사용

 

공유 메모리 함수

 

#include <sys/types.h>
#include <sys/shm.h>

int shmget(key_t key, int size, int shmflg)
void *shmat( int shmid, const void *shmaddr, int shmflg )
int shmdt( const void *shmaddr)
int shmctl(int shmid, int cmd, struct shmid_ds *buf)

 

shmget

 

shmget은 커널에 공유 메모리 공간을 요청하기 위해 호출하는 시스템 호출 함수다.

 

shmget Argument

 

key

 

key는 여러 개의 공유메모리 중 원하는 공유 메모리에 접근하기 위한 값이다. key 값은 커널에 의해 관리되며, key 값을 통해서 선택적인 공유메모리에 접근할 수 있다.

 

size

 

size는 공유메모리의 최소크기다.

새로운 공유메모리를 생성하고자 한다면 크기를 명시해주어야 한다. 존재하는 메모리를 참조한다면 크기는 0으로 명시한다.

 

shmflg

 

shmflg는 공유 메모리의 접근권한, 생성방식을 명시하기 위해 사용한다. 권한은 파일권한과 같이 유저, 그룹, Other에 대한 읽기, 쓰기 권한을 지정할 수 있다. 단 실행권한은 줄 수 없게 되어 있다.

또한, IPC_CREAT와 IPC_EXCL을 이용해 생성방식을 명시할 수 있다.

IPC_CREAT는 key를 식별번호로 가지는 공유메모리 공간을 생성한다.

IPC_EXCL은 IPC_CREAT와 같이 사용되며 만약 공유메모리 공간이 이미 존재할 경우 error를 리턴한다.

 

 

shmat

 

공유메모리 공간을 생성했으면 공유메모리에 접근할 수 있는 int형의 "식별자"를 얻는다. 이 식별자를 "shmat"를 이용해서 지금의 프로세스가 공유메모리를 사용할 수 있도록 "덧붙임" 작업을 해주어야 한다.

 

shmat Argument 

 

shmid

 

shmid는 "shmget"을 이용해서 얻어낸 식별자 번호다.

 

shmaddr

 

shmaddr은 메모리가 붙은 주소를 명시하기 위해 사용한다. "0(NULL)"을 사용할 경우 커널이 메모리가 붙을 주소를 명시하게 된다. 특별한 사항이 없다면 0을 사용한다.

 

shmflg

 

읽기전용, 읽기/쓰기, 쓰기 전용의 접근 방식을 정의할 수 있다.

 

 

shmdt

 

프로세스가 공유메모리를 더 사용할 필요 없다면 이 함수를 이용해서 맵핑정보를 없앤다. 맵핑정보를 없애는 것일 뿐 공유메모리를 없애는 것은 아니다.

 

 

shmctl

 

공유메모리 영역을 제어하기 위해서 사용한다. 공유메모리를 삭제하거나 잠금 설정, 해제 또는 권한을 변경하기 위한 목적으로 사용한다.

 

shmctl Argument

 

cmd

 

cmd를 이용해 shmid가 가리키는 공유메모리를 제어하며 cmd를 이용해 원하는 제어를 할 수 있다.

cmd를 이용한 명령어는 "IPC_STAT, IPC_SET, IPC_RMID"가 있다.

 

IPC_STAT

 

공유메모리 공간에 관한 정보를 가져오기 위해 사용한다. 정보는 buf에 저장된다.

 

IPC_SET

 

공유메모리 공간에 대한 사용자권한 변경을 위해 사용한다. 사용자 권한 변경을 위해서는 슈퍼 유저 혹은 사용자권한을 가지고 있어야 한다.

 

IPC_RMID

 

공유메모리 공간을 삭제하기 위해 사용한다. 이 명령을 사용한다고 해서 곧바로 사용되는 건 아니다. 공유메모리 공간을 더 사용하는 프로세스가 없을 때 삭제된다. 해당 공유메모리 공간에 대해서 삭제표시를 하는 거로 생각하면 된다.

 

 

공유메모리 정보

 

ipcs -l 옵션을 사용하면 IPC 자원 제한 정보를 확인할 수 있다.

 

ipcs -l 옵션

 

ipcs -m 옵션을 사용하면 현재 사용 중인 IPC 자원 정보를 확인할 수 있다.

 

ipcs -m 옵션

 

현재 사용 중인 ipc 자원을 보게 되면 key 값에 "0x00001d6a"가 있다. 이 숫자는 16진수로 10진수로 변환하게 되면 

hint에 있던 key 값인 7530이 된다.

권한은 666, byet 크기는 1028이다.

 

이 정보를 가지고 공유 메모리를 실행하는 실행 파일을 만들어야 한다.

 

더보기

 

IPC 정보와 위에서 배운 공유 메모리로 코드를 만든다.

 

ipc 실행 코드

 

기본형

int shmget(key_t key, int size, int shmflg)

 

key 인자에 key 값인 7530을 넣고 size에 1028, 권한에 0666을 넣는다.

 

기본형

void *shmat( int shmid, const void *shmaddr, int shmflg )

 

shmat으로 맵핑을 한다. 

shmget으로 얻은 식별자 shmid를 넣는다. 이때 shmget으로 얻은 식별자의 변수는 변할 수 있다.

주소로 "0(NULL)"을 사용할 경우 커널이 메모리가 붙을 주소를 명시하게 되므로 NULL을 준다.

 

코드 작성을 끝내고 컴파일 후 실행시켜준다.

댓글