search
HomeWeb Front-endJS TutorialJavascript reverse and anti-reverse

Javascript reverse and anti-reverse

Dec 05, 2017 am 10:25 AM
javascriptjsReverse

popunderjs Originally there was open source code on github, but later it was estimated that the author discovered the huge commercial value of this demand, so he simply stopped open source and charged directly. So now if we want to study its implementation plan, we can only go to the official website to pick up its source code.

File structure

script.js is the main function, which implements all functions of popunder and defines multiple API methods

license.demo.js is the authorization file. Only with this file can you successfully call the methods in script.js

Prevent being reversed

For such a commercially valuable code to be openly used by you, you must consider the issue of being reversed. Let's see how it works against reverse engineering.

First, open the console and find 2 problems:

  1. All the contents of the console have been cleared repeatedly, Only this sentence is output: Console was cleared script.js?0.5309098417125133:1

  2. ##Cannot breakpoint debugging, because once the breakpoint debugging function is enabled, it will Being directed to an anonymous function (function() {debugger})

In other words, the commonly used breakpoint debugging method can no longer be used, we can only Take a look at the source code and see if you can understand its logic. However, its source code is like this:

<span style="font-size: 16px;">var a = typeof window === S[0] && typeof window[S[1]] !== S[2] ? window : global;<br>    try {<br>        a[S[3]](S[4]);<br>        return function() {}<br>        ;<br>    } catch (a) {<br>        try {<br>            (function() {}<br>            [S[11]](S[12])());<br>            return function() {}<br>            ;<br>        } catch (a) {<br>            if (/TypeError/[S[15]](a + S[16])) {<br>                return function() {}<br>                ;<br>            }<br>        }<br>    }<br></span>

It can be seen that the source code is impossible to read, so we still have to find a way to break its anti-reverse measures.

Use tools to cleverly crack anti-reverse engineering

First, step by step in the breakpoint debugging mode, check what operations it has performed, and suddenly found out Such a piece of code:

<span style="font-size: 16px;">(function() {<br>    (function a() {<br>        try {<br>            (function b(i) {<br>                if (('' + (i / i)).length !== 1 || i % 20 === 0) {<br>                    (function() {}<br>                    ).constructor('debugger')();<br>                } else {<br>                    debugger ;<br>                }<br>                b(++i);<br>            }<br>            )(0);<br>        } catch (e) {<br>            setTimeout(a, 5000);<br>        }<br>    }<br>    )()<br>}<br>)();<br></span>

This code mainly has two parts. One is to judge whether the console is opened through the b() function in the try {} block. If so, it will call itself, repeatedly. Enter the debugger breakpoint to interfere with our debugging. If the console is not opened, calling the debugger will throw an exception. At this time, set the timer in the catch {} block and call the b() function after 5 seconds.

In this way, everything actually starts from the setTimeout function (because the b() function is all a closure call and cannot be broken from the outside world), so as long as it is called in setTimeout , this infinite loop can be broken by not letting it execute.

So we just need to simply override setTimeout... For example:

<span style="font-size: 16px;">window._setTimeout = window.setTimeout;<br>window.setTimeout = function () {};<br></span>

but! This operation cannot be done in the console! Because when you open the console, you will inevitably be sucked into the infinite loop of the b() function. There is no point in overriding setTimeout at this time.

At this time, our tool TamperMonkey comes into play. By writing the code into the TM script, it can be executed even without opening the console.

TM After the script is written, refresh the page, wait until it is completely loaded, and then open the console. At this time, the debugger will no longer appear!

Then it’s the console’s turn to refresh the code

Click on the link on the right side of Console was cleared to locate the specific code. Click {} to beautify the compressed code and find that it actually uses setInterval to repeatedly call console.clear() to clear the console and output the message

Console was cleared

, but note that setInterval cannot be directly overridden. Because this function also has important uses elsewhere.

So we can prevent its screen clearing behavior by overriding the console.clear() function and filtering the log information.

is also written into the TamperMonkey script, code:

<span style="font-size: 16px;">window.console.clear = function() {};<br>window.console._log = window.console.log;<br>window.console.log = function (e) {<br>    if (e['nodeName'] && e['nodeName'] == 'p') {<br>        return ;<br>    }<br>    return window.console.error.apply(window.console._log, arguments);<br>};<br></span>

The reason why error is used to output information is to view its call stack, which is helpful for understanding the program logic.

Basically, after completing these tasks, this code can be debugged normally like an ordinary program. But there is another problem. Its main code is often obfuscated and encrypted, so it is very difficult to debug. Let’s briefly talk about the process.

Obfuscation encryption method one: hide method calls and reduce readability

You can see a piece of code at the beginning from license.demo.js Is such that:

<span style="font-size: 16px;">var zBCa = function T(f) {<br>    for (var U = 0, V = 0, W, X, Y = (X = decodeURI("+TR4W%17%7F@%17.....省略若干"),<br>    W = '',<br>    'D68Q4cYfvoqAveD2D8Kb0jTsQCf2uvgs'); U     V++) {<br>        if (V === Y.length) {<br>            V = 0;<br>        }<br>        W += String["fromCharCode"](X["charCodeAt"](U) ^ Y["charCodeAt"](V));<br>    }<br>    var S = W.split("&&");<br></span>

 

通过跟踪执行,可以发现 S 变量的内容其实是本程序所有要用到的类名、函数名的集合,类似于 var S = ['console', 'clear', 'console', 'log'] 。如果要调用 console.clear() 和 console.log() 函数的话,就这样

<span style="font-size: 16px;">var a = window;<br>a[S[0]][S[1]]();<br>a[S[2]][S[3]]();<br></span>

 

混淆加密方法二:将函数定义加入到证书验证流程

license.demo.js 中有多处这样的代码:

<span style="font-size: 16px;">a['RegExp']('/R[\S]{4}p.c\wn[\D]{5}t\wr/','g')['test'](T + '')<br></span>

 

这里的 a 代表 window,T 代表某个函数, T + '' 的作用是把 T 函数的定义转成字符串,所以这段代码的意思其实是,验证 T 函数的定义中是否包含某些字符。

每次成功的验证,都会返回一个特定的值,这些个特定的值就是解密核心证书的参数。

可能是因为我重新整理了代码格式,所以在重新运行的时候,这个证书一直运行不成功,所以后来就放弃了通过证书来突破的方案。

逆向思路:输出所有函数调用和参数

通过断点调试,我们可以发现,想一步一步深入地搞清楚这整个程序的逻辑,是十分困难,因为它大部分函数之间都是相互调用的关系,只是参数的不同,结果就不同。

所以我后来想了个办法,就是只查看它的系统函数的调用,通过对调用顺序的研究,也可以大致知道它执行了哪些操作。

要想输出所有系统函数的调用,需要解决以下问题:

  1. 覆盖所有内置变量及类的函数,我们既要覆盖 window.console.clear() 这样的依附在实例上的函数,也要覆盖依附在类定义上的函数,如 window.HTMLAnchorElement.__proto__.click()

  2. 需要正确区分内置函数和自定义函数

经过搜索后,找到了区分内置函数的代码:

<span style="font-size: 16px;">// Used to resolve the internal `[[Class]]` of values<br>  var toString = Object.prototype.toString;<br><br>  // Used to resolve the decompiled source of functions<br>  var fnToString = Function.prototype.toString;<br><br>  // Used to detect host constructors (Safari > 4; really typed array specific)<br>  var reHostCtor = /^\[object .+?Constructor\]$/;<br><br>  // Compile a regexp using a common native method as a template.<br>  // We chose `Object#toString` because there's a good chance it is not being mucked with.<br>  var reNative = RegExp('^' +<br>    // Coerce `Object#toString` to a string<br>    String(toString)<br>    // Escape any special regexp characters<br>    .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&')<br>    // Replace mentions of `toString` with `.*?` to keep the template generic.<br>    // Replace thing like `for ...` to support environments like Rhino which add extra info<br>    // such as method arity.<br>    .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'<br>  );<br><br>  function isNative(value) {<br>    var type = typeof value;<br>    return type == 'function'<br>      // Use `Function#toString` to bypass the value's own `toString` method<br>      // and avoid being faked out.<br>      ? reNative.test(fnToString.call(value))<br>      // Fallback to a host object check because some environments will represent<br>      // things like typed arrays as DOM methods which may not conform to the<br>      // normal native pattern.<br>      : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;<br>  }<br></span>

 

然后结合网上的资料,写出了递归覆盖内置函数的代码:

<span style="font-size: 16px;">function wrapit(e) {<br>    if (e.__proto__) {<br>        wrapit(e.__proto__);<br>    }<br>    for (var a in e) {<br>        try {<br>            e[a];<br>        } catch (e) {<br>            // pass<br>            continue;<br>        }<br>        var prop = e[a];<br>        if (!prop || prop._w) continue;<br><br>        prop = e[a];<br>        if (typeof prop == 'function' && isNative(prop)) {<br>            e[a] = (function (name, func) {<br>                return function () {<br>                    var args = [].splice.call(arguments,0); // convert arguments to array<br>                    if (false && name == 'getElementsByTagName' && args[0] == 'iframe') {<br>                    } else {<br>                        console.error((new Date).toISOString(), [this], name, args);<br>                    }<br>                    if (name == 'querySelectorAll') {<br>                        //alert('querySelectorAll');<br>                    }<br>                    return func.apply(this, args);<br>                };<br>            })(a, prop);<br>            e[a]._w = true;<br>        };<br>    }<br>}<br></span>

 

使用的时候只需要:

<span style="font-size: 16px;">wrapit(window);<br>wrapit(document);<br></span>

 

然后模拟一下正常的操作,触发 PopUnder 就可以看到它的调用过程了。

参考资料:

A Beginners’ Guide to Obfuscation Detect if function is native to browser Detect if a Function is Native Code with JavaScript

以上内容就是Javascript逆向与反逆向的教程,希望能帮助到大家。

相关推荐:

JavaScript中undefined与null的区别详解

JavaScript中confirm()方法的使用介绍

JavaScript中的后退与刷新的实例详解

The above is the detailed content of Javascript reverse and anti-reverse. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Python vs. JavaScript: A Comparative Analysis for DevelopersPython vs. JavaScript: A Comparative Analysis for DevelopersMay 09, 2025 am 12:22 AM

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Python vs. JavaScript: Choosing the Right Tool for the JobPython vs. JavaScript: Choosing the Right Tool for the JobMay 08, 2025 am 12:10 AM

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript: Understanding the Strengths of EachPython and JavaScript: Understanding the Strengths of EachMay 06, 2025 am 12:15 AM

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScript's Core: Is It Built on C or C  ?JavaScript's Core: Is It Built on C or C ?May 05, 2025 am 12:07 AM

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript Applications: From Front-End to Back-EndJavaScript Applications: From Front-End to Back-EndMay 04, 2025 am 12:12 AM

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Python vs. JavaScript: Which Language Should You Learn?Python vs. JavaScript: Which Language Should You Learn?May 03, 2025 am 12:10 AM

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

JavaScript Frameworks: Powering Modern Web DevelopmentJavaScript Frameworks: Powering Modern Web DevelopmentMay 02, 2025 am 12:04 AM

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

The Relationship Between JavaScript, C  , and BrowsersThe Relationship Between JavaScript, C , and BrowsersMay 01, 2025 am 12:06 AM

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)