--1. 블러킹 정보 확인
SELECT * FROM SYS.sysprocesses WHERE blocked > 0

SP_WHO
SP_WHO2

--2. lock 세부 정보
sp_lock

select *
from sys.dm_tran_locks


--3. 실행쿼리 확인
DBCC INPUTBUFFER(58)


--4.KILL

KILL 58


/*
BEGIN

IF OBJECT_ID('UNILITE.LOCK_TEST') IS NOT NULL
DROP TABLE UNILITE.LOCK_TEST

CREATE TABLE UNILITE.LOCK_TEST
(
ID INT ,
ITEM VARCHAR(20),
QTY INT
)


BEGIN TRAN


INSERT INTO LOCK_TEST (ID, ITEM, QTY)
VALUES(1, 'APPLE',20)
--ROLLBACK
--COMMIT

END


BEGIN

SELECT *
FROM LOCK_TEST

END


아쉽게도 VisualStudio2012버전 부터는 Macro IDE기능을 사용할 수 없게 됐다.

개인적으로 Doxygen용 자동주석 매크로기능을 위해 활용하고 있었는데

VS2012부터 보이지 않아 어디에 숨겼는지 한참을 찾았다.

결국 구글링을 해보니 MS에서 의도적으로 뺀거라고 한다. 전체 VS유저중 사용률이 1%미만 이라나.

Macro외에도 tool 전체의 Performance향상을 위해 몇몇 IDE기능을 줄였다고 한다.

http://social.msdn.microsoft.com/Forums/vstudio/en-US/d8410838-085b-4647-8c42-e31b669c9f11/macros-in-visual-studio-11-developer-preview

 

암튼 자동 주석같은 매크로 기능은 플러그인 프로젝트를 통해 계속 이용할 수 있다. :)

 

1. Visual Studio 추가기능 프로젝트 생성

적당한 이름으로 생성해 준다.

2. 확장 기능을 개발할 언어를 선택해준다. (난 C# 으로)

3. 메뉴에 확장기능 항목이 추가되도록 한다. (우리가 만든 확장기능은 도구 메뉴에서 확인가능하다.)

이후에는 계속 다음을 눌러 프로젝트가 생성되도록 한다.

 

4. Connect.cs파일에서 Exec함수를 찾고 아래 내용을 추가한다.

Exec라는 함수이름 대로 우리가 개발한 확장기능을 나중에 VS에서 사용할때 호출되는 함수다. (사진 클릭해서 원본으로 보기)

 

5. 컴파일이 성공하면 종료 후 다시 실행한다.

적당한 프로젝트 하나를 연 후 소스코드의 적당한 위치에 커서를 위치 시키고 "도구" 메뉴에 우리가 추가한 플러그인을 실행한다.

Doxygen 주석이 추가된걸 확인할 수 있다.

 

6. 매번 메뉴를 클릭하는건 귀찮으니 우리가 개발한 확장기능에 단축키를 할당할 수 도 있다.

도구 - 옵션 - 키보드 선택 후 comment(프로젝트 이름)로 검색하면 개발한 확장기능이 검색된다.

선택 후 "바로 가기 키 누르기"에서 적당한 단측키를 할당해준다.(Ctrl + `은 개인적으로 사용하지 않는 키라서 이걸로 정했음)

확인을 누르고 닫은 후 앞으로는 메뉴 대신 위에서 할당한 단축키를 사용하면 된다.

 

7. 확장기능 배포

내가 만든 확장기능은 dll형태로 일반 프로젝트와 동일하게 프로젝트 폴더(Debug나 Release)에 생성된다.

VS에 설치되는 폴더는 C:\Users\jung\Documents\Visual Studio 2012\Addins 이며 FunctionComment - For Testing.AddIn

이라는 파일명으로 위자드가 자동 생성해준 것을 볼수 있다.

파일을 메모장으로 열어보면 <Assembly> 항목에 우리가 만든 dll위치가 들어가 있는것을 볼수 있는데

원하는 위치에 dll을 설치하고 이 경로만 바꿔주면 된다.

 

 

 

 추가한 소스

public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
  {
   handled = false;
   if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
   {
    if(commandName == "Doxgen2012.Connect.Doxgen2012")
    {
                    EnvDTE.TextSelection textSelection = (EnvDTE.TextSelection)_applicationObject.ActiveWindow.Selection;
                    textSelection.Insert("//-----------------------------------------------------------------------------------//");
                    textSelection.NewLine();
                    textSelection.Insert("//");
                    textSelection.NewLine();
                    textSelection.Insert("// @brief     :  ");
                    textSelection.NewLine();
                    textSelection.Insert("// @param     :  ");
                    textSelection.NewLine();
                    textSelection.Insert("// @return    :  ");
                    textSelection.NewLine();
                    textSelection.Insert("// @author    :  ");
                    textSelection.Insert(System.Environment.UserName);
                    textSelection.NewLine();
                    textSelection.Insert("// @date      :  ");
                    textSelection.Insert(System.DateTime.Now.ToLongDateString());
                    textSelection.Insert("  ");
                    textSelection.Insert(System.DateTime.Now.ToLongTimeString());
                    textSelection.NewLine();
                    textSelection.Insert("//");
                    textSelection.NewLine();
                    textSelection.Insert("//-----------------------------------------------------------------------------------//");

     handled = true;
     return;
    }
   }
  }
  private DTE2 _applicationObject;
  private AddIn _addInInstance;
 } 

 

 

 

 참고 : http://www.dzone.com/articles/missing-macros-visual-studio

 

출처 : http://www.2cpu.co.kr/bbs/board.php?bo_table=nas&wr_id=334


Synology NAS의 Video Station을 설치하고, PC나 폰의 DS Video로 영상을 감상하면 Frame Rate가 낮아 정상적으로 영상을 보기가 어렵습니다. 그저 스트리밍이 가능하다는것에 의의를 두는 그런 느낌이였죠. 이제 이걸 AirVideo 부럽지 않은 동영상 스트리밍 환경을 구축하여 봅시다.

제가 전에 동영상 스트리밍을 이용하던 환경은 이렇습니다.
1) Synology NAS + WebDAV
2) iPad + nPlayer($2.99) + Wibro, Tethering
3) Android + Dice Player + 3G or LTE

1번에서 동영상 파일에 접근을 위해  WebDAV를 사용합니다. WebDAV를 사용하면 80(HTTP), 443(HTTPS)포트를 이용하기 때문에 거의 모든곳에서 접속할 수 있습니다. 해당 환경을 만든 다음, WebDAV를 지원하는 iPad(iPhone)의 nPlayer 앱이나 Android의 DicePlayer 앱을 사용하여 구축해놓은 Synology NAS에 접속하여 정상적으로 영상을 즐깁니다.

위와 같이 사용하면 다음과 같은 문제점이 발생합니다. 
1) nPlayer의 DTS 라이센스 관련 업데이트로 인해 DTS 코덱이 들어간 영상은 소리가 나오지 않습니다. (AV Player 등 타 플레이어도 마찬가지)
2) 모바일 환경(3G, Wibro, LTE)에서 대역폭 이상의 높은 비트레이트의 파일을 재생할 경우 끊김이 발생할 확률이 높습니다. 통신망 환경이 좋지 못하면 더더욱 그렇습니다.

따라서, 두가지의 문제를 해결하려면 트랜스코딩(실시간 인코딩)이 가능해야 합니다. 첫번째 해결책은 iOS의 AirVideo 앱을 이용하는 것이고, 두번째 해결책은 Video Station을 이용하는 방법이 있습니다. iOS의 AirVideo를 써 본 결과, 컨테이터에 따라 자막까지 알아보기 힘든 화질 저하가 발생하는 영상들이 있었기에 해당 앱으로는 일찌감치 포기하였습니다. 안드로이드의 경우 Qloud Media가 있는것 같은데 써보지는 않았고요. 때문에, 마지막 카드인 Video Station에 집중하여 봤습니다.

Synology NAS에 들어간 Video Station은 트랜스코딩도 지원할 뿐더러, 방대한 양의 DB를 통해서 라이브러리를 정리해 주기도 합니다. 정말 좋은 App이죠. 다 좋은데 이놈의 문제점은 트랜스코딩 과정을 거치면서 Frame Rate가 반토막나서 영상을 집중하여 보기가 힘듭니다. 고민을 좀 하다가, 시놀로지 홈페이지에 패키지 파일이 올라온것을 캐치하여 한번 뜯어보았습니다. tar로 압축이 되어있었기 때문에, 의외로 쉽게 찾아 낼 수 있었습니다. 

이 과정에서 제가 목표했던것은 다음과 같습니다.
1) Frame Rate가 24프레임 이상 지원 되어야 할 것
2) 자막은 필수
3) 모바일 환경에서 통신망 환경에 따라 비트레이트 변경을 통해 끊김없는 감상이 가능해야 할 것.



자, 그럼 시작합니다.

1) Frame Rate가 24프레임 이상 지원 되어야 할 것
먼저, 패키지 관리자에서 Video Station을 설치하여 줍니다. (이미 설치되어있다면 패스) 
그 다음 시놀로지 관리패널 > 제어판 > 터미널로 들어가 SSH 서비스 활성화에 체크하여 줍니다. 

다음으로, 쉘을 이용해 root 계정으로 시놀로지에 접속합니다. 비밀번호는 관리패널의 admin 계정과 같습니다. 윈도우 사용자는 putty를 이용하세요.
MacBook-Pro:~ Ryun$ ssh root@192.168.0.100

그다음 VideoStation이 설치된 디렉토리로 접근합니다. 여기서 저의 경우 VideoStation이 volume1(볼륨1)에 설치되어있기 때문에 경로는  /volume1/@appstore/VideoStation/etc 로 나타납니다.
RyunBox> cd /volume1/@appstore/VideoStation/etc

그 다음 뭐가있는지 확인해보면, 
RyunBox> ls -l

drwxr-xr-x    2 root     root          4096 May  1 03:20 HDHomeRun_channelmap
drwxr-xr-x    2 root     root          4096 May  1 03:20 KernelFirmwares
drwxr-xr-x    2 root     root         20480 May  1 03:22 KernelModules
-rw-r--r--    1 root     root           189 Apr 12 16:18 SYNO.SDS.VideoStation.Application.legacy.conf
-rw-r--r--    1 root     root         37580 Apr 12 16:18 TransInfo_HLS
-rw-r--r--    1 root     root         41468 Apr 12 16:18 TransInfo_SS
-rw-r--r--    1 root     root          5034 May  1 04:17 TransProfile
-rw-r--r--    1 root     root            95 Apr 12 16:18 country
-rw-r--r--    1 root     root            31 Apr 12 16:18 default.conf
drwxr-xr-x    2 root     root          4096 May  1 03:20 index
-rw-r--r--    1 root     root           571 Apr 12 16:18 model
-rw-r--r--    1 root     root           740 Apr 12 16:18 modelmap
-rw-r--r--    1 root     root           865 Apr 12 16:18 plugin.conf
drwxr-xr-x   38 root     root          4096 May  1 03:20 synodvb_t
-rw-r--r--    1 root     root           262 Apr 12 16:18 videostation_port

여기서 트랜스코딩에 관여하는 설정이 들어간 파일은 3가지 정도 됩니다.  (모두 JSON String으로 되어있음)
-rw-r--r--    1 root     root         37580 Apr 12 16:18 TransInfo_HLS
-rw-r--r--    1 root     root         41468 Apr 12 16:18 TransInfo_SS
-rw-r--r--    1 root     root          5034 May  1 04:17 TransProfile

TransInfo_HLS와 TransInfo_SS는 원본파일의 컨테이너를 분류하기 위한 JSON String이 들어가있고, TransProfile은 그렇게 컨테이너별로 분류된 것에 따라 실제 ffmpeg에 넣어주는 Parameter에 대한 정보가 JSON String으로 들어있습니다. 분류는 VideoStation이 알아서 해 줄 것이므로, 따라서 우리는 TransProfile 파일만 고쳐주면 됩니다 :) 
(분류를 따로 해주고 싶으시다면 TransProfile을 참고하여 TransInfo_HLS TransInfo_HLS의 String을 변경해주시면 됩니다.)

그럼 vi에디터로 TransProfile 파일을 열어봅시다.
RyunBox> vi TransProfile
{
"mpegts_cga_x264_vb200_vr_aac_ab40": "-threads 0 -vcodec libx264 -vsync 2 -vprofile baseline -level 30 -s cga -b 200k -r 15 -acodec libfaac -ab 40k -ac 2 -f mpegts -mpegts_copyts 1",
....
...
(파일 내용이 조금 긴 관계로 맨 처음 줄만 가져오고 나머지는 생략합니다.)

여기서 Frame Rate를 담당하는 부분은 "-r" Parameter 입니다. 기본으로 15로 세팅되어 있는데, 이를 24이상으로 바꾸어 줍니다. 전 30으로 설정해 주었습니다. 이 부분은 NAS 성능에 따라 적당히 조절하여 주셔야 합니다. 참고로, 시중에 유통되는 DVD(NTSC PAL)의 Frame Rate는 23.976fps 입니다. 따라서 24fps 정도면 원활한 영상을 보실 수 있습니다.

"mpegts_cga_x264_vb200_vr_aac_ab40": "-threads 0 -vcodec libx264 -vsync 2 -vprofile baseline -level 30 -s cga -b 200k -r 30 -acodec libfaac -ab 40k -ac 2 -f mpegts -mpegts_copyts 1",

첫줄에 해당하는 것을 바꾸었으니, 다른 줄도 모두 바꾸어 줍니다. -r 값이 없는것들은 명시적으로 적어주시면 됩니다.
:wq! 명령어를 입력하여 저장하고 나와서 이제 DS Video+ 앱으로 트랜스코딩을 하면 자연스러운 영상이 재생되는걸 보실겁니다.
이렇게 3개의 조건 중, 1번 조건은 만족하였습니다.


2) 자막은 필수
두번째로, 자막이 나와야 합니다. 이 부분은 간단합니다. 보통 우리가 보는 영상에 같이 들어있는 대부분의 자막은 smi 확장자로 이루어져 있습니다. 하지만 Video Station에서는 srt 자막 파일만 지원하기에, 포털 사이트에서 smi to srt 변환 프로그램을 이용해서 smi 파일을 srt로 변환한 다음, 같은 폴더에 넣어주면 해결됩니다. 자막은 나중에 플레이 시작시 물어봅니다. (좋은건, 자막이 영상에 같이 인코딩되지 않음!)


3) 모바일 환경에서 통신망 환경에 따라 비트레이트 변경을 통해 끊김없는 감상이 가능해야 할 것.
마지막은 더이상 할게 없습니다. 720P영상들 중 1.4GB정도 되는 영상들은 영상 비트레이트가 1400~1600kbps 정도 됩니다. 원활한 3G 환경에서는 끊김없이 재생이 가능한데, 아시다시피 모바일 네트워크 환경은 Handover 구역이라던지, 늘 외부 요소에 의해 불안정 합니다. 따라서, 비트레이트를 조정할 방법이 있어야 합니다. 하지만 이 부분은 감사하게도 VideoStation에서 이미 지원하고 있습니다.

DS Video+ 앱의 옵션에 가보면 영상 품질을 높음, 중간, 낮음,자동 처럼 3~4단계로 분류하고 있는데, 원본은 말 그대로 원본 파일 자체를 플레이어에 넘겨주는 것이고(iOS에서 MP4 컨테이너 외 재생 불가), 나머지 옵션은 트랜스코딩 옵션을 켜야 작동합니다. 옵션 별 비트레이트는 아까 위에서 수정하였던 TransProfile 파일에 잘 들어가 있으며, 기본적으로 VideoStation에서는 해상도와 영상 컨테이너에 따라 200k~1500k 까지의 품질을 지원합니다. 만약 변경하고 싶으신분은 파일을 열어 "-b" Parameter를 수정하여 주시면 됩니다. 통신망 상태에 따라 화면이 끊길때 중간중간 옵션을 변경하면서 감상하시면 됩니다.


4) 마치며
이렇게해서 목표를 모두 달성했습니다. 대부분의 코덱에 관련없이 PC, iOS, Android에서 자막과 함께 부드러운 영상 재생이 가능하며, 모바일 환경을 감안하여 비트레이트를 조절해서 볼 수 있습니다. 개인적으로는 VideoStation의 라이브러리 기능까지 더 해지니, 어떤 Application보다 더 좋은 스트리밍 환경을 구축했다고 봅니다.


ps. TransProfile파일은 VideoStation 업데이트마다 매번 수정해주어야 할 것 같아 보입니다.
ps2. smi 파일을 srt로 변환하는 스크립트를 이미 포고플러그에 적용중인 사람들이 있는것 같으니, 변환 프로그램이 불편하다면 직접 시놀로지에 적용시켜보는것도 좋을듯 하네요.
ps3. Android에서 제조사 기본 동영상 플레이어에 따라 자막이 안나올수도 있으니, 그렇다면 DicePlayer를 이용하시는것도 괜찮습니다.

 


Memory Allocator for Multithreaded Applications

출처 : http://www.mimul.com/pebble/default/2011/05/15/1305469792430.html 

 

응용 프로그램에서 메모리 사용은 필수 불가결한 거죠. 그런데도 메모리에 대한 사용상 효율, 성능을 잘 고려하지 않고 그냥 있는 malloc을 사용하고 말죠. 그런데 트래픽이 많은 서비스가 요즘 많아지다보니 메모리 사용에도 신경을 써야하는 경우가 많습니다.
그래서 메모리 할당에 관해 정보를 정리하고 공유합니다.


메모리를 할당받기 위해 사용하는 malloc()함수는 일반적으로 glibc에 포함된 메모리 할당자에서 구현이 되어 있습니다. 그리고 메모리 할당자는 ptmalloc입니다.
메모리 할당자의 역할은 brk/sbrk/mmap등을 사용해서 시스템으로부터 큰 메모리 영역을 할당 받아서, 이것을 적절하게 분할하여 어플리케이션이 요청하는 메모리 할당을 처리하게 됩니다.
하지만, 빈번하게 메모리를 할당/해제하고 수십 개의 쓰레드가 동작하는 프로그램에서는 어쩔 수 없이 메모리 단편화(Memory Fragmentation)가 발생하여 메모리 사용량이 늘어나게 되죠.
그래서 규모가 큰 어플리케이션들은 glibc의 기본 메모리 할당자인 ptmalloc이 메모리 단편화 문제가 심하고, multi thread, multi processor에 대한 고려가 적어서 performance bottleneck이 존재하여 다른 메모리 할당자를 사용하는 경우가 있습니다.


데이터 섹션(메모리 사용 구조)

 - 전역 메모리(Global Memory) : 지역 함수(Local Function), 전역 변수(Global Variable), 정적 변수(Static Variable)
 - 스택 메모리(Stack Memory) : 지역변수와 매개 변수가 저장된 곳. 컴파일 타임에 크기 결정. 메모리 생명 주기를 알기 때문에 단편화가 안일어남.
 - 힙 메모리(Heap Memory) : 동적 메모리 할당을 위한 곳. 프로그래머가 할당 및 해제해야 함. 런타임에 크기 결정. 메모리 생명 주기를 모르기 때문에 단편화가 일어남.

컴파일러 및 링커가 메모리 할당 기능을 수행할 때에는 메모리 단편화가 일어나지 않습니다. 왜냐하면 컴파일러가 데이터의 수명을 알고 있기 때문입니다.
메모리 할당자는 기본적으로 오버헤드, 내부 단편화, 외부 단편화 등 3가지 측면에서 메모리를 낭비합니다.

메모리 낭비 종류

 - 오버헤드 : 메모리 할당자는 할당 상태를 설명해 주는 일부 데이터를 저장해야 하는데. 즉, 모든 자유 블록의 위치, 크기, 소유정보, 그리고 내부 상태와 관련된 정보를 저장해야 합니다. 일반적으로 메모리 할당자가 이러한 오버헤드(부가) 정보를 저장하기에 가장 좋은 장소는, 할당자가 자체 관리하는 메모리.
 - 내부 단편화 : 모든 메모리 할당 작업은 프로세서 아키텍처에 따라 4, 8, 16으로 나뉠 수 있는 주소에서 시작되어야 함. 이렇게 미리 정의된 크기로만 클라이언트에게 블록을 할당하는 데는 또 다른 이유가 있을 수 있다. 만약 클라이언트가 41바이트 블록을 요청하면 42, 48 또는 그 이상의 바이트를 얻게 된다. 클라이언트가 요청한 크기를 반올림한 결과 남게 되는 여분의 공간. 이것이 내부 단편화.
 - 외부 단편화 : 애플리케이션이 연속해서 세 블록을 할당한 후, 가운데를 제거하면 외부 단편화가 발생.


Memory Allocator 종류

 - tcMalloc : Google에서 만들었고 오픈 소스며, 메모리 프로파일 기능도 제공함. Linux, 작은 사이즈의 allocation에 최적화 된 것, MacOsx, Windows 지원. 레퍼런스 가장 많음. 임베드 시스템에도 많이 활용됨, NUMA 아키텍처 지원
 - jemalloc : 오픈 소스며, Linux ,MacOsx에 최적화 되었고 Windows도 지원. FireFox, Facebook에서 쓰여 레퍼런스가 늘어가고 있음. NUMA 아키텍처 지원은 아직 레퍼런스 찾지 못함
 - nedMalloc : 오픈소스며 간단하고 Windows에 최적화. dlmalloc을 뿌리로 둠.

싱글 스레드 환경에서는 ptmalloc과 위의 메모리 관리자와의 성능과 효율이 크게 다르지 않을 수 있고 멀티 쓰레드 환경에서 위의 메모리 할당자를 사용하므로써 많은 성능 향상을 보았다고 함.


tcMalloc 소개

 1. 작동 방식(성능 향상 방식)
  - 중앙 메모리 관리자와 쓰레드별 메모리 관리자를 구분하고 작은 크기(32K 이하)의 메모리 할당/해제 요청은 쓰레드별 메모리 관리자가 처리하고, 부족할 경우 중앙 메모리 관리자에서 얻어오는 방식으로 처리함.
  - 큰 메모리(32K 이상)는 전역 관리자에서 페이지 크기(4K) 단위로 클래스를 나누어 mmap()을 이용하여 할당하는 함.
 2. 지원 환경
  - Linux (32 and 64 bit), Mac OSX, Windows (32 bit only), Solaris
  - NUMA-aware TCMalloc(NUMA아키텍처 지원됨)
 3. 사용 사례
  - Webkit, MySQL, HyperTable, Memcached, Redis, Nginx


jemalloc 소개

 1. 작동 방식(성능 향상 방식)
  - 쓰레드별 메모리 관리자 Arena와 작은 단위의 잦은 메모리 할당의 경우, arena를 참조 하지 않고, 바로 malloc을 할 수 있도록, 각 스레드에게 thread cache라는 영역을 가지고 있어 성능 향상을 줌.
 2. 지원 환경
  - Linux(32, 64 bit), Windows, MacOSX
 3. 사용 사례
  - FireFox, FaceBook


nedMalloc 소개

 1. 작동 방식(성능 향상 방식)
  - dlmalloc에서 출발했고, 오픈 소스며 내용은 간단하지만 성능도 좋다는 평으로 알려짐.
 2. 지원 환경
  - Windows(32) 최적화됨, MacOSX, Linux
 3. 사용 사례
  - 소소한 개인 사용자 위주. 윈도우 개발자들이 많이 채택함. 일부 Javascript 엔진에 사용


SLAB Allocator

 - 슬랩은 내부 단편화 문제를 해결할 뿐만이 아니라 커널 내에서 흔히 일어나는 dynamic memory 할당의 overhead를 줄이기 위하여 캐싱하는 역할을 하여 성능 개선에도 큰 도움을 주고 있음.
 - 캐시는 관리가 필요한 오브젝트 종류별로(예를 들면task_struct, file, buffer_head, inode 등) 작성되고 그 오브젝트의 슬랩을 관리하고 슬랩은 하나 이상의 연속된 물리 페이지로 구성되어 있으며, 일반적으로 하나의 페이지로 구성된다. 캐시는 이러한 슬랩들의 복수개로 구성됨.
 - 자주 사용되는 오브젝트들을 미리 할당하여 놓고 사용자 요구가 있을 때 마다 바로 반환하는 것이다. 이것은 물리 메모리를 확보하기 위하여 검색 및 회수, 반환과 같은 긴 여행을 떠날 필요가 없으므로 시스템의 성능을 향상시킨다. 또한 다 사용된 오브젝트들을 반납받아 커널의 메모리 할당자에게 반환하지 않고 보관했다가 재사용하기 때문에 시스템의 성능을 향상시킬 수 있게 됨.


응용 예(MySQL-tcMalloc)

 - MySQL 성능 향상 위한 tcMalloc 적용 예


// 64bit 머신일 경우에만 필요함. libunwind
wget http://download.savannah.gnu.org/releases/
  libunwind/libunwind-0.99-alpha.tar.gz
tar zxvf libunwind-0.99-alpha.tar.gz
cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install

wget http://google-perftools.googlecode.com/
   files/google-perftools-1.7.tar.gz
tar zxvf google-perftools-1.7.tar.gz
cd google-perftools-1.7/
./configure
make && make install

vi /etc/ld.so.conf
/usr/local/lib 라인 추가
/sbin/ldconfig

vi /usr/local/mysql/bin/mysqld_safe
export LD_PRELOAD=/usr/local/lib/libtcmalloc.so


[참고 사이트]

 

출처 : http://www.gamedevforever.com/165

 

 

 

Posted by 죠쉬

지난 두번에 걸쳐 다루었던 PGP 방식의 프로토콜은 거의 모든 상황에서 사용이 가능한 완전체에 한없이 수렴하는 프로토콜 이다. 그렇기 때문에 대부분의 환경에서 안전하게 데이터를 주고받는 용도로 사용할 수 있는 좋은 방식이기도 하다. 왜 좋은지에 대해서는 아래의 링크에서 확인해 보시라.

 

http://www.gamedevforever.com/141


위의 포스팅에서 i5 2.5GHz 급의 CPU라면 하나의 코어로 대략 초당 282,489,299 바이트, 17,655,581번의 128비트 AES 암호화 연산이 가능하다는 것에 대해 이야기 했었다. 계산해 보면 개발중인 게임에서 PGP, GPG 혹은 SSL을 사용할 수 있을지 여부에 대해 확인 해 볼 수 있을 것이다. 틀림없이 어떤 환경에서는 그정도의 연산 조차 아끼고 싶은 경우가 있을 수 있다. 특히 휴대용 게임기나 스마트 폰 등의 제한적인 환경이라면 더더욱 암/복호화 연산이 부담스러울 가능성이 있다.

이번 글을 통해 전달하고자 하는 내용은 두 가지 이다. 첫번째는 XOR이 암호화 하는데 사용되는 특징이 있기는 하지만, 그 자체는 암호화하는 효과가 전혀 없으므로 XOR 만 가지고는 해결되지 않는다는 것을 보이는 것 이고, 두번째는 암호화를 할 때 사용하는 몇가지 기법을 이야기 하고자 한다.


1. XOR를 이용한 데이터 숨기기

XOR은 CPU에서 제공하는 연산이므로 128비트를 암 복호화 하는데 만여 사이클이 소요되는 AES 암/복호화와 달리 많아야 100 사이클 정도면 128비트를 암호화 할 수 있다. 물론, 구현하는 방법에 따라, CPU의 종류에 따라 달라질 수 는 있겠지만, 근본적인 차이는 발생할 수 없다. XOR를 이용하여 암호화 한다면, 대충 다음과 같은 방법으로 암호화가 진행 될 수 있을 것 이다.



오! 그럴듯 해 보인다. 뭔가 알 수 없는 형태로 데이터가 변환되어서 전송되었다. 훔쳐보고 싶어 하거나, 조작하고 싶어하는 공격자는 원래 데이터가 뭔지 상상할 수 도 없을 것이다. 그러니 이걸로 대 만족이다! 그럼 이걸로 글을 마치겠다... 일리가 없잖습니까?

 

위에 언급한 XOR 방식의 가장 치명적인 단점은 쉽게 키의 크기를 알아낼 수 있고, 키 자체도 알아내기 어렵지 않다는 것 이다. 물론 어떤 방식으로 XOR를 했는지 알아내기 위해서 시간을 투자해야 하겠지만 결국 알아내는 건 많이 어렵지 않다. 그럼 위의 방식을 한번 공격해 보겠다. 먼저 공격을 위해서 한가지 전제를 해야 한다. 위의 방식을 이용해서 모든 데이터를 암호화 한다 - 채팅 내용까지 위의 방식을 사용한다는 전제를 해두겠다. 물론, 채팅을 암호화 하지 않는다고 해서 공격하는게 불가능 하지는 않지만, 가장 간단한 방법으로 공격하기 위해서 채팅의 내용까지 암호화 한다고 전제 하는 것 이다.

 

공격 방법은 아주 단순하다. 채팅창에 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[각주:1]"를 입력하는 것 이다. 그리고 전송되는 패킷을 관찰하면 다음과 같은 내용을 포함한 패킷이 날아가는걸 볼 수 있을 것 이다.

 

 

6E2AE83 6E2AE83 6E2AE83 6E2AE83 .... 6E2AE83 6E2AE83 6E2AE83 6E2AE83

 

보기 좋으라고 네 바이트 단위로 잘라 놓기는 했지만, 어찌 되었든 XOR를 이용해서 숨겼다는 사실만 알면, 반복되는 주기만 관찰을 하면 쉽게 키의 크기를 알 수 있다. 위의 경우에는 숨길 때 사용한 키의 크기가 네 바이트 라는 것을 알 수 있다. 그리고, 운영체제에서 기본적으로 제공하는 계산기를 실행시킨 후 다음을 계산해 보면 된다.

 

6E2AE83 XOR 41414141 (AAAA의 아스키 코드 값)

 

그러면, 짜잔! 계산기에 다음과 같은 값이 나올 것 이다.

 

47A3EFC2

 

뭐... 뭐냐?

 

프로그램 코드를 분석해 볼 필요도 없다. 그냥 시도해 보면 된다. 해봐서 아니면 그냥 다른 방법을 사용했을 가능 성이 높으니 사용된 다른 방법이 무엇이 있을지 고민하면 된다. 위의 암호문을 포함한 패킷이 날아가고, XOR을 이용한 게 아니라면 답은 하나 뿐이다. 128 비트 블럭 암호를 ECB 모드로 암호화 한 것 이다. 원하는 평문에 대한 암호문을 알아낼 수 있으니 이전에 이야기 했던 차분 공격법을 이용하면 오래 걸리지 않아 키를 알아 낼 수 있을 것이다. 또 다른 문제는, 궂이 키를 알아내지 않더라도 전달되는 데이터의 일부를 변경할 수 있다는 문제점도 있다. 단순히 특정 비트-바이트의 값을 수정하는 것 만으로도 원하는 데이터를 변형 할 수 있다. 그렇기 때문에 XOR로 데이터를 숨기는건 그다지 효용성이 높지 못하다.



2. 기존의 암호화 방식을 끌어다 써보자 - CBC의 Chaining 을 가져다 써보자

 

그러면 어떻게 해결을 해야 할 것 인가? 위에서 잠시 말했듯 이 암호화된 문자열이 6E2AE83 6E2AE83 6E2AE83 ... 와 같이 주기를 가지고 반복된다면 해당길이의 키를 사용한 XOR 이거나 ECB 모드를 사용한 블록암호중 하나로 볼 수 있는 것 이다. 이전 게시물 에서 ECB 모드의 문제점에 대해 이야기 하면서 다른 모드를 사용하면 문제가 해결 된다는 것에 대해 언급한 것을 혹시 기억할지 모르겠다. 다시 말해서 위의 경우에도 CBC, PCBC, CFB, OFB 등등의 방식을 흉내내서 문제를 해결 할 가능성이 있다는 걸 생각해 볼 수 있을 것 이다. 


1에서 언급된 문제를 해결하기 위해, 다음과 같이 CBC를 변형해서 XOR를 이용해서 전송방식 - 프로토콜을 변형해 보도록 하겠다.


XOR를 이용하여 원래 데이터를 숨길때 Chaining을 해보았습니다!


오! 이전 보다 조금 더 그럴듯 해 보인다. 이전 암호화 단위의 암호문을 그 다음 단위의 평문을 암호화하는 키로 사용했다. 복호화 할 때에는 첫 번째 값을 그 다음 번 값을 복호화하는 키로 사용해 주면 된다. 게다가 이 방법을 사용하면 공격자가 임의의 위치에 있는 데이터를 바꾸게 되면 그 이후의 데이터들도 영향을 받게 되기 때문에 전달되는 데이터는 복호화 하기 전엔 변경할 수 없다. 이렇게 하면 같은 키를 사용하더라도 처음부터 끝까지 완전히 같은 데이터가 아닌 다음에는 만들어진 암호문이 다르게 보일 것 이다. 이렇게 해주면 공격자는 키를 예측하기 위해 더 많은 고민을 할 수 밖에 없다. 똑같이 단순하게 XOR를 사용한 것 이지만 앞서 사용했던 방법 보다는 조금더 공격자를 고민하게 만들 수 있다. 그러나, 같은 평문은 같은 암호문을 만들기 때문에, 공격자는 어떤 규칙이 있다는 것을 쉽게 발견해 낼 수 있고, 공격 방법을 찾아내기 위해 그 규칙을 이용 하려고 시도 할 것 이다. 그러면, 어떻게 문제를 해결 할 수 있을까?



3. 그럼, 암호화 할 때 마다 다른 결과를 얻도록 해보자


문제를 해결하기 위해서 암호화 하는 것의 가장 기본적인 정의를 끌어들여 보겠다. 가장 안전한 암호화 방식은 공격자가 암호문과 랜덤 값 간에 구별을 하지 못하는 방식이다. 즉, 평문을 암호화 해서 만든 데이터 100 바이트와, 랜덤 함수를 이용해서 만든 데이터 100 바이트를 구별하지 못하면 - 암호화 해서 만들어진 암호문이 랜덤 값 100 바이트로 보인다면 공격자는 공격할 방법을 찾지 못하게 된다. 이 내용을 단순하게 문자 그대로 받아들여 보자. 다시 말해서 평문의 첫 네 바이트를 랜덤값으로 채워 넣는 것이다. 이 방식은 블록암호의 모드에서 사용되는 IV와 유사한 역할을 하는 것이다. 오히려 블록 암호의 모드에서는 IV 값을 알아야 하지만, 이 경우에는 최초의 랜덤 값을 몰라도 복호화가 되기 때문에 IV를 전달하지 않아도 된다. 이 아이디어를 적용한 방식을 그림으로 그리면 다음과 같이 될 것 이다. 


랜덤 값을 초기 값으로 하여 Chaining을 해보았습니다. 매우 그럴듯해 보입니다.


굉장히 그럴 듯 해 보이는 결과물을 얻었다. 랜덤 값을 특정 값과 XOR을 하면, XOR의 특성상 그 결과 값은 랜덤 값 일 수 밖에 없다. 그러므로, 랜덤 값과 키를 XOR를 하면 랜덤 값이 되고, 암호화 하고자 하는 평문 값과 앞서 얻은 키가 포함된 랜덤 값을 XOR를 해주면 랜덤 값이된다. 출력 결과물인 암호문은 말 그대로 랜덤 값 열이기 때문에 공격자는 전송되는 데이터가 암호문인지 아니면 그냥 랜덤값을 보내는 것 인지 구별이 불가능하다. 암호학에서 말하는 가장 이상적인 암호문 인 것이다! ... 이게 사실 이라면, 그동안 암호학을 연구하던 수학자와 암호 연구자들은 전 부 다 Bing신이 되는 거다. 그러나, 필자같은 반푼이도 아는 것을 두번째로 똑똑하다고 하면 암살이라도 할 똑똑한 분들께서 발견하지 못하고 복잡한 수학적 계산을 필요로 하는 블록암호를 만들었을리는 없는 것 이다.


위의 그럴듯해 보이는 방법의 문제점은, 키가 없어도 암호문을 복호화 할 수 있다는 것 이다. 일단 다음 그림을 보자.


슬프게도, 키나 첫 번재 랜덤값은 몰라도 암호는 깨진다.


위 그림을 보면 알겠지만, 전송되는 암호열의 첫번째 암호문을 그 다음 암호블록과 XOR 해주면 평문을 얻을 수 있다. 그러므로 애시당초 키는 필요도 없었다. 공격자가 암호화 방식을 모른다면 혹시 속아넘어가 줄 수... 조차 없다. XOR의 특성상 Chaining 방식은 사용이 불가능 하기 때문이다. 2에서 언급된 방법을 이용해서 암호화를 하는 경우 그 앞에서 사용했던 "A" 잔뜩 입력하기 기법을 사용하면 다음과 같은 결과물을 얻게 된다.


6E2AE83 47A3EFC2 6E2AE83 47A3EFC2 6E2AE83 47A3EFC2 6E2AE83 47A3EFC2


그리고, 여기에서 언급된 방법 이라면 다음과 같은 결과를 얻게 될 것 이다.


RANDOM RANDOM 47A3EFC2 RANDOM 47A3EFC2 RANDOM 47A3EFC2 RANDOM 47A3EFC2

 


...

(다시 한 번 수고해 주신 L 군에게 감사한다.)


패턴이 반복 될 뿐 아니라, 전송되는 데이터열에 비밀 키 까지 예쁘게 포함되어 있다. 이... 이건 아니잖아...


4. 결론


기본적으로 XOR 연산은 두 값을 섞어서 제 삼의 값을 만들어 내기 때문에 암호화에 사용할 수 있을 것 처럼 보인다. 그러나 XOR 연산은 '복원'의 특성을 가지고 있기 때문에 XOR 만을 이용하여 암호를 만든다면 알려져 있는 그 어떤 방식을 사용한다 할 지라도 약간의 노동 만으로도 원문을 얻어낼 수 있다. 게다가 XOR 은 사칙연산과 마찬가지로 아주 단순하기 때문에 그 자체만 가지고는 응용할 수 있는 영역에 한계가 있다. 그러므로 아무리 연산시간이 부족하다 할 지라도 XOR 만 가지고 전송하는 데이터를 암호화 하려는 시도는 원하는 목적을 달성 할 수 없을 것 이다.


겨우 그딴 소리를 하려고 이 글을 읽게 만들었단 말이냐! 죽고 시프냐!


자... 잠시만, 돌은 내려 놓으시고! !!! !!!! !!!! 아악!


그러나 XOR은 제일 처음에 말씀 드렸던 것과 같이 암호하는데 사용됩니다... 되... 되옵니다. 그렇기 때문에 XOR를 사용하는데 있어 한계를 알고 계시옵는 것은 이 후에 다른 방법을 사용하시어 전송하는 데이터를 암호화 하시옵는데 도움이 되실 것 이옵니다. 다음 번에는 XOR과 의사난수 발생장치(PRNG)와 해시 함수(HASH FUNCTIONS)를 이용하여 빠르고 깨지기 힘든 암호문을 만들어 전달하는 방법에 대하여 설명해 올리도록 하겠사옵나이다. 그리고, 그 다음에는 실제 사용할 수 있을 법 한 프로토콜을 만들어 올리겠나이다... 그... 그러니... 쇠구슬은...


아악!!!!!


*     *     *


'발행' 버튼을 누르면 예약일과 상관없이 바로 포스트가 열린다는 걸 몰랐습니다. 그래서 어제 밤에 쓰다만, 아니 타이핑 하다 만 글이 올라가 버리고 말았네요. 오늘 내일 여유있게 쓰려고 했는데... 일단 트윗에 포스트가 날아갔기에 부랴부랴 타이핑 작업을 마쳤습니다. 혹시 미리 보시고 '이쉐키 뭐얏'이라고 생각하신 분이 계시다면 용서하시길 부탁드립니다. (__)


우좌지 당간에, 그런 이유로  원래 스케쥴 보다 이틀 일찍 포스트 했습니다.


  1. A의 갯수를 세지는 말아 주세요. 그냥 충분히 많은 갯수의 A인 겁니다. 한 백개정도? [본문으로]

+ Recent posts