KR20190090810A - 셀프 디버깅 - Google Patents

셀프 디버깅 Download PDF

Info

Publication number
KR20190090810A
KR20190090810A KR1020197017015A KR20197017015A KR20190090810A KR 20190090810 A KR20190090810 A KR 20190090810A KR 1020197017015 A KR1020197017015 A KR 1020197017015A KR 20197017015 A KR20197017015 A KR 20197017015A KR 20190090810 A KR20190090810 A KR 20190090810A
Authority
KR
South Korea
Prior art keywords
debugger
code
software
software process
fragment
Prior art date
Application number
KR1020197017015A
Other languages
English (en)
Other versions
KR102684371B1 (ko
Inventor
스테인 볼커트
뵨 드 슈터
버트 아바스
Original Assignee
나그라비젼 에스에이
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by 나그라비젼 에스에이 filed Critical 나그라비젼 에스에이
Publication of KR20190090810A publication Critical patent/KR20190090810A/ko
Application granted granted Critical
Publication of KR102684371B1 publication Critical patent/KR102684371B1/ko

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • G06F11/3624Software debugging by performing operations on the source code, e.g. via a compiler
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • G06F11/3644Software debugging by instrumenting at runtime
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/52Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/52Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow
    • G06F21/54Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems during program execution, e.g. stack integrity ; Preventing unwanted data erasure; Buffer overflow by adding security routines or objects to programs
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2221/00Indexing scheme relating to security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F2221/03Indexing scheme relating to G06F21/50, monitoring users, programs or devices to maintain the integrity of platforms
    • G06F2221/033Test or assess software

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Computer Security & Cryptography (AREA)
  • Computer Hardware Design (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Software Systems (AREA)
  • Quality & Reliability (AREA)
  • Debugging And Monitoring (AREA)

Abstract

본 발명에 따르면 소프트웨어를 보안하기 위한 방법, 컴퓨터 프로그램 제품 및 장치가 제공된다. 본 발명에 따르면, 방법은 디버거 프로세스를 소프트웨어 프로세스에 첨부하는 단계를 포함할 수 있다. 소프트웨어 프로세스의 실행 동안, 코드 프로세스의 기능과 관련된 동작은 디버거 프로세스 내에서 수행된다. 결과적으로, 디버거 프로세스는 소프트웨어 프로세스의 기능에 영향을 미치지 않고 대체되거나 전복될 수 없다. 따라서 수정되거나 악의적인 디버깅 기술에 의한 감염으로부터 소프트웨어 프로세스가 보호될 수있다.

Description

셀프 디버깅
본 개시에 이르는 작업은 승인 협약 n°609734 하에서 [유럽 연합][유럽 원자력 에너지 조합] 7번째 프레임워크 프로그램([FP7/2007-2013] [FP7/2007-2011])으로부터의 펀딩받아 이루어졌다.
본 발명은 소프웨어 보안에 관한 것으로 구체적으로는 디버깅 기술을 이용하여 애플리케이션 또는 라이브러리 등의 소프트웨어를 공격으로부터 보호하는 것에 관한 것이다.
디버깅은 코드내 에러가 시결될 수 있는 프로세스이다. 이를 위한 한가지 툴은 많은 운영체제가 디버깅될 코드와 쌍을 이루는 것을 허용하는 유틸리티의 유형인 디버거이다. 예외(exception) 또는 다른 에러가 발생되면, 이는 디버거에 보고되고 이어서 디버거는 코드를 검사하고 그 문제의 원인이 식별될 수 있다.
디버거와 코드를 페어링하는 능력은 악의적 파티들에 의해 해당 코드의 보안을 손상시키는데 이용되어 왔다. 특히 디버거는 코드 작업(operation)을 식별할 수 있기 때문에 취약원(source of vulnerability)이 될 수 있다.
이러한 공격에 대항하여 코드를 보호하기 위한 기술이 개발되어 왔다. 이러한 기술은, 활성 디버거가 코드에 불법적으로 결합된 시점을 코드가 식별하는 것을 허용하는 시도를 포함한다. 또 다른 해결책은 실행시 코드 자체가 디버거를 초기화하도록 코드를 설계하는 것이다(이런 디버거는 "셀프 디버거"라고도 함). 대부분의 운영 체제는 하나의 디버거만이 주어진 프로세스와 페어링되도록 하는데, 즉 악의적인 디버거가 사용하고자 하는 공간을 셀프 디버거가 점령하는 것을 의미하다.
본 발명은 디버깅 기술을 이용하여 애플리케이션 또는 라이브러리 등의 소프트웨어를 공격으로부터 보호하는 것을 목적으로 한다.
본 발명에 따르면 코드의 연산(operation)을 보호하기 위한 방법이 제공된다. 본 발명에 따르면, 이 방법은 코드 프로세스를 런칭하고 코드 프로세스에 부여된(attached) 디버거 프로세스를 초기화하는 단계를 포함한다. 코드 프로세스 실행 동안, 코드 프로세스의 함수(function)에 중대하게 연관된 연산은 디버거 프로세스 내에서 수행될 수 있다. 결과적으로, 디버거 프로세스는 코드 프로세스의 기능에 영향을 주지 않고 대체되거나 전복(subverted)될 수 없다. 따라서 수정되거나 악의적인 디버깅 기술에 의한 검사(inspection)로부터 코드 프로세스가 보호될 수 있다.
명세서에서, "중대하게(critically)"라는 표현은 디버거 프로세스에서 수행된 이들 연산들에 의해 생성되는 출력이 코드 프로세스의 나머지 부분에 대한 입력으로서 기능하고, 상기 코드 프로세스가 코드 프로세스의 다른 입력을 고려한 그 정확한 출력을 생성하는데 그 입력이 필수적임을 의미하는 것으로 이해될 수 있다.
일부 양태에서, 소프트웨어를 보호하기 위한 방법이 제공된다. 이 방법은 소프트웨어 프로세스를 런칭하고 디버거 프로세스를 소프트웨어 프로세스에 부여하는 단계를 포함할 수 있다. 그런 다음 디버거 프로세스가 적어도 한 번 호출되도록 코드 프로세스가 실행될 수 있다. 호출시, 하나 이상의 함수가 디버거 프로세스 내에서 수행될 수 있으며, 이들 함수는 소프트웨어 프로세스와 관련된 데이터에 의존하는 출력을 갖는다. 이 출력은 소프트웨어 프로세스와 관련된 데이터에 따라 달라질 수 있으므로(즉, 미리 결정되지 않음) 소프트웨어 프로세스 및 디버거 프로세스가 모두 정확하게 작동할 때 만 전체 기능이 달성될 수 있다. 이는 디버거 프로세스와의 간섭으로 인해 코드를 분석할 공간을 남겨두지 않는다.
이런 양태의 소프트웨어 프로세스는, 디버거에 의해 디버깅되는 프로세스의 공간을 차지하기 때문에 "디버기(debuggee)" 프로세스로 간주될 수 있다. 디버거 프로세스는 소프트웨어 프로세스가 런칭되거나 조금 후에 초기화될 수 있다. 예를 들면, 특정 함수(예:라이브러리)가 소프트웨어 프로세스에 로드될 때 디버거 프로세스가 초기화될 수 있다. 일부 예에서, 소프트웨어 프로세스는 디버거 프로세스를 초기화하도록 분기(forks)한다. 다른 예에서는 디버거 프로세스는 먼저 초기화되고 이어서 소프트웨어 프로세스를 생성하도록 분기한다.
일부 실시예에서, 출력은 소프트웨어 프로세스가 이용하기 위한 데이터 출력을 포함한다. 따라서 디버거 프로세스 내의 함수의 출력은 소프트웨어 프로세스의 나중의 연상에 직접적으로 영향을줄 수 있으며, 따라서 결합해제가 쉽지 않은 방식으로 두 개의 프로세스를 엄격하게 결합한다. 디버거 프로세스 내에서 함수의 출력은 소프트웨어 프로세스에 대한 데이터 입력을 포함하고, 데이터 입력은 소프트웨어 프로세스의 실행에 있어 중대하다.
일부 실시예에서, 주어진 함수의출력은 연속된 실행을 위해 소프트웨어 프로세스 내에서 리턴의 다중 포인트를 지시할 수도 있다. 따라서, 적어도 하나의 함수에 대한 리턴 포인트는(고정적이라기 보다) 가변적이다. 따라서 제어 흐름은 디버거 프로세스의 동작에 따라 변화되고 휩게 유추되거나 재현될 수 없다.
일부 실시예에서, 디버거 프로세스는 하나 이상의 함수가 소프트웨어 프로세스의 어드레스 공간 내의 메모리로부터 데이터를 검색할 수 있도록 메모리 지원 기능을 제공한다. 따라서 프로그램-관련 함수는 마치 소프트웨어 프로세스 내에서 이들이 수행되는 것 처럼 데이터를 처리할 수 있는 능력을 갖는다.
디버거 프로세스는 코드 프로세스 내의 중단점(break point)이 도달될 때 호출될 수 있다. 디버거 프로세스는 소프트웨어 프로세스가 완료되면 소프트웨어 프로세스에서 분리될 수 있다. 소프트웨어 프로세스가 완료되었거나 그렇지 않은 경우(예를 들면 중지된 경우) 종료될 수 있다. 대안적으로 전체로서 프로세스가 종료되기를 기다리기 보다는 소프트웨어 프로세스 내의 기능이 종료될 때 디버거 프로세스는 소프트웨어 프로세스에서 분리될 수 있다.
일부 실시예에서, 소프트웨어 프로세스는 애클리케이션과 같은 실행가능한 것을 구현한다. 즉, 코드 프로세스는 라이브러리를 구현한다.
본 발명의 다른 양태에서, 보호된 코드를 생성하는 방법이 제공된다. 디버거에 이송(migrated)될 오브젝트 코드 내의 코드 프래그먼트(fragments)는 식별될 수 있다. 이어서 바이너리 코드가 생성되고 런타임시 디버거 프로세스가 소프트웨어 프로세스에 연결되게 하고 식별된 코드 프래그먼트이 디버거 프로세스 내에서 실행된다. 소프트웨어 프로세스와 디버거 프로세스는 단일 프로세스에서 분기될 수 있다. 예를 들면, 소프트웨어 프로세스는 디버거 프로세스를 초기화할 수 있다.
생성 단계는 바이너리 코드 내에 일반 디버거 기능에 대응하는 미리 정의된 코드를 통합하는 단계를 포함할 수 있다. 생성 단계는 디버거의 일부 미리 정의된 양태를 통합하는 링킹 단계일 수 있으며 이러한 양태은 "미니-디버거"라고 불릴 수 있다. 이와 같이, 전체 디버거는 식별된 코드 프래그먼트을 포함함으로써 소스 코드에 관련된 일부의 양태들 뿐만 아니라 일부의 일반적인 양태를 포함한다.
이 방법은 소스 코드로부터 디버거로 이송될 코드 프래그먼트을 식별하는 하나 이상의 주석(annotations)을 추출하는 단계를 포함할 수 있다. 그런 다음 소스 코드가 컴파일되어 오브젝트 코드가 생성된다. 그런 다음 바이너리 코드를 오브젝트 코드로부터 생성되고 식별된 코드 프래그먼트은 바이너리 코드로 디버거와 통합될 수 있다. 이러한 방식으로, 바이너리 코드의 생성은 식별된 프래그먼트을 다른 위치로 이동시키기 위한 재기록 요소를 포함하는 링킹 단계일 수 있다. 바이너리 코드가 사용될 때 소스 코드의 기능과 관련될 수 있는 원본 소스 코드의 양태를 포함하는 디버거가 생성된다.
일부 실시예에서, 바이너리 코드는 소스 코드에 대응하지만 식별된 코드 프래그먼트은 제외하는 제1 바이너리 코드 파일 및 디버거에 대응하는 제2 바이너리 코드 파일을 포함한다. 대안적으로 단일 바이너리 코드 파일에 소스 코드와 디버거가 모두 포함할 수 있다.
본 발명의 다른 양태는 전술한 양태들의 방법들을 수행하기 위한 컴퓨터 실행가능 명령어들을 포함하는 컴퓨터 실행가능 프로그램 제품에 관한 것이다. 본 발명의 양태들은 또한 전술한 양태들의 방법들을 수행하도록 구성된 장치들에 관한 것일 수 있다.
몇몇 특정 실시예들은 동일한 특징에 대해 동일한 번호로 나타낸 첨부된 도면을 참조하여 예시적인 방식으로 이하에 설명된다.
바이너리 기술을 통해, 본 발명은 원래의 소프트웨어에서 셀프 디버거로 모든 기능 청크(chunck)를 이송(migrate)할 수있다. 이는 몇 가지 장점을 제공한다. 첫번째, 셀프 디버거의 입력-출력 동작은 더 이상 미리 결정되지 않는다. 셀프 디버거가 개입할 때 마다 미리 결정되지 않은 다른 기능을 실행하지만 대신 보호되는 프로그램의 기능이 변화되는 것 만큼 변화될 수 있다. 이는 자동화된 분석, 해독(deobfuscation) 및 해체(deconstruction)에 대한 보호 기능을 더 강화할 수 있다. 두번째, 공격자가 원래 프로그램과 동일한 제어 흐름 및 데이터 흐름을 파악할 수 있는 경우에도 공격자가 보호 기능을 풀고 원래 프로그램을 재구성하는 것이 더욱 어려워진다. 이러한 두 가지 강점의 조합은 공격자가 추적하거나 라이브-디버그될 기능 프로그램을 유지하면서 셀프 디버거를 분리하는 것이 더 어려워진다.
본 발명에 따르면 전술한 목적을 달성할 수 있다.
도 1은 종래의 코드 프로세스 및 본 발명의 커플 코드 프로세스 및 디버거 프로세스의 주요 특징을 나타내는 도면;
도 2는 실시예에 따른 런타임 단계들을 나타내는 흐름도;
도 3은 본 발명에 따른 바이너리 생성의 주요 특성를 나타내는 도면.
도 4는 바람직한 실시예의 구현을 위한 하드웨어 기반구조를 나타낸 도면.
도 1은 본 발명에 따른 셀프-디버깅 방식의 기본 개념을 나타낸다. 이 실시 예는 Linux(및 Android와 같은 파생물)를 대상으로하며, Windows 및 OS X와 같은 다른 환경에도 적용될 수 있다.
도 1의 왼쪽에는 작은 제어 흐름 그래프 프래그먼트(fragment)을 포함한 원래의 보호되지 않은 애플리케이션이 표시되어 있다. 표시된 어셈블리 코드는(의사: pseudo)ARMv7 코드이다. 이 보호되지 않은 애플리케이션은 두 부분, 즉 도면의 중앙에 도시된 바와 같이 원래의 애플리케이션에 가장 대응하는 디버기(debuggee) 및
우측에 도시된 바와 같은 디버거로 이루어진 보호된 애플리케이션으로 변환된다. 디버기와 디버거에 주입된 새로운 구성요소 이외에도 원래 애플리케이션과의 주요 차이점은 제어 흐름 그래프 프래그먼트이 애플리케이션에서 디버거로 마이그레이션된다는 점이다. 이 특정 실시예는 함수 호출(function calls)과 같은 절차간 제어 흐름을 포함하지 않는 모든 단일-엔트리(single-entry), 다중-종료(multiple-exit) 코드 프래그먼트을 지원한다.
이러한 프래그먼트들의 마이그레이션은 단순한 복사 이상의 것이다. 보호된 애플리케이션에서 디버거 주소 공간에서 실행되는 마이그레이션된 코드가 디버기 주소 공간에 여전히 잔류하는 데이터에 액세스 할 수 있기 때문에 LDR 명령과 같은 메모리 리퍼런스는 변형되어야 한다. 모든 관련 구성요소 및 변형은 이하의 섹션에서 자세히 설명한다.
마이그레이션된 프래그먼트는 애플리케이션의 동작에 바람직하게 중요하다. 즉, 디버거 프로세스로 마이그레이션된 그런 작업(operation)에 의해 생성된 출력은 코드 프로세스의 나머지 부분에 대한 입력으로 사용되며, 코드 프로세스가 그 코드 프로세스의 다른 입력으로 주어진 그 정확한 출력을 생성하는 것을 허용하기 위해서는 그 입력이 필요하다. 이 요구사항은 실제로는 실수하기 쉽다. 예를 들면, 일반적인 프로그래머는 디버거 컨텍스트 내의 코드 프로세스의 변수 초기화를 실행하는 것을 고려할 수 있다. 그러나 일반적으로 디버거 프로세스 내에서 코드 프로세스로부터 변수의 초기화를 실행하는 것은 충분하지 않는데, 이는 실제로는 프로세스 내에서 변수 초기화(예를 들면, 함수로의 입력시 로컬 변수)가 양호한 프로그래밍 수행의 결과로서, 프로세스의 정확한 기능과 정확한 출력의 생성에 대해 실제 요구되지 않는 소스 프로그래밍 언어 정의 요건을 충족하기 위해, 수행되기 때문이다. 이는 변수가 코드 프로세스의 실행된 경로에서 단순히 사용되지 않거나, 초기값이 코드 프로세스의 실행 또는 출력에 영향을 주기 전에 겹쳐써지기 때문일 수 있다.
런타임시 이 보호된 애플리케이션의 작동은 다음과 같다. 먼저, 디버기는 단계 s21에서 원래 애플리케이션인 것 처럼 런치된다. 새로 주입된 이니셜라이저는 디버거의 이니셜라이저가 디버기 프로세스에 즉시 연결되는 디버거의 새로운 프로세스를 분기한다(fork off). 따라서, 디버거 프로세스는 단계 s22에서 런치되고 디버거 프로세스에 부여된다.
나중 프로그램 실행 중에 마이그레이션된 코드 프래그먼트의 진입점에 도달하면 애플리케이션에서 제어의 한 가지 가능한 흐름이 도 1의 화살표를 따른다. 애플리케이션/디버기에서, 예외 유도 명령(exception inducing instruction)이 실행되고 단계 s23에서 예외가 발생된다(도 1에서 1). 디버거는 이 예외를 통지받고 단계 s24에서 디버거 루프에서 이를 처리한다(도 1의 2). 그 중에서도 이 루프의 코드는 디버기로부터 프로세스 상태를 가져와서 대응하는 마이그레이션된 코드 프래그먼트을 찾고 다음 단계 s25(도 1의 3)에서 프래그먼트의 진입점으로 컨트롤을 전달하는 책임을 가진다. 언급한 바와 같이, 그 프래그먼트 메모리 액세스는 그대로 수행될 수 없다. 따라서 이들은 단계 s26에서 디버기의 어드레스 공간 내 메모리에 액세스하는 메모리 지원 함수(5)의 호출(4)에 의해 대체된다. 출구점(6)이 마이그레이션된 코드 프래그먼트에 최종적으로 도달되면, 단계 s27에서 디버거 루프(7) 내의 대응하는 지점으로 컨트롤이 전송되고, 단계 s28에서 디버거에서 계산된 데이터로 디버기의 상태를 갱신하고 단계 s29에서 컨트롤은 디버기로 다시 전송된다. 도면에 예시된 실시예와 같이 여러 출구가 있는 코드 프래그먼트에 있어서 디버기 내 여러 연속점으로 컨트롤이 다시 전송될 수 있다. 이와 관련하여, 본 발명의 디버거는 디버기와 디버거 사이의 순방향 및 역방향 컨트롤 흐름 전달 사이에서 일대일 맵핑을 구현하는 기존의 셀프 디버거보다 더 복잡한 방식으로 행동한다.
결과적으로 애플리케이션이 종료되면 임베디드 파이널라이저(종료자)가 필요한 분리 작업을 수행한다.
이 스키마는 실행파일(예 : 주 기능 및 진입점이 있는 바이너리)을 보호하기 위해서 개발될 수 없고 또한 공유 라이브러리를 보호하기 위해 개발될 수 없다는 점에 유의해야 한다. 실행 파일과 마찬가지로 라이브러리는 OS 로더에 의해 로드되거나 언로드될 때 실행되는 이니셜라이저(초기화자) 및 파이널라이저(종료자)를 포함할 수 있다. 이 때 분기(forking), 부여(attaching) 및 분리(detaching)의 모든 필요한 작업이 수행될 수 있다.
다음 설명은 주로 애플리케이션을 보호하는 것을 언급하지만, 암시적으로 애플리케이션과 라이브러리가 동일하게 적용될 수 있다. 특히 라이브러리와 관련된 한 가지 양태는 디버거의 적절한 초기화 및 종료화가 필요하다는 것이다. 이는 프로그램의 단일 실행 내에서 여러 번 로드 및 언로드되는 라이브러리에 있어서 일반적이기 때문에 필수적이다. 예를 들면, 반복적인 로딩 및 언로딩은 미디어 플레이어 및 브라우저의 플러그인에서 자주 발생하다. 또한 주(main) 프로그램은 그들이 자체적으로 런칭될 때 단 하나의 스레드로 구성되지만 라이브러리가 로딩 및 언로딩될 때 복수의 스레드로 구성될 수 있다.
툴 지원(TOOL SUPORT)
도 3은 하나의 이용가능한 개념적인 툴 흐름을 나타낸다.
소스 코드 주석(Source Code Annotations)
디버거로 마이그레이션될 코드 프래그먼트을 결정하기 위해, 여러가지 옵션이 존재한다. 도면에서 표시되고, 또한 구현시 본 발명에서 사용하고자 하는 하나는 단계 s31에서 디버거 프로세스에 마이그레이션될 코드 영역의 시작과 끝을 마킹하는 프라그마(pragma), 코멘트 또는 기타 다른 형태의 주석을 소스 코드에 주석달기하는 것이다. 간단한 그렙(grep)은 단계 s32에서 주석과 그 라인 번호를 추출하고 주석 파일에 그 정보를 저장하기에 충분하다.
대안적인 옵션은 보호될 프로시저 또는 소스 코드 파일을 리스트화하거나, 또는 관심있는 프래그먼트를 반자동으로 선택하기 위해 트레이스 또는 프로파일을 수집하는 것이다.
이와 관련하여 디버거로 마이그레이션될 프래그먼트는 핫(hot) 프래그먼트일 필요는 없다라는 점에 유의해야 한다. 디버기와 디버거 사이에 강한 연결을 얻기위해, 이는 예외를 비교적 자주 발생시키기에 충분하지만, 이는 가장 핫한 코드 경로에 있을 필요는 없다. 프래그먼트의 선택에 대한 추가 고려사항은 아래에 자세히 설명된다. 발생하는 모든 예외는 상당한 양의 오버헤드(컨텍스트 전환, 많은 ptrace 호출 등)를 유도하므로 보호 레벨을 손상시키지 않으면서 그들의 수를 최소화하는 것이 중요하다.
표준 컴파일러 및 툴
개시된 셀프-디버깅 방식을 전개하기 위해, 임의의 "표준" 컴파일러가 단계 s33에서 사용될 수 있다. 이 기술은 컴파일러에 의해 생성된 코드에 어떠한 제한도 인가하지 않는다. 실험 평가에서 코드 생성을 적응하거나 조정할 필요가 없는 GCC와 LLVM이 모두 사용되었다.
그러나 컴파일러와 바이너리 유틸리티(어셈블러 및 링커)는 링크-타임 재기록기(rewriter)에 충분히 정확한 심볼과 재배치(relocation) 정보를 제공해야 한다는 요구조건이 있다. 이는 신뢰할 수 있고 보수적 인 링크 타임 코드 분석 및 변환을 인에이블하여 선택한 코드 프래그먼트의 마이그레이션 및 변형을 포함한 전체 셀프 디버깅 스킴을 구현하는데 필요하다. 충분히 정확한 정보를 일반적으로 사용되는 툴에 대해 제공할 수 있다. ARM의 소유의 컴파일러는 기본적으로 오랫동안 그렇게 해왔고, GNU binutils, GCC, LLVM에 있어서, 매우 간단한 패치가 과도한 공격적인 심볼 완화 및 재배치 단순화를 수행하는 것을 방지하고, 그들로 하여금 코드내 데이터를 마킹하기 위한 맵핑 심볼을 삽입하도록 한다. 이러한 요구사항은 이전에 문서화되었으며, 이들은 수동으로 작성된 어셈블리 코드로 가득한 Linux 커널 및 C 라이브러리의 CISC(x86) 및 RISC(ARMv7) 버전의 양자와 같이 복잡하고 보수적인 코드의 안정적이고 보수적인 링크 타임 재기록을 수행하기 충분하다는 것을 보여주었다.
디버거의 크고 일반적인 부분인 "미니-디버거"는 표준 컴파일러로 사전 컴파일된 다음 보호될 애플리케이션에 간단히 링크될 수 있다. 마이그레이션된 각각의 프래그먼트에 대한 디버그 루프의 프롤로그 및 에필로그와 같은 다른 부분은 특정 프래그먼트에 대한 이들이 주문화된 바와 같이 링크-타임 재기록기에 의해 생성된다.
링크 타임 재기록기가 소스 코드에서 주석처리된 프래그먼트을 식별할 수 있도록 하기 위해 소스 코드 파일에서 추출된 라인 번호 정보를 전달(pass)하고 컴파일러가 디버그 정보를 지닌 오브젝트 파일을 생성하도록 하는 것으로 충분하다. 그런 다음 디버그 정보는 바이너리 코드 내의 모든 주소를 소스 라인 번호에 매핑하여, 재기록기는 주석의 라인 번호에 링크할 수 있다.
바이너리, 라이브러리 및 프로세스
링크 타임 재기록기는 단계 s35에서 보호된 애플리케이션을 생성하기 위한 두 가지 옵션을 갖는다. 첫 번째 옵션은 두 개의 바이너리를 생성하는 것인데, 하나는 애플리케이션/디버기용이고 다른 하나는 디버거용이다. 보안 측면에서, 애플리케이션의 의미(semantics)와 구현이 여러 바이너리로 분산되고 공격자가 보호를 무효시키는 것, 즉 디버기를 원래 애플리케이션에 패치하는 것이 더 어려워지기 때문에 이는 바람직하다. 이 옵션은 추가 런타임 오버 헤드를 도입하지만 디버거를 런칭하면 두 번째 바이너리 로딩을 요구한다.
아래의 추가 예에서 사용되는 대안적인 옵션은 모든 디버기 코드와 모든 디버거 코드를 하나의 바이너리에 포함시키는 것이다. 이 경우 간단한 분기로 디버거를 런칭할 수 있다. 여부와 상관없이, 그리고 어느 정도까지, 이는 셀프 디버깅에 의해 제공되는 보호에 대한 공격을 완화시키는 것은 알려져 있는 연구 문제이다.
구현
초기화 및 종료화(Initialization & Finalization)
추가의 초기화 루틴은 보호된 바이너리에 추가될 수 있다. 이 루틴은 바이너리가 로드되자마자 호출되고(높은 우선 순위가 할당되어 있기 때문), 그 후에 바이너리의 .int의 섹션 내에 나열된 다른 모든 루틴이 실행된다.
이 초기화 루틴은 fork()를 호출하여 부(parent) 및 자(child)라는 두 개의 프로세스를 생성한다. 초기화 루틴이 완료되면 부 프로세스는 일반적으로 다음 초기화 루틴을 호출하여 실행을 계속한다.
디버거 및 디버기 역할을 할당하기 위한 두 가지 옵션이 존재한다. 분기 후, 자 프로세스가 부 프로세스에 연결되거나 부 프로세스가 자 프로세스에 연결된다. 전자의 경우, 자 프로세스는 디버거가되고 부 프로세스는 디버기가 된다. 후자의 경우 역할은 명확히 역전된다.
전자의 옵션이 선호된다. 부 프로세스(즉, 디버기(debuggee))는 메인 애플리케이션 프로세를 유지하고 동일한 프로세스 ID(PID)를 유지한다. 이는, 예를 들면 보호 라이브러리의 로딩 및 분기(forking) 전에 그들이 설정되기 때문에, 원래의 PID에 의존하는 모든 외부의 애플리케이션 및 프로세스간 통신 채널의 계속적인 실행 또는 사용을 용이하게 한다.
그러나 이 스킴은 그 자체 문제가 있다. 전술한 바와 같이, 공유 라이브러리는 프로그램 실행 중 어느 순간에서도(dlopen() 및 dlclose())를 사용하여 로드 및 언로드될 수 있다. 따라서 원래 로드 및 분기된 디버거가 초기화를 아직 완료하지 않은 상태에서 보호 공유 라이브러리가 다시 언로드되고 로드될 수 있다는 잠재적 문제점이 있다. 이는 이로 인해 두 개의 디버거 프로세스가 동시에 존재할 수 있고, 양자 모두 디버기에 연결하기 위해 시도를 한다(하나는 실패됨). 이 상황을 피하기 위해 dlopen()을 호출한 스레드의 실행을 차단하다. 따라서 그 시간까지, 그 스레드는 dlopen()에서 얻은 핸들을 사용하여 dlclose()를 호출할 수 없고, 핸들을 다른 스레드로 전달할 수도 없다. 디버기의 초기화 루틴 내의 무한 루프는 디버거가 그 처리를 허용하기 이전에 스레드의 로딩이 초기화 루틴으로부터 탈출하는 것을 방지한다.
초기화 루틴은 또한 종료자(파이널라이저)를 디버기에 설치하다. 이 종료자는 많은 일을 하지 않는다. 프로그램 종료시(또는 공유 라이브러리가 언로드 될 때), 이는 미니-디버거로 하여금 모든 디버기 스페드로부터 분리하도록 하여 디버거 프로세스의 셧 다운을 유발하는 SIGUSR1 신호를 발생시켜 이런 사실을 미니-디버거에 단순히 알려준다.
멀티스레드 지원
특히 보호된 공유 라이브러리의 경우에는 디버거의 연결은 간단하지 않다. 라이브러리가 로드될 때, 애플리케이션은 여러 스레드로 구성될 수 있다. 그 중 하나의 스레드만이 dlopen을 호출하는 동안 디버기 초기화 루틴을 실행한다. 하나의 포크만 실행되기 때문에 이는 바람직하지만, 단 하나의 스레드만이 이전 섹션에서 언급한 무한 루프로 들어가는 단점이 있다. 디버기 프로세스 내의 다른 스레드는 계속 실행되며, 디버기 초기화 루틴 또는 디버거 초기화 루틴 실행 중 어는 지점에서라도 새 스레드를 생성할 수 있다. 적절한 보호를 보장하기 위해, 디버거는 그 초기화의 일부로서 디버기 프로세스의 모든 스레드에 연결되어야 한다. 그 동안 디버기에서 생성된 어떤 스레드라도 디버거에서 놓치지 않는 것을 보장하기 위해 프로세스의 모든 스레드에 대한 엔트리(entry)를 포함하는 /proc/[pid]/task 디렉토리를 사용한다. 디버거 프로세스는 이 디렉토리 내의 엔트리들을 반복처리하고 새로운 엔트리가 발견되지 않을 때까지 이 반복 처리를 유지하여 모든 스레드에 연결한다. PTRACE_ATTACH 요청을 통해 발생되는 스레드에 대한 연결시, 스레드 또한 중지되고(디버거는 OS에 의해 이 이벤트를 수신함), 이는 새로운 스레드를 더 이상 생성할 수 없음을 의미한다. 따라서 유한한 수의 스레드를 생성하는 어떤 프로그램에 있어서도 모든 스레드에 연결하는 반복 프로시저가 종료되는 것이 보장된다. 모든 스레드가 일단 연결되어 지면 디버기 내의 무한 루프가 종료되고 중지된 스레드는 계속되는 것이 허용될 수 있다. 프로그램 실행 중에 나중에 추가 스레드가 생성되면 디버거는 OS에 의해 자동으로 그들에 연결되며 필요한 모든 부기(bookkeeping)이 수행될 수 있는 신호를 취득한다.
제어 흐름
마이그레이션된 코드 프래그먼트의 내부 및 외부에서의 제어 흐름의 변환은 여러 부분으로 구성된다. 본 발명에서는 디버거에 통보에 대한 예외 발생, 디버거에게 실행될 프래그먼트를 알려주는 ID 전송, 모든 코드 프래그먼트에 추가된 사용자 정의 프롤로그 및 에필로그에 대해 논의한다.
예외 발생(Rasing Exceptions)
디버거의 실제 통보는 예외 발생을 유발하는 모든 명령어를 통해 일어날 수 있다. 구현에 있어서, 본 발명은 단순화를 위해 소프트웨어 브레이크 포인트(즉, ARMv7의 BKPT 명령어)를 사용한다. 이외에, 불법적이거나 정의되지 않은 명령어에 의해 야기되는 것들과 같이 눈에 덜 띄는 예외가 물론 사용될 수 있다. 그러한 명령이 직접 제어 흐름(직접 분기(branch) 또는 폴스 스루 경로(fall-through path))을 통해 도달할 수 있을 때 이들은 정적(statically)으로 쉽게 감지될 수 있다. 그러나 간접 제어 흐름 전송을 사용하여 코드 섹션 내의 데이터로 점프하고 데이터 비트가 불법적이거나 정의되지 않은 명령어에 대응하는 경우, 정적 감지가 훨씬 더 어려워 질 수 있다. 유사하게, 그들의 피연산자(operand)가 "유효하지 않은(invalid)" 경우에만 예외를 생성(throw)하는 합법적인 명령이, 명령의 목표를 무효하도록 사용될 수 있다. 이러한 명령은 제로에 의한 나눗셈(division), 유효하지 않은 메모리 액세스(즉, 세그먼테이션 결함) 또는 유효하지 않은 포인터의 역 참조(버스 오류를 야기)를 포함한다.
ID 전송(Transferring IDs)
본질적으로 디버거에게 일부 코드 프래그먼트을 실행하도록 요청하는 것과 같이, 본 발명은 요청 스레드에 예외를 발생시키는 디버그 스레드를 호출한다.
디버거는 OS에 의한 요청에 대해 통보받은 후 어떤 프래그먼트를 실행할 것인지 알아내야 한다. 이를 가능하게 하기 위해, 디버기는 여러 가지 방법으로 프래그먼트의 ID를 전달할 수 있다. 하나의 옵션은 단순히 명령을 포홈하는 예외의 주소를 ID로 사용하는 것이다. 다른 옵션은 예외를 발생시키기 바로 전에 고정 레지스터 내에 또는 고정 메모리 위치에 ID를 배치하는 것에 의해 ID를 전달하는 것이다. 구현시 후자의 옵션이 사용된다. 디버기 내에서 여러 스레드가 동시에 상이한 프래그먼트을 요청할 수 있으므로 메모리 위치는 글로벌 위치가 될 수 없다. 대신에, 스레드-로컬이어야 한다. 각각의 스레드는 그 자체 스택을 가지고 있기 때문에, 본 발명은 프래그먼트의 ID를 쓰레드 요청 스택의 탑부를 통해 전달하는 것을 선택하였다.
예외를 발생하는데 사용된 명령어 유형에 따라 물론 다른 방법도 구상될 수 있다. 예를 들면, 나눗셈(제로에 의한) 명령의 나누기 피연산자가 ID를 전달하는 데에도 사용될 수도 있다.
프롤로그와 에필로그
미니-디버거의 디버거 루프는, 프래그먼트가 실행되기 전에, 디버기의 프로그램 상태를 페치하고 그 실행 후 다시 전송하는 책임이 있다. 이를 위해 표준 ptrace 기능이 사용된다.
모든 마이그레이션된 코드 프래그먼트에 대해, 디버그 루프는 코드 프래그먼트 응답(resp) 전과 후에 실행될 사용자 정의 프롤로그 및 에필로그를 포함한다. 프롤로그는 구조(struct)로부터 필요한 값을 레지스터에 로드하고 에필로그는 필요한 값을 구조에 다시 기록한다. 프롤로그는 프래그먼트에서 실제로 사용되는 레지스터(소위 상주(live-in) 레지스터로 불림)만 로드한다는 관점에서 사용자화된다. 에필로그는 만료되고(live-out)(즉, 디버기에서 소비됨), 코드 프래그먼트에서 덮어 쓰여진 값만 저장한다.
메모리 액세스
마이그레이션된 코드 프래그먼트의 모든 로딩 또는 저장 연산에 있어서, 디버기 메모리에 대한 액세스가 필요로 된다. 이러한 액세스를 구현하는 여러 옵션이 존재한다. 첫 번째는 단순히 ptrace 기능을 사용하는 것이다. 디버거는 디버기의 주소 공간에서 읽고 쓰기 위해 PTRACE_PEEKDATA 및 PTRACE_POKEDATA 요청을 수행 할 수 있다. 이 경우 워드당(per word) 읽기 또는 쓰기를 위해 ptrace 시스템 호출이 필요하며 이는 상당한 오버 헤드를 야기한다. 최근의 일부 Linux 버전은 더 넓은 액세스를 지원하지만 이들은 Android와 같이 어디서나 이용가능한 것은 아니다.
두 번째 옵션은 디버거 내에서 디버기의 /proc/[pid]/mem 파일을 열고 이 파일을 읽기하거나 쓰기 하는 것이다. 이는 구현하기가 더 쉽고 단일 시스템 호출로 더 넓은 데이터를 읽거나 쓸 수 있으며 따라서 종종 이 방법이 더 빠르다. 그러나 다른 프로세스의 /proc/[pid]/mem에 대한 쓰기는 Linux/Android 커널의 모든 버전에서 지원되지 않으므로 본 발명의 프로토 타입 쓰기 요청은 여전히 첫 번째 옵션으로 구현된다.
세 번째 옵션은 두 번째 옵션에서 만들어진다: 바이너리 재기록기가 마이그레이션된 코드 프래그먼트에서 어떤 메모리 페이지를 엑세스할지 결정하는 경우, 디버그 루프는 실제로 옵션 2를 사용하여 이들 페이지를 디버거 주소 공간에 복사 할 수 있다. 디버거 내의 프래그먼트 그런 다음 복사된 페이지에 액세스하기 위해 정규의 로드 및 저장 연산을 실행하고, 프래그먼트가 실행 된 후, 업데이트된 페이지가 다시 디버기에 복사됩니다. 이 옵션은 예를 들면 코드 프래그먼트가 스택의 버퍼에 액세스하는 루프를 포함하는 경우 더 빠를 수 있다. 세 번째 옵션과 이전 두 개의 옵션을 비교하기 위해 수행된 실험에서 이 기술은 최대 8개 메모리 액세스에 대해 가치가 있는 것으로 밝혀졌다. 그러나 본 발명은 본 발명의 프로토 타입에서 이를 신뢰성 있는 지원을 구현하지는 못하였다. 코드 프래그먼트에 의해 액세스될 페이지를 결정하기 위한 보수적인 링크-타임 분석은 이 시점에서 향후 작업으로 남겨졌다.
네 번째로 가능한 옵션은 할당된 모든 메모리(또는 적어도 힙(heap))가 디버거와 디버기 사이의 공유 메모리로서 할당되도록 사용자 정의 힙 메모리 관리 라이브러리(malloc, free, ...)를 제공하여 디버그를 저긍하는 것이다. 이어서 디버거 내의 코드 프래그먼트가 직접적으로 데이터에 액세스할 수 있다. 물론 두 개의 주소 공간 사이에 주소 변환을 포함하도록 프래그먼트을 재기록할 필요가 있지만 이 옵션의 오버 헤드는 다른 옵션의 오버 헤드보다 훨씬 적을 수 있다. 이 옵션을 구현하고 이를 평가하는 것은 이 시점에서 향후 작업으로 남겨졌다.
보안 관점에서, 상이한 옵션은, 이들이 공격자가 프로그램의 원래 시멘틱을 역-엔지니어링하고 또한 셀프-디버깅 버전을 원래의 프로그램의 등가물로 해체하는데 어려움을 주는 관점에서 상이한 영향을 갖는다.
셀프 디버깅과 다른 보호 기능의 결합
MATE 공격에 대한 강력한 소프트웨어 보호를 제공하기 위해, 추가 보호 기술이 채용가능하다. 예를 들면, 셀프 디버깅 상부에 모든 종류의 공격을 방지하기 위해 안티-탬퍼링(anti-tampering) 기술과 함께 정적 분석을 방지하기위한 난독화(obfuscation)가 사용될 수 있다.
예를 들면, 셀프 디버깅 방법을 구현하는 바이너리 재기록기는 다음 중 하나 이상과 같은 여러 가지 다른 보호를 적용할 수 있다.
· 제어 흐름 난독화: 불투명한 술어(predicates)의 공지된 난독화, 제어 흐름 플랫화(flattening), 및 브랜치 함수;
· 코드 레이아웃 랜덤화: 코드 레이아웃 중에 모든 함수로부터의 코드가 혼합되고 레이아웃이 랜덤화됨;
· 코드 이동성 : 정적 바이너리에서 코드 프래그먼트을 제거하고, 런타임에서 소위 모바일 코드처럼 애플리케이션에 다운로드하는 기술;
· 코드 가드(guards): 코드가 변경되지 않았는지 체크하기 위해 해시가 프로세스 주소 공간 내의 코드 상에서 계산되는 기술의 온라인 및 오프라인 구현;
· 제어 흐름 무결성: 내부 함수가 외부의 코드로부터 호출되는 것을 방지하기 위해 리턴 주소가 체크되는 간단한 기술;
· 명령어 세트 가상화: 네이티브 코드가 네이티브로 실행되는 대신 내장된 가상 머신에 의해 번역된 바이트코드로 번역되는 기술.
셀프 디버깅 기술과 모든 보호 기능을 결합하는 것은 실제 문제가 되지 않는다. 링크 타임 재기록기에서, 모든 보호에 대한 모든 변환을 수행하기 위해 양호한 순서를 결정하고, 이들 기술들이 실제로 작성되지 않은 경우 여러 기술들을 동일한 코드 프래그먼트에 적용하는 것을 방지하는 것은 어렵지 않다. 예를 들면, 모바일 코드는 임의의 위치로 재배치될 수 있다. 모든 보호를 정확하게 처리하는 것은 약간의 부기가 필요하지만 복잡한 것은 아니다.
런타임 동작에 관해서 기술도 함께 구성된다. 여러 기술들은 초기화자 및 종료자를 필요로 하지만, 본 발명에서는 디버거 프로세스는 디버거일 뿐이며 코드 이동성이나 다른 기술을 위한 다른 클라이언트가 아니어야 하므로, 디버거 프로세스에서 다른 보호의 초기화자를 실행하는 것을 원하지 않았다. 다른 초기화자가 실행되는 것을 방지하기 위해 셀프 디버거 초기화자에는 가장 높은 우선순위가 부여된다. 이들은 바이너리 또는 라이브러리가 로드될 때 먼저 실행되고, 디버거 초기화 루틴은 실제 초기화자와 디버그 루프 모두를 구현하다. 그러므로 루틴은 절대 끝나지 않으며(즉, 종료자가 호출되지 않는 한) 컨트롤은 바이너리에 있을 수도 있는 다른 초기화자로로 절대 전달되지 않는다.
평가
평가 플랫폼
셀프 디버거의 하나의 구현은 ARMv7 플랫폼을 대상으로 한다. 구체적으로, 이 구현예는 Linux 3.15 및(unrooted)Android 4.3 + 4.4에서의 구현을 대상으로 광범위하게 평가된다. 이 기술은 여전히 리눅스(4.7)와 안드로이드(7.0)의 최신 버전에서 작동한다는 것이 확인되었으며, 또한 이는 사실이다.
테스트 하드웨어는 여러 개발자 보드(developer board)로 구성되었다. Linux의 경우 단일 코어 Texas Instruments OMAP4 프로세서를 이용하는 Panda 보드, 이중 코어 Samsung Exynos 프로세서를 이용하는 Arndale 보드 및 단일 코어 프리스케일 i.MX6q 프로세서를 이용하는 Boundary Device Nitrogen 6X/SABRE Lite 보드가 사용되었다. 후자의 보드는 안드로이드 버전에도 이용되었다.
툴 체인에서, GCC 4.8, LLVM 3.4 및 GNU binutils 2.23이 사용되었다. 코드는 다음 플래그로 컴파일되었다 : -Os-march=armv7-a-marm-mfloat-abi = softfp -mfpu = neon-msoft-float.
사용 사례(Use cases)
셀프 디버깅 방법은 여러 사용 사례에서 기능하는 것으로 나타났다. 예를 들면 디지털 저작권 관리 시나리오에서 다음과 같은 실질적인 고려 사항이 발생되었다.
이 사용 사례는 Android 미디어 프레임 워크와 Android DRM 프레임 워크용에서 C 및 C ++로 작성된 두 개의 플러그인으로 구성된다. 이들 라이브러리는 암호화 된 동영상에 대한 액세스를 얻고 이들을 해독하는데 필요하다. Java로 프로그래밍 된 비디오 앱은 비디오에 액세스하기 위한 GUI로 사용된다. 이 애플리케이션은 안드로이드의 미디어서버 및 DRM 프레임 워크와 통신하여 플러그인이 필요한 벤더의 프레임 워크에 통보한다. 필요에 따라 이 프레임 워크는 플러그인을 로드한다. 구체적으로, 이러한 서버는 Android에서 실행되는 미디어서버 및 drm서버 프로세스이다.
실험 및 개발 중에, 이 사용 사례를 이 기술에 대한 완벽한 스트레스 테스트로 만드는 몇 가지 기능이 관찰되었다. 첫째, 미디어서버는 멀티 스레드이며 항상 새로운 스레드를 생성하고 종료시킨다. 둘째, 플러그인 라이브러리가 종종 로드되고 언로드된다. 경우에 따라 라이브러리 초기화가 완료되기 전에 언로드가 시작된다. 셋째, 프로세스가 충돌하자마자 새로운 인스턴스가 런칭된다. 경우에 따라 이는 Java 비디오 플레이어가 방해받지 않고 기능하도록 허용할 수 있으며, 그렇지 않을 수도 있다. 이는 본 발명의 기술 구현을 단순한 어플리케이션을 위해 이미 존재하는 것들 보다 복잡하게 한다. 네 번째로, 미디어서버와 drm서버는 프로세스 간 통신에 빈번하게 포함된다. 그럼에도 불구하고 전술한 원칙에 따라 성공적인 구현이 이루어졌다.
이 기술은 다른 많은 사용 사례 시나리오에 적용될 수도 있다. 예를 들면, 보안이 필요한 임의적인 다른 시나리오의 모바일 뱅킹을 예로 들 수 있다.
도 4는 컴퓨팅 장치로 하여금 여기에서 논의된 방법 중 하나 이상을 수행하게 하는 명령 세트가 실행될 수 있는 컴퓨팅 장치(400)의 구현예의 블록도를 나타낸다. 대안적인 구현예에서, 컴퓨팅 장치는 근거리 통신망(LAN), 인트라넷, 엑스트라넷 또는 인터넷 내의 다른 기계들에 접속(예를 들면, 네트워크 연결됨)될 수 있다. 컴퓨팅 장치는 클라이언트-서버 네트워크 환경에서 서버 또는 클라이언트 머신의 용량으로 동작하거나, 피어-투-피어(또는 분산) 네트워크 환경에서 피어 머신으로서 동작할 수 있다. 컴퓨팅 장치는 개인용 컴퓨터(PC), 태블릿 컴퓨터, 셋톱 박스(STB), 개인 휴대 정보 단말기(PDA), 셀룰러 전화, 웹 기기, 서버, 네트워크 라우터, 스위치 또는 브릿지, 또는 그 머신에 의해 취해지는 특정 액션을 지정하는 일련의 명령(순차적 또는 기타)을 실행할 수 있는 임의의 머신일 수 있다. 또한, 단지 하나의 컴퓨팅 장치가 도시되어 있지만, "컴퓨팅 장치"라는 용어는 본 명세서에서 논의된 하나 이상의 방법을 수행하기 위해 명령어의 하나의 집합(또는 여러 집합)을 개별적으로 또는 공동으로 실행하는 머신들(예를 들면 컴퓨터)의 임의의 집합을 포함할 수 있다.
예시적인 컴퓨팅 장치(400)는 프로세싱 장치(402), 메인 메모리(404)(예를 들면, ROM, 플래시 메모리, 및 SDRAM 또는 RDRAM 등의 DRAM 등), 정적 메모리(406)(예컨대, 플래시 메모리, SRAM 등), 및 각각의 다른 버스(430)을 통해 통신하는 2차 메모리(예를 들면, 데이터 저장 장치(418))를 포함한다.
프로세싱 장치(402)는 마이크로 프로세서, 중앙 프로세싱 장치 등과 같은 하나 이상의 범용 프로세서를 나타낸다. 특히, 프로세싱 장치(402)는 CISC(complex instruction set computing) 마이크로 프로세서, RISC(reduced instruction set computing) 마이크로 프로세서, VLIW(very long instruction word) 마이크로 프로세서, 다른 명령 세트를 구현하는 프로세서, 또는 명령어 세트의 조합을 구현하는 프로세서일 수 있다. 프로세싱 장치(402)는 ASIC(Application Specific Integrated Circuit), FPGA(field programmable gate array), DSP(digital signal processor), 네트워크 프로세서 등과 같은 하나 이상의 특수 목적 프로세싱 장치일 수도 있다. 프로세싱 장치(402)는 본 명세서에서 논의된 동작들 및 단계들을 수행하기 위한 프로세싱 로직(명령들(422))을 실행하도록 구성된다.
컴퓨팅 장치(400)는 또한 네트워크 인터페이스 장치(408)를 더 포함할 수 있다. 컴퓨팅 장치(400)는 또한 비디오 디스플레이 유닛(410)(예를 들면, 액정 디스플레이(LCD) 또는 브라운관(CRT)), 영숫자 입력 장치(412)(예를 들면, 키보드 또는 터치 스크린), 커서 제어 장치(414)(예를 들면, 마우스 또는 터치 스크린), 및 오디오 장치(416)(예를 들면, 스피커)를 포함할 수도 있다.
데이터 저장 장치(418)는 하나 이상의 머신 판독가능 저장 매체(또는 더 구체적으로는 하나 이상의 비일시적 컴퓨터 판독가능 저장 매체)(428)를 포함 할 수 있으며, 여기에는 전술한 방법 또는 기능들 중 하나 이상을 포함하는 명령어(422)의 하나 이상의 세트가 저장되어 진다. 명령(422)은 또한 컴퓨터 시스템(400)에 의해 그들이 실행되는 동안 메인 메모리 또는 프로세싱 장치(402) 내에서 완전히 또는 적어도 부분적으로 상주하며, 메인 메모리(404) 및 프로세싱 장치(402)는 또한 컴퓨터 판독가능 저장 매체를 구성한다.
전술한 다양한 방법들은 컴퓨터 프로그램에 의해 구현될 수 있다. 컴퓨터 프로그램은 컴퓨터로 하여금 전술한 하나 이상의 다양한 방법의 기능을 수행시키기 위해 지시하도록 구성된 컴퓨터 코드를 포함할 수 있다. 그러한 방법을 수행하기 위한 컴퓨터 프로그램 및/또는 코드는 컴퓨터와 같은 장치, 하나 이상의 컴퓨터 판독가능 매체 또는 보다 일반적으로는 컴퓨터 프로그램 제품에 제공될 수 있다. 컴퓨터 판독가능 매체는 일시적 또는 비일시적 일 수 있다. 하나 이상의 컴퓨터 판독가능 매체는 예를 들면 전자, 자기, 광학, 전자기, 적외선 또는 반도체 시스템, 또는 예를 들면 인터넷을 통해 코드를 다운로드 하는 것 같이 데이터 전송을 위한 전파 매체일 수 있다. 대안적으로, 하나 이상의 컴퓨터 판독가능 매체는 반도체 또는 고체 상태 메모리, 자기 테이프, 착탈식 컴퓨터 디스켓, RAM(random access memory), 판독 전용 메모리(read-only memory), 강성 자기 디스크, 및 CD-ROM, CD-R/W 또는 DVD와 같은 광학 디스크 등의 하나 이상의 물리적 컴퓨터 판독가능 매체의 형태를 가질 수 있다.
구현예에서, 본 명세서에 기술된 모듈, 부품 및 다른 특징들(예를 들면, 도 4와 관련한 제어 유닛(410))은 개별 구성요소로서 구현되거나 또는 ASICS, FPGAs, DSPs 또는 개별 서버의 일부분으로서의 유사한 장치들과 같은 기능이 통합된 하드웨어 구성요소로 구현될 수 있다.
"하드웨어 구성요소"는 특정 동작을 수행할 수 있는 실재하는(예를 들면, 비일시적) 물리적 구성요소(예를 들면, 하나 이상의 프로세서 세트)이고, 특정 물리적 방식으로 구성되거나 배열될 수있다. 하드웨어 구성요소는 특정 동작을 수행하도록 영구적으로 구성된 전용 회로 또는 로직(logic)을 포함할 수 있다. 하드웨어 구성요소는 FPGA(Field Programmable Gate Array) 또는 ASIC와 같이 특수 목적용의 프로세서일 수도 있고 이를 포함할 수도 있다. 하드웨어 구성요소는 또한 특정 동작을 수행하기 위해 소프트웨어에 의해 일시적으로 구성되는 프로그래밍 가능한 로직 또는 회로를 포함 할 수있다.
따라서, "하드웨어 구성요소"라는 표현은 전술한 특정 동작을 수행하기 위해 또는 특정 방식으로 동작하기 위해, 물리적으로 구성되거나, 영구적으로 구성되거나(예: 하드 와이어드), 또는 임시적으로 구성된(예를 들면 프로그래밍) 실재하는 엔티티를 강조하는 것으로 이해되어야 한다.
또한, 모듈 및 구성요소는 하드웨어 장치 내의 펌웨어 또는 기능회로로 구현 될 수 있다. 또한, 모듈 및 구성요소는 하드웨어 장치 및 소프트웨어 구성요소의 임의의 조합으로 또는 소프트웨어(예를 들면, 머신 판독가능 매체 또는 전송 매체에 저장된 코드 또는 그에 매설된 다른 것)만으로 구현될 수도 있다.
특별히 언급하지 않는 한, 이하의 설명으로부터 명백한 바와 같이, 명세서 내에서 "수신", "결정", "비교", "가능", "유지", "식별", "대체" 등의 용어는, 컴퓨터 시스템의 레지스터 및 메모리 내의 물리적(전자적) 양으로 표현되는 데이터를 컴퓨터 시스템 메모리 또는 레지스터 또는 다른 정보 저장, 전송, 또는 디스플레이 장치 내의 물리적 양으로 표현되는 유사한 다른 데이터로 조작 및 변환하는 컴퓨터 시스템 또는 유사한 전자 컴퓨팅 장치의 액션 및 프로세스를 나타낸다.
전술한 설명은 예시적인 것으로 제한적이지 않은 것으로 이해되어야 한다. 전술한 설명을 읽고 이해하는 것으로부터 많은 다른 구현예가 가능하다는 것은 당업자에게 자명하다. 본 발명이 특정 예시적인 구현예를 참조하여 설명되었지만, 본 발명은 전술한 구현예에 한정되지 않고 첨부된 청구 범위의 사상 및 범위 내에서 변형 및 변경하여 실시될 수 있다는 것은 자명하다.
따라서, 본 발명의 명세서 및 도면은 제한적인 의미라기보다는 예시적인 의미로 간주되어야 한다. 따라서, 본 발명의 범위는 청구범위가 속하는 등가물의 전체 범위와 함께, 첨부된 청구범위를 참조하여 결정되어야 한다.

Claims (15)

  1. 소프트웨어를 보안하기 위한 방법에 있어서,
    소프트웨어 프로세스를 런칭하는 단계;
    소프트웨어 프로세스에 디버거 프로세스를 첨부(attaching)하는 단계;
    디버거 프로세스가 적어도 한번 호출(invoked)되도록 소프트웨어 프로세스를 실행하는 단계;
    디버거 프로세스의 호출에 응답하여 소프트웨어 프로세스와 연관된 데이터에 의존하는 출력을 갖는 하나 이상의 기능을 상기 디버거 프로세스 내에서 수행하는 단계를 더 포함하는 것을 특징으로 하는 방법.
  2. 제1항에 있어서,
    상기 출력은 상기 소프트웨어 프로세스에서 사용되기 위한 데이터 출력을 포함하는 방법.
  3. 제1항 또는 제2항에 있어서,
    주어진 기능의 출력은 연속 실행을 위한 소프트웨어 프로세스 내의 복수의 리턴 포인트를 나타내는 방법.
  4. 제1항 내지 제3항 중 어느 한 항에 있어서,
    상기 디버거 프로세스는 상기 하나 이상의 기능이 상기 소프트웨어 프로세스의 어드레스 공간 내의 메모리로부터 데이터를 검색할 수 있게 하는 메모리 지원 능력(capabilities)을 제공하는 방법.
  5. 제1항 내지 제4항 중 어느 한 항에 있어서,
    상기 디버거 프로세스는 상기 소프트웨어 프로세스 내의 브레이크 포인트에 도달될 때 호출되는 방법.
  6. 제1항 내지 제5항 중 어느 한 항에 있어서,
    상기 소프트웨어 프로세스가 완료될 때 상기 소프트웨어 프로세스로부터 상기 디버거 프로세스를 분리(detaching)하는 단계를 더 포함하는 방법.
  7. 제1항 내지 제6항 중 어느 한 항에 있어서,
    상기 소프트웨어 프로세스는 애플리케이션과 같은 실행 가능한 것을 구현하는 방법.
  8. 제1항 내지 제7항 중 어느 한 항에 있어서,
    상기 소프트웨어 프로세스는 라이브러리를 구현하는 방법.
  9. 제1항 내지 제8항 중 어느 한 항에 기재된 방법을 수행하기 위한 컴퓨터 실행 가능한 코드를 포함하는 컴퓨터 실행 가능한 프로그램 제품.
  10. 제1항 내지 제8항 중 어느 한 항에 기재된 방법을 수행하도록 구성된 장치.
  11. 보호된 코드를 생성하는 방법에 있어서,
    디버거로 마이그레이션될 오브젝트 코드 내의 코드 프래그먼트(fragments)을 식별하는 단계; 및
    실행시에 디버거 프로세스가 소프트웨어 프로세스에 첨부되도록 야기하는 바이너리 코드를 생성하는 단계 - 상기 식별된 코드 프래그먼트는 상기 디버거 프로세스 내에서 실행됨 - ; 를 포함하는 것을 특징으로하는 방법.
  12. 제11항에 있어서,
    상기 바이너리 코드를 생성하는 단계는 상기 바이너리 코드 내에 일반 디버거 기능에 대응하는 미리 정의된 코드를 통합(incorporating)하는 단계를 포함하는 방법.
  13. 제11항 또는 제12항에 있어서,
    상기 바이너리 코드는 식별된 코드 프래그먼트를 제외하고 소스 코드에 대응하는 제1 바이너리 코드 파일 및 상기 디버거에 대응하는 제2 바이너리 코드 파일을 포함하는 방법.
  14. 제11항 내지 제13항 중 어느 한 항에 기재된 방법을 수행하기 위한 컴퓨터 실행 가능한 코드를 포함하는 컴퓨터 실행 가능한 프로그램 제품.
  15. 제11항 내지 제13항 중 어느 한 항에 기재된 방법을 수행하도록 구성된 장치.
KR1020197017015A 2016-12-05 2017-12-05 셀프 디버깅 KR102684371B1 (ko)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
EP16202259.4 2016-12-05
EP16202259.4A EP3330859A1 (en) 2016-12-05 2016-12-05 Self-debugging
PCT/EP2017/081587 WO2018104344A1 (en) 2016-12-05 2017-12-05 Self-debugging

Publications (2)

Publication Number Publication Date
KR20190090810A true KR20190090810A (ko) 2019-08-02
KR102684371B1 KR102684371B1 (ko) 2024-07-11

Family

ID=

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
KR102271273B1 (ko) * 2020-11-26 2021-06-29 숭실대학교산학협력단 네이티브 코드 분석방지 우회를 위한 프로세스 래핑 방법, 이를 수행하기 위한 기록 매체 및 장치
US11886589B2 (en) 2020-11-26 2024-01-30 Foundation Of Soongsil University-Industry Cooperation Process wrapping method for evading anti-analysis of native codes, recording medium and device for performing the method

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
KR102271273B1 (ko) * 2020-11-26 2021-06-29 숭실대학교산학협력단 네이티브 코드 분석방지 우회를 위한 프로세스 래핑 방법, 이를 수행하기 위한 기록 매체 및 장치
WO2022114391A1 (ko) * 2020-11-26 2022-06-02 숭실대학교 산학협력단 네이티브 코드 분석방지 우회를 위한 프로세스 래핑 방법, 이를 수행하기 위한 기록 매체 및 장치
US11886589B2 (en) 2020-11-26 2024-01-30 Foundation Of Soongsil University-Industry Cooperation Process wrapping method for evading anti-analysis of native codes, recording medium and device for performing the method

Also Published As

Publication number Publication date
CN110088736A (zh) 2019-08-02
BR112019011434A2 (pt) 2019-10-22
JP7042270B2 (ja) 2022-03-25
US20190286551A1 (en) 2019-09-19
EP3330859A1 (en) 2018-06-06
US11580007B2 (en) 2023-02-14
CN110088736B (zh) 2023-05-23
PT3549020T (pt) 2021-12-02
EP3549020A1 (en) 2019-10-09
WO2018104344A1 (en) 2018-06-14
JP2019537150A (ja) 2019-12-19
ES2901532T3 (es) 2022-03-22
EP3549020B1 (en) 2021-10-13

Similar Documents

Publication Publication Date Title
Williams-King et al. Egalito: Layout-agnostic binary recompilation
US11580007B2 (en) Self-debugging
Kroes et al. Delta pointers: Buffer overflow checks without the checks
EP3906488B1 (en) Method and contract rewriting framework system for supporting smart contracts in a blockchain network
Simon et al. What you get is what you C: Controlling side effects in mainstream C compilers
CA2930424C (en) Improved control flow integrity system and method
Volckaert et al. Cloning your gadgets: Complete ROP attack immunity with multi-variant execution
US20100095281A1 (en) Internal Function Debugger
Abrath et al. Tightly-coupled self-debugging software protection
US20230267067A1 (en) Software protection from attacks using self-debugging techniques
Stüttgen et al. Robust Linux memory acquisition with minimal target impact
Saito et al. A survey of prevention/mitigation against memory corruption attacks
TWI801505B (zh) 帶鏈結分支指令的分支目標變體
Arras et al. SaBRe: load-time selective binary rewriting
Di Bartolomeo et al. {ARMore}: Pushing Love Back Into Binaries
KR102684371B1 (ko) 셀프 디버깅
Pappas Defending against return-oriented programming
Harper‐Cyr et al. Fast and flexible tracepoints in x86
Sotirov Hotpatching and the rise of third-party patches
Muntean et al. ρFEM: Efficient Backward-edge Protection Using Reversed Forward-edge Mappings
Majlesi-Kupaei et al. A Framework for Robust, Low-Overhead Binary Instrumentation
Wurster et al. Towards efficient dynamic integer overflow detection on ARM processors
Saeed et al. Tag‐Protector: An Effective and Dynamic Detection of Illegal Memory Accesses through Compile Time Code Instrumentation
Rasmussen et al. Dynamic Software Updating with Gosh! Current Status and the Road Ahead
Thakar Secure RISCV Design for Side-Channel Evaluation Platform

Legal Events

Date Code Title Description
E902 Notification of reason for refusal
AMND Amendment
E90F Notification of reason for final refusal
AMND Amendment
E601 Decision to refuse application
AMND Amendment
E902 Notification of reason for refusal
AMND Amendment
X701 Decision to grant (after re-examination)