196 lines
5.4 KiB
JavaScript
196 lines
5.4 KiB
JavaScript
const constants = [
|
|
'exports',
|
|
'270328ewawLo',
|
|
'instantiate',
|
|
'1OsuamQ',
|
|
'Incorrect!',
|
|
'length',
|
|
'copy_char',
|
|
'value',
|
|
'1512517ESezaM',
|
|
'innerHTML',
|
|
'check_flag',
|
|
'result',
|
|
'1383842SQRPPf',
|
|
'924408cukzgO',
|
|
'getElementById',
|
|
'418508cLDohp',
|
|
'input',
|
|
'Correct!',
|
|
'573XsMMHp',
|
|
'arrayBuffer',
|
|
'183RUQBDE',
|
|
'38934oMACea',
|
|
];
|
|
|
|
const get_const = function(addr, _seemingly_unused) {
|
|
addr = addr - 0x11d;
|
|
let result = constants[addr];
|
|
return result;
|
|
};
|
|
|
|
// Stack aligner of some sort?
|
|
(function() {
|
|
while (!![]) {
|
|
try {
|
|
const result =
|
|
-parseInt(get_const(0x122))
|
|
+ -parseInt(get_const(0x12f))
|
|
+ -parseInt(get_const(0x126)) * -parseInt(get_const(0x12b))
|
|
+ -parseInt(get_const(0x132))
|
|
+ parseInt(get_const(0x124))
|
|
+ -parseInt(get_const(0x121)) * -parseInt(get_const(0x11f))
|
|
+ parseInt(get_const(0x130));
|
|
if (result === 0x252604) break;
|
|
else constants['push'](constants['shift']());
|
|
} catch (e) {
|
|
constants['push'](constants['shift']());
|
|
}
|
|
}
|
|
}());
|
|
|
|
let exports;
|
|
|
|
// Load the WebAssembly module and get its exports
|
|
(async () => {
|
|
let checkFlagWasm = await fetch('./index.wasm'),
|
|
arrayBufferResult = await WebAssembly['instantiate'](await checkFlagWasm['arrayBuffer']()),
|
|
arrayBufferResultInstance = arrayBufferResult['instance'];
|
|
exports = arrayBufferResultInstance['exports'];
|
|
})();
|
|
|
|
function onButtonPress() {
|
|
let value = document['getElementById']('input')['value'];
|
|
const copy_char = exports['copy_char'];
|
|
|
|
for (let i = 0x0; i < value['length']; i++) {
|
|
const char_code = value['charCodeAt'](i);
|
|
copy_char(char_code, i);
|
|
}
|
|
|
|
exports['copy_char'](0x0, value['length']), exports['check_flag']() == 0x1
|
|
? document['getElementById']('result')['innerHTML'] = 'Correct!'
|
|
: document['getElementById']('result')['innerHTML'] = 'Incorrect!';
|
|
}
|
|
|
|
// First attempt at reverse engineering copy_char/func3.
|
|
// This is a relatively direct translation.
|
|
|
|
function copy_char(var0, var1) {
|
|
const key = "\xf1\xa7\xf0\x07\xed";
|
|
// (global $global0 (mut i32) (i32.const 66864))
|
|
// (global $global1 i32 (i32.const 1072))
|
|
const var2 = exports['global0']['value'];
|
|
const var3 = 16;
|
|
const var4 = var2 - var3;
|
|
exports['memory']['buffer'][var4 + 12] = var0;
|
|
exports['memory']['buffer'][var4 + 8] = var1;
|
|
var5 = exports['memory']['buffer'][var4 + 12];
|
|
if (var5 !== 0) {
|
|
const var6 = 4;
|
|
const var7 = exports['memory']['buffer'][var4 + 8];
|
|
const var8 = 5;
|
|
const var9 = var7 % var8;
|
|
const var10 = var6 - var9;
|
|
const var11 = key.charCodeAt(var10);
|
|
const var12 = 24;
|
|
const var13 = var11 << var12;
|
|
const var14 = var13 >> var12;
|
|
const var15 = exports['memory']['buffer'][var4 + 12];
|
|
const var16 = var15 ^ var14;
|
|
exports['memory']['buffer'][var4 + 12] = var16;
|
|
}
|
|
const var17 = exports['memory']['buffer'][var4 + 12];
|
|
const var18 = exports['memory']['buffer'][var4 + 8];
|
|
exports['memory']['buffer'][var18 + 1072] = var17;
|
|
}
|
|
|
|
// Let's shorten it more and get rid of all the memory shuffling
|
|
|
|
function copy_char(c, i) {
|
|
const key = "\xf1\xa7\xf0\x07\xed";
|
|
if (c !== 0) {
|
|
const key_index = (4 - (i % 5));
|
|
const key_char = key.charCodeAt(key_index);
|
|
c ^= key_char;
|
|
}
|
|
exports['memory']['buffer'][i + 1072] = c;
|
|
}
|
|
|
|
|
|
// copy_char
|
|
// (func $func3 (param $var0 i32) (param $var1 i32)
|
|
// (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32) (local $var6 i32) (local $var7 i32) (local $var8 i32) (local $var9 i32) (local $var10 i32) (local $var11 i32) (local $var12 i32) (local $var13 i32) (local $var14 i32) (local $var15 i32) (local $var16 i32) (local $var17 i32) (local $var18 i32)
|
|
// global.get $global0
|
|
// local.set $var2
|
|
// i32.const 16
|
|
// local.set $var3
|
|
// local.get $var2
|
|
// local.get $var3
|
|
// i32.sub
|
|
// local.set $var4
|
|
// local.get $var4
|
|
// local.get $var0
|
|
// i32.store offset=12
|
|
// local.get $var4
|
|
// local.get $var1
|
|
// i32.store offset=8
|
|
// local.get $var4
|
|
// i32.load offset=12
|
|
// local.set $var5
|
|
// block $label0
|
|
// local.get $var5
|
|
// i32.eqz
|
|
// br_if $label0
|
|
// i32.const 4
|
|
// local.set $var6
|
|
// local.get $var4
|
|
// i32.load offset=8
|
|
// local.set $var7
|
|
// i32.const 5
|
|
// local.set $var8
|
|
// local.get $var7
|
|
// local.get $var8
|
|
// i32.rem_s
|
|
// local.set $var9
|
|
// local.get $var6
|
|
// local.get $var9
|
|
// i32.sub
|
|
// local.set $var10
|
|
// local.get $var10
|
|
// i32.load8_u offset=1067
|
|
// local.set $var11
|
|
// i32.const 24
|
|
// local.set $var12
|
|
// local.get $var11
|
|
// local.get $var12
|
|
// i32.shl
|
|
// local.set $var13
|
|
// local.get $var13
|
|
// local.get $var12
|
|
// i32.shr_s
|
|
// local.set $var14
|
|
// local.get $var4
|
|
// i32.load offset=12
|
|
// local.set $var15
|
|
// local.get $var15
|
|
// local.get $var14
|
|
// i32.xor
|
|
// local.set $var16
|
|
// local.get $var4
|
|
// local.get $var16
|
|
// i32.store offset=12
|
|
// end $label0
|
|
// local.get $var4
|
|
// i32.load offset=12
|
|
// local.set $var17
|
|
// local.get $var4
|
|
// i32.load offset=8
|
|
// local.set $var18
|
|
// local.get $var18
|
|
// local.get $var17
|
|
// i32.store8 offset=1072
|
|
// return
|
|
// )
|
|
// (data (i32.const 1024) "\9dn\93\c8\b2\b9A\8b\94\90\dd>\94\97\90\dd?\c4\c2\c9\dd4\c2\c5\97\db1\93\92\c0\da6\93\93\c1\d9>\91\c1\97\90\00\00")
|