Skip to content

Instantly share code, notes, and snippets.

@clucle
Created August 4, 2018 09:00
Show Gist options
  • Save clucle/6457a39989f6542ae1419dcaf296fcc8 to your computer and use it in GitHub Desktop.
Save clucle/6457a39989f6542ae1419dcaf296fcc8 to your computer and use it in GitHub Desktop.
C++ Korea 제4회 세미나 정리

처음 만나는 Modern C++의 세계

windows subsystem for linux

윈도우 환경에서 linux로 test docker, cuda 는 잘 안된다. linux 용 windows 하위 시스템 (windows 기능) windows 국가또는 지역, 지역설정에서 utf-8 charset 설정 가능 (보안프로그램이 동작이 잘 안할 수 있다.) Linux (export LC_ALL, LANG = ko_KR.UTF-8) curl은 대부분의 protocol을 지원한다.

modern c++

boost 에 영향을 많이 받음

  1. singleton : 환경설정, logger들을 singleton으로 사용.
  2. ptree : 읽을 파일과 ptree만 입력 (json, ini 등) c++17 에서 structured binindg const auto& [data, type] 이런식으로 받아짐
  3. cmd line argument : programoptions - variable map(얼마나 올지 모르니까)
  4. log : spdlog header file 몇개로 돌아간다. spdlog fmt 를 사용해서 formatting (printf는 buffer overflow가 나서 죽을 수 있음) boost의 format은 에러가나면 죽는다.
  5. curlite : 프로토콜 쉽게 사용. 301 code를 받으면 follow location을 처리해야한다 CURLOPT_FOLLOWLOCATION
  6. file system : 11 - boost / 14 - experimental / 17 - standard (os 다같이)
  7. thread : parallel for

복셀 기반 네트워크 게임 최적화 기법

  1. 충돌처리 복셀 오브젝트를 최적화된 삼각형으로 바꿈 최적화된 매시로 변환 랜더링 시에는 문제가 되지만 충돌처리에는 문제가 없음. 평면방정식으로 그룹화 멀티스레드로 충돌처리. kd-tree 코드 (서버에서 유용) 오브젝트별로 속도벡터로 봤을 때 충돌을 할 것 같은 복셀을 thread에 넣어줌

  2. rendering culling // 지형지물이 실시간으로 바껴서 못씀. bsp/pvs bsp / room/ portal

occlusion culling sw occlusion culling hw occlusion culling with d3d query // (voxel은 오브젝트가 너무많아서 안됨) hierarchical occlusion culling with copute shader

KD-Tree x, y, z 의 bst tree

  1. network 전체 월드를 특정 간격으로 자른 그리드 패킷전송의 지역적 구분 단위가 된다. 플레이어나 npc가 움직일 때 sector table이 변함 boxel게임에서는 플레이어마다 sector table을 가진다 맵을 패킷상에서 조금씩 받아야 한다. (위치 주변 얼마) 서버 입장에서는 플레이어한테는 얼마를 줘야 하는지 모름. 플레이어가 어느섹터에 방문했는지 저장을 해둠. 안보이는 곳에서 복셀을 뽀갰으면 그것을 받아야 하나 말아야 하나. 방문한 곳이 부셔지면 (안보여도) 정보를 받아서 클라이언트에서 정보만 바꿈 안 방문한 곳이라면 그냥 폐기

  2. 패킷 줄이기 복셀 데이터 압축 (패턴으로 표현)

  3. 결론 메모리 줄이자! 속도 빠르게!

Optimize C++

최적화가 무엇인지 이해하고 어떻게 접근하는지 이해해보자

1. 최적화란?

일반적 접근방식 Profile 접근 - 필요할 때 (성능이 문제가 된다), 필요한 만큼 (최적화 목표를 설정), 필요한 위치 (병목 구간), 때로는 눈속임 ?(체감이 중요)

2. Visual studio Profiler

디버그 - 성능 프로파일러

3. 최적화에 관계된 것들

  1. 프로세서
  • Multi Core
  • Insturction Pipe-line
  • Simultaneous Multithreading
  • SIMD 명령어 하나가 여러개의 데이터를 처리해준다.
  • GPGPU

compile option이 어떤 것을 하는지 알 수 있다. Thread, Lambda

  1. 저장장치
  • Cache
  • Memory Bus
  • File System

STL, Constructor/destructor

  1. OS
  • Virtual Memory
  • Word Alignment
  • ALlocation
  • Memory Copy
  1. exception 알고리즘, 프로그래머

4. Optimize C++

  1. Memoization & Lazy evaluation
  2. STL vector pointer로 값 변경 (인덱스 접근 x)
  3. Dynamic binding, Dynamic casting Loop 안에 넣지 말것

외계인만 아는 C++ 타입 파생 규칙

char (*Func(int (&)[3]))[3]; ?????

int arr[3]; ARRAYSIZE(arr) : 어떻게 만들어야 할까? 사람 Version.

#define ARRAYSIZE sizeof(A) / sizeof((A)[0])

int* arr = new int[3]; ARRAYSIZE(arr) 64bit : 2 32bit : 1 64bit에서 (포인터의 크기가 8, 요소는 4)

외계인 Version.

template <typenmae T, size_t N> char (*RtlpNumberof(T (&)[N]))[N];
#define ARRAYSIZE(A) (sizeof(*RtlpNumberOf(A)))

문법을 제대로 배운적이 없다. Right-Left Rule 외계인의 가르침

독해는 했지만 원하는 타입은 어떻게 파생할까? 타입 파생 규칙의 기본을 알아보자

  1. 이름 자리[NP] 각 Type마다 식별자가 놓이는 자리는 고정되어있다. 기본타입(char, int 등)의 이름자리는 type 의 바로 오른쪽에 있다. 이름자리에 식별자를 넣으면 객체를 정의할 수 있다.

1.1 배열 타입 파생 1 배열 요소의 타입에서 시작. 배열 요소의 수가 n일 때 n 을 [NP]옆에 붙인다. [NP]를 생락하면 최종 타입

int[NP] -> int[NP][3] -> int [3]
  • 중요 이름자리 [NP]는 변하지 않는다.

1.2 배열 타입 파생 2 int요소 3개인 배열이 요소로서 2개인 배열

int[NP] -> int [NP][3] -> int[NP][2][3] -> int [2][3]

2.1 포인터 타입 파생 1 포인터의 대상(가리키는)타입에서 시작. 간접연산자 (*)를 [NP]바로 왼쪽에 붙인다. 필요한 경우 [NP]와 결합 우선 순위를 높이기 위해 괄호로 묶는데 [NP]의 결합 우선순위 오른쪽 심볼 > 왼쪽 심볼 int요소 3개인 배열을 가리키는 포인터

int [NP] -> int [NP][3] -> int (*[NP])[3] -> int (*)[3]

2.2 포인터 타입 파생 2 배열명은 첫번째 배열 요소를 가리키는 상수 포인터

int* p1 = &arr;
int (*p3)[3] = &arr; 

3.1 함수 타입 파생 1 함수의 반환 타입에서 시작한다. 인자열을 [NP] 바로 뒤에 붙인다 int 요소 3개인 배열을 가리키는 포인터를 반환하는 함수 (단, 함수 인자열은 (char))

여기까지가 c, 아래부터 c++

4.1 클래스 맴버를 가리키는 포인터 타입 파생 일반적으로 포인터란 메모리의 특저 영역을 가리키는 것이지만, 클래스 맴버를 가리키는 포인터는 비정적 맴버 그 자체를 가리킨다.

class CTest
{
public:
    int m_Member; // 비정적 멤버
    static int s_Member; // 정적 멤버
}
int CTest::s_Member

void main() {
    CTest t;
    &t.m_Member; //메모리영역
    &CTest::s_Member; // 메모리영역
    &CTest::m_Member; // m_Member 그자체 offset  
}

4.2 클래스 맴버의 타입에서 시작한다. 클래스 범위 연산자(CLASS::)를 [NP] 바로 왼쪽에 붙인다 간접 연산자를 바로 왼쪽에 붙인다 필요한 경우 CLSS::*와 괄호로 묶는다. 생략하면 최종 타입을 얻는다 Class의 맴버인 int 요소 2개인 배열을 가리키는 포인터

int [NP] -> int [NP][2] -> int Class::[NP][2] -> int (Class::*[NP])[2]

왜 Class까지 묶었는가 -> Class:: 옆에는 [ 를 허용하지 않는다.


객채 정의 남아있던 [NP]를 객체 이름으로 바꾸고 ;를 붙여주면 정의가된다

typedef를 이용한 타입 정의 이름자리를 새로운 이름으로 변경하고 typedef 를 붙이면 기본타입으로 사용 할 수 있다.

c++ metaprogramming 활용하여 난독화 library 구현하기

디컴파일시 원본과 유사한 코드

취약을 줄여나가며 지속적인 개선 가능한 형태로 만들어야함. 분석을 어렵게 하여 공격 시도를 줄여야함.

Solution 중 하나가 난독화.

  1. source code obfuscator 컴파일 전, 소스코드를 난독화. source language에 의존
  2. binary code obfuscator 컴파일 이후, 바이너리 코드를 난독화, target machine에 의존

이중 source code obfuscator를 알아보자

  • Direct source code obfuscation 수작업
  • Pre-processing obfuscator 컴파일전 전처리 난독화
  • Abstract syntax tree or Intermeiate representation obfuscator
  • Bytecode obfuscator

Pre-porecessing 을 알아보자 어떻게 구현할것인가? semantic은 유지하면서 코드를 변경하는 일 (Macro는 가능할 수 도있지만 좋지 않다)

c++ 의 template metaprogramming을 이용해보자 Metaprogramming is writing porgrams that generate or manipulate code Template // enable generic programming, provide type safely Template를 활용하여 컴파일 타임에 동작하는 프로그램을 만드는 프로그래밍

  • 예제는 나중에 자료로 보자 Factorial // binary에는 전체가 계산된 값이 들어간다. Loop unrolling // loop를 풀어서 직접 쓴다 장점 : 컴파일 시간이 늘어난다, 실행시간이 빨라진다, generic programming 단점 : 가독성이떨어짐, 디버깅어려움, 컴파일 에러시 원인찾기 어려움.

난독화 라이브러리 구현하기

문자열 난독화, 제어흐름 난독화 ADVobfuscator

string obfuscation - 문자열을 알아보기 힘든 방식으로 바꾸는 것 주요한 url, function, class, error, log, string, etc... 문자열의 글자마다 encrypt key

control flow obfuscation 아무것도 하지 않는 코드 삽입, 코드를 여기저기 복사하고 옮김, 인코딩 Final state Machine을 이용. 중간 어딘가에서 보호하고 싶은 함수를 실행. Boost 의 Meta state machine을 사용하셔서 만들었다구 한다. (다른 state machine library사용 가능) unroller에서 얼마 이상, 얼마 미만 값의 필요없는 state를 돌다가 실행 (for로 하면 보임) OBFUSCATED_CALL_RET 으로 함수 호출, 함수 주소도 보일 수 있으면 랜덤하게 보냈다가 다시 돌려서 실행

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment