안녕하세요, 당신의 알고리즘이 얼마나 멋지고 독특한지 생각해 본 적이 있나요? ? 많은 프로그래머와 회사가 그렇게 하기 때문에 자신의 작업을 모든 사람과 공유하는 것을 주저할 수 있습니다. 코드의 일부가 서버(클라이언트-서버 애플리케이션의 경우)로 이동하면 이 문제가 조금 더 나아지지만 이 접근 방식이 항상 가능한 것은 아닙니다. 때로는 민감한 코드 섹션을 바로 공개해야 하는 경우도 있습니다.
이 기사에서는 JavaScript의 난독화에 대해 살펴보고 알고리즘을 숨기고 코드 연구를 더 어렵게 만드는 방법을 살펴보겠습니다. 또한 AST가 무엇인지 알아보고 난독화 구현을 위해 AST와 상호 작용하는 데 사용할 수 있는 도구를 제공할 것입니다.
여기 어리석은 예가 있습니다. 이런 상황을 상상해 봅시다:
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
안타깝게도 Bob은 경품 페이지에 액세스할 수 없어 상당히 화가 났습니다. 그는 이유를 이해하지 못합니다. 그러다가 그는 크고 좋은 모니터를 가진 사용자는 허용되지 않는다는 경품 규칙을 알게 됩니다.
다행히 Bob은 고등학교 때 컴퓨터 과학 수업을 몇 개 수강했습니다. 그는 F12 키를 눌러 과감하게 개발자 콘솔을 열고 스크립트를 연구하고 주최자가 화면 해상도를 확인한다는 것을 깨닫습니다. 그런 다음 그는 휴대전화로 참여하기로 결정하고 테스트를 성공적으로 통과했습니다.
해피엔딩으로 끝나는 가상의 이야기 - 하지만 주인공이 이전 코드 대신 이것을 보았다면 이보다 좋을 수 없었을 것입니다:
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
장담하는데, 이건 횡설수설이 아니라 JavaScript입니다! 그리고 동일한 작업을 수행합니다. 여기 콘솔에서 코드를 실행해볼 수 있습니다.
이런 경우 우리 영웅은 경품 행사에 참여하지 않고 자신의 운명을 받아들였을 것이고 주최측에서는 계획을 지켰을 것입니다.
그럼 여기서 요점은 무엇인가요? 축하합니다. jjencode 도구와 난독화가 무엇인지, 어떤 역할을 할 수 있는지 알아보았습니다.
요약하면 난독화는 프로그램 코드나 데이터를 사람이 이해하기 어렵지만 기계나 프로그램에서는 작동하는 형식으로 변환하는 프로세스입니다.
이론은 이쯤하고 좀 더 실제적인 예로 넘어가 볼까요??. 이제 인터넷에서 쉽게 찾을 수 있는 난독화를 사용하여 코드를 변환해 보겠습니다. 우리의 "노하우" 작업이 포함된 좀 더 흥미로운 코드를 살펴보겠습니다. 그리고 F12에 도달하기에는 너무 게으르지 않은 모든 사람이 이에 대해 알 수 있다는 것은 매우 바람직하지 않습니다.
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
이 코드는 장치 및 브라우저 데이터를 수집하고 결과를 콘솔에 출력합니다. 예를 들어(출력을 코드 성능의 지표로 사용합니다)
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
이제 위 코드를 가져와 인기 있는 JS용 난독 처리기인 obfuscator.io로 수정해 보겠습니다. 결과적으로 다음과 같은 코드를 얻게 됩니다.
function getGpuData(){ let cnv = document.createElement("canvas"); let ctx = cnv.getContext("webgl"); const rendererInfo = ctx.getParameter(ctx.RENDERER); const vendorInfo = ctx.getParameter(ctx.VENDOR); return [rendererInfo, vendorInfo] } function getLanguages(){ return window.navigator.languages; } let data = {}; data.gpu = getGpuData(); data.langs = getLanguages(); console.log(JSON.stringify(data))
짜잔! 이제 기계만이 이 코드를 기꺼이 구문 분석할 수 있습니다(당신과 나는 아마도 그들 중 하나가 아닐 것입니다 ?). 그럼에도 불구하고 여전히 작동하며 동일한 결과를 생성합니다. 변경 사항을 확인하세요.
이 경우 정적 코드 분석에 부담을 준다는 점에서 마지막 기술이 아마도 가장 불쾌할 것입니다.
알겠습니다. 모든 비밀이 숨겨져 있는 것 같습니다. 코드를 프로덕션에 배포해볼까요?
잠깐만요... 코드 난독화를 위한 서비스가 있다면 이 기능을 되돌릴 수 있는 서비스가 있을까요? 물론 ?, 그리고 하나 이상! 그중 하나인 webcrack을 사용해 보겠습니다. 그리고 읽을 수 있는 원본 코드를 얻을 수 있는지 확인하세요. 다음은 이 deobfuscator를 사용한 결과입니다.
{"gpu":["ANGLE (NVIDIA, NVIDIA GeForce GTX 980 Direct3D11 vs_5_0 ps_5_0), or similar","Mozilla"],"langs":["en-US","en"]}
앗 ?. 물론 변수명을 돌려주지는 않았지만, 고마워요.
그래서 이 경우 코드를 침착하게 연구하는 데 유일한 장애물은 난독화 장치를 사용하려는 연구원의 의지라는 것이 밝혀졌습니다. 의심할 여지 없이 다른 솔루션과 사용자 정의를 사용하는 것도 가능하지만 대중적인 난독화의 경우 대중적인 난독화를 기대할 가능성이 높습니다.
싸우지도 않고 절망하고 비밀을 포기해야 할까요? 물론 그렇지 않습니다! 우리가 무엇을 더 할 수 있는지 봅시다....
난독처리기 - 마치 판타지 세계의 마법사처럼 들리지 않나요? ??♂️
확실히 누군가는 코드를 작성하는 동안 코드를 난독화할 수 있으며 타고난 마술사입니다. 당신은 의도치 않게 한동안 스스로 그러한 주문을 시전할 수 있었을 수도 있습니다. 그런데 '선임 프로그래머'들의 비판으로 인해 그 기술이 사라졌고 잠재적으로 프로그램을 조사하기 어렵게 만들 수 있는 아이디어가 있다면 어떻게 해야 할까요? 이 경우 코드 구조 자체와 상호 작용하고 이를 수정할 수 있는 도구를 사용하는 것이 합리적입니다. 살펴보겠습니다.
단순히 텍스트처럼 코드와 상호 작용하고 특정 구성을 정규식으로 바꾸는 등의 방법으로 코드를 수정하는 것도 가능합니다. 하지만 이 방법을 따르면 난독화하는 것보다 코드와 시간을 망칠 가능성이 더 높습니다.
보다 안정적이고 제어된 수정을 위해 이를 추상 구조인 트리(AST - 추상 구문 트리)로 가져와서 관심 있는 요소와 구성을 변경할 수 있는 것이 좋습니다. .
JS 코드 작업에는 다양한 솔루션이 있으며 최종 AST에는 차이가 있습니다. 이번 글에서는 이를 위해 babel을 사용하겠습니다. 아무것도 설치할 필요가 없으며 astexplorer와 같은 리소스에서 모든 것을 실험해 볼 수 있습니다.
(바벨을 엉망으로 만들고 싶지 않다면 Shift-refactor를 확인하세요. **CSS 선택기를 사용하여 AST와 상호 작용할 수 있습니다. 학습을 위한 아주 최소한이고 편리한 접근 방식 그러나 바벨과 다른 특정 버전의 AST를 사용합니다. Shift-query 대화형 데모에서 이 도구에 대한 CSS 쿼리를 테스트할 수 있습니다.
이제 간단한 예를 통해 브라우저를 떠나지 않고도 이러한 도구를 쉽게 사용할 수 있는 방법을 살펴보겠습니다. 동일한 이름의 함수에서 테스트 변수의 이름을 변경됨으로 변경해야 한다고 가정해 보겠습니다.
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
이 코드를 astexplorer에 붙여넣으면(위에서 JavaScript 및 @babel/parser 선택) 거기에 AST로 표시되어야 합니다. 테스트 변수를 클릭하면 오른쪽 창에서 이 코드 섹션의 구문을 볼 수 있습니다.
문제를 해결하기 위해 다음 babel 플러그인을 작성할 수 있습니다. 이 플러그인은 코드를 구문 분석하고 그 안의 모든 이름 식별자를 찾아 특정 조건이 충족되면 이름을 바꿉니다. astexplorer의 왼쪽 하단 창에 붙여넣습니다(transform 슬라이더를 켜고 babelv7을 선택하여 표시합니다).
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
이 플러그인에는 콘솔 출력이 포함된 이유가 있습니다. 이를 통해 브라우저 콘솔에서 출력을 검사하여 플러그인을 디버깅할 수 있습니다. 이 경우 식별자 유형의 모든 노드에 대한 정보를 출력합니다. 이 정보에는 노드 자체(node), 상위 노드(parent) 및 환경(범위 - 현재 컨텍스트에서 생성된 변수 및 이에 대한 참조 포함)에 대한 데이터가 포함됩니다.
따라서 오른쪽 하단 창에서 다른 식별자에 영향을 주지 않고 소스 코드의 변수가 성공적으로 변경되었음을 확인할 수 있습니다.
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
이 예를 바탕으로 코드를 구문 분석하고 수정하는 방법이 조금 더 명확해졌기를 바랍니다. 어쨌든 완료된 작업을 요약하겠습니다.
이제 코드 수정 방법이 명확해졌습니다. 난독화라고 부를 수 있는 좀 더 유용한 것을 시도해 보겠습니다 :) 이전 섹션에서 난독화하려고 시도한 더 복잡한 코드를 사용하겠습니다. 이제 그 안에 있는 모든 변수와 함수의 이름을 임의의 이름으로 변경하겠습니다. 따라서 잠재적인 리버스 엔지니어는 일부 코드 요소의 목적에 대한 정보가 더 적습니다.
또한 JS 코드를 자유롭게 사용하여 문제를 디버깅할 수 있습니다. 고통만큼 좋은 스승은 없다고 ?.
다음 플러그인은 작업을 완료하는 데 도움이 됩니다.
function getGpuData(){ let cnv = document.createElement("canvas"); let ctx = cnv.getContext("webgl"); const rendererInfo = ctx.getParameter(ctx.RENDERER); const vendorInfo = ctx.getParameter(ctx.VENDOR); return [rendererInfo, vendorInfo] } function getLanguages(){ return window.navigator.languages; } let data = {}; data.gpu = getGpuData(); data.langs = getLanguages(); console.log(JSON.stringify(data))
이 코드의 역할은 무엇인가요? 이전 예와 거의 동일합니다.
플러그인 실행 결과, 임의의 변수 이름과 함수가 포함된 다음 코드를 얻습니다.
{"gpu":["ANGLE (NVIDIA, NVIDIA GeForce GTX 980 Direct3D11 vs_5_0 ps_5_0), or similar","Mozilla"],"langs":["en-US","en"]}
콘솔에서 코드를 실행하여 확인할 수 있습니다. 조작 후에도 여전히 작동합니다! 그리고 이것이 좋은 난독화 장치의 주요 품질입니다 ✨.
그런데 난독화의 품질은 어떻습니까? 나로서는 악이 아직 그렇게 강하지 않다. 이름을 바꾸더라도 숙련된 프로그래머라면 이 코드의 목적을 쉽게 이해할 수 있을 것이다. JS 축소기가 이 작업을 처리할 수 있다면 무슨 의미가 있을까요? 이제 리버서에 대해 좀 더 실용적이고 번거로운 작업을 수행하는 것이 가능합니까? 주문이 하나 더 있어요...
“모든 것”이라고 썼을 때는 조금 자신 있었을지 모르지만, 지금 우리가 할 일은 코드의 동작을 최대한 숨기는 것입니다. 이 섹션에서는 정적 분석을 복잡하게 하고 "클라이언트"가 코드를 파고드는 것을 잠재적으로 방지하기 위해 문자열과 다양한 개체 속성을 숨길 것입니다!
이전 단계에서 얻은 숨겨진 이름이 포함된 코드에 다음 플러그인을 적용해 보겠습니다.
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
이미 코드 주석에서 이 플러그인의 작업을 조금 설명했지만, 이 플러그인이 수행하는 작업을 단계별로 간략하게 설명하겠습니다.
파싱 작업이 순차적으로 수행되는 것이 아니라 AST 처리 중에 필요한 노드를 찾으므로 참고할 만합니다.
이 플러그인을 실행하면 다음 코드를 얻게 됩니다.
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
결과 코드에서 볼 수 있듯이 모든 속성은 지정된 인덱스를 사용하는 getData 함수 호출로 대체되었습니다. 우리는 문자열에 대해서도 동일한 작업을 수행하고 함수 호출을 통해 문자열을 가져오기 시작했습니다. 속성 이름과 문자열 자체를 base64로 인코딩하여 눈에 띄기 어렵게 했습니다...
이미 눈치채셨을 것 같습니다. 이 플러그인과 일반적인 코드에는 현 단계에서 결함이 있습니다. 예를 들어 다음 사항을 수정할 수 있습니다.
이러한 단순성과 단점에도 불구하고 이미 난독화라고 할 수 있다고 생각합니다. 하지만 오픈 소스 난독 처리기와 유사한 작업을 수행하므로 우리는 어떻게 다릅니까?
우리는 원래 문제를 기억해야 합니다. 이러한 난독화는 공개 난독화 도구에게는 아주 쉬운 일이었습니다. 이제 우리가 얻은 코드를 가져와서 webcrack에서 난독화해 보겠습니다! (아직도 우리의 주문을 다룰 수 없기를 바랍니다.) 실질적인 중요성이 달성되었다고 말할 수 있을 것 같습니다. 우리의 "보호된" 코드는 더 이상 공개 난독화 도구를 통해 한 번의 클릭으로 되돌릴 수 없습니다
이제 새로운 주문을 배워 보겠습니다. 공개 난독화 도구는 우리 플러그인을 처리할 수 없지만 난독화의 실제 개념을 연구한 결과 소스 코드를 복원하는 데 사용할 수 있는 몇 가지 패턴을 발견할 수 있습니다.
자세히 알아보고 다음을 구체적으로 활용해 보세요.
이러한 단점을 고려하여 다음 플러그인을 구현할 수 있습니다.
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
이 난독화 플러그인의 기능을 설명해 보겠습니다.
결과적으로 다음 코드를 얻습니다.
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
그래서 우리는 표시된 단점을 활용하여 babel에 대한 간단한 플러그인을 작성하여 속성과 문자열을 숨기는 난독화를 제거할 수 있었습니다.
이 작은 예를 통해 babel의 도움으로 이러한 귀찮은 일에 대처할 수 있는 방법을 설명할 수 있기를 바랍니다. 이러한 접근 방식을 사용하면 더 복잡한 난독화를 해결할 수도 있습니다. 가장 중요한 것은 코드에서 패턴을 찾고 AST를 능숙하게 작동하는 것입니다.
코드 리버스 엔지니어링을 복잡하게 만드는 기술인 난독화와 이를 구현하는 도구에 대해 알아봤습니다. JavaScript 코드를 난독화하는 공개 솔루션이 있지만 즉시 이러한 보호 기능을 제거할 수 있는 공개 솔루션도 많이 있습니다.
따라서 공개 난독화 도구로 제거할 수 없는 코드를 보호하기 위한 솔루션을 직접 작성해야 합니다. JS에서 난독화를 구현하는 신뢰할 수 있는 방법 중 하나는 원하는 코드의 AST와 상호 작용하는 사용자 정의 바벨 플러그인을 작성하여 이를 읽기 어려운 형식으로 바꾸는 것입니다.
물론 이 영역에는 난독화에 대한 알려진 기술과 접근 방식이 있지만 그럼에도 불구하고 잠재적으로 코드 학습을 더 어렵게 만들 수 있는 창의성과 새로운 "트릭"이 여전히 열려 있습니다. 이러한 기술이 많이 있음에도 불구하고 코드는 항상 클라이언트의 "손에" 있기 때문에 알고리즘의 비밀성을 전혀 보장하지 않습니다. 게다가 디버깅이 가능해 코드를 더 쉽게 연구할 수 있습니다. 난독화를 사용하면 의욕이 부족한 연구자를 오히려 외면하게 되어 리버스 엔지니어링 비용이 증가합니다.
몇 가지 고급 접근 방식이 있습니다. 예를 들어 난독화 중 하나는 코드 가상화입니다. 간단히 말해서 JS에서 사용자 정의 바이트코드를 실행할 가상 머신을 생성하는 것입니다. 이 접근 방식은 정적 분석 가능성을 거의 완전히 제거하고 디버깅을 최대한 어렵게 만듭니다. 그런데 이건 별개의 논제인가요?....
이 주제에 대한 정보를 얻는 것이 도움이 되었기를 바랍니다. 처음에 난독화된 코드에 대해 더 이상 자신이나 프로그래머를 비난하지 마세요. 이 마법사들에게 감사드립니다 ??♀️! 여기에서 마술의 최신 트렌드에 대해 토론하게 되어 기쁩니다.
위 내용은 실험실을 번거롭게 하지 않고 JavaScript로 난독화를 만드는 방법은 다음과 같습니다: AST, Babel, 플러그인.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!