Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YangSeungWon/3de1311c1e03195577f4f52bae76dd02 to your computer and use it in GitHub Desktop.
Save YangSeungWon/3de1311c1e03195577f4f52bae76dd02 to your computer and use it in GitHub Desktop.

m0leCon CTF 2020 Teaser - play-me-piano

tags: wasm

[name=whysw@PLUS]

Attachments

Attachments are uploaded on gist.

Challenge

https://challs.m0lecon.it:8005/

When each button is pressed, review('what you pressed') is called. If it is long pressed, review('-') is also called.

Solution

Make ELF binary file in order to analyze in IDA

$ ./wasm2c chall.wasm --no-debug-names -o chall.c

Modified address of wasm-rt.h in chall.h to absolute path.

Made main.c file to compile.

int main(int argc, char* argv[]){
    return 0;
}
$ gcc chall.c ~/tools/wabt/wasm2c/wasm-rt-impl.c main.c -o chall

now we have ELF binary file.


Static Analysis

pseudo code

int data[98] = { 
  0x2a, 0x39, 0x67, 0x7e, 0x71, 0x2d, 0x21, 0x21, 0x72, 0x43, 0x41, 0x3a, 
  0x09, 0x0c, 0x04, 0x05, 0x52, 0x42, 0x40, 0x19, 0x0a, 0x77, 0x51, 0x42, 
  0x05, 0x23, 0x36, 0x5b, 0x0c, 0x67, 0x66, 0x22, 0x00, 0x4b, 0x27, 0x38, 
  0x47, 0x72, 0x6e, 0x5b, 0x75, 0x2b, 0x2c, 0x32, 0x5e, 0x53, 0x47, 0x5a, 
  0x22, 0x70, 0x74, 0x6d, 0x7b, 0x00, 0x77, 0x68, 0x61, 0x74, 0x27, 0x73, 
  0x20, 0x74, 0x68, 0x69, 0x73, 0x3f, 0x00, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e, 
  0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x68, 0x78, 0x20, 
  0x2e, 0x2e, 0x2e, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e, 0x2e, 
  0x00, 0x2a, 
};

int cnt = 0;

char f5(char arg){
    cnt++;
    data[97] = arg ^ data[cnt] ^ data[97];
    return data[97];
}

status review(char input){
    char res = f5(input);
    if(cnt-1 < 4){
        if(data[48+cnt] == res){
            return keepgoing;
        }else{
            data[97] = 0x2a;
            cnt = 0;
            return fail;
        }
    }
    if(res > 0x7f){
        data[97] = 0x2a;
        cnt = 0;
        return fail;
    }
    if(cnt == 47){
        if(res == '}'){
            return success;
        }
        else{
            return fail;
        }
    }
    return keepgoing;
}

Brute Forcing...?

I made python code that do brute force... but we can know if these notes are right when all 48 notes are set. So we can know first 4 notes only: CCGG

Google knows everything

WOW!

so the answer is ... ccggaag-ffeeddc-ggffeed-ggffeed-ccggaag-ffeeddc-

data = [0x2a, 0x39, 0x67, 0x7e, 0x71, 0x2d, 0x21, 0x21, 0x72, 0x43, 0x41, 0x3a, 0x09, 0x0c, 0x04, 0x05, 0x52, 0x42, 0x40, 0x19, 0x0a, 0x77, 0x51, 0x42, 0x05, 0x23, 0x36, 0x5b, 0x0c, 0x67, 0x66, 0x22, 0x00, 0x4b, 0x27, 0x38, 0x47, 0x72, 0x6e, 0x5b, 0x75, 0x2b, 0x2c, 0x32, 0x5e, 0x53, 0x47, 0x5a, 0x22, 0x70, 0x74, 0x6d, 0x7b, 0x00, 0x77, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3f, 0x00, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x68, 0x78, 0x20, 0x2e, 0x2e, 0x2e, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e, 0x2e, 0x00, 0x2a]

cand = "cdefgab-"

cnt = 0

def f5(arg):
    global cnt
    cnt += 1;
    data[97] = ord(arg) ^ data[cnt] ^ data[97]
    return data[97]


def review(pressed):
    cnt_ = cnt
    res = f5(pressed)
    if cnt_ < 4:
        if data[49+cnt_] == res:
            return res
        else:
            return False
    if cnt_ == 47:
        if res == ord('}'):
            return res
        else:
            return False
    return res

flag = ""
for note in "ccggaag-ffeeddc-ggffeed-ggffeed-ccggaag-ffeeddc-":
    res = review(note)
    flag += chr(res)
    print(flag)

output : ptm{7w1nKl3_7W1NkL3_My_w3b_574r_w3lL_Pl4y3d_hKr}

#include <math.h>
#include <string.h>
#include "chall.h"
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#define LIKELY(x) __builtin_expect(!!(x), 1)
#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0)
#define FUNC_PROLOGUE \
if (++wasm_rt_call_stack_depth > WASM_RT_MAX_CALL_STACK_DEPTH) \
TRAP(EXHAUSTION)
#define FUNC_EPILOGUE --wasm_rt_call_stack_depth
#define UNREACHABLE TRAP(UNREACHABLE)
#define CALL_INDIRECT(table, t, ft, x, ...) \
(LIKELY((x) < table.size && table.data[x].func && \
table.data[x].func_type == func_types[ft]) \
? ((t)table.data[x].func)(__VA_ARGS__) \
: TRAP(CALL_INDIRECT))
#define MEMCHECK(mem, a, t) \
if (UNLIKELY((a) + sizeof(t) > mem->size)) TRAP(OOB)
#define DEFINE_LOAD(name, t1, t2, t3) \
static inline t3 name(wasm_rt_memory_t* mem, u64 addr) { \
MEMCHECK(mem, addr, t1); \
t1 result; \
memcpy(&result, &mem->data[addr], sizeof(t1)); \
return (t3)(t2)result; \
}
#define DEFINE_STORE(name, t1, t2) \
static inline void name(wasm_rt_memory_t* mem, u64 addr, t2 value) { \
MEMCHECK(mem, addr, t1); \
t1 wrapped = (t1)value; \
memcpy(&mem->data[addr], &wrapped, sizeof(t1)); \
}
DEFINE_LOAD(i32_load, u32, u32, u32);
DEFINE_LOAD(i64_load, u64, u64, u64);
DEFINE_LOAD(f32_load, f32, f32, f32);
DEFINE_LOAD(f64_load, f64, f64, f64);
DEFINE_LOAD(i32_load8_s, s8, s32, u32);
DEFINE_LOAD(i64_load8_s, s8, s64, u64);
DEFINE_LOAD(i32_load8_u, u8, u32, u32);
DEFINE_LOAD(i64_load8_u, u8, u64, u64);
DEFINE_LOAD(i32_load16_s, s16, s32, u32);
DEFINE_LOAD(i64_load16_s, s16, s64, u64);
DEFINE_LOAD(i32_load16_u, u16, u32, u32);
DEFINE_LOAD(i64_load16_u, u16, u64, u64);
DEFINE_LOAD(i64_load32_s, s32, s64, u64);
DEFINE_LOAD(i64_load32_u, u32, u64, u64);
DEFINE_STORE(i32_store, u32, u32);
DEFINE_STORE(i64_store, u64, u64);
DEFINE_STORE(f32_store, f32, f32);
DEFINE_STORE(f64_store, f64, f64);
DEFINE_STORE(i32_store8, u8, u32);
DEFINE_STORE(i32_store16, u16, u32);
DEFINE_STORE(i64_store8, u8, u64);
DEFINE_STORE(i64_store16, u16, u64);
DEFINE_STORE(i64_store32, u32, u64);
#define I32_CLZ(x) ((x) ? __builtin_clz(x) : 32)
#define I64_CLZ(x) ((x) ? __builtin_clzll(x) : 64)
#define I32_CTZ(x) ((x) ? __builtin_ctz(x) : 32)
#define I64_CTZ(x) ((x) ? __builtin_ctzll(x) : 64)
#define I32_POPCNT(x) (__builtin_popcount(x))
#define I64_POPCNT(x) (__builtin_popcountll(x))
#define DIV_S(ut, min, x, y) \
((UNLIKELY((y) == 0)) ? TRAP(DIV_BY_ZERO) \
: (UNLIKELY((x) == min && (y) == -1)) ? TRAP(INT_OVERFLOW) \
: (ut)((x) / (y)))
#define REM_S(ut, min, x, y) \
((UNLIKELY((y) == 0)) ? TRAP(DIV_BY_ZERO) \
: (UNLIKELY((x) == min && (y) == -1)) ? 0 \
: (ut)((x) % (y)))
#define I32_DIV_S(x, y) DIV_S(u32, INT32_MIN, (s32)x, (s32)y)
#define I64_DIV_S(x, y) DIV_S(u64, INT64_MIN, (s64)x, (s64)y)
#define I32_REM_S(x, y) REM_S(u32, INT32_MIN, (s32)x, (s32)y)
#define I64_REM_S(x, y) REM_S(u64, INT64_MIN, (s64)x, (s64)y)
#define DIVREM_U(op, x, y) \
((UNLIKELY((y) == 0)) ? TRAP(DIV_BY_ZERO) : ((x) op (y)))
#define DIV_U(x, y) DIVREM_U(/, x, y)
#define REM_U(x, y) DIVREM_U(%, x, y)
#define ROTL(x, y, mask) \
(((x) << ((y) & (mask))) | ((x) >> (((mask) - (y) + 1) & (mask))))
#define ROTR(x, y, mask) \
(((x) >> ((y) & (mask))) | ((x) << (((mask) - (y) + 1) & (mask))))
#define I32_ROTL(x, y) ROTL(x, y, 31)
#define I64_ROTL(x, y) ROTL(x, y, 63)
#define I32_ROTR(x, y) ROTR(x, y, 31)
#define I64_ROTR(x, y) ROTR(x, y, 63)
#define FMIN(x, y) \
((UNLIKELY((x) != (x))) ? NAN \
: (UNLIKELY((y) != (y))) ? NAN \
: (UNLIKELY((x) == 0 && (y) == 0)) ? (signbit(x) ? x : y) \
: (x < y) ? x : y)
#define FMAX(x, y) \
((UNLIKELY((x) != (x))) ? NAN \
: (UNLIKELY((y) != (y))) ? NAN \
: (UNLIKELY((x) == 0 && (y) == 0)) ? (signbit(x) ? y : x) \
: (x > y) ? x : y)
#define TRUNC_S(ut, st, ft, min, max, maxop, x) \
((UNLIKELY((x) != (x))) ? TRAP(INVALID_CONVERSION) \
: (UNLIKELY((x) < (ft)(min) || (x) maxop (ft)(max))) ? TRAP(INT_OVERFLOW) \
: (ut)(st)(x))
#define I32_TRUNC_S_F32(x) TRUNC_S(u32, s32, f32, INT32_MIN, INT32_MAX, >=, x)
#define I64_TRUNC_S_F32(x) TRUNC_S(u64, s64, f32, INT64_MIN, INT64_MAX, >=, x)
#define I32_TRUNC_S_F64(x) TRUNC_S(u32, s32, f64, INT32_MIN, INT32_MAX, >, x)
#define I64_TRUNC_S_F64(x) TRUNC_S(u64, s64, f64, INT64_MIN, INT64_MAX, >=, x)
#define TRUNC_U(ut, ft, max, maxop, x) \
((UNLIKELY((x) != (x))) ? TRAP(INVALID_CONVERSION) \
: (UNLIKELY((x) <= (ft)-1 || (x) maxop (ft)(max))) ? TRAP(INT_OVERFLOW) \
: (ut)(x))
#define I32_TRUNC_U_F32(x) TRUNC_U(u32, f32, UINT32_MAX, >=, x)
#define I64_TRUNC_U_F32(x) TRUNC_U(u64, f32, UINT64_MAX, >=, x)
#define I32_TRUNC_U_F64(x) TRUNC_U(u32, f64, UINT32_MAX, >, x)
#define I64_TRUNC_U_F64(x) TRUNC_U(u64, f64, UINT64_MAX, >=, x)
#define DEFINE_REINTERPRET(name, t1, t2) \
static inline t2 name(t1 x) { \
t2 result; \
memcpy(&result, &x, sizeof(result)); \
return result; \
}
DEFINE_REINTERPRET(f32_reinterpret_i32, u32, f32)
DEFINE_REINTERPRET(i32_reinterpret_f32, f32, u32)
DEFINE_REINTERPRET(f64_reinterpret_i64, u64, f64)
DEFINE_REINTERPRET(i64_reinterpret_f64, f64, u64)
static u32 func_types[4];
static void init_func_types(void) {
func_types[0] = wasm_rt_register_func_type(1, 1, WASM_RT_I32, WASM_RT_I32);
func_types[1] = wasm_rt_register_func_type(0, 0);
func_types[2] = wasm_rt_register_func_type(1, 0, WASM_RT_I32);
func_types[3] = wasm_rt_register_func_type(0, 1, WASM_RT_I32);
}
static void _start(void);
static void stackRestore(u32);
static u32 stackAlloc(u32);
static u32 stackSave(void);
static u32 review(u32);
static u32 f5(u32);
static u32 g0;
static void init_globals(void) {
g0 = 5244176u;
}
static wasm_rt_memory_t memory;
static void _start(void) {
FUNC_PROLOGUE;
FUNC_EPILOGUE;
}
static void stackRestore(u32 p0) {
FUNC_PROLOGUE;
u32 i0;
i0 = p0;
g0 = i0;
FUNC_EPILOGUE;
}
static u32 stackAlloc(u32 p0) {
FUNC_PROLOGUE;
u32 i0, i1;
i0 = g0;
i1 = p0;
i0 -= i1;
i1 = 4294967280u;
i0 &= i1;
p0 = i0;
g0 = i0;
i0 = p0;
FUNC_EPILOGUE;
return i0;
}
static u32 stackSave(void) {
FUNC_PROLOGUE;
u32 i0;
i0 = g0;
FUNC_EPILOGUE;
return i0;
}
static u32 review(u32 p0) {
u32 l1 = 0;
FUNC_PROLOGUE;
u32 i0, i1, i2, i3;
i0 = 1124u;
i0 = i32_load((&memory), (u64)(i0));
l1 = i0;
i0 = p0;
i0 = i32_load8_s((&memory), (u64)(i0));
i0 = f5(i0);
p0 = i0;
i0 = l1;
i1 = 3u;
i0 = (u32)((s32)i0 <= (s32)i1);
if (i0) {
i0 = 1091u;
i1 = l1;
i2 = 1073u;
i1 += i2;
i1 = i32_load8_u((&memory), (u64)(i1));
i2 = p0;
i3 = 255u;
i2 &= i3;
i1 = i1 == i2;
if (i1) {goto B1;}
goto B0;
}
i0 = p0;
i1 = 4294967264u;
i0 += i1;
i1 = 255u;
i0 &= i1;
i1 = 94u;
i0 = i0 > i1;
if (i0) {goto B0;}
i0 = 1091u;
i1 = l1;
i2 = 47u;
i1 = i1 != i2;
if (i1) {goto B1;}
i0 = 1104u;
i1 = 1078u;
i2 = p0;
i3 = 125u;
i2 = i2 == i3;
i0 = i2 ? i0 : i1;
B1:;
goto Bfunc;
B0:;
i0 = 1121u;
i1 = 42u;
i32_store8((&memory), (u64)(i0), i1);
i0 = 1124u;
i1 = 0u;
i32_store((&memory), (u64)(i0), i1);
i0 = 1078u;
Bfunc:;
FUNC_EPILOGUE;
return i0;
}
static u32 f5(u32 p0) {
u32 l1 = 0;
FUNC_PROLOGUE;
u32 i0, i1, i2, i3;
i0 = 1124u;
i1 = 1124u;
i1 = i32_load((&memory), (u64)(i1));
i2 = 1u;
i1 += i2;
i2 = 49u;
i1 = REM_U(i1, i2);
l1 = i1;
i32_store((&memory), (u64)(i0), i1);
i0 = 1121u;
i1 = 1121u;
i1 = i32_load8_u((&memory), (u64)(i1));
i2 = l1;
i3 = 1024u;
i2 += i3;
i2 = i32_load8_u((&memory), (u64)(i2));
i3 = p0;
i2 ^= i3;
i1 ^= i2;
p0 = i1;
i32_store8((&memory), (u64)(i0), i1);
i0 = p0;
i1 = 24u;
i0 <<= (i1 & 31);
i1 = 24u;
i0 = (u32)((s32)i0 >> (i1 & 31));
FUNC_EPILOGUE;
return i0;
}
static const u8 data_segment_data_0[] = {
0x2a, 0x39, 0x67, 0x7e, 0x71, 0x2d, 0x21, 0x21, 0x72, 0x43, 0x41, 0x3a,
0x09, 0x0c, 0x04, 0x05, 0x52, 0x42, 0x40, 0x19, 0x0a, 0x77, 0x51, 0x42,
0x05, 0x23, 0x36, 0x5b, 0x0c, 0x67, 0x66, 0x22, 0x00, 0x4b, 0x27, 0x38,
0x47, 0x72, 0x6e, 0x5b, 0x75, 0x2b, 0x2c, 0x32, 0x5e, 0x53, 0x47, 0x5a,
0x22, 0x70, 0x74, 0x6d, 0x7b, 0x00, 0x77, 0x68, 0x61, 0x74, 0x27, 0x73,
0x20, 0x74, 0x68, 0x69, 0x73, 0x3f, 0x00, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e,
0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x68, 0x78, 0x20,
0x2e, 0x2e, 0x2e, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e, 0x2e,
0x00, 0x2a,
};
static const u8 data_segment_data_1[] = {
0x10, 0x05, 0x50,
};
static void init_memory(void) {
wasm_rt_allocate_memory((&memory), 256, 256);
memcpy(&(memory.data[1024u]), data_segment_data_0, 98);
memcpy(&(memory.data[1136u]), data_segment_data_1, 3);
}
static void init_table(void) {
uint32_t offset;
}
/* export: 'memory' */
wasm_rt_memory_t (*WASM_RT_ADD_PREFIX(Z_memory));
/* export: 'review' */
u32 (*WASM_RT_ADD_PREFIX(Z_reviewZ_ii))(u32);
/* export: '_start' */
void (*WASM_RT_ADD_PREFIX(Z__startZ_vv))(void);
/* export: 'stackSave' */
u32 (*WASM_RT_ADD_PREFIX(Z_stackSaveZ_iv))(void);
/* export: 'stackAlloc' */
u32 (*WASM_RT_ADD_PREFIX(Z_stackAllocZ_ii))(u32);
/* export: 'stackRestore' */
void (*WASM_RT_ADD_PREFIX(Z_stackRestoreZ_vi))(u32);
static void init_exports(void) {
/* export: 'memory' */
WASM_RT_ADD_PREFIX(Z_memory) = (&memory);
/* export: 'review' */
WASM_RT_ADD_PREFIX(Z_reviewZ_ii) = (&review);
/* export: '_start' */
WASM_RT_ADD_PREFIX(Z__startZ_vv) = (&_start);
/* export: 'stackSave' */
WASM_RT_ADD_PREFIX(Z_stackSaveZ_iv) = (&stackSave);
/* export: 'stackAlloc' */
WASM_RT_ADD_PREFIX(Z_stackAllocZ_ii) = (&stackAlloc);
/* export: 'stackRestore' */
WASM_RT_ADD_PREFIX(Z_stackRestoreZ_vi) = (&stackRestore);
}
void WASM_RT_ADD_PREFIX(init)(void) {
init_func_types();
init_globals();
init_memory();
init_table();
init_exports();
}
#ifndef CHALL_H_GENERATED_
#define CHALL_H_GENERATED_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "/home/whysw/tools/wabt/wasm2c/wasm-rt.h"
#ifndef WASM_RT_MODULE_PREFIX
#define WASM_RT_MODULE_PREFIX
#endif
#define WASM_RT_PASTE_(x, y) x ## y
#define WASM_RT_PASTE(x, y) WASM_RT_PASTE_(x, y)
#define WASM_RT_ADD_PREFIX(x) WASM_RT_PASTE(WASM_RT_MODULE_PREFIX, x)
/* TODO(binji): only use stdint.h types in header */
typedef uint8_t u8;
typedef int8_t s8;
typedef uint16_t u16;
typedef int16_t s16;
typedef uint32_t u32;
typedef int32_t s32;
typedef uint64_t u64;
typedef int64_t s64;
typedef float f32;
typedef double f64;
extern void WASM_RT_ADD_PREFIX(init)(void);
/* export: 'memory' */
extern wasm_rt_memory_t (*WASM_RT_ADD_PREFIX(Z_memory));
/* export: 'review' */
extern u32 (*WASM_RT_ADD_PREFIX(Z_reviewZ_ii))(u32);
/* export: '_start' */
extern void (*WASM_RT_ADD_PREFIX(Z__startZ_vv))(void);
/* export: 'stackSave' */
extern u32 (*WASM_RT_ADD_PREFIX(Z_stackSaveZ_iv))(void);
/* export: 'stackAlloc' */
extern u32 (*WASM_RT_ADD_PREFIX(Z_stackAllocZ_ii))(u32);
/* export: 'stackRestore' */
extern void (*WASM_RT_ADD_PREFIX(Z_stackRestoreZ_vi))(u32);
#ifdef __cplusplus
}
#endif
#endif /* CHALL_H_GENERATED_ */
var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){err("no native wasm support detected")}var wasmMemory;var wasmTable=new WebAssembly.Table({"initial":2,"maximum":2+0,"element":"anyfunc"});var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);ret=convertReturnValue(ret);if(stack!==0)stackRestore(stack);return ret}function cwrap(ident,returnType,argTypes,opts){argTypes=argTypes||[];var numericArgs=argTypes.every(function(type){return type==="number"});var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return function(){return ccall(ident,returnType,argTypes,arguments,opts)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heap[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";throw new WebAssembly.RuntimeError(what)}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="chall.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(){var info={"env":asmLibraryArg,"wasi_snapshot_preview1":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=exports["memory"];updateGlobalBufferAndViews(wasmMemory.buffer);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}__ATINIT__.push();var asmLibraryArg={};var asm=createWasm();Module["asm"]=asm;var _review=Module["_review"]=function(){return(_review=Module["_review"]=Module["asm"]["review"]).apply(null,arguments)};var __start=Module["__start"]=function(){return(__start=Module["__start"]=Module["asm"]["_start"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["stackSave"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["stackAlloc"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["stackRestore"]).apply(null,arguments)};Module["asm"]=asm;Module["cwrap"]=cwrap;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}var calledMain=false;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function callMain(args){var entryFunction=Module["__start"];try{entryFunction();var ret=0;exit(ret,true)}catch(e){if(e instanceof ExitStatus){return}else if(e=="unwind"){noExitRuntime=true;return}else{var toLog=e;if(e&&typeof e==="object"&&e.stack){toLog=[e,e.stack]}err("exception thrown: "+toLog);quit_(1,e)}}finally{calledMain=true}}function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(shouldRunNow)callMain(args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&noExitRuntime&&status===0){return}if(noExitRuntime){}else{ABORT=true;EXITSTATUS=status;exitRuntime();if(Module["onExit"])Module["onExit"](status)}quit_(status,new ExitStatus(status))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=false;if(Module["noInitialRun"])shouldRunNow=false;noExitRuntime=true;run();
(module
(type (;0;) (func (param i32) (result i32)))
(type (;1;) (func))
(type (;2;) (func (param i32)))
(type (;3;) (func (result i32)))
(func (;0;) (type 1)
nop)
(func (;1;) (type 2) (param i32)
local.get 0
global.set 0)
(func (;2;) (type 0) (param i32) (result i32)
global.get 0
local.get 0
i32.sub
i32.const -16
i32.and
local.tee 0
global.set 0
local.get 0)
(func (;3;) (type 3) (result i32)
global.get 0)
(func (;4;) (type 0) (param i32) (result i32)
(local i32)
i32.const 1124
i32.load
local.set 1
local.get 0
i32.load8_s
call 5
local.set 0
block ;; label = @1
block (result i32) ;; label = @2
local.get 1
i32.const 3
i32.le_s
if ;; label = @3
i32.const 1091
local.get 1
i32.const 1073
i32.add
i32.load8_u
local.get 0
i32.const 255
i32.and
i32.eq
br_if 1 (;@2;)
drop
br 2 (;@1;)
end
local.get 0
i32.const -32
i32.add
i32.const 255
i32.and
i32.const 94
i32.gt_u
br_if 1 (;@1;)
i32.const 1091
local.get 1
i32.const 47
i32.ne
br_if 0 (;@2;)
drop
i32.const 1104
i32.const 1078
local.get 0
i32.const 125
i32.eq
select
end
return
end
i32.const 1121
i32.const 42
i32.store8
i32.const 1124
i32.const 0
i32.store
i32.const 1078)
(func (;5;) (type 0) (param i32) (result i32)
(local i32)
i32.const 1124
i32.const 1124
i32.load
i32.const 1
i32.add
i32.const 49
i32.rem_u
local.tee 1
i32.store
i32.const 1121
i32.const 1121
i32.load8_u
local.get 1
i32.const 1024
i32.add
i32.load8_u
local.get 0
i32.xor
i32.xor
local.tee 0
i32.store8
local.get 0
i32.const 24
i32.shl
i32.const 24
i32.shr_s)
(memory (;0;) 256 256)
(global (;0;) (mut i32) (i32.const 5244176))
(export "memory" (memory 0))
(export "review" (func 4))
(export "_start" (func 0))
(export "stackSave" (func 3))
(export "stackAlloc" (func 2))
(export "stackRestore" (func 1))
(data (;0;) (i32.const 1024) "*9g~q-!!rCA:\09\0c\04\05RB@\19\0awQB\05#6[\0cgf\22\00K'8Grn[u+,2^SGZ\22ptm{\00what's this?\00zzz...\00\00\00\00\00\00\00thx ...zzzzzz...\00*")
(data (;1;) (i32.const 1136) "\10\05P"))
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Play me piano</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans" rel="stylesheet">
<style>
body {
color: gray;
font-family: 'Open Sans', sans-serif;
font-style: italic;
font-weight: 300;
text-align: center;
}
.piano {
margin: auto;
padding: auto;
width: 700px;
height: 700px;
}
.tile {
width: calc(100% / 7);
height: 100%;
box-sizing: border-box;
float: left;
color: lightgray;
border: 1px solid lightgray;
position: relative;
}
.tile:hover {
border: 2px solid darkgray;
}
.tile:active {
border: 4px solid darkgray;
}
.key {
margin-bottom: 10px;
position: absolute;
width: 100%;
bottom: 0;
}
.request {
margin: 1em;
font-size: 3em;
}
.review {
margin: 1em;
font-size: 1.5em;
}
</style>
</head>
<body>
<div class="request">
Play me a song before bed!
</div>
<div class="piano">
<div class="tile">
<div class="key">C</div>
<audio>
<source src="/audio/c.mp3" type="audio/mpeg">
</audio>
</div>
<div class="tile">
<div class="key">D</div>
<audio>
<source src="/audio/d.mp3" type="audio/mpeg">
</audio>
</div>
<div class="tile">
<div class="key">E</div>
<audio>
<source src="/audio/e.mp3" type="audio/mpeg">
</audio>
</div>
<div class="tile">
<div class="key">F</div>
<audio>
<source src="/audio/f.mp3" type="audio/mpeg">
</audio>
</div>
<div class="tile">
<div class="key">G</div>
<audio>
<source src="/audio/g.mp3" type="audio/mpeg">
</audio>
</div>
<div class="tile">
<div class="key">A</div>
<audio>
<source src="/audio/a.mp3" type="audio/mpeg">
</audio>
</div>
<div class="tile">
<div class="key">B</div>
<audio>
<source src="/audio/b.mp3" type="audio/mpeg">
</audio>
</div>
</div>
<div class="review">
You know, THAT one!
</div>
<script>
Module = {
onRuntimeInitialized: function() {
var review = Module.cwrap("review", "string", ["string"]);
$(".tile").mousedown((event) => {
let target = $(event.target);
let hold_timer = setTimeout(() => {
target.mouseup(() => {
target.unbind("mouseup");
console.log("-");
$(".review").text(review("-"));
});
}, 250);
target.mouseup(() => {
clearTimeout(hold_timer);
});
let audio = target.find("audio")[0];
audio.currentTime = 0;
audio.play();
note = target.text().trim().toLowerCase();
console.log(note);
$(".review").text(review(note));
});
},
};
</script>
<script async src=chall.js></script>
</body>
</html>
int main(int argc, char* argv[]){
return 0;
}
data = [0x2a, 0x39, 0x67, 0x7e, 0x71, 0x2d, 0x21, 0x21, 0x72, 0x43, 0x41, 0x3a, 0x09, 0x0c, 0x04, 0x05, 0x52, 0x42, 0x40, 0x19, 0x0a, 0x77, 0x51, 0x42, 0x05, 0x23, 0x36, 0x5b, 0x0c, 0x67, 0x66, 0x22, 0x00, 0x4b, 0x27, 0x38, 0x47, 0x72, 0x6e, 0x5b, 0x75, 0x2b, 0x2c, 0x32, 0x5e, 0x53, 0x47, 0x5a, 0x22, 0x70, 0x74, 0x6d, 0x7b, 0x00, 0x77, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3f, 0x00, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x68, 0x78, 0x20, 0x2e, 0x2e, 0x2e, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x2e, 0x2e, 0x2e, 0x00, 0x2a]
cand = "cdefgab-"
cnt = 0
def f5(arg):
global cnt
cnt += 1;
data[97] = ord(arg) ^ data[cnt] ^ data[97]
return data[97]
def review(pressed):
cnt_ = cnt
res = f5(pressed)
if cnt_ < 4:
if data[49+cnt_] == res:
return res
else:
return False
if cnt_ == 47:
if res == ord('}'):
return res
else:
return False
return res
flag = ""
for note in "ccggaag-ffeeddc-ggffeed-ggffeed-ccggaag-ffeeddc-":
res = review(note)
flag += chr(res)
print(flag)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment