
난독화된 JavaScript를 시각적으로 리버스 엔지니어링합니다. 변환을 연결하고, AST 변경을 검사하며, 재사용 가능한 디난독화 플러그인을 작성합니다.
JavaScript 난독 해제를 위한 시각적 작업대입니다. 변환 체인을 구축하고, 단계별로 실행하며, 자신만의 플러그인을 작성할 수 있습니다.


이 애플리케이션은 JavaScript 프로그램의 추상 구문 트리(AST)를 보여줍니다. 이 아이디어는 obfuscatio.io 관련 악성코드 샘플을 분석하던 중 떠올랐으며, 결국 BabelJS를 이용한 난독 해제에 대해 더 깊이 알게 되었습니다. 난독화된 JS(예: webpack 번들, obfuscator.io 출력물, 패킹된 악성코드 샘플)를 역공학 해본 적이 있다면 그 고통을 아실 겁니다. 이 도구를 사용하면 다음을 할 수 있습니다:
npm install
npm start
# http://localhost:3000 열기
끝입니다.
왼쪽 사이드바 - 모든 사용 가능한 변환(내장 + 레시피의 플러그인) 및 레시피 체인 (Cyberchef 참고)
중앙 - 입력/출력 편집기. 왼쪽에 난독화된 코드를 붙여넣고 오른쪽에서 변환된 코드를 확인하세요.
오른쪽 패널 - AST 뷰어, 스코프 분석기, 보기 쉬운 요약

BabelJS를 사용하면 스코프와 바인딩을 볼 수 있습니다. 예를 들어 사용되지 않는 변수가 있는지 확인하는 데 특히 유용합니다. 이 뷰를 통해 변수가 참조되는 위치도 찾을 수 있습니다.

+ 버튼을 클릭하거나 Ctrl+N을 눌러 스크립트 편집기를 엽니다. 변환은 다음에 접근할 수 있는 JS 코드일 뿐입니다:
// 사용 가능한 전역 변수:
ast // 파싱된 Babel AST
traverse // 트리 순회: traverse({ Identifier(path) { ... } })
t // Babel 타입: t.isStringLiteral(node), t.identifier('x')
config // 레시피 카드의 사용자 설정
stats // 변경 사항 추적: stats.replaced = 5
parser // 코드 파싱: parser.parse('var x = 1')
generate // 코드 생성: generate(node).code
run // Eval 도우미: run('1+1') => 2 (위험! 본인 컴퓨터의 샌드박스에서만 실행하세요)
예시 - 모든 "debug" 문자열 제거 (StringLiteral):
// 다음 두 줄은 아래 스크린샷과 같이 레시피 체인에 매개변수로 나타납니다
const targetValue = config.targetValue || 'debug';
const removeMatches = config.removeMatches !== false;
traverse({
StringLiteral(path) {
if (path.node.value === targetValue) {
if (removeMatches) {
path.remove();
stats.removed = (stats.removed || 0) + 1;
}
}
}
});
다음 중 선택할 수 있습니다:
아래 스크린샷은 다음을 보여줍니다:

난독화 기법에 따라 실패할 수 있으며, 사용자 정의 스크립트가 필요할 수 있습니다. 또한 이를 수정하여 새 사용자 정의 스크립트로 저장할 수 있습니다.
| 이름 | 설명 |
|---|---|
| Beautify | 코드를 깔끔하게 포맷팅 |
| Constant Folding | 1 + 2 → 3, "a" + "b" → "ab" |
| Decode Strings | \x48\x65\x6c\x6c\x6f → "Hello" 디코딩 |
| Inline Array Values | 단순 배열 요소 접근 인라인화 |
| Inline String Array | 난독화 도구에서 사용하는 문자열 배열 인라인화 |
| Opaque Predicate Removal | 항상 참/거짓인 조건 제거 |
| Remove Comments | 모든 주석 제거 |
| Remove IIFE | (function(){...})() 래퍼 제거 |
| Remove Unused Code | 죽은 변수와 함수 삭제 |
| Simplify Literals | !0 → true, void 0 → undefined |
직접 만든 .js 파일을 plugins/<category>/ 하위 폴더에 넣으세요. 폴더별로 그룹화되어 사이드바에 표시됩니다.

예를 들어:
Bracket-to-dot-notation.js → "Decode Strings")plugins/Utilities/ → 카테고리 "nyx")/**
* Bracket to Dot Notation
* console["log"] 같은 것을 console.log로 변경
*
* Category: utilities
*/
// 스크립트 편집기 - Ctrl+Enter 실행, Ctrl+E 닫기
// traverse(visitor)를 사용하여 AST 수정
// Babel 타입에 't' 사용
traverse({
MemberExpression(path) {
if(path.node.computed === true){
// 대괄호 표기법
prop = path.node.property
if(t.isStringLiteral(prop) &&
/^[a-zA-Z_][a-zA-Z_0-9]*$/.test(prop.value)
){
path.node.computed = false; // 1단계
// 2단계 리터럴을 식별자로 변경
path.node.property = t.identifier(prop.value)
}
}
}
});
매개변수를 추가하는 두 가지 방법:
targetValue와 removeMatches)를 생성하려고 시도합니다.const targetValue = config.targetValue || 'debug';
const removeMatches = config.removeMatches !== false;

포함 내용:

| 키 | 동작 |
|---|---|
Ctrl+E | 스크립트 편집기 토글 |
Ctrl+Shift+E | Eval 패널 토글 (위험) |
Ctrl+S | 프로젝트 저장 |
중첩된 노드가 많으면 독립 실행형에 문제가 있을 수 있습니다. 해결 방법이 항상 작동하지 않을 수 있습니다.
npm으로 빌드하려면 다음을 사용하세요.
npm run build # Windows 전용
출력은 dist/에 생성됩니다. 사용자 정의 변환을 사용하려면 plugins/ 폴더를 exe 옆에 복사하세요.
깊게 중첩된 코드(예: JSFuck)는 스택을 터뜨릴 수 있습니다. 빌드 스크립트는 Windows에서 자동으로 스택 크기를 늘리려고 시도합니다. 스택 오버플로가 발생하면 소스에서 npm start를 실행해 보세요 ( --stack-size=65536 사용).
독립 실행형 실행 파일로 빌드할 때 스택 크기를 늘리는 방법을 아직 찾지 못했습니다. 아시는 분은 알려주세요!
다음으로 제작되었습니다:

질문이 있거나 문제가 있습니까? GitHub 이슈를 열어주세요.