ptrace는 리눅스 기반 생성된 프로세스가 어떻게 움직이며, 어떤식으로 데이타를 읽고 쓰는지, 

어떤에러를 내는지 추적을 하기위해 마련된 시스템 콜입니다.


이것은 주로 디버그를 위해 사용되며, 따라서 디버거는 일종의 ptrace명령어 묶음 유틸리티라고 보면 됩니다.

프로그래머는 디버거를 통해 ptrace를 손쉽게 사용할수 있으며, 

자신이 만든 프로그램이 어떻게 수행되는지 총괄적으로 관제할수 있습니다.


다음은 ptrace 설명 및 사용법을 잘 설명해주고 있는 사이트들입니다.

 ptrace 설명 (영문)  http://www.linuxmanpages.com/man2/ptrace.2.php
 ptrace 설명 (국문)  http://linux4u.kr/manpage/ptrace.2.html
 ptrace 설명 및 예제 (국문)  http://goo.gl/Gk9vs
 ptrace 메모리 덤프 (국문) http://xpack.tistory.com/119



프로그램을 개발하다보면 사람인지라 버그나 메모리릭이 생기는 것은 당연합니다.


참조: 네이버웹툰, 스마트폰 게임 개발 이야기에서...


따라서 이를 빠르게 발견하고 해결하는 것이 중요합니다.

여기서는 C코드로 짠(콘솔 응용프로그램) 환경에서 메모리릭을 발견하고 잡는 방법을 알아보겠습니다.

다음과 같이 메인 프로젝트를 만들고 메모리릭을 감지하는 코드를 추가합니다. (강조된 부분)

  
// MemoryLeak.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

#ifdef _DEBUG
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

int _tmain(int argc, _TCHAR* argv[])
{
#ifdef _DEBUG
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif

	// 메모리릭 발생코드
	char * szName = new char[100];
	szName = "mooyou";
	printf("%s", szName);

	return 0;
}


위의 코드를 실행하면 출력창에 메모리릭이 발생되었다고 나타납니다.

출력 정보를 보면 memoryleak.cpp 파일의 18번째 라인에서 100 bytes 크기의 메모리릭이 발생되었습니다.

이 정보만으로도 충분히 메모리릭을 잡을수 있습니다.



여기서 더 나아가 메모리 블록 위치 정보를 통해서 직접적으로 메모리릭이 발생한 코드로 이동까지 해보겠습니다.

이를위해 다음과 같이 _CrtSetDbgFlag 바로아래 _CrtSetBreakAlloc( 97 ); 코드를 추가합니다.

이는 메모리릭 발생 위치에 BreakPoint를 설정합니다.

  
// MemoryLeak.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

#ifdef _DEBUG
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

int _tmain(int argc, _TCHAR* argv[])
{
#ifdef _DEBUG
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
	_CrtSetBreakAlloc( 97 );
#endif

	// 메모리릭 발생코드
	char * szName = new char[100];
	szName = "mooyou";
	printf("%s", szName);

	return 0;
}


즉, 출력된 메모리 블록 위치 정보를 이용하여 BreakPoint를 설정하고, 실행시 설정된 곳으로 이동하겠다라는 것입니다 !

코드를 추가하고 실행하면 다음과 같은 메시지 박스가 나타납니다.

BreakPoint에 의해 중단점을 트리거 했다라는 내용이고 여기서는 중단을 누르면 됩니다.

하지만 누르고 나서 코드를 보면 메모리릭이 발생한 원하는 위치가 아닌 dbgheap.c 파일의 내용이 보이게 됩니다.

모르는 코드화면이 나왔다고 해서 전혀 걱정할 필요가 없습니다. 정상적인 화면이고... 제대로 잘 찾아온 것입니다. 

메모리릭이 발생한 곳으로 이동하려면 호출 스택에서 작업위치를 찾아가면 됩니다.

호출 스택은 보통 출력창과 같은 탭에 있고, 없다면 Ctrl + Alt + C를 눌러 호출 스택을 불러옵니다.

호출 스택은 현재 프로그램에서 실행된 명령을 순차적으로 나열한 것으로 맨 위에 찍힌 스택이 최근에 사용한 명령입니다.

현재 보이는 위치(노란색 화살표)가 msvcr100.dll로 dbgheap.c의 내용을 가르킵니다.

즉, 작업한 코드 영역이 아니죠. 따라서 작업한 영역인 MemoryLeak 스택을 더블클릭하여 이동합니다.

짜잔~ 왼쪽에 초록색 화살표가 보이시나요?

호출 스택을 이용하여 메모리릭이 발생한 위치로 이동하였습니다.



 
Introduction

CodeJam은 한국 저작권위원회에서 프로그램 저작권 관리와 코드 난독화 등을 제공하는 사이트이다.

사이트주소: http://www.codejam.or.kr/


프로그램 저작권 관리는 저작자를 식별할 수 있는 워터마크(watermark)정보를 자동으로 생성하여 이를 프로그램 소스코드에 삽입하고 향후 삽입된 저작자 정보를 자동으로 추출하여 검증해 주는 서비스이다. 본 서비스의 목적은 소프트웨어 소스코드의 유출 및 도용 시에도 삽입된 저작자 식별 정보를 검증하여 저작권 침해 사실을 용이하게 입증함으로써 저작권자 권리 구제의 실효성을 확보하여 소프트웨어 지적재산권 관련 분쟁의 위험을 최소화 하는 것이다.



프로그램 코드 난독화는 특정 난독화 알고리즘(Layout, Data, Control Obfuscation)을 적용하여 소스코드를 분석하기 어렵게 변환해주는 시스템이다. 본 시스템의 목적은 상세설계에 준하는 설계구조와 주석문, 프로그램 처리방식, 기능 배치, 구성 등의 설계아이디어 또는 해당하는 알고리즘이나 성능 및 최적화를 위한 구현 노하우 등이 내포되어 있는 SW 소스코드의 원천기술 유출을 방지하는 것이다.



Method

CodeJam의 저작권 워터마크, 난독화등의 코드 변환은 모두 사이트에서 이루어진다.


먼저 로그인을 하고,



서비스 이용으로 들어가 코드 변환을 한다.



ActiveX가 아닌 Java로 구현되어 있다.



자바 설치가 완료되면 다음과 같은 화면이 나타난다. 

변환하기 위한 소스 폴더 선택과 보호강도를 지정하고, 난독화 실행을 클릭하면 난독화가 수행된다.



난독화 결과 화면



Conclude

코드 난독화 결과물이 보호강도를 가장 높게 하더라도 전문적인 난독화 서비스보다는 높지 않다.

하지만 저작권 관리, 난독화등 코드변환을 사이트에서 쉽게 무료로 변환 가능하므로 유용하게 사용할 수 있을것으로 보인다.


난독화된 c코드

#include <stdio.h>

#define MABANG_SIZE 5 

int MABANG[MABANG_SIZE][MABANG_SIZE]; void init_MABANG(); void move_MABANG(int &row, int &col, int count); void process_MABANG(); void print_MABANG(); void main() { init_MABANG(); process_MABANG(); print_MABANG(); } void init_MABANG() { for(int Rc2hTbzn2xMmQYcV=0; Rc2hTbzn2xMmQYcV<MABANG_SIZE; Rc2hTbzn2xMmQYcV++) { if(0<MABANG_SIZE){ MABANG[Rc2hTbzn2xMmQYcV][0] = 0; }if(1<MABANG_SIZE){ MABANG[Rc2hTbzn2xMmQYcV][1] = 0; }for(int fNbUnAITfcUEkNDz=2; fNbUnAITfcUEkNDz<MABANG_SIZE; fNbUnAITfcUEkNDz++) { MABANG[Rc2hTbzn2xMmQYcV][fNbUnAITfcUEkNDz] = 0; } } } void move_MABANG(int &row, int &col, int count) { MABANG[row][col] = count; row -= 1; col += 1; if(row < 0 && col > MABANG_SIZE-1) { row += 2; col -= 1; } else if(row < 0) { row = MABANG_SIZE-1; } else if(col > MABANG_SIZE-1) { col = 0; } else if(MABANG[row][col] != 0) { row += 2; col -= 1; } else { } } void process_MABANG() { int CBbtF1gJvMzPdA7c = 0; int R7R5hHlcgu6tTD6p = MABANG_SIZE/2; for(int Vz1JrpWh_SwYjvMZ=1; Vz1JrpWh_SwYjvMZ<=MABANG_SIZE*MABANG_SIZE; Vz1JrpWh_SwYjvMZ++) { move_MABANG(CBbtF1gJvMzPdA7c, R7R5hHlcgu6tTD6p, Vz1JrpWh_SwYjvMZ); } } void print_MABANG() { for(int lHXsEid3LaTqU3oN=0; lHXsEid3LaTqU3oN<MABANG_SIZE; lHXsEid3LaTqU3oN++) { if(0<MABANG_SIZE){ printf("%4d", MABANG[lHXsEid3LaTqU3oN][0]); }if(1<MABANG_SIZE){ printf("%4d", MABANG[lHXsEid3LaTqU3oN][1]); }for(int dSdb3Zlsgje_bG59=2; dSdb3Zlsgje_bG59<MABANG_SIZE; dSdb3Zlsgje_bG59++) { printf("%4d", MABANG[lHXsEid3LaTqU3oN][dSdb3Zlsgje_bG59]); } printf("\n"); } 

}


'정보이야기 > 보안정보' 카테고리의 다른 글

샌드박스(Sandbox) 개념  (5) 2012.05.29
리버스 엔지니어링 툴 정리  (1) 2012.05.24