2

I am trying to understand obfuscation algorithms and I saw that codes. For example the real code is;

<p>ABC</p>

and the encoded version is following code;

var erp = new Array;
erp[0] = 1013988929;
erp[1] = 1111702575;
erp[2] = 28734;
var em = '';
for(i=0;i<erp.length;i++){
    tmp = erp[i];
    if(Math.floor((tmp/Math.pow(256,3)))>0){
        em += String.fromCharCode(Math.floor((tmp/Math.pow(256,3))));
    };
    tmp = tmp - (Math.floor((tmp/Math.pow(256,3))) * Math.pow(256,3));
    if(Math.floor((tmp/Math.pow(256,2)))>0){
        em += String.fromCharCode(Math.floor((tmp/Math.pow(256,2))));
    };
    tmp = tmp - (Math.floor((tmp/Math.pow(256,2))) * Math.pow(256,2));
    if(Math.floor((tmp/Math.pow(256,1)))>0){
        em += String.fromCharCode(Math.floor((tmp/Math.pow(256,1))));
    };
    tmp = tmp - (Math.floor((tmp/Math.pow(256,1))) * Math.pow(256,1));
    if(Math.floor((tmp/Math.pow(256,0)))>0){
        em += String.fromCharCode(Math.floor((tmp/Math.pow(256,0))));
    };
};
document.write(em);

How this code works? I tired change "erp" array value to 65 its means "A" then its worked. Its all time worked for normal char codes. But how this scripts identified "1111702575" value? And how can I can create obfuscation for this algorithm.

2 Answers 2

4

Overall this is a pretty simple conversion of 32-bit integers (4 bytes) to 4 1-byte chars which are concatenated in the em variable.

First you can notice that strings <p>A, BC</ and p> are crypt respectively to integers 1013988929, 1111702575 and 28734 (the third string contains only 2 symbols so the third integer is less than 2^16).

The code in the for loop represents decryption algorithm which converts one integer into 4 symbols.

The ifs check whether there are enough bits in the number to extract symbol from them. For example the third sting (p> has only 2 symbols and the third integer 28734 represent them). Notice the checks:

if(Math.floor((tmp/Math.pow(256,3)))>0)
if(Math.floor((tmp/Math.pow(256,2)))>0)
if(Math.floor((tmp/Math.pow(256,1)))>0)
if(Math.floor((tmp/Math.pow(256,0)))>0)

The string concatenations:

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,3))));
em += String.fromCharCode(Math.floor((tmp/Math.pow(256,2))));
em += String.fromCharCode(Math.floor((tmp/Math.pow(256,1))));
em += String.fromCharCode(Math.floor((tmp/Math.pow(256,0))));

just extract one symbol from the integer. Converts one byte (256 bits) into one of the 256 symbols in the ASCII table.

Sign up to request clarification or add additional context in comments.

Comments

-1

You are looking at an obfuscation algorithm that is based on converting characters into their numerical representation and storing them as integers in an array. The code you posted is decrypting this data and converting it back into a readable string. Here's how it works:

  1. Each integer in the array erp is made up of four bytes, and each byte represents the ASCII value of one character.

  2. In the loop, the code is dividing the integer by powers of 256 to get the individual bytes back. This is done by utilizing the bitwise layout of the 32-bit integer.

  3. Math.floor((tmp/Math.pow(256,3))) is extracting the first (most significant) byte.

  4. Math.floor((tmp/Math.pow(256,2))) is extracting the second byte.

  5. Math.floor((tmp/Math.pow(256,1))) is extracting the third byte.

  6. Math.floor((tmp/Math.pow(256,0))) is extracting the fourth (least significant) byte.

  7. The String.fromCharCode() function is used to convert each byte back to a character based on ASCII values.

Now, for your question about the value 1111702575. This can be explained as follows:

  • 1111702575 is 0x42430A3C in hexadecimal.
  • This breaks down into the ASCII codes: 0x42 (B), 0x43 (C), 0x0A (line feed), 0x3C (<).

If you are looking to create obfuscation, you would need to do the reverse process: convert characters to ASCII codes, then combine them into 32-bit integers. Here is an example code to achieve that:

Decoding:

var encodedArray = [1013988929, 1111702575, 28734]; // Declare an array with encoded values
var decodedString = ''; // Initialize an empty string to hold the decoded string

// Loop through each element in the encoded array
for (var i = 0; i < encodedArray.length; i++) {
    var value = encodedArray[i]; // Store the current encoded value in 'value'
    var decodedChunk = ''; // Initialize an empty string to hold the decoded chunk

    // Keep looping until 'value' becomes 0
    while (value > 0) {
        var charCode = value % 256; // Calculate the remainder when 'value' is divided by 256
        decodedChunk = String.fromCharCode(charCode) + decodedChunk; // Convert the remainder to a character and prepend it to 'decodedChunk'
        value = Math.floor(value / 256); // Divide 'value' by 256 and store the result back into 'value'
    }

    decodedString += decodedChunk; // Append the 'decodedChunk' to the 'decodedString'
}

console.log(decodedString); // Output the 'decodedString' to the console

Encoding:

function encodeString(input) { // Define a function named 'encodeString' that takes an input string
    var encodedArray = []; // Initialize an empty array to hold the encoded values
    var currentChunk = 0; // Initialize a variable to accumulate the encoding of up to 4 characters
    var bytesInChunk = 0; // Initialize a variable to keep track of the number of characters in the current chunk

    // Loop through each character in the input string
    for (var i = 0; i < input.length; i++) {
        var charCode = input.charCodeAt(i); // Get the ASCII value of the current character

        currentChunk = currentChunk * 256 + charCode; // Multiply 'currentChunk' by 256 and add the ASCII value of the current character
        bytesInChunk++; // Increment the number of characters in the current chunk

        // Check if 'bytesInChunk' is equal to 4
        if (bytesInChunk === 4) {
            encodedArray.push(currentChunk); // Append 'currentChunk' to 'encodedArray'
            currentChunk = 0; // Reset 'currentChunk'
            bytesInChunk = 0; // Reset 'bytesInChunk'
        }
    }

    // Check if there are any characters left in 'currentChunk'
    if (bytesInChunk > 0) {
        encodedArray.push(currentChunk); // Append the remaining 'currentChunk' to 'encodedArray'
    }

    return encodedArray; // Return the 'encodedArray'
}

var inputString = '<p>ABC</p>'; // The string to be encoded
var encodedArray = encodeString(inputString); // Call 'encodeString' function with 'inputString' as an argument

console.log(encodedArray); // Output the 'encodedArray' to the console

It's important to note that the provided code is a simple and easily reversible obfuscation technique. It is not a strong security measure. For more robust obfuscation, advanced algorithms and transformations are used to make the code harder to understand and reverse engineer.

If you're interested in creating obfuscation techniques, there are libraries and tools available that provide more sophisticated and secure methods. These tools often offer various obfuscation transformations, including name mangling, code splitting, and control flow obfuscation, among others.

I've even provided a PHP based example on GitHub: https://github.com/DevilsNerve/HTML-obfuscator

Remember that while obfuscation can make code more difficult to understand, it does not provide absolute security. Determined attackers can still reverse engineer obfuscated code given enough time and resources.

All the best,

Austen

1 Comment

This looks like it's mostly ChatGPT

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.