FMHY Base64 Auto Decoder

Decode base64-encoded links in some pastebins and make URLs clickable

Size

9.1 KB

Version

2.5

Created

Nov 5, 2025

Updated

about 1 month ago

1// ==UserScript==
2// @name         FMHY Base64 Auto Decoder
3// @version      2.5
4// @author       Rust1667
5// @description  Decode base64-encoded links in some pastebins and make URLs clickable
6// @match        *://rentry.co/*
7// @match        *://rentry.org/*
8// @match        *://pastes.fmhy.net/*
9// @match        *://bin.disroot.org/?*#*
10// @match        *://privatebin.net/?*#*
11// @match        *://textbin.xyz/?*#*
12// @match        *://bin.idrix.fr/?*#*
13// @match        *://privatebin.rinuploads.org/?*#*
14// @match        *://pastebin.com/*
15// @grant        none
16// @icon         https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://fmhy.net&size=64
17// @namespace https://greasyfork.org/users/980489
18// @downloadURL https://update.greasyfork.org/scripts/485772/FMHY%20Base64%20Auto%20Decoder.user.js
19// @updateURL https://update.greasyfork.org/scripts/485772/FMHY%20Base64%20Auto%20Decoder.meta.js
20// ==/UserScript==
21
22
23(function() {
24    'use strict';
25
26    // Regular expression to match base64-encoded strings
27    const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/;
28
29    // Function to decode base64 string
30    function decodeBase64(encodedString) {
31        return atob(encodedString);
32    }
33
34    // Function to check if a string is a URL
35    function isURL(str) {
36        const pattern = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i;
37        return pattern.test(str);
38    }
39
40    // Different script for different pastebins
41    var currentUrl = window.location.href;
42    const rentryOrSnowbinRegex =          /^(https?:\/\/(?:rentry\.co|rentry\.org|pastes\.fmhy\.net)\/[\w\W]+)/;
43    const FMHYmainBase64PageRegex =       /^https:\/\/rentry\.(?:co|org)\/fmhybase64(?:#.*)?/i;
44    const fmhyBase64RawRentryPageRegex =  /^https:\/\/rentry\.(co|org)\/FMHYBase64\/raw$/i;
45    const privatebinDomainsRegex =        /^(https?:\/\/(?:bin\.disroot\.org|privatebin\.net|textbin\.xyz|bin\.idrix\.fr|privatebin\.rinuploads\.org)\/[\w\W]+)/;
46    const pastebinComRegex =              /^https:\/\/pastebin\.com\/.*/;
47
48    // PASTEBIN.COM
49    if (pastebinComRegex.test(currentUrl)) {
50      let elements = document.querySelectorAll('.de1');
51        elements.forEach(function(element) {
52            let text = element.textContent.trim();
53            if (text.startsWith('aHR0')) {
54              let decodedText = decodeBase64(text);
55
56              // Get the color of the original text
57              let originalColor = window.getComputedStyle(element).color;
58
59              // Turn each valid URL in the decoded text into a clickable link
60              let htmlWithLinks = decodedText.replace(
61                /(https?:\/\/[^\s]+)/g, // find anything that looks like a URL
62                '<a href="$1" target="_blank" style="color: ' + originalColor + ';">$1</a>'
63              );
64
65              // Replace newlines with <br> for readability
66              htmlWithLinks = htmlWithLinks.replace(/\n/g, '<br>');
67
68              // Replace the original text with the new clickable version
69              element.innerHTML = htmlWithLinks;
70            }
71        });
72
73
74    //RENTRY OR PASTES.FMHY
75    } else if (rentryOrSnowbinRegex.test(currentUrl) && !fmhyBase64RawRentryPageRegex.test(currentUrl)) {
76
77      // Select appropriate tags based on the URL matching
78      var elementsToCheck = FMHYmainBase64PageRegex.test(currentUrl) ? document.querySelectorAll('code') : document.querySelectorAll('code, p');
79
80      // Loop through each selected element
81      elementsToCheck.forEach(function(element) {
82          // Get the content of the element
83          var content = element.textContent.trim();
84
85          // Check if the content matches the base64 regex
86          if (base64Regex.test(content)) {
87              // Decode the base64-encoded string
88              var decodedString = decodeBase64(content).trim();
89
90              // If the decoded string has URLs, decode it and linkify when possible
91              if (isURL(decodedString) || (decodedString.includes('http') && decodedString.includes('\n'))) {
92
93                  // One line
94                  if (!decodedString.includes('\n')) {
95                    var link = document.createElement('a');
96                    link.href = decodedString;
97                    link.textContent = decodedString;
98                    link.target = '_self'; // Open link in the same tab
99                    element.textContent = ''; // Clear the content of the element
100                    element.appendChild(link); // Append the link to the element
101                  }
102                  //Multiple lines
103                  else {
104                    const lines = decodedString.split("\n");
105                    const links = lines.map(line => isURL(line.trim()) ? "<a href='" + line.trim() + "'>" + line.trim() + "</a>" : line.trim());
106                    element.innerHTML = links.join("<br>");
107                  }
108
109              }
110          }
111      });
112
113
114
115    //FMHY-BASE64 RAW RENTRY PAGE
116    } else if (fmhyBase64RawRentryPageRegex.test(currentUrl)) {
117
118        // Find all lines starting with "* `"
119        const lines = document.body.innerText.split('\n');
120        for (let i = 0; i < lines.length; i++) {
121            const line = lines[i];
122            if (line.includes('`')) {
123                const startIndex = line.indexOf('`');
124                const endIndex = line.lastIndexOf('`');
125                const encodedText = line.substring(startIndex + 1, endIndex).trim();
126                const decodedText = atob(encodedText);
127                const newLine = line.substring(0, startIndex) + decodedText + line.substring(endIndex + 1);
128                lines[i] = newLine;
129            }
130        }
131
132        // Update the page content with decoded lines
133        document.body.innerText = lines.join('\n');
134
135
136
137
138    // PRIVATEBIN
139    } else if (privatebinDomainsRegex.test(currentUrl)) {
140
141      // Wait for the decryption process to finish
142      function waitForDecryption() {
143          const prettyPrintElement = document.getElementById('prettyprint');
144          if (prettyPrintElement && prettyPrintElement.textContent.trim() !== '') {
145              let decryptedText = prettyPrintElement.innerHTML.trim();
146              const lines = decryptedText.split('\n');
147
148              // Flag to track if any modifications were made
149              let modified = false;
150
151              // Iterate through each line
152              lines.forEach(line => {
153                  // Check if the line contains a potential Base64 encoded string
154                  if (base64Regex.test(line)) {
155                      // Attempt to decode the potential Base64 encoded string
156                      try {
157                          const decodedText = decodeBase64(line);
158                          // Trim the decoded text before checking if it's a URL
159                          const trimmedText = decodedText.trim();
160                          // If trimmed decoded string is a URL, make it clickable
161                          if (isURL(trimmedText)) {
162                              // Replace the line with the decoded and linked text
163                              decryptedText = decryptedText.replace(line, '<a href="' + trimmedText + '">' + trimmedText + '</a>');
164                              modified = true;
165                          }
166                      } catch (error) {
167                          // If an error occurs during decoding, show it in an alert message
168                          //alert("Unable to decode the string: " + line);
169                      }
170                  } else if (line.startsWith('`') && line.endsWith('`')) {
171                      // Check if the line starts and ends with backticks
172                      let textInsideBackticks = line.slice(1, -1);
173                      // Check if textInsideBackticks is a Base64 encoded string
174                      if (base64Regex.test(textInsideBackticks)) {
175                      // Attempt to decode the text inside backticks
176                        try {
177                            const decodedText = decodeBase64(textInsideBackticks);
178                            // Trim the decoded text before checking if it's a URL
179                            const trimmedText = decodedText.trim();
180                            // If trimmed decoded string is a URL, make it clickable
181                            if (isURL(trimmedText)) {
182                                // Replace the line with the decoded and linked text
183                                decryptedText = decryptedText.replace(line, '<a href="' + trimmedText + '">' + trimmedText + '</a>');
184                                modified = true;
185                            }
186                        } catch (error) {
187                            // If an error occurs during decoding, show it in an alert message
188                            //alert("Unable to decode the string: " + textInsideBackticks);
189                        }
190                      }
191                  }
192              });
193
194              // If modifications were made, show modified text in the page
195              if (modified) {
196                prettyPrintElement.innerHTML = decryptedText;
197              }
198
199          } else {
200              setTimeout(waitForDecryption, 500); // Check again in 500ms
201          }
202      }
203
204      // Start waiting for decryption
205      waitForDecryption();
206    }
207
208
209
210
211
212})();
213