Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
LeetObfuscator — LLVM 패스를 통해 C/C++를 난독화합니다: 문자열 암호화, 제어 흐름 평탄화, MBA 재작성, 그리고 리버스 엔지니어링을 무력화하기 위한 분석 방지 기능. | Kitploit
도구/GitHubGitHub/zydak/leetobfuscator
Code AnalysisReverse EngineeringBinary Analysis
GitHubzydak/leetobfuscator

LeetObfuscator

LLVM 패스를 통해 C/C++를 난독화합니다: 문자열 암호화, 제어 흐름 평탄화, MBA 재작성, 그리고 리버스 엔지니어링을 무력화하기 위한 분석 방지 기능.

저장소 보기
445401개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

LeetObfuscator

██╗     ███████╗███████╗████████╗
██║     ██╔════╝██╔════╝╚══██╔══╝
██║     █████╗  █████╗     ██║
██║     ██╔══╝  ██╔══╝     ██║
███████╗███████╗███████╗   ██║
╚══════╝╚══════╝╚══════╝   ╚═╝

 ██████╗ ██████╗ ███████╗██╗   ██╗███████╗ ██████╗ █████╗ ████████╗ ██████╗ ██████╗
██╔═══██╗██╔══██╗██╔════╝██║   ██║██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗
██║   ██║██████╔╝█████╗  ██║   ██║███████╗██║     ███████║   ██║   ██║   ██║██████╔╝
██║   ██║██╔══██╗██╔══╝  ██║   ██║╚════██║██║     ██╔══██║   ██║   ██║   ██║██╔══██╗
╚██████╔╝██████╔╝██║     ╚██████╔╝███████║╚██████╗██║  ██║   ██║   ╚██████╔╝██║  ██║
 ╚═════╝ ╚═════╝ ╚═╝      ╚═════╝ ╚══════╝ ╚═════╝╚═╝  ╚═╝   ╚═╝    ╚═════╝ ╚═╝  ╚═╝

A simple obfuscator for C/C++ x64 and x86 code

이것은 LLVM 포크로 만들어졌기 때문에 난독화하려면 실제 소스가 필요합니다. 임의의 실행 파일을 난독화하는 도구가 아닙니다. 컴파일러의 수정된 버전입니다.

결과를 확인하고 싶다면, 이것으로 2개의 크랙미를 만들어 난독화했습니다. releases에서 미리 컴파일된 clang 바이너리와 함께 받을 수 있습니다.

  • Crackme1(릴리스 v0.1) - 매우 단순하며, 하드코딩된 키와 사용자 입력을 단일 xor 연산 후 비교합니다. 난독화가 없다면 크랙하는 데 5분이면 충분합니다.
  • Crackme2는 Windows에서 안티디버그가 작동하면 곧 공개될 예정입니다

기능

이 모든 것은 -O3 플래그로 컴파일되었으며 모든 스크린샷은 IDA Pro 9.4에서 가져온 것입니다. Binary Ninja와 Ghidra로도 테스트했으며, 결과는 같거나 더 나빴습니다.

문자열 암호화

컴파일 시점에 문자열을 암호화하고 암호화된 문자열이 사용되는 모든 곳에 복호화 함수를 삽입합니다. 이는 바이너리에서 어떤 문자열도 검색할 수 있는 능력을 완전히 비활성화합니다. 또한 모든 문자열은 복호화 함수에 하드코딩된 고유한 키를 가지고 있어 이를 덤프하고 복호화하는 것을 훨씬 어렵게 만듭니다. 이러한 복호화 함수는 인라인화되기도 합니다. (아래에서는 시연을 위해 인라인화하지 않았습니다)


패스 적용 전

적용 후

혼합 불리언 산술 (MBA)

산술 연산을 MBA 등가 표현으로 대체합니다. 먼저 MBA 디오브푸스케이터를 통해 실행하지 않는 한 원래 연산이 무엇을 했는지 확인하는 것은 사실상 불가능합니다. 물론 이 난독화는 MBA가 가장 오래된 수법이기 때문에 다소 약하며, 이를 처리하는 많은 도구가 있습니다. 예를 들어 CoBRA는 이를 성공적으로 원래 표현식으로 디오브푸스케이트합니다:

./cobra-cli --mba "((x^y) - (((x^y)&0xFF)&0xA) + 10) * ((x^y) - ((x^y)|0xA) + 10) + ((x^y) - (((x^y)&0xFF)|0xFFFFFFF5) - 11) * (~(x^y) - (~(x^y)|0xA) + 10)" --bitwidth 32

10 * (x ^ y)

그래서 제가 AAMBA 패스를 만들었습니다.


패스 적용 전

적용 후

아키텍처 하드닝 MBA (AAMBA)

이진 연산의 피연산자를 ADC(X, 255) - 255 - CF 및 SBB(X, 255) + 255 + CF로 대체합니다. 물론 항상 X로 평가되지만, 표현식을 캐리 플래그에 의존하게 만듭니다. 디컴파일러가 CF의 상태를 추적하지 않는 한(때로는 불가능함) 매우 혼란스러워져 이러한 표현식을 폴딩할 수 없게 됩니다. 이전 MBA 패스와 결합하면 산술 연산을 훨씬 더 난독화할 수 있어 매우 잘 어울립니다. 아래에서 볼 수 있듯이 디컴파일러는 추가 변수를 생성하고 많은 __PAIR64__ 및 __CFADD__ 호출을 사용하므로 CoBRA 같은 도구에 붙여넣기가 훨씬 더 어려워집니다(여전히 불가능하지는 않음). IDA의 gooMBA 플러그인도 이를 단순화하는 데 도움이 되지 않습니다. 또한 IDA의 디컴파일러는 어느 정도 캐리 플래그를 추적하지만, 이를 제어 흐름 난독화와 결합하면 실행 없이는 추적이 사실상 불가능해집니다. 이전 연산이 무엇이었는지 알 수 없기 때문입니다. CF를 1로 설정했을 수도 있고 아닐 수도 있으므로, 이후 패스들이 이 패스에 더욱 누적됩니다.


패스 적용 전

적용 후

제어 흐름 평탄화

함수 내의 모든 블록을 수집하여 하나의 거대한 상태 머신으로 만듭니다. 함수 시작 부분에 점프 테이블을 생성하고 모든 블록 포인터를 그 안에 배치합니다. 그런 다음 각 블록 끝의 일반 점프 대신 모든 것이 간접 점프를 사용하는 디스패처를 통해 라우팅됩니다. 이는 실행 없이 정적으로 해석하는 것이 거의 불가능합니다. 또한 레지스터를 스택으로 강등하므로, 블록을 반으로 나누면 이전 블록의 모든 변수가 스택에 있게 되어 모든 표현식에 변수가 아주 많이 존재하게 됩니다. 단일 블록의 연산을 CoBRA로 실행하면 알 수 없는 변수가 너무 많아 많이 디오브푸스케이트할 수 없습니다.

안티 분석

유효하지 않은 어셈블리를 포함하는 여러 가짜 블록을 생성합니다. 이는 디스어셈블러를 크게 혼란스럽게 만드는데, 디스어셈블러가 절대 실행되지 않는 기술적으로 유효하지 않은 바이트를 만나더라도 여전히 이를 이해하려고 시도하기 때문입니다. 따라서 바이트가 불완전하면 그 뒤에 오는 바이트로부터 명령어를 생성하여 사실상 이를 소비합니다. 이는 동기화를 깨뜨려 그 이후의 모든 명령어를 파괴합니다. Windows 바이너리에서는 IDA가 어느 정도 복구할 수 있으며, 드물게 그래프를 생성하고 가능한 것을 디컴파일할 수 있습니다(깨지고 불완전하지만). 반면 Linux 바이너리에서는 그래프 뷰가 완전히 깨지고 디컴파일이 비활성화됩니다. 또한 RDTSC 타이머와 기타 안티 디버그 검사를 삽입하며, 디버거를 감지하면 크래시가 발생합니다.


Windows

Linux

게다가, 해당 패스가 0xFF로 시작하는 명령어를 만나면 그 앞에 단일 0xEB 바이트를 삽입합니다. 이렇게 하면 JMP RIP+1이 생성되어 제어 흐름은 변경되지 않지만(RIP가 원래 명령어로 한 바이트만큼 진행될 뿐), 디스어셈블러는 다시 동기화가 깨지게 됩니다. 0xFF로 시작하는 명령어는 대부분 INC/DEC와 간접 JMP/CALL입니다. 안타깝게도 일반적인 호출과 점프는 대부분 상대 주소 방식(0xE8/0xE9/0xEB)이라 영향을 받지 않습니다. 하지만 이 기법은 모든 것이 간접 점프를 사용하는 디스패처 패스와 함께 사용할 때 특히 유용합니다. 호출에는 그다지 유용하지 않은데, 이 기법의 영향을 받는 호출은 간접 호출뿐이며, 일반적으로 가상 호출, 함수 포인터를 통한 호출, 그리고 일부 외부/라이브러리 호출이 여기에 해당합니다.

변수 분할

변수를 여러 부분으로 분할하고 각 부분에 대해 개별적으로 연산을 수행하며, MBA 패스와 매우 잘 어울려 단순한 로직을 이미 그런 상태에서 더욱 복잡하게 만듭니다. 간단히 말해 int32는 4개의 int8로 분할될 수 있으며, 지원되는 연산(AND, OR, XOR, ADD, SUB, ICMP)이 수행되면 원래의 int32 대신 int8들에 대해 하나씩 수행됩니다.


패스 적용 전

적용 후

안티 앨리어싱

함수 내의 모든 스택 로컬 변수를 하나의 큰 공유 스택 버퍼에 던져 넣고, 그 인덱스는 실행할 때마다 무작위화되어 런타임에 계산됩니다. 이렇게 하면 디컴파일러가 변수를 앨리어싱할 수 없게 되어, 동일한 변수에 여러 번 접근하는 것이 서로 다른 값에 접근하는 것으로 나타납니다. 이는 디스패처 및 변수 분할 패스와 매우 잘 어울립니다. 디스패처는 레지스터를 스택으로 강등시키고, 변수 분할은 이를 여러 변수로 분할하므로 이러한 스택 슬롯이 많이 생기게 됩니다.


패스 적용 전

적용 후

나노마이트

예외를 통해 제어 흐름을 난독화합니다. 모든 호출을 int3 트랩으로 대체합니다. 트랩이 발생하면 제어 흐름이 예외 핸들러로 이동하여 RIP를 실제 호출로 조정합니다. 또한 트랩 바로 뒤에 유효하지 않은 바이트를 삽입하여 디스어셈블러의 동기화를 더욱 깨뜨립니다.

도구 다운로드