[논문리뷰] LLM4Decompile: Decompiling Binary Code with Large Language Models

Genne Chung·2024년 3월 19일
0

Introduction

Decompile

디컴파일이란 기계어를 사람의 코드로 번역하는 과정이다.

예전에 학부 시절에 잠시 어셈블리를 배웠던 적이 있는데, 이 어셈블리 코드로부터 고수준 코드(파이썬, C, C++같은)로 변환하는 과정을 디컴파일이라고 한다.

예-전 학부때 배웠던 것을 떠올려 보자면 원래 코드는 다음과 같은 과정으로 만들어진다.

(블록 코딩 ->) 고수준 언어(C, java, python, ruby, scalar, ...)로 코드 작성 -> 저수준 코드 -> 바이너리

고수준 언어에서 저수준 언어로 우선 컴파일을 진행하고, 컴파일된 코드를 컴퓨터가 실행할 때 알아서 바이너리로 해석된다. 그래서 파이썬 같은 인터프리터 기반 코드 말고 컴파일러가 붙은 자바나 C 같은 경우 한 번 코드를 컴파일한 뒤 사용한다.

그럼 왜 디컴파일을 해야 되는가? 찾아보니 다음과 같은 이유들이 있다고 한다.

  1. 원본 코드에 접근할 수 없는데 원본 코드 정보를 알아내야 함: 버그가 생겼거나 하는 경우
  2. 호환성: 다른 코드로 바꾸고 싶어요
  3. 보안 취약점 탐색: 디컴파일된 코드를 통해 개선점을 찾을 수 있다고 한다

Decompile LLM

transformer를 활용한 모델은 존재했었다고 한다. 그러나 현재 LLM의 정확도나 비-hallucination 정도가 많이 올라간 상황에서, 해당 구조를 사용하여 디컴파일을 할 수 있겠다는 생각이 들어 LLM에 디컴파일 데이터를 먹였다고 한다.

Methods

큰 모델 학습용 데이터를 잘 만들었다.

우선 코드 페어 자체는 Anghabench라는 compilable c 파일 public collection을 통해 만들었다고 한다.
(잘 모르지만) 컴파일 시 optimization level이라는 것이 존재한다고 한다. 보통 O0(no optimization)에서 O3(Agressive optimization - 대신 시간이 오래 걸린다고 함)까지 존재하는데, 이를 코드마다 프롬프트에 태그처럼 달아서 모델이 해당 optimization level에 따라 다르게 생성하도록 했다고 한다.

데이터는 이렇게 만들고, 학습할 때 objective를 실험을 통해 결정했다.

보통 language model의 경우 모델의 형태에 따라 세 가지 objective가 생긴다.

  1. mask 맞추기
  2. sequence to sequence(sts)
  3. next token prediction(stp)

사실 굳이 타고들어가면 더 있지만, 일단 기본적으로 1 -> bert 2 -> T5 3 -> CLM 이다. (사실 T5같은 인코더-디코더 모델은 1,2가 동시에 있다)

여하튼 입출력이 asm -> src(src code) 인 것이니 1은 제외하고 2와 3중에 training objective 를 고른다.

2를 선택할 경우 src가 라벨이 되고, 3을 선택할 경우 asm+src가 라벨이 된다.

실험을 통해 2를 사용하는 것이 가장 도움이 되었다는 것을 밝혔다

sts랑 ntp를 같이 사용할 수 있지만 재컴파일에서 실패할 가능성이 더 컸기 때문에 적합하지 않았다고 판단했다.

profile
NLP / LLM

0개의 댓글

관련 채용 정보