首先找到wasm初始化的位置,然后hook初始化后的实例
// === 封装:一键读取 WASM 内存中的字符串(修复版)===
(function initWasmStringReader() {
try {
const instance = window.wasmInstance;
if (!instance) {
console.error('❌ window.wasmInstance 未定义,请先加载 WASM 实例');
return;
}
// 🔧 修复点:支持 .e 和通用查找
const exportedMemory =
instance.exports.e || // 你的实际导出名
instance.exports.memory || // 标准名
Object.values(instance.exports).find(
val => val instanceof WebAssembly.Memory
);
if (!exportedMemory) {
console.error('❌ 未找到 WebAssembly.Memory,当前导出项:', Object.keys(instance.exports));
return;
}
const memory = exportedMemory;
const u8 = new Uint8Array(memory.buffer);
// 核心函数:通过地址读取字符串
window.readWasmStr = function readWasmStr(ptr, maxLen = 1024) {
// 输入校验
if (typeof ptr !== 'number' || ptr < 0) {
console.warn('⚠️ 无效地址:', ptr);
return null;
}
if (ptr === 0) {
console.log('📌 [0x0] null pointer');
return null;
}
// 检查地址是否越界
if (ptr >= u8.length) {
console.warn(`⚠️ 地址 0x${ptr.toString(16)} 超出内存范围 (最大 0x${u8.length.toString(16)})`);
return null;
}
// 查找 \0 结束符
let end = ptr;
let len = 0;
while (len < maxLen && u8[end] !== 0 && end < u8.length) {
end++;
len++;
}
// 解码 UTF-8 字符串
const str = new TextDecoder('utf-8').decode(u8.subarray(ptr, end));
// 打印带格式的结果
console.log(`📌 0x${ptr.toString(16)} (${ptr}):`, str);
return str;
};
// ✅ 增强提示:显示内存大小
const totalPages = memory.buffer.byteLength / 65536;
console.log(`✅ readWasmStr(addr) 已就绪!内存页数: ${totalPages} (≈${(totalPages * 64).toFixed(1)}MB)`);
console.log('📝 示例:readWasmStr(7798784)');
console.log('🔍 提示:内存来自 exports.e,支持读取字符串');
} catch (err) {
console.error('❌ 初始化失败:', err);
}
})();
因为我做的是图像解密,他的解密是在wasm中做的,我采用的是倒推的方式找的解密后js是在哪个交互函数中拿到结果的。同样进行hook
// 在 Console 中执行
const canvas = document.getElementById('click-grid-0');
const ctx = canvas.getContext('2d');
// 保存原始方法
const originalPutImageData = ctx.putImageData;
ctx.putImageData = function(...args) {
console.debug('putImageData called with:', args);
// 创建一个临时 canvas 来存放 ImageData
const tempCanvas = document.createElement('canvas');
tempCanvas.width = args[0].width; // ImageData width
tempCanvas.height = args[0].height; // ImageData height
// 获取上下文并绘制 ImageData
const tempCtx = tempCanvas.getContext('2d');
tempCtx.putImageData(args[0], 0, 0);
// 转换为 Base64(PNG 格式)
const base64 = tempCanvas.toDataURL('image/png');
// 输出 Base64 字符串
console.log('Base64 URL:');
console.log(base64);
// 可选:在页面上显示该图片
const img = document.createElement('img');
img.src = base64;
img.style.margin = '10px';
img.style.border = '1px solid #ccc';
document.body.appendChild(img);
debugger; // 断点在这里,查看调用栈
return originalPutImageData.apply(this, args);
};
因为wasm会开辟一块线下地址和js进行交互。实例化的时候会会返回wasm导出的地址。我们挂载到全局,然后封装一个方法,对内存的值进行读取,因为wasm基本都是对内存进行操作。
// === 封装:一键读取 WASM 内存中的字符串(修复版)===
(function initWasmStringReader() {
try {
const instance = window.wasmInstance;
if (!instance) {
console.error('❌ window.wasmInstance 未定义,请先加载 WASM 实例');
return;
}
// 🔧 修复点:支持 .e 和通用查找
const exportedMemory =
instance.exports.e || // 你的实际导出名
instance.exports.memory || // 标准名
Object.values(instance.exports).find(
val => val instanceof WebAssembly.Memory
);
if (!exportedMemory) {
console.error('❌ 未找到 WebAssembly.Memory,当前导出项:', Object.keys(instance.exports));
return;
}
const memory = exportedMemory;
const u8 = new Uint8Array(memory.buffer);
// 核心函数:通过地址读取字符串
window.readWasmStr = function readWasmStr(ptr, maxLen = 1024) {
// 输入校验
if (typeof ptr !== 'number' || ptr < 0) {
console.warn('⚠️ 无效地址:', ptr);
return null;
}
if (ptr === 0) {
console.log('📌 [0x0] null pointer');
return null;
}
// 检查地址是否越界
if (ptr >= u8.length) {
console.warn(`⚠️ 地址 0x${ptr.toString(16)} 超出内存范围 (最大 0x${u8.length.toString(16)})`);
return null;
}
// 查找 \0 结束符
let end = ptr;
let len = 0;
while (len < maxLen && u8[end] !== 0 && end < u8.length) {
end++;
len++;
}
// 解码 UTF-8 字符串
const str = new TextDecoder('utf-8').decode(u8.subarray(ptr, end));
// 打印带格式的结果
console.log(`📌 0x${ptr.toString(16)} (${ptr}):`, str);
return str;
};
// ✅ 增强提示:显示内存大小
const totalPages = memory.buffer.byteLength / 65536;
console.log(`✅ readWasmStr(addr) 已就绪!内存页数: ${totalPages} (≈${(totalPages * 64).toFixed(1)}MB)`);
console.log('📝 示例:readWasmStr(7798784)');
console.log('🔍 提示:内存来自 exports.e,支持读取字符串');
} catch (err) {
console.error('❌ 初始化失败:', err);
}
})();
1997

被折叠的 条评论
为什么被折叠?



