'java reverse engineering ( 자바 역공학 )'에 해당되는 글 1건
- 2008.08.20 java reverse engineering ( 자바 역공학 )
개발이 완료되어 유지보수가 이루어지고 있는 소프트웨어 시스템의 구성요소를 알아 내고,
구성요소들 간의 관계를 식별하고, 대상(object) 시스템을 분석하는 과정이다.
즉, 소프트웨어 생명주기의 마지막 단계에서 얻어지는 프로그램이나 문서 등을 이용하여
생명주기 초기 단계의 생성물에 해당하는 정보나 문서들을 만들어 내는 일로서,
설계부터 순차적으로 이루어지는 순공학에 상대되는 개념으로 역공학이라 한다.
처음에는 하드웨어 분야에서 완제품으로부터 제품의 설계사양을 추출하려는 목적에서 출발했으며,
리코프(M.G.Rekoff)는 이를 "복잡한 하드웨어 시스템의 견본을 분석하여 일련의 설계명세를 개발하는 과정"이라고 정의하였다.
그런데 컴퓨터를 기반으로 하는 소프트웨어 공학이 널리 소개되면서 기존의 정보시스템을 소프트웨어 공학의 방법으로
재정의하여 시스템의 품질을 향상하고 유지보수와 관련된 업무를 개선하려는 요구가 생겼고,
이를 충족시키는 방법으로 역공학이 이용되기 시작했다.
이렇게 역공학은 시스템을 이해하여 적절히 변경하는 소프트웨어 유지보수 과정의 일부이다.
대상 시스템을 변경시키거나 새로운 시스템으로 개선하는 것이 아니라 기존 시스템을 분석하는 작업이라 할 수 있다.
그렇다고 소프트웨어 유지보수 단계에만 한정되는 것은 아니고,
직간접적으로 소프트웨어 개발을 지원하기도 한다.
기존 시스템에 역공학을 적용하여 설계구조를 뽑아 내고,
이를 이용해 시스템 분석과 설계를 향상시키는 일이 그런 예이다.
또한 역공학된 설계 정보는 새로운 시스템 설계의 출발점이 되기도 하며,
수정되어 새로운 시스템을 탄생시키기도 한다.
그러나 역공학은 다분히 한시적인 기술로 전락할 가능성이 있다.
순공학의 자동화기술 분야가 발전하면 역공학의 필요성은 상대적으로 줄어들게 된다.
또한 현재 개발되어 있는 역공학의 도구와 기술이 많은 부분 통합되어 있지 않아
실제로 도입하여 적용하는데 장애물이 되고 있다.
■ 리버스엔지니어링이란?
- 하드웨어 또는 소프트웨어에 대한 분해,분석을 통해 당해 제품에
구현된 아이디어(원리, 기술, 방법, 기능, 알고리즘, 노하우등을 포함)를 추출해 내는 일련의 행위
- ‘역공학’, ‘역분석’ 등으로 불리기도 함
■ 리버스엔지니어링 허용의 필요성
- 패키지 솔루션의 경우 실행모듈형태로 제공받는게 일반적인데
소스코드의 변경이 필요해질경우 개작, 번역 등을 수반하게되어 저작권자의
허락 없이 이루어지게 되므로 저작권 침해의 문제가 발생
이러한 경우까지 저작권자를 과도하게 보호한다면 권리자․이용자간의 이익 형평과 공익을
추구하는 저작권 제도의 취지에 반하게 되므로 일정한 경우에는 리버스엔지니어링을 허용하는 것이 필요
리버스 엔지니어링이란?
리버스 엔지니어링이란 완성된 제품을 상세하게 분석하여 제품의 기본적인 설계 개념과 적용 기술들을 파악하고
재현하는 것입니다. 설계 개념→개발 작업→제품화의 통상적인 추진 과정을 거꾸로 수행하는 학문으로 역공학이라고도 합니다.
보통 소프트웨어 제품은 판매시 소스는 제공하지 않으나 각종 도구를 활용하여 컴파일된 실행 파일과 동작 상태를
정밀 분석하면 그 프로그램의 내부 동작과 설계 개념을 어느 정도는 추적할 수 있습니다.
이러한 정보를 이용하면 크랙, 즉 실행 파일을 수정하거나 프로그램의 동작을 변경하는 것이 가능하고,
또 유사한 동작의 복제 프로그램이나 보다 기능이 향상된 프로그램도 개발해 낼 수가 있게 됩니다.
소프트웨어에 대한 역공학 자체는 위법 행위가 아니지만,
대부분의 제품이 이의 금지를 명문화 하고 있어 이러한 수법으로 개발한 제품은 지적 재산권을 침해할 위험성이 있습니다.
리버스 엔지니어링의 기술
- 언패킹(UNPACKING)
일반적인 SW들은 리버스엔지니어링을 막기 위해서 암호화를 하거나 압축을 하여 소스코드를 볼 수 없도록 하고 있습니다.
이러한 과정을 패킹(PACKING)이라고 합니다.
소스코드를 보기 위해서는 이렇게 패킹된 코드를 풀어야 하는데 이러한 과정을 언패킹(UNPACKING)이라고 합니다.
- 분석단계
언패킹된 파일은 리버스엔지니어링을 위해 기본적으로 정적 분석(static analysis)과
동적 분석(dynamic analysis)단계를 거치게 됩니다.
리버스 엔지니어링의 종류
통상적으로 컴파일된 바이너리(EXE, DLL, SYS 등)를 디스어셈블러라는 도구를 이용하여
어셈블리 코드를 출력한 후 그것을 C언어 소스형태로 다시 옮겨 적고 적당한 수정을 통해
리버스하고 있는 파일과 동일한 동작을 하는 프로그램을 만드는 것이 있습니다.
모든 어셈블리 코드를 소스 형태로 옮기지 않고 그냥 동작 방식만을 알아낸다거나
일정 부분만 수정하는 것들도 리버스 엔지니어링이라고 할 수 있습니다.
예를 들면 바이러스를 분석하는 일은 모든 코드를 알아낼 필요가 없기 때문에 동작 방식만 알아내면 됩니다.
그리고 크랙처럼 일정 부분만 수정하여 사용제한을 푸는 것 등도 이에 해당됩니다.
실행파일을 디스어셈블 하지 않고도 그 실행파일이 만들어내는 데이터 파일이나 패킷등을 분석하여
똑같이 재구현하는 것도 리버스 엔지니어링입니다. 예를 들면 오래전 PC 게임에서 많이 하던일인데,
HEX 에디터 등으로 세이브 파일을 분석하여 에디트를 만들거나 게임자체를 조작하는 것이 있고,
당나귀와 호환되는 이뮬 같은 프로그램은 당나귀 프로토콜의 패킷을 분석하여 동일한 동작을 하도록 만들어낸 것입니다.
리버스 엔지니어링에서 가장 많이 사용되는 방식은 첫번째로 이야기 했던
바이너리를 디스어셈블 하여 코드를 얻어내는 것입니다.
이것을 하기 위해서는 먼저 인텔 어셈블리를 배워야 하고, 물론 C언어도 알아야 됩니다.
그런데 여기서 컴파일된 바이너리가 VC나 gcc등으로 컴파일한 것이 대부분이지만
비주얼 베이직으로 컴파일 한 것도 있고 델파이(파스칼)로 컴파일 한 것도 있을 것입니다.
이 바이너리들은 모두 CPU에서 직접 실행되는 것들이기 때문에 디스어셈블 해보면 모두 똑같은 방식으로 되어 있습니다.
그래서 VC, VB, 델파이(파스칼)등으로 컴파일 된 것도 디스어셈블 한 뒤 C 소스 코드로 옮길 수 있습니다.
물론 리버스 하는 사람이 VB나 파스칼로 옮겨 적을 수도 있을 것입니다.
하지만 C언어로 하는 것이 가장 간편합니다.
대부분 리버스해서 얻어내는 것들은 프로그램의 로직(알고리즘)이기 때문에 어느 언어로 표현하든 결과는 똑같기 때문입니다.
자바나 닷넷으로 컴파일 된 바이너리는 CPU에서 직접 실행되지 않고 자바 가상머신이나 닷넷 프레임워크를 통해서 실행됩니다.
그래서 자바로 컴파일된 바이너리를 열어보면 자바 바이트코드 문법으로 되어 있고
닷넷으로 컴파일 된 것은 MSIL이라는 문법으로 되어 있습니다.
이런 것을은 인텔 어셈블리와 문법이나 명령어가 다르므로 따로 자바 바이트코드나 MSIL을 공부해서 리버스 하면 되겠습니다.
윈도우용 바이너리를 리버스 한다고 하면 윈도우 API를 알아야 하고 기타 리눅스나 BSD라면 해당 OS의 API를 알아야 합니다.
그리고 당연히 인텔 어셈블리를 알고 있어야 하고, 인텔 CPU가 돌아가는 방식을 알아야 합니다.
프로그램은 단순히 로직만으로 이루어져 있지 않고 시스템의 API를 호출하여 여러가지 동작을 하기 때문에
각 API의 사용방법과 동작결과를 알고 있어야 어셈블리 코드에서
C소스 코드로 옮기고 다시 소스를 재구현할 수 있기 때문입니다.
어플리케이션을 리버스하는 경우 윈도우 커널에 대한 지식이 없어도
리버스가 가능하지만 커널 레벨로 동작하는 드라이버나 기타 서비스는 윈도우 커널에 대한 지식이 필요합니다.
어셈블리에서 C소스 코드로 옮기는 작업은 한마디로 단순 반복작업입니다.
디스어셈블된 코드에서 call은 함수이고 각종 점프 명령어들은 if, for, while, switch, goto 등의 C언어 제어문입니다.
mov 명령어는 변수에 값을 대입한다거나 하는 것이고 push, pop 명령은 함수를 호출하면서
인자값을 넘겨줄 때 사용합니다. 이 어셈블리 명령의 조합을 읽어 C코드로 구현을 하면 됩니다.
각종 도구들
리버스 엔지니어링에서는 디스어셈블러라는 도구가 매우 필수적입니다.
자주 쓰이는 것들로는 리버스계에서 아주 유명한 소프트아이스(SoftICE, 이하 소아)라는 프로그램이 있습니다.
소아의 특징으로는 윈도우가 돌고 있는 상태에서 Ctrl+D를 누르면 윈도우가 멈추고 소아 창이 떠서 현재 실행되고 있는
어셈블리 코드를 보여줍니다. 정말 강력하고 편리한 기능입니다.
이 기능이 소아를 쓰는 이유이기도 합니다.
물론 그냥 바이너리를 열어서 디스어셈블도 가능하며 요즘은 비주얼 소프트아이스라고 나와서
원격 디버깅도 가능합니다. 단 비쌉니다.
WinDBG(Windows Debugger)는 MS에서 배포하는 무료 디버거인데 윈도우 내부를 분석하는데 매우 유용한 도구입니다.
심볼 서버에서 심볼 파일을 받아와서 윈도우 내부 DLL들의 함수이름과 구조체 등을 볼 수 있습니다.
물론 이것도 그냥 바이너리를 열어 디스어셈블이 가능합니다.
OllyDBG, 아주 편리한 도구입니다. 리버스하기에는 딱 알맞은 도구가 아닌가 싶습니다.
디스어셈블 뿐만 아니라 이 디버거가 어셈블리 코드를 분석하여 사용자에게 많은
정보(함수 이름, 인자값 이름, 서브루틴끼리 묶어주는 기능, 점프명령의 도착점 표시 기능 등)를 제공해 줍니다.
W32dasm는 OllyDBG처럼 인터렉티브 하지는 않지만 상당히 쓸만한 도구입니다.
기타 IDA나 PE Browse등의 프로그램이 있는데 사용자 취향에 따라 골라 쓰면 되겠습니다.
거의 모든 디버거에서 레지스터, 스택, 메모리 상태 등을 표시해 주고 있으므로 코드 분석에 많은 도움이 됩니다.
마지막으로 주의할 점은 같은 바이너리를 디스어셈블한다고 하더라도 디스어셈블러마다 분석해 내는 코드가
조금씩 다른 경우가 있습니다. 그래서 한가지 디버거만 쓰다 보면 엉뚱한 코드를 보기 쉽습니다.
여러가지 디버거를 돌려 가면서 코드를 분석하는 것도 좋은 방법입니다.
'My work space > Java' 카테고리의 다른 글
java reverse engineering 간단정리 (자바역공학) (0) | 2008.08.20 |
---|---|
정규식(Regular Expression) 표현법 및 예제 (0) | 2008.08.20 |
자바와 MS Access DB연동 (0) | 2008.08.20 |
Log4J비용계산 (0) | 2008.08.20 |
싱글톤패턴(Single Pattern) (0) | 2008.08.20 |