Skip to content

Instantly share code, notes, and snippets.

@seia-soto
Last active December 4, 2022 05:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seia-soto/3b6ea1b35631cbe64f9b05b4636e495f to your computer and use it in GitHub Desktop.
Save seia-soto/3b6ea1b35631cbe64f9b05b4636e495f to your computer and use it in GitHub Desktop.
Inspector
// ==UserScript==
// @name New script
// @namespace Violentmonkey Scripts
// @match *://*/*
// @grant unsafeWindow
// @version 1.0
// @author -
// @description 12/2/2022, 12:42:04 PM
// ==/UserScript==
"use strict";
(() => {
// src/inspector.ts
(() => {
let thisWindow = window;
if (typeof unsafeWindow !== "undefined") {
console.log("unsafeWindow found");
thisWindow = unsafeWindow;
}
const tails = [];
const proxyLog = new Proxy(
console.log,
{
apply(target, thisArg, argArray) {
tails.push(argArray.join(" "));
}
}
);
const defaultGetOwnPropertyDescriptor = thisWindow.Object.getOwnPropertyDescriptor;
const mocks = [
{
reference: thisWindow.Object,
key: "getOwnPropertyDescriptor",
use: defaultGetOwnPropertyDescriptor(thisWindow.Object, "getOwnPropertyDescriptor")
},
{
reference: Object,
key: "getOwnPropertyDescriptors",
use: defaultGetOwnPropertyDescriptor(thisWindow.Object, "getOwnPropertyDescriptors")
}
];
const defineProperty = new Proxy(
thisWindow.Object.defineProperty,
{
apply(target, thisArg, argArray) {
const [obj, key] = argArray;
mocks.push({
reference: obj,
key
});
return Reflect.apply(target, thisArg, argArray);
}
}
);
function createNativeCodeLiteral(name) {
return `function ${name}() { [native code] }`;
}
const defaultGetOwnPropertyDescriptors = Object.getOwnPropertyDescriptors;
const defaultReflectGetOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor;
Object.defineProperties(
Object,
{
getOwnPropertyDescriptor: {
get() {
function getOwnPropertyDescriptor(obj, key) {
for (const entry of mocks) {
if (entry.reference === obj && entry.key === key) {
return entry.use;
}
}
return defaultGetOwnPropertyDescriptor(obj, key);
}
getOwnPropertyDescriptor.toString = function toString() {
return createNativeCodeLiteral("getOwnPropertyDescriptor");
};
return getOwnPropertyDescriptor;
}
},
getOwnPropertyDescriptors: {
get() {
function getOwnPropertyDescriptors(obj) {
const result = defaultGetOwnPropertyDescriptors(obj);
for (const entry of mocks) {
if (entry.reference === obj) {
if (typeof entry.use === "undefined") {
delete result[entry.key];
continue;
}
result[entry.key] = entry.use;
}
}
return result;
}
getOwnPropertyDescriptors.toString = function toString() {
return createNativeCodeLiteral("getOwnPropertyDescriptors");
};
return getOwnPropertyDescriptors;
}
}
}
);
Object.defineProperties(
Reflect,
{
getOwnPropertyDescriptor: {
get() {
function getOwnPropertyDescriptor(obj, key) {
for (const entry of mocks) {
if (entry.reference === obj && entry.key === key) {
return entry.use;
}
}
return defaultReflectGetOwnPropertyDescriptor(obj, key);
}
getOwnPropertyDescriptor.toString = function toString() {
return createNativeCodeLiteral("getOwnPropertyDescriptor");
};
return getOwnPropertyDescriptor;
}
}
}
);
defineProperty(
thisWindow,
"__seia_get_tails__",
{
get() {
return console.log(JSON.stringify(tails));
},
enumerable: false
}
);
const inspected = [];
const whitelisted = [
{
reference: Object,
key: "defineProperty"
},
{
reference: Object,
key: "defineProperties"
}
];
function inspect(obj = thisWindow, prefix = "window") {
for (const old of inspected) {
if (obj === old) {
return;
}
}
inspected.push(obj);
for (const key in obj) {
const original = obj[key];
try {
if (typeof whitelisted.find((whitelist) => whitelist.reference === obj && whitelist.key === key) !== "undefined") {
continue;
}
defineProperty(
obj,
key,
{
get() {
proxyLog("get", prefix + "." + key, original);
if (typeof original === "object") {
inspect(original, prefix + "." + key);
} else if (typeof original === "function") {
return new Proxy(
original,
{
apply(target, thisArg, argArray) {
proxyLog("apply", prefix + "." + key, original, argArray);
return Reflect.apply(target, thisArg, argArray);
}
}
);
}
return original;
}
}
);
} catch (e) {
console.error(e);
}
}
}
inspect(thisWindow);
inspect(thisWindow.Object, "Object");
inspect(thisWindow.Array, "Array");
inspect(thisWindow.JSON, "JSON");
})();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment