SlideShare a Scribd company logo
1 of 25
제프리 리처의
WINDOWS VIA C/C++
2017-12-26
신희민
Chapter 01 : 에러 핸들링
윈도우 함수가 실패함
: 내부적으로 함수를 호출한 스레드의 스레드 지역 저장소에 적절한 에러 코드를 저장해 준다.
-> 이렇한 메커니즘을 통해 여러 개의 스레드가 동시에 수행될 경우라도
상호간에 영향을 미치지 않고 각 스레드별로 에러 코드를 유지할 수 있게 된다.
DWORD GetLastError();
: 이 함수는 단순히 가장 최근에 호출된 함수의 에러 코드를 스레드 지역 저장소로부터 가져옴.
Visual Studio의 기능을 이용하여 조회 가능
도구 -> 오류조회
Chapter 02 : 문자와 문자열로 작업하기
Buffer overrun(버퍼 오버런)
: 애플리케이션과 운영체제의 보안 취약점을 공격하는 주요 방법
C 런타임 라이브러리의 함수를 사용하면 문자열을 다룰 때 발생할 수 있는 버퍼 오버런을 미연에 방지
Chapter 02 : 문자와 문자열로 작업하기
StrSafe.h 헤더 파일을 포함하면 String.h 헤더 파일도 같이 포함된다.
: StrSafe.h에 대한 include 구문은 다른 include 구문보다 반드시 뒤쪽에 위치되어야 한다.
_tcscpy나 _tcscat 같은 기존 함수에는 동일한 이름에 _S가 붙은 안전 문자열 함수가 제공된다.
PTSTR _tcscpy(PTSTR strDestination, PCTSTR strSource);
Errno_t _tcscpy_s(PTSTR strDestination, size_t numberOfcharacters, PCTSTR strSource);
PTSTR _tcscat(PTSTR strDestination, PCTSTR strSource);
Errno_t _tcscat_s(PTSTR strDestination, size_t numberOfcharacters, PCTSTR strSource);
Size_t numberOfcharacter는 _countof 매크로를 사용하면 쉽게 계산가능
안전 문자열을 사용하는것을 권고한다.
Chapter 02 : 문자와 문자열로 작업하기
안전(_s로 끝나는) 문자열 함수는 내부적으로 가장 먼저 인자의 유효성을 검증
: 인자 값이 NULL인지, 정수 값이 유효한 범위 내에 있는지, 열거형 값이 유효한지
버퍼는 결과를 저장할 만큼 충분한지 등을 테스트
만일 테스트가 실패하면 errno에 에러 코드를 설정하고, 성공 실패 여부를 나타내는 errno_t형 값을 반환
에러의 원인을 출력
Chapter 02 : 문자와 문자열로 작업하기
Strcpy_s를 사용할 시
: 복사하려는 버퍼보다 복사되는 버퍼의 길이가 더 짧을 경우 에러메시지가 뜨며 실패
StringCchcopy를 사용 할 시
: 복사하려는 버퍼보다 복사되는 버퍼의 길이가 더 짧을 경우엔 잘림 현상이 발생
Chapter 03 : 커널 오브젝트
숙달된 윈도우 소프트웨어 개발자가 되기 위해서는
반드시 커널 오브젝트에 대해 완벽하게 이해!
Chapter 03 : 커널 오브젝트
운영체제나 우리가 개발하는 애플리케이션은
프로세스, 스레드, 파일 등과 같은 수많은 리소스를 관리하기 위해 커널 오브젝트를 사용한다.
그렇다면 커널 오브젝트란?
Chapter 03 : 커널 오브젝트
커널 오브젝트
: Windows 운영체제에서 리소스들을 관리하기 위한 데이터를 저장하는 메모리 블록
엑세스 토큰 오브젝트, 이벤트 오브젝트, 파일 오브젝트, 파일-매핑 오브젝트, I/O 콤플리션 포트 오브젝트, 잡 오브젝트, 메일슬롯 오브젝트, 뮤텍스 오브젝트, 파이프 오브젝트…
이런 것들…
Chapter 03 : 커널 오브젝트
커널 오브젝트의 데이터 구조체는 커널에 의해서만 접근이 가능하기 때문에 애플리케이션에서
데이터 구조체가 저장되어 있는 메모리 위치를 직접 접근하여 그 내용을 변경하는 것은 불가능한다.
: 구조체에 대한 직접적인 접근을 제한함으로써 마이크로소프트는 이미 개발되어 있는 애플리케이션에
영향을 미치지 않고도 구조체에 내용을 임의로 추가, 삭제, 변경할 수 있다.
마이크로소프트는 정제된 방법을 통해 구조체에 내용에 접근할 수 있도록 일련의 함수 집합을 제공
-> 커널 오브젝트의 내부적인 값에 접근 할 수 있다.
커널 오브젝트를 생성하는 함수를 호출하면 함수는 각 커널 오브젝트를 구분하기 위한 핸들 값을 반환
Chapter 03 : 커널 오브젝트
운영체제를 견고하게 하기 위해 이러한 핸들 값들은 프로세스별로 독립적으로 유지된다.
-> 만일 어떤 스레드가 다른 프로세스의 스레드에게 자신의 핸들 값을 전달했을 경우
이 핸들 값을 이용하여 수행하는 동작은 실패할 수도 있고 혹은 더 좋지 않은 결과를 초래
-> 각 프로세스 별로 독립된 프로세스 핸들 테이블이 존재하고
동일한 핸들값이라도 전혀 다른 커널 오브젝트를 참조 할 수 있기 때문이다.
Chapter 03 : 커널 오브젝트
1. 사용 카운트
커널 오브젝트는 프로세스가 아니라 커널에 의해 소유된다.
프로세스가 특정 함수를 통해 커널 오브젝트를 생성한 후 종료된다 하더라도
반드시 생성된 커널 오브젝트가 프로세스와 함께 삭제 되는 것은 아니다.
커널 오브젝트는 자신을 생성한 프로세스 보다 더 오랫동안 삭제되지 않고 남아 있을 수 있다.
각 커널 오브젝트는 내부적으로 사용 카운트 값을 유지하고 있기 때문에 커널은 이 값을 통해
얼마나 많은 프로세스들이 커널 오브젝트를 사용하고 있는지 알 수 있다.
다른 프로세스가 이미 생성된 커널 오브젝트에 접근 권한을 획득하면 사용 카운트가 증가
프로세스가 종료되면 커널은 이 프로세스가 사용하고 있던 커널 오브젝트의 사용 카운트를 감소 시킴
-> 이 값이 0이 되면 커널 오브젝트는 삭제된다.
Chapter 03 : 커널 오브젝트
1. 보안
커널 오브젝트는 보안 디스크립터를 통해 보호될 수 있다.
IpSecurityDescriptor멤버만이 보안과 관련되어 있다.
오브젝트 생성시 커널 오브젝트의 접근 권한을 제한하고자 한다면 보안 디스크립터를 생성 후 초기화
Chapter 03 : 커널 오브젝트
Section 02 : 프로세스의 커널 오브젝트 핸들 테이블
프로세스가 초기화 되면 커널 오브젝트 핸들 테이블 할당
프로세스 별로 핸들이 독립적으로 유지
핸들 테이블은 사용자 오브젝트나 GDI 오브젝트에 의해서는 사용되지 않고 유일하게 커널 오브젝트에서 사용
: 프로세스 핸들 테이블은 커널 오브젝트에 대한 포인터, 액세스 마스크, 플래그로 구성
Chapter 03 : 커널 오브젝트
Section 02 : 프로세스의 커널 오브젝트 핸들 테이블
커널 오브젝트 생성
프로세스가 최초로 초기화되면 프로세스의 핸들 테이블은 비어있다.
프로세스 내의 스레드가 CreateFileMapping과 같은 함수를 호출하면 커널은 커널 오브젝트를 위한
메모리 블록을 할당하고 초기화
커널은 프로세스의 핸들 테이블을 조사하여 비어 있는 공간을 찾아낸다.
앞에 보이는 표핸들 테이블은 완전히 비어 있기 때문에 커널은 인덱스가 1인 위치를 찾아내어 초기화
Chapter 03 : 커널 오브젝트
Section 02 : 프로세스의 커널 오브젝트 핸들 테이블
커널 오브젝트를 생성하는 모든 함수는 프로세스 별로 고유한 핸들 값을 반환하며,
이 값은 프로세스내의 모든 스레드에 의해 사용될 수 있다.
Create함수로 반환되는 핸들값을 4로 나누거나 오른쪽으로 2비트 시프트하면
커널 오브젝트에 대한 정보를 저장하고 있는 프로세스 핸들 테이블의 인덱스 값을 얻는다.
커널 오브젝트 핸들을 인자로 취하는 함수를 호출할 때에는
항상 Create* 류의 함수 중 하나를 호출하여 반환된 핸들 값을 전달
만일 유효하지 않은 핸들 값을 전달하게 되면 이러한 함수들은 실패하고 GetLastError 호출 결과를 반환
핸들 값은 실제로 프로세스 핸들 테이블의 인덱스 값으로 활용 될 수 있기 때문에 프로세스 별로 고유한 값
다른 프로세스에 의해 사용될 수 없는 값
이유 : 다른 프로세스와 공유를 시도하면 다른 프로세스의 프로세스
핸들 테이블로부터 동일한 인덱스 값을 가진 완전히 다른 커널 오브젝트를참조하게 될 것
Chapter 03 : 커널 오브젝트
Section 02 : 프로세스의 커널 오브젝트 핸들 테이블
커널 오브젝트를 생성하는 함수가 실패하면 반환되는 핸들 값은 보통 0(NULL)
시스템의 가용 메모리가 매우 작거나 보안 문제로 인해 함수가 실패하는 경우 몇몇 함수들은
-1(INVALID_HANDLE_VALUE)를 반환
CraeteFile 함수의 경우 주어진 파일을 여는데 실패하면 NULL 대신 INVALID_HANDLE_VALUE 반환
커널 오브젝트를 생성하는 함수의 반환 값을 확인할 때에는 상당한 주의가 필요하다.
Chapter 03 : 커널 오브젝트
Section 02 : 프로세스의 커널 오브젝트 핸들 테이블
커널 오브젝트 삭제
커널 오브젝트를 어떻게 생성했는지와 상관없이 CloseHandle 함수를 호출하여 더 이상 커널
오브젝트를 사용하지 않을 것임을 시스템에게 알려줌
BOOL CloseHandle(HANDLE hobject); // 구조체 내의 사용 카운트 멤버를 감소시킨다.
// 만일 0이 되면 커널 오브젝트를 파괴하고 메모리부터 제거
CLoseHandle()을 사용하여
사용 카운트 -1
사용 카운트가 0이면 삭제
Chapter 03 : 커널 오브젝트
Section 03 : 프로세스간 커널 오브젝트의 공유
서로 다른 프로세스에서 각기 수행되는 스레드들 간에 동일 커널 오브젝트를 공유해야 하는 경우
Ex) 파일-매핑 오브젝트는 단일 머신에서 수행되는 두 프로세스 사이에서 데이터의 블록을 공유
메일슬롯과 명명파이프를 이용하면 네트워크로 연결된 서로 다른 머신 사이에서 데이터를 주고받음
해결방안
1. 오브젝트 핸들의 상속 이용
2. 명명된 오브젝트 사용
3. 오브젝트 핸들의 복사 이용
Chapter 03 : 커널 오브젝트
Section 03 : 프로세스간 커널 오브젝트의 공유
1. 오브젝트 핸들의 상속을 이용하는 방법
오브젝트 핸들의 상속은 오브젝트를 공유하고자 하는 프로세스들이 parent-child 관계여야 한다.
인덱스 포인터 엑세스마스
크
플래그
1 0xF0000000 0x???????? 0x00000000
2 0x00000000 (N/A) (N/A)
3 0xF0000010 0x???????? 0x00000001
bInheritHandle 멤버 FALSE
bInheritHandle 멤버 TRUE
Chapter 03 : 커널 오브젝트
Section 03 : 프로세스간 커널 오브젝트의 공유
1. 오브젝트 핸들의 상속을 이용하는 방법
bInhertHandles 매개변수로 TRUE를 전달하면 child process는 parent process의 상속가능한 핸들 값들을 상
속하게 된다. 매개변수에 TRUE를 전달하여 CreateProcess함수를 호출하여 child process 생성
(어느 프로세스의 생성 절차와 마찬가지로 child process를 생성하는 과정에서 프로세스 핸들 테이블 생성)
추가 적인 한가지 작업을 수행한다.
: Parent process의 핸들 테이블을 조사하여 상속 가능한 핸들을 찾아내는 일
시스템은 찾아낸 항목들을 child process의 핸들 테이블에 복사.
Child process 핸들 테이블 내의 복사 위치는 parent process의 핸들 테이블에서의 위치와 정확히 일치
-> 특정 커널 오브젝트를 구분하는 핸들 값이 페어런트 프로세스와 차일드 프로세스에 걸쳐 동일한 값 이용
운영체제는 핸들 테이블의 항목을 복사하는 작업과 병행하여 커널 오브젝트 내의 사용 카운트를 증가
Chapter 03 : 커널 오브젝트
Section 03 : 프로세스간 커널 오브젝트의 공유
1. 오브젝트 핸들의 상속을 이용하는 방법
Parent process와 child process간에만 가능하다.
오브젝트 핸들 상속은 child process를 새로 생성할 때에만 적용이 가능한다.
-> 만약 부모 프로세스가 상속이 가능한도록 새로운 커널 오브젝트를 생성한다 하더라도,
이미 수행되고 있었던 child process가 새로운 핸들을 상속받지 못한다.
Child process는 어떤 핸들이 상속되어있는지를 모르기때문에 알려줘야만 쓸 수 있다.
-> child process 수행 시 명령행 인자를 이용하여 커널 오브젝트의 핸들 값 전달
-> 프로세스간 통신 방법을 이용하여 parent proces가 child proces에게 커널 오브젝트의 핸들 전달
-> parent process가 환경변수 블록에 상속할 커널 오브젝트에 대한 핸들값을 가지고있는
새로운 환경변수를 추가 하는 것
Chapter 03 : 커널 오브젝트
Section 03 : 프로세스간 커널 오브젝트의 공유
2. 명명된 오브젝트 사용
이름을 이용하여 커널 오브젝트를 공유하려면 당연히 커널 오브젝트에 이름을 지정해야 한다.
에러 발생 (ERROR_INVALID_HANDLE)
B프로세스가 CreateMutex에 성공한다 하더라도 실제로는 새로운 뮤텍스가 생성되는 것이 아닌
기존의 뮤텍스 오브젝트에 접근할 수 있는 B 프로세스 고유의 핸들 값이 생성
Chapter 03 : 커널 오브젝트
Section 03 : 프로세스간 커널 오브젝트의 공유
3. 오브젝트 핸들 복사
프로세스 간에 커널 오브젝트를 공유하는 마지막 방법은 DuplicateHandle 함수를 사용하는 것
: DuplicateHandle 함수는 특정 프로세스 핸들 테이블 내의 항목을 다른 프로세스 핸들 테이블로 복사
첫 번째와 세 번째 매개변수인 hSourceProcessHandle과
hTargetProcessHandle에 프로세스 커널 오브젝트의 핸들.
두번째 매개변수인 hSourceHandle로는 어떤 타입의 커널 오브젝트라도 전달
phTargetHandle로는 HANDLE 변수의 주소값을 전달
5,6번째 매개변수는 액세스 마스크와 상속 플래그 지정
마지막 매개변수는 DUPLICATE_SAME_ACCESS와 DUPLICATE_CLOSE_SOURCE
DUPLICATE_SAME_ACCESS는 소스 프로세스의 핸들과 동일한 액세스 마스크
DUPLICATE_CLOSE_SOURCE는 소스 프로세스의 핸들을 삭제
Chapter 03 : 커널 오브젝트
Section 03 : 프로세스간 커널 오브젝트의 공유
3. 오브젝트 핸들 복사
인덱스 포인터 액세스 마스크 플래그
1 0x00000000 (N/A) (N/A)
2 0xF0000020 0x???????? 0x00000000
인덱스 포인터 액세스 마스크 플래그
1 0x00000000 (N/A) (N/A)
2 0xF0000030 0x???????? 0x00000000
인덱스 포인터 액세스 마스크 플래그
1 0xF0000020 0x???????? 0x00000001
2 0xF0000030 0x???????? 0x?????????
DuplicateHandle(1, 2, 2, &hobj, 0, TRUE, DUPLICATE_SAME_ACCESS
S프로세스
C프로세스
C프로세스가 S
프로세스 핸들
을 받음

More Related Content

What's hot

Windows via c/c++ 스터디9장
Windows via c/c++ 스터디9장Windows via c/c++ 스터디9장
Windows via c/c++ 스터디9장HolyTak
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Yong Joon Moon
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화sung ki choi
 
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. JobHyosung Jeon
 
윈도우 메모리맵파일
윈도우 메모리맵파일 윈도우 메모리맵파일
윈도우 메모리맵파일 Dong-Jin Park
 
스톰 미리보기
스톰 미리보기스톰 미리보기
스톰 미리보기June Yi
 
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용 [GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용 Sehyeon Nam
 
모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디quxn6
 
Stl vector, list, map
Stl vector, list, mapStl vector, list, map
Stl vector, list, mapNam Hyeonuk
 
C++ VECTOR, LIST, MAP
C++ VECTOR, LIST, MAPC++ VECTOR, LIST, MAP
C++ VECTOR, LIST, MAPJae Woo Woo
 
Realm.io for iOS
Realm.io for iOSRealm.io for iOS
Realm.io for iOSEunjoo Im
 
Java script의 이해
Java script의 이해Java script의 이해
Java script의 이해seungkyu park
 
스레드
스레드스레드
스레드xxbdxx
 

What's hot (20)

Gpg1
Gpg1Gpg1
Gpg1
 
Windows via c/c++ 스터디9장
Windows via c/c++ 스터디9장Windows via c/c++ 스터디9장
Windows via c/c++ 스터디9장
 
Storm 훑어보기
Storm 훑어보기Storm 훑어보기
Storm 훑어보기
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. Job
 
윈도우 메모리맵파일
윈도우 메모리맵파일 윈도우 메모리맵파일
윈도우 메모리맵파일
 
스톰 미리보기
스톰 미리보기스톰 미리보기
스톰 미리보기
 
Gcd ppt
Gcd pptGcd ppt
Gcd ppt
 
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용 [GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
 
모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디
 
Nodejs_chapter3
Nodejs_chapter3Nodejs_chapter3
Nodejs_chapter3
 
Stl vector, list, map
Stl vector, list, mapStl vector, list, map
Stl vector, list, map
 
C++ VECTOR, LIST, MAP
C++ VECTOR, LIST, MAPC++ VECTOR, LIST, MAP
C++ VECTOR, LIST, MAP
 
Realm.io for iOS
Realm.io for iOSRealm.io for iOS
Realm.io for iOS
 
Java script의 이해
Java script의 이해Java script의 이해
Java script의 이해
 
Rx java essentials
Rx java essentialsRx java essentials
Rx java essentials
 
스레드
스레드스레드
스레드
 
Stl 컨테이너
Stl 컨테이너Stl 컨테이너
Stl 컨테이너
 
C++ stl
C++ stlC++ stl
C++ stl
 

Similar to Windows via c++ part 1

Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)문익 장
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 patternjinho park
 
Api design for c++ pattern
Api design for c++ patternApi design for c++ pattern
Api design for c++ patternjinho park
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇Seungyong Lee
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장 Shin heemin
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4성연 김
 
Android Programming
Android ProgrammingAndroid Programming
Android ProgrammingJake Yoon
 
Android Programming - Input
Android Programming - InputAndroid Programming - Input
Android Programming - InputJake Yoon
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디quxn6
 
04 안드로이드 응용프로그램의 구조
04 안드로이드 응용프로그램의 구조04 안드로이드 응용프로그램의 구조
04 안드로이드 응용프로그램의 구조Wanbok Choi
 
I phone 2 release
I phone 2 releaseI phone 2 release
I phone 2 releaseJaehyeuk Oh
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinDong Chan Shin
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019min woog kim
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링xxbdxx
 
Software Architect day - 웹 프레임워크 종결 - metaworks3
Software Architect day - 웹 프레임워크 종결 -  metaworks3Software Architect day - 웹 프레임워크 종결 -  metaworks3
Software Architect day - 웹 프레임워크 종결 - metaworks3uEngine Solutions
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptInjae Lee
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 

Similar to Windows via c++ part 1 (20)

Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 pattern
 
Api design for c++ pattern
Api design for c++ patternApi design for c++ pattern
Api design for c++ pattern
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
 
Android Programming
Android ProgrammingAndroid Programming
Android Programming
 
Android Programming - Input
Android Programming - InputAndroid Programming - Input
Android Programming - Input
 
MEC++ 5
MEC++ 5MEC++ 5
MEC++ 5
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디
 
04 안드로이드 응용프로그램의 구조
04 안드로이드 응용프로그램의 구조04 안드로이드 응용프로그램의 구조
04 안드로이드 응용프로그램의 구조
 
I phone 2 release
I phone 2 releaseI phone 2 release
I phone 2 release
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링
 
Software Architect day - 웹 프레임워크 종결 - metaworks3
Software Architect day - 웹 프레임워크 종결 -  metaworks3Software Architect day - 웹 프레임워크 종결 -  metaworks3
Software Architect day - 웹 프레임워크 종결 - metaworks3
 
AWS DevDay 실습 가이드 - 콘테이너
AWS DevDay 실습 가이드 - 콘테이너AWS DevDay 실습 가이드 - 콘테이너
AWS DevDay 실습 가이드 - 콘테이너
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4ppt
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 

Windows via c++ part 1

  • 1. 제프리 리처의 WINDOWS VIA C/C++ 2017-12-26 신희민
  • 2. Chapter 01 : 에러 핸들링 윈도우 함수가 실패함 : 내부적으로 함수를 호출한 스레드의 스레드 지역 저장소에 적절한 에러 코드를 저장해 준다. -> 이렇한 메커니즘을 통해 여러 개의 스레드가 동시에 수행될 경우라도 상호간에 영향을 미치지 않고 각 스레드별로 에러 코드를 유지할 수 있게 된다. DWORD GetLastError(); : 이 함수는 단순히 가장 최근에 호출된 함수의 에러 코드를 스레드 지역 저장소로부터 가져옴. Visual Studio의 기능을 이용하여 조회 가능 도구 -> 오류조회
  • 3. Chapter 02 : 문자와 문자열로 작업하기 Buffer overrun(버퍼 오버런) : 애플리케이션과 운영체제의 보안 취약점을 공격하는 주요 방법 C 런타임 라이브러리의 함수를 사용하면 문자열을 다룰 때 발생할 수 있는 버퍼 오버런을 미연에 방지
  • 4. Chapter 02 : 문자와 문자열로 작업하기 StrSafe.h 헤더 파일을 포함하면 String.h 헤더 파일도 같이 포함된다. : StrSafe.h에 대한 include 구문은 다른 include 구문보다 반드시 뒤쪽에 위치되어야 한다. _tcscpy나 _tcscat 같은 기존 함수에는 동일한 이름에 _S가 붙은 안전 문자열 함수가 제공된다. PTSTR _tcscpy(PTSTR strDestination, PCTSTR strSource); Errno_t _tcscpy_s(PTSTR strDestination, size_t numberOfcharacters, PCTSTR strSource); PTSTR _tcscat(PTSTR strDestination, PCTSTR strSource); Errno_t _tcscat_s(PTSTR strDestination, size_t numberOfcharacters, PCTSTR strSource); Size_t numberOfcharacter는 _countof 매크로를 사용하면 쉽게 계산가능 안전 문자열을 사용하는것을 권고한다.
  • 5. Chapter 02 : 문자와 문자열로 작업하기 안전(_s로 끝나는) 문자열 함수는 내부적으로 가장 먼저 인자의 유효성을 검증 : 인자 값이 NULL인지, 정수 값이 유효한 범위 내에 있는지, 열거형 값이 유효한지 버퍼는 결과를 저장할 만큼 충분한지 등을 테스트 만일 테스트가 실패하면 errno에 에러 코드를 설정하고, 성공 실패 여부를 나타내는 errno_t형 값을 반환 에러의 원인을 출력
  • 6. Chapter 02 : 문자와 문자열로 작업하기 Strcpy_s를 사용할 시 : 복사하려는 버퍼보다 복사되는 버퍼의 길이가 더 짧을 경우 에러메시지가 뜨며 실패 StringCchcopy를 사용 할 시 : 복사하려는 버퍼보다 복사되는 버퍼의 길이가 더 짧을 경우엔 잘림 현상이 발생
  • 7. Chapter 03 : 커널 오브젝트 숙달된 윈도우 소프트웨어 개발자가 되기 위해서는 반드시 커널 오브젝트에 대해 완벽하게 이해!
  • 8. Chapter 03 : 커널 오브젝트 운영체제나 우리가 개발하는 애플리케이션은 프로세스, 스레드, 파일 등과 같은 수많은 리소스를 관리하기 위해 커널 오브젝트를 사용한다. 그렇다면 커널 오브젝트란?
  • 9. Chapter 03 : 커널 오브젝트 커널 오브젝트 : Windows 운영체제에서 리소스들을 관리하기 위한 데이터를 저장하는 메모리 블록 엑세스 토큰 오브젝트, 이벤트 오브젝트, 파일 오브젝트, 파일-매핑 오브젝트, I/O 콤플리션 포트 오브젝트, 잡 오브젝트, 메일슬롯 오브젝트, 뮤텍스 오브젝트, 파이프 오브젝트… 이런 것들…
  • 10. Chapter 03 : 커널 오브젝트 커널 오브젝트의 데이터 구조체는 커널에 의해서만 접근이 가능하기 때문에 애플리케이션에서 데이터 구조체가 저장되어 있는 메모리 위치를 직접 접근하여 그 내용을 변경하는 것은 불가능한다. : 구조체에 대한 직접적인 접근을 제한함으로써 마이크로소프트는 이미 개발되어 있는 애플리케이션에 영향을 미치지 않고도 구조체에 내용을 임의로 추가, 삭제, 변경할 수 있다. 마이크로소프트는 정제된 방법을 통해 구조체에 내용에 접근할 수 있도록 일련의 함수 집합을 제공 -> 커널 오브젝트의 내부적인 값에 접근 할 수 있다. 커널 오브젝트를 생성하는 함수를 호출하면 함수는 각 커널 오브젝트를 구분하기 위한 핸들 값을 반환
  • 11. Chapter 03 : 커널 오브젝트 운영체제를 견고하게 하기 위해 이러한 핸들 값들은 프로세스별로 독립적으로 유지된다. -> 만일 어떤 스레드가 다른 프로세스의 스레드에게 자신의 핸들 값을 전달했을 경우 이 핸들 값을 이용하여 수행하는 동작은 실패할 수도 있고 혹은 더 좋지 않은 결과를 초래 -> 각 프로세스 별로 독립된 프로세스 핸들 테이블이 존재하고 동일한 핸들값이라도 전혀 다른 커널 오브젝트를 참조 할 수 있기 때문이다.
  • 12. Chapter 03 : 커널 오브젝트 1. 사용 카운트 커널 오브젝트는 프로세스가 아니라 커널에 의해 소유된다. 프로세스가 특정 함수를 통해 커널 오브젝트를 생성한 후 종료된다 하더라도 반드시 생성된 커널 오브젝트가 프로세스와 함께 삭제 되는 것은 아니다. 커널 오브젝트는 자신을 생성한 프로세스 보다 더 오랫동안 삭제되지 않고 남아 있을 수 있다. 각 커널 오브젝트는 내부적으로 사용 카운트 값을 유지하고 있기 때문에 커널은 이 값을 통해 얼마나 많은 프로세스들이 커널 오브젝트를 사용하고 있는지 알 수 있다. 다른 프로세스가 이미 생성된 커널 오브젝트에 접근 권한을 획득하면 사용 카운트가 증가 프로세스가 종료되면 커널은 이 프로세스가 사용하고 있던 커널 오브젝트의 사용 카운트를 감소 시킴 -> 이 값이 0이 되면 커널 오브젝트는 삭제된다.
  • 13. Chapter 03 : 커널 오브젝트 1. 보안 커널 오브젝트는 보안 디스크립터를 통해 보호될 수 있다. IpSecurityDescriptor멤버만이 보안과 관련되어 있다. 오브젝트 생성시 커널 오브젝트의 접근 권한을 제한하고자 한다면 보안 디스크립터를 생성 후 초기화
  • 14. Chapter 03 : 커널 오브젝트 Section 02 : 프로세스의 커널 오브젝트 핸들 테이블 프로세스가 초기화 되면 커널 오브젝트 핸들 테이블 할당 프로세스 별로 핸들이 독립적으로 유지 핸들 테이블은 사용자 오브젝트나 GDI 오브젝트에 의해서는 사용되지 않고 유일하게 커널 오브젝트에서 사용 : 프로세스 핸들 테이블은 커널 오브젝트에 대한 포인터, 액세스 마스크, 플래그로 구성
  • 15. Chapter 03 : 커널 오브젝트 Section 02 : 프로세스의 커널 오브젝트 핸들 테이블 커널 오브젝트 생성 프로세스가 최초로 초기화되면 프로세스의 핸들 테이블은 비어있다. 프로세스 내의 스레드가 CreateFileMapping과 같은 함수를 호출하면 커널은 커널 오브젝트를 위한 메모리 블록을 할당하고 초기화 커널은 프로세스의 핸들 테이블을 조사하여 비어 있는 공간을 찾아낸다. 앞에 보이는 표핸들 테이블은 완전히 비어 있기 때문에 커널은 인덱스가 1인 위치를 찾아내어 초기화
  • 16. Chapter 03 : 커널 오브젝트 Section 02 : 프로세스의 커널 오브젝트 핸들 테이블 커널 오브젝트를 생성하는 모든 함수는 프로세스 별로 고유한 핸들 값을 반환하며, 이 값은 프로세스내의 모든 스레드에 의해 사용될 수 있다. Create함수로 반환되는 핸들값을 4로 나누거나 오른쪽으로 2비트 시프트하면 커널 오브젝트에 대한 정보를 저장하고 있는 프로세스 핸들 테이블의 인덱스 값을 얻는다. 커널 오브젝트 핸들을 인자로 취하는 함수를 호출할 때에는 항상 Create* 류의 함수 중 하나를 호출하여 반환된 핸들 값을 전달 만일 유효하지 않은 핸들 값을 전달하게 되면 이러한 함수들은 실패하고 GetLastError 호출 결과를 반환 핸들 값은 실제로 프로세스 핸들 테이블의 인덱스 값으로 활용 될 수 있기 때문에 프로세스 별로 고유한 값 다른 프로세스에 의해 사용될 수 없는 값 이유 : 다른 프로세스와 공유를 시도하면 다른 프로세스의 프로세스 핸들 테이블로부터 동일한 인덱스 값을 가진 완전히 다른 커널 오브젝트를참조하게 될 것
  • 17. Chapter 03 : 커널 오브젝트 Section 02 : 프로세스의 커널 오브젝트 핸들 테이블 커널 오브젝트를 생성하는 함수가 실패하면 반환되는 핸들 값은 보통 0(NULL) 시스템의 가용 메모리가 매우 작거나 보안 문제로 인해 함수가 실패하는 경우 몇몇 함수들은 -1(INVALID_HANDLE_VALUE)를 반환 CraeteFile 함수의 경우 주어진 파일을 여는데 실패하면 NULL 대신 INVALID_HANDLE_VALUE 반환 커널 오브젝트를 생성하는 함수의 반환 값을 확인할 때에는 상당한 주의가 필요하다.
  • 18. Chapter 03 : 커널 오브젝트 Section 02 : 프로세스의 커널 오브젝트 핸들 테이블 커널 오브젝트 삭제 커널 오브젝트를 어떻게 생성했는지와 상관없이 CloseHandle 함수를 호출하여 더 이상 커널 오브젝트를 사용하지 않을 것임을 시스템에게 알려줌 BOOL CloseHandle(HANDLE hobject); // 구조체 내의 사용 카운트 멤버를 감소시킨다. // 만일 0이 되면 커널 오브젝트를 파괴하고 메모리부터 제거 CLoseHandle()을 사용하여 사용 카운트 -1 사용 카운트가 0이면 삭제
  • 19. Chapter 03 : 커널 오브젝트 Section 03 : 프로세스간 커널 오브젝트의 공유 서로 다른 프로세스에서 각기 수행되는 스레드들 간에 동일 커널 오브젝트를 공유해야 하는 경우 Ex) 파일-매핑 오브젝트는 단일 머신에서 수행되는 두 프로세스 사이에서 데이터의 블록을 공유 메일슬롯과 명명파이프를 이용하면 네트워크로 연결된 서로 다른 머신 사이에서 데이터를 주고받음 해결방안 1. 오브젝트 핸들의 상속 이용 2. 명명된 오브젝트 사용 3. 오브젝트 핸들의 복사 이용
  • 20. Chapter 03 : 커널 오브젝트 Section 03 : 프로세스간 커널 오브젝트의 공유 1. 오브젝트 핸들의 상속을 이용하는 방법 오브젝트 핸들의 상속은 오브젝트를 공유하고자 하는 프로세스들이 parent-child 관계여야 한다. 인덱스 포인터 엑세스마스 크 플래그 1 0xF0000000 0x???????? 0x00000000 2 0x00000000 (N/A) (N/A) 3 0xF0000010 0x???????? 0x00000001 bInheritHandle 멤버 FALSE bInheritHandle 멤버 TRUE
  • 21. Chapter 03 : 커널 오브젝트 Section 03 : 프로세스간 커널 오브젝트의 공유 1. 오브젝트 핸들의 상속을 이용하는 방법 bInhertHandles 매개변수로 TRUE를 전달하면 child process는 parent process의 상속가능한 핸들 값들을 상 속하게 된다. 매개변수에 TRUE를 전달하여 CreateProcess함수를 호출하여 child process 생성 (어느 프로세스의 생성 절차와 마찬가지로 child process를 생성하는 과정에서 프로세스 핸들 테이블 생성) 추가 적인 한가지 작업을 수행한다. : Parent process의 핸들 테이블을 조사하여 상속 가능한 핸들을 찾아내는 일 시스템은 찾아낸 항목들을 child process의 핸들 테이블에 복사. Child process 핸들 테이블 내의 복사 위치는 parent process의 핸들 테이블에서의 위치와 정확히 일치 -> 특정 커널 오브젝트를 구분하는 핸들 값이 페어런트 프로세스와 차일드 프로세스에 걸쳐 동일한 값 이용 운영체제는 핸들 테이블의 항목을 복사하는 작업과 병행하여 커널 오브젝트 내의 사용 카운트를 증가
  • 22. Chapter 03 : 커널 오브젝트 Section 03 : 프로세스간 커널 오브젝트의 공유 1. 오브젝트 핸들의 상속을 이용하는 방법 Parent process와 child process간에만 가능하다. 오브젝트 핸들 상속은 child process를 새로 생성할 때에만 적용이 가능한다. -> 만약 부모 프로세스가 상속이 가능한도록 새로운 커널 오브젝트를 생성한다 하더라도, 이미 수행되고 있었던 child process가 새로운 핸들을 상속받지 못한다. Child process는 어떤 핸들이 상속되어있는지를 모르기때문에 알려줘야만 쓸 수 있다. -> child process 수행 시 명령행 인자를 이용하여 커널 오브젝트의 핸들 값 전달 -> 프로세스간 통신 방법을 이용하여 parent proces가 child proces에게 커널 오브젝트의 핸들 전달 -> parent process가 환경변수 블록에 상속할 커널 오브젝트에 대한 핸들값을 가지고있는 새로운 환경변수를 추가 하는 것
  • 23. Chapter 03 : 커널 오브젝트 Section 03 : 프로세스간 커널 오브젝트의 공유 2. 명명된 오브젝트 사용 이름을 이용하여 커널 오브젝트를 공유하려면 당연히 커널 오브젝트에 이름을 지정해야 한다. 에러 발생 (ERROR_INVALID_HANDLE) B프로세스가 CreateMutex에 성공한다 하더라도 실제로는 새로운 뮤텍스가 생성되는 것이 아닌 기존의 뮤텍스 오브젝트에 접근할 수 있는 B 프로세스 고유의 핸들 값이 생성
  • 24. Chapter 03 : 커널 오브젝트 Section 03 : 프로세스간 커널 오브젝트의 공유 3. 오브젝트 핸들 복사 프로세스 간에 커널 오브젝트를 공유하는 마지막 방법은 DuplicateHandle 함수를 사용하는 것 : DuplicateHandle 함수는 특정 프로세스 핸들 테이블 내의 항목을 다른 프로세스 핸들 테이블로 복사 첫 번째와 세 번째 매개변수인 hSourceProcessHandle과 hTargetProcessHandle에 프로세스 커널 오브젝트의 핸들. 두번째 매개변수인 hSourceHandle로는 어떤 타입의 커널 오브젝트라도 전달 phTargetHandle로는 HANDLE 변수의 주소값을 전달 5,6번째 매개변수는 액세스 마스크와 상속 플래그 지정 마지막 매개변수는 DUPLICATE_SAME_ACCESS와 DUPLICATE_CLOSE_SOURCE DUPLICATE_SAME_ACCESS는 소스 프로세스의 핸들과 동일한 액세스 마스크 DUPLICATE_CLOSE_SOURCE는 소스 프로세스의 핸들을 삭제
  • 25. Chapter 03 : 커널 오브젝트 Section 03 : 프로세스간 커널 오브젝트의 공유 3. 오브젝트 핸들 복사 인덱스 포인터 액세스 마스크 플래그 1 0x00000000 (N/A) (N/A) 2 0xF0000020 0x???????? 0x00000000 인덱스 포인터 액세스 마스크 플래그 1 0x00000000 (N/A) (N/A) 2 0xF0000030 0x???????? 0x00000000 인덱스 포인터 액세스 마스크 플래그 1 0xF0000020 0x???????? 0x00000001 2 0xF0000030 0x???????? 0x????????? DuplicateHandle(1, 2, 2, &hobj, 0, TRUE, DUPLICATE_SAME_ACCESS S프로세스 C프로세스 C프로세스가 S 프로세스 핸들 을 받음