VMWare에 Ubuntu 24.04 환경을 세팅하고 Tigress를 이용하여 코드 난독화를 진행하였다.

https://tigress.wtf/tigress-download.html
해당 링크에서 Linux버전으로 설치 하였고
sudo apt install -y build-essential ocaml ocaml-findlib camlp4 libsqlite3-dev wget unzip
sudo dpkg --force-architecture -i tigress_4.0.10-1_any.deb
tigress --version
위 명령어를 통해 설치하면 되고 마지막 버전이 잘 뜬다면 성공적으로 설치된 것이다.
tigress \
--Verbosity=1 \
--Environment=x86_64:Linux:Gcc:5.1 \
--Transform=Virtualize \
--Functions=main \
--out=result.c test1.c
난독화 실행 코드다. c를 c언어로 난독화 하며, 위의 명령어는 가상화 난독화를 수행하는 명령어다. 난독화 할 함수를 지정이 가능한데 --Functions 뒤에 난독화 하고 싶은 함수를 지정해 주면 된다.
지금까지 생성한 데이터셋 코드들을 난독화 해야 하기 때문에, 이를 python 코드로 자동으로 난독화를 수행하였다.
import os
import subprocess
SOURCE_DIR = "AtCoder"
OUTPUT_DIR_FLATTENING = "Flattening"
OUTPUT_DIR_OPAQUE = "OpaquePredicate"
TIGRESS_CMD = "tigress"
TIGRESS_ENV = "--Environment=x86_64:Linux:Gcc:5.1"
VERBOSITY = "--Verbosity=0"
TRANSFORM_FLATTEN = "--Transform=Flatten"
TRANSFORM_OPAQUE = "--Transform=InitOpaque"
FUNCTIONS = "--Functions=main"
MAX_FILES = 2500
TIMEOUT_SECONDS = 5
# 출력 폴더 생성
os.makedirs(OUTPUT_DIR_FLATTENING, exist_ok=True)
os.makedirs(OUTPUT_DIR_OPAQUE, exist_ok=True)
# C 파일 목록 읽기
try:
c_files = sorted(f for f in os.listdir(SOURCE_DIR) if f.endswith(".c"))[:MAX_FILES]
except FileNotFoundError:
print(f"❌ 디렉토리 '{SOURCE_DIR}'가 존재하지 않습니다.")
exit(1)
processed_prefixes = set()
for idx, filename in enumerate(c_files, 1):
src_path = os.path.join(SOURCE_DIR, filename)
base_name = os.path.splitext(filename)[0]
try:
contest_user = "_".join(base_name.split("_")[:2])
except IndexError:
print(f"⚠️ 파일 이름 형식이 잘못됨: {filename}")
continue
if contest_user in processed_prefixes:
print(f"[SKIP] 이미 처리된 사용자: {contest_user}")
continue
processed_prefixes.add(contest_user)
with open(src_path, 'r') as f:
lines = f.readlines()
if not any("#include <stdlib.h>" in line for line in lines):
insert_idx = 0
for i, line in enumerate(lines):
if line.strip().startswith("#include"):
insert_idx = i + 1
lines.insert(insert_idx, "#include <stdlib.h>\n")
with open(src_path, 'w') as f:
f.writelines(lines)
out_flatten = os.path.join(OUTPUT_DIR_FLATTENING, f"{base_name}_fla.c")
out_opaque = os.path.join(OUTPUT_DIR_OPAQUE, f"{base_name}_opa.c")
# Flattening 난독화
try:
subprocess.run([
TIGRESS_CMD,
VERBOSITY,
TIGRESS_ENV,
TRANSFORM_FLATTEN,
FUNCTIONS,
f"--out={out_flatten}",
src_path
], timeout=TIMEOUT_SECONDS)
except subprocess.TimeoutExpired:
print(f"⏱️ [TIMEOUT] Flattening 실패: {filename}")
continue
# Opaque Predicate 난독화
try:
subprocess.run([
TIGRESS_CMD,
VERBOSITY,
TIGRESS_ENV,
TRANSFORM_OPAQUE,
FUNCTIONS,
f"--out={out_opaque}",
src_path
], timeout=TIMEOUT_SECONDS)
except subprocess.TimeoutExpired:
print(f"⏱️ [TIMEOUT] Opaque 실패: {filename}")
continue
print(f"[{idx}/{len(c_files)}] {filename} 난독화 완료")
print("난독화 끝")
코드는 디렉토리에서 C파일들을 가져와 Tigress Flattening, OpaquePrdicate 난독화를 수행한다. 난독화 할 파일의 개수를 지정이 가능하며, 난독화 수행 시간을 제한하여 초과될 경우 건너 뛰도록 하였다.
OpaquePrdicate 난독화를 하기 위해 <stdlib.h>를 추가하는 코드를 추가하였으며, 파일 이름에서 대회명_유저명 을 고유 값으로 하여 코드가 겹치지 않도록 하였다.


결과적으로 127,280개의 AtCoder사이트를 통해 가져온 non-switch 코드를 이용하여 Flattening 난독화 코드 10,482개, OpaquePredicate 난독화 코드 10,462개의 코드를 생성하였다.