mirror of
https://github.com/thegeneralist01/twitter-tid-deobf-fork
synced 2026-01-09 14:50:26 +01:00
add 2
Signed-off-by: ふぁ <yuki@yuki0311.com>
This commit is contained in:
parent
7c2bf7527f
commit
51ad406da4
4 changed files with 1130 additions and 4 deletions
163
deobf2.js
Normal file
163
deobf2.js
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
const fs = require("fs");
|
||||
const babel = require("@babel/core");
|
||||
const t = require("@babel/types");
|
||||
const parser = require("@babel/parser");
|
||||
const traverse = require("@babel/traverse").default;
|
||||
const generate = require("@babel/generator").default;
|
||||
const { readFileSync } = require("fs");
|
||||
|
||||
let beautify_opts = {
|
||||
comments: true,
|
||||
minified: false,
|
||||
concise: false,
|
||||
};
|
||||
const [_, __, input, output] = process.argv;
|
||||
const script = readFileSync(input, "utf-8");
|
||||
const AST = parser.parse(script, {});
|
||||
|
||||
const inlineDestructuredVariables = {
|
||||
VariableDeclaration(path) {
|
||||
const { node, scope } = path;
|
||||
|
||||
node.declarations.forEach((declarator) => {
|
||||
const { id, init } = declarator;
|
||||
|
||||
// Handle array destructuring
|
||||
if (t.isArrayPattern(id) && t.isArrayExpression(init)) {
|
||||
const elementsLeft = id.elements;
|
||||
const elementsRight = init.elements;
|
||||
|
||||
// Ensure both sides have the same number of elements
|
||||
if (elementsLeft.length !== elementsRight.length) return;
|
||||
|
||||
elementsLeft.forEach((leftElem, index) => {
|
||||
const rightElem = elementsRight[index];
|
||||
if (!leftElem || !rightElem) return;
|
||||
|
||||
if (t.isIdentifier(leftElem)) {
|
||||
const varName = leftElem.name;
|
||||
const binding = scope.getBinding(varName);
|
||||
|
||||
// Ensure the variable is not reassigned
|
||||
if (binding && binding.constant) {
|
||||
// Replace all references
|
||||
binding.referencePaths.forEach((refPath) => {
|
||||
// Resolve nested identifiers recursively
|
||||
replaceWithResolvedValue(refPath, rightElem, scope);
|
||||
});
|
||||
// Optionally remove the declarator
|
||||
// binding.path.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle object destructuring if needed
|
||||
// (Similar logic can be applied here if your code contains object destructuring)
|
||||
});
|
||||
|
||||
// Optionally remove the entire declaration if all variables have been inlined
|
||||
if (node.declarations.every((decl) => !scope.getBinding(decl.id.name))) {
|
||||
path.remove();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Helper function to resolve nested identifiers and member expressions
|
||||
function replaceWithResolvedValue(refPath, valueNode, scope) {
|
||||
if (t.isIdentifier(valueNode)) {
|
||||
const binding = scope.getBinding(valueNode.name);
|
||||
|
||||
if (binding && binding.constant && binding.path.node.init) {
|
||||
// Recursively replace with the actual value
|
||||
replaceWithResolvedValue(refPath, binding.path.node.init, scope);
|
||||
} else {
|
||||
refPath.replaceWith(valueNode);
|
||||
}
|
||||
} else if (t.isMemberExpression(valueNode)) {
|
||||
// Resolve the object and property if possible
|
||||
const objectNode = valueNode.object;
|
||||
const propertyNode = valueNode.property;
|
||||
|
||||
let resolvedObjectNode = objectNode;
|
||||
if (t.isIdentifier(objectNode)) {
|
||||
const objectBinding = scope.getBinding(objectNode.name);
|
||||
if (
|
||||
objectBinding &&
|
||||
objectBinding.constant &&
|
||||
objectBinding.path.node.init
|
||||
) {
|
||||
resolvedObjectNode = objectBinding.path.node.init;
|
||||
}
|
||||
}
|
||||
|
||||
refPath.replaceWith(
|
||||
t.memberExpression(resolvedObjectNode, propertyNode, valueNode.computed)
|
||||
);
|
||||
} else {
|
||||
refPath.replaceWith(valueNode);
|
||||
}
|
||||
}
|
||||
|
||||
const evaluateMemberExpressions = {
|
||||
MemberExpression(path) {
|
||||
const { node } = path;
|
||||
|
||||
if (t.isIdentifier(node.object) && t.isStringLiteral(node.property)) {
|
||||
const objectName = node.object.name;
|
||||
const propertyName = node.property.value;
|
||||
if (objectName === "window") {
|
||||
path.replaceWithSourceString(propertyName);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const evaluateCallExpressions = {
|
||||
MemberExpression(path) {
|
||||
const { node } = path;
|
||||
if (t.isIdentifier(node.object) && t.isStringLiteral(node.property)) {
|
||||
const objectName = node.object.name;
|
||||
const propertyName = node.property.value;
|
||||
const validObjects = [
|
||||
"document",
|
||||
"crypto",
|
||||
"Array",
|
||||
"Uint8Array",
|
||||
"TextEncoder",
|
||||
"RTCPeerConnection",
|
||||
"Promise",
|
||||
"Math",
|
||||
"String",
|
||||
];
|
||||
if (validObjects.includes(objectName)) {
|
||||
path.replaceWithSourceString(`${objectName}.${propertyName}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
traverse(AST, inlineDestructuredVariables);
|
||||
traverse(AST, evaluateMemberExpressions);
|
||||
traverse(AST, evaluateCallExpressions);
|
||||
|
||||
const final_code = generate(AST, beautify_opts).code;
|
||||
|
||||
babel.transform(
|
||||
final_code,
|
||||
{
|
||||
plugins: [
|
||||
"babel-plugin-minify-constant-folding",
|
||||
"babel-plugin-minify-dead-code-elimination",
|
||||
"babel-plugin-transform-inline-consecutive-adds",
|
||||
],
|
||||
},
|
||||
function (err, result) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
} else {
|
||||
const transformedCode = result.code;
|
||||
fs.writeFileSync(output, transformedCode);
|
||||
}
|
||||
}
|
||||
);
|
||||
0
output.log
Normal file
0
output.log
Normal file
960
package-lock.json
generated
960
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
|
@ -4,16 +4,21 @@
|
|||
"description": "fork of twitter-tid-deobf",
|
||||
"main": "deobf.js",
|
||||
"scripts": {
|
||||
"run": "node deobf.js"
|
||||
"run": "node deobf.js source/a.js output/a.js && node deobf2.js output/a.js output/b.js",
|
||||
"run2": "node deobf.js source/a.js output/a.js && node deobf2.js output/a.js output/b.js && node deobf.js output/b.js output/b.js && node deobf2.js output/b.js output/a.js"
|
||||
},
|
||||
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/cli": "^7.24.0",
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/generator": "~7.24.0",
|
||||
"@babel/parser": "~7.24.0",
|
||||
"@babel/traverse": "~7.24.0",
|
||||
"@babel/types": "~7.24.0"
|
||||
"@babel/types": "~7.24.0",
|
||||
"babel-plugin-minify-constant-folding": "^0.5.0",
|
||||
"babel-plugin-minify-dead-code-elimination": "^0.5.2",
|
||||
"babel-plugin-transform-inline-consecutive-adds": "^0.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue