Last active
December 30, 2024 07:09
-
-
Save akku1139/7becfbf3b54af766feef38e7257a395f to your computer and use it in GitHub Desktop.
ASUSN CTF 2 - Reversing - whitespace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <assert.h> | |
| #include <setjmp.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| // インライン展開の定義 (C++以外) | |
| #ifndef __cplusplus | |
| # if defined(_MSC_VER) | |
| # define inline __inline | |
| # define __inline__ __inline | |
| # elif !defined(__GNUC__) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) | |
| # define inline | |
| # define __inline | |
| # endif | |
| #endif | |
| // 定数定義 | |
| #define STACK_SIZE 65536 | |
| #define HEAP_SIZE 65536 | |
| #define CALL_STACK_SIZE 65536 | |
| // 配列の要素数を取得するマクロ | |
| #define ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0])) | |
| // スワップマクロ | |
| #define SWAP(type, a, b) \ | |
| do { \ | |
| type temp = *(a); \ | |
| *(a) = *(b); \ | |
| *(b) = temp; \ | |
| } while (0) | |
| // スタック操作関数 | |
| static inline int pop(void); | |
| static inline void push(int value); | |
| static inline void duplicate_n(size_t n); | |
| static inline void slide(size_t n); | |
| static inline void swap_top(void); | |
| // 算術演算関数 | |
| static inline void add(void); | |
| static inline void subtract(void); | |
| static inline void multiply(void); | |
| static inline void divide(void); | |
| static inline void modulo(void); | |
| // ヒープ操作関数 | |
| static inline void heap_store(void); | |
| static inline void heap_read(void); | |
| // グローバル変数 | |
| static int stack[STACK_SIZE]; | |
| static int heap[HEAP_SIZE]; | |
| static jmp_buf call_stack[CALL_STACK_SIZE]; // 未使用 | |
| static size_t stack_top = 0; | |
| static size_t call_stack_top = 0; // 未使用 | |
| int main(void) { | |
| // 文字列 "What is the flag?(End with line break):\n" を出力 | |
| push('W'); putchar(pop()); | |
| push('h'); putchar(pop()); | |
| push('a'); putchar(pop()); | |
| push('t'); putchar(pop()); | |
| push(' '); putchar(pop()); | |
| push('i'); putchar(pop()); | |
| push('s'); putchar(pop()); | |
| push(' '); putchar(pop()); | |
| push('t'); putchar(pop()); | |
| push('h'); putchar(pop()); | |
| push('e'); putchar(pop()); | |
| push(' '); putchar(pop()); | |
| push('f'); putchar(pop()); | |
| push('l'); putchar(pop()); | |
| push('a'); putchar(pop()); | |
| push('g'); putchar(pop()); | |
| push('?'); putchar(pop()); | |
| push('('); putchar(pop()); | |
| push('E'); putchar(pop()); | |
| push('n'); putchar(pop()); | |
| push('d'); putchar(pop()); | |
| push(' '); putchar(pop()); | |
| push('w'); putchar(pop()); | |
| push('i'); putchar(pop()); | |
| push('t'); putchar(pop()); | |
| push('h'); putchar(pop()); | |
| push(' '); putchar(pop()); | |
| push('l'); putchar(pop()); | |
| push('i'); putchar(pop()); | |
| push('n'); putchar(pop()); | |
| push('e'); putchar(pop()); | |
| push(' '); putchar(pop()); | |
| push('b'); putchar(pop()); | |
| push('r'); putchar(pop()); | |
| push('e'); putchar(pop()); | |
| push('a'); putchar(pop()); | |
| push('k'); putchar(pop()); | |
| push(')'); putchar(pop()); | |
| push(':'); putchar(pop()); | |
| push('\n'); putchar(pop()); | |
| // 入力ループ | |
| input_loop: | |
| push(0); | |
| fflush(stdout); | |
| heap[pop()] = getchar(); // 入力をヒープの0番地に格納 | |
| push(0); | |
| heap_read(); | |
| duplicate_n(0); | |
| push('\n'); | |
| subtract(); | |
| if (!pop()) { | |
| goto process_input; | |
| } | |
| goto input_loop; | |
| process_input: | |
| pop(); // 不要な値をポップ | |
| // フラグの計算と出力 | |
| // (元のコードの冗長なpush/arith_sub/dup_n/arith_mul/heap_read/arith_add/swap/heap_storeを整理) | |
| int offsets[] = {125, 114, 51, 75, 99, 52, 104, 95, 101, 84, 49, 72, 119, 95, 82, 95, 85, 123, 110, 115, 117, 115, 97}; | |
| for(size_t i = 0; i < ARRAY_LENGTH(offsets); ++i){ | |
| push(1); | |
| push(1); | |
| heap_read(); | |
| add(); | |
| push(1); | |
| swap_top(); | |
| heap_store(); | |
| } | |
| push(1); | |
| heap_read(); | |
| if (!pop()) { | |
| goto output_yes; | |
| } | |
| push('N'); putchar(pop()); | |
| push('O'); putchar(pop()); | |
| push('!'); putchar(pop()); | |
| goto end; | |
| output_yes: | |
| push('Y'); putchar(pop()); | |
| push('E'); putchar(pop()); | |
| push('S'); putchar(pop()); | |
| push('!'); putchar(pop()); | |
| end: | |
| exit(EXIT_SUCCESS); | |
| } | |
| static inline int pop(void) { | |
| assert(stack_top > 0); | |
| return stack[--stack_top]; | |
| } | |
| static inline void push(int value) { | |
| assert(stack_top < ARRAY_LENGTH(stack)); | |
| stack[stack_top++] = value; | |
| } | |
| static inline void duplicate_n(size_t n) { | |
| assert(n < stack_top && stack_top < ARRAY_LENGTH(stack)); | |
| stack[stack_top++] = stack[stack_top - (n + 2)]; | |
| } | |
| static inline void slide(size_t n) { | |
| assert(stack_top > n); | |
| stack[stack_top - (n + 1)] = stack[stack_top - 1]; | |
| stack_top -= n; | |
| } | |
| static inline void swap_top(void) { | |
| assert(stack_top > 1); | |
| SWAP(int, &stack[stack_top - 1], &stack[stack_top - 2]); | |
| } | |
| static inline void add(void) { | |
| assert(stack_top > 1); | |
| stack[stack_top - 2] += stack[stack_top - 1]; | |
| stack_top--; | |
| } | |
| static inline void subtract(void) { | |
| assert(stack_top > 1); | |
| stack[stack_top - 2] -= stack[stack_top - 1]; | |
| stack_top--; | |
| } | |
| static inline void multiply(void) { | |
| assert(stack_top > 1); | |
| stack[stack_top - 2] *= stack[stack_top - 1]; | |
| stack_top--; | |
| } | |
| static inline void divide(void) { | |
| assert(stack_top > 1 && stack[stack_top - 1] != 0); | |
| stack[stack_top - 2] /= stack[stack_top - 1]; | |
| stack_top--; | |
| } | |
| static inline void modulo(void) { | |
| assert(stack_top > 1 && stack[stack_top - 1] != 0); | |
| stack[stack_top - 2] %= stack[stack_top - 1]; | |
| stack_top--; | |
| } | |
| static inline void heap_store(void) { | |
| int value = pop(); | |
| int addr = pop(); | |
| assert(0 <= addr && addr < (int)ARRAY_LENGTH(heap)); | |
| heap[addr] = value; | |
| } | |
| static inline void heap_read(void) { | |
| int addr = pop(); | |
| assert(0 <= addr && addr < (int)ARRAY_LENGTH(heap)); | |
| push(heap[addr]); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <assert.h> | |
| #include <setjmp.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #ifndef __cplusplus | |
| # if defined(_MSC_VER) | |
| # define inline __inline | |
| # define __inline__ __inline | |
| # elif !defined(__GNUC__) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) | |
| # define inline | |
| # define __inline | |
| # endif | |
| #endif | |
| #define STACK_SIZE 65536 | |
| #define HEAP_SIZE 65536 | |
| #define CALL_STACK_SIZE 65536 | |
| #define LENGTHOF(array) (sizeof(array) / sizeof((array)[0])) | |
| #define SWAP(type, a, b) \ | |
| do { \ | |
| type __tmp_swap_var__ = *(a); \ | |
| *(a) = *(b); \ | |
| *(b) = __tmp_swap_var__; \ | |
| } while (0) | |
| inline static int pop(void); | |
| inline static void push(int e); | |
| inline static void dup_n(size_t n); | |
| inline static void slide(size_t n); | |
| inline static void swap(void); | |
| inline static void arith_add(void); | |
| inline static void arith_sub(void); | |
| inline static void arith_mul(void); | |
| inline static void arith_div(void); | |
| inline static void arith_mod(void); | |
| inline static void heap_store(void); | |
| inline static void heap_read(void); | |
| static int stack[STACK_SIZE]; | |
| static int heap[HEAP_SIZE]; | |
| static jmp_buf call_stack[CALL_STACK_SIZE]; | |
| static size_t stack_idx = 0; | |
| static size_t call_stack_idx = 0; | |
| int main(void) | |
| { | |
| push(87); | |
| putchar(pop()); | |
| push(104); | |
| putchar(pop()); | |
| push(97); | |
| putchar(pop()); | |
| push(116); | |
| putchar(pop()); | |
| push(32); | |
| putchar(pop()); | |
| push(105); | |
| putchar(pop()); | |
| push(115); | |
| putchar(pop()); | |
| push(32); | |
| putchar(pop()); | |
| push(116); | |
| putchar(pop()); | |
| push(104); | |
| putchar(pop()); | |
| push(101); | |
| putchar(pop()); | |
| push(32); | |
| putchar(pop()); | |
| push(102); | |
| putchar(pop()); | |
| push(108); | |
| putchar(pop()); | |
| push(97); | |
| putchar(pop()); | |
| push(103); | |
| putchar(pop()); | |
| push(63); | |
| putchar(pop()); | |
| push(40); | |
| putchar(pop()); | |
| push(69); | |
| putchar(pop()); | |
| push(110); | |
| putchar(pop()); | |
| push(100); | |
| putchar(pop()); | |
| push(32); | |
| putchar(pop()); | |
| push(119); | |
| putchar(pop()); | |
| push(105); | |
| putchar(pop()); | |
| push(116); | |
| putchar(pop()); | |
| push(104); | |
| putchar(pop()); | |
| push(32); | |
| putchar(pop()); | |
| push(108); | |
| putchar(pop()); | |
| push(105); | |
| putchar(pop()); | |
| push(110); | |
| putchar(pop()); | |
| push(101); | |
| putchar(pop()); | |
| push(32); | |
| putchar(pop()); | |
| push(98); | |
| putchar(pop()); | |
| push(114); | |
| putchar(pop()); | |
| push(101); | |
| putchar(pop()); | |
| push(97); | |
| putchar(pop()); | |
| push(107); | |
| putchar(pop()); | |
| push(41); | |
| putchar(pop()); | |
| push(58); | |
| putchar(pop()); | |
| push(10); | |
| putchar(pop()); | |
| ST: | |
| push(0); | |
| fflush(stdout); | |
| heap[pop()] = getchar(); | |
| push(0); | |
| heap_read(); | |
| dup_n(0); | |
| push(10); | |
| arith_sub(); | |
| if (!pop()) { | |
| goto SS; | |
| } | |
| goto ST; | |
| SS: | |
| pop(); | |
| push(1); | |
| push(0); | |
| heap_store(); | |
| push(125); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(114); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(51); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(75); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(99); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(52); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(104); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(95); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(101); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(84); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(49); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(72); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(119); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(95); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(82); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(95); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(85); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(123); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(110); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(115); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(117); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(115); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(97); | |
| arith_sub(); | |
| dup_n(0); | |
| arith_mul(); | |
| push(1); | |
| heap_read(); | |
| arith_add(); | |
| push(1); | |
| swap(); | |
| heap_store(); | |
| push(1); | |
| heap_read(); | |
| if (!pop()) { | |
| goto STS; | |
| } | |
| push(78); | |
| putchar(pop()); | |
| push(79); | |
| putchar(pop()); | |
| push(33); | |
| putchar(pop()); | |
| goto STT; | |
| STS: | |
| push(89); | |
| putchar(pop()); | |
| push(69); | |
| putchar(pop()); | |
| push(83); | |
| putchar(pop()); | |
| push(33); | |
| putchar(pop()); | |
| STT: | |
| exit(EXIT_SUCCESS); | |
| return EXIT_SUCCESS; | |
| } | |
| inline static int pop(void) | |
| { | |
| assert(stack_idx < LENGTHOF(stack)); | |
| return stack[--stack_idx]; | |
| } | |
| inline static void push(int e) | |
| { | |
| assert(stack_idx < LENGTHOF(stack)); | |
| stack[stack_idx++] = e; | |
| } | |
| inline static void dup_n(size_t n) | |
| { | |
| assert(n < stack_idx && stack_idx < LENGTHOF(stack) - 1); | |
| stack[stack_idx] = stack[stack_idx - (n + 1)]; | |
| stack_idx++; | |
| } | |
| inline static void slide(size_t n) | |
| { | |
| assert(stack_idx > n); | |
| stack[stack_idx - (n + 1)] = stack[stack_idx - 1]; | |
| stack_idx -= n; | |
| } | |
| inline static void swap(void) | |
| { | |
| assert(stack_idx > 1); | |
| SWAP(int, &stack[stack_idx - 1], &stack[stack_idx - 2]); | |
| } | |
| inline static void arith_add(void) | |
| { | |
| assert(stack_idx > 1); | |
| stack_idx--; | |
| stack[stack_idx - 1] += stack[stack_idx]; | |
| } | |
| inline static void arith_sub(void) | |
| { | |
| assert(stack_idx > 1); | |
| stack_idx--; | |
| stack[stack_idx - 1] -= stack[stack_idx]; | |
| } | |
| inline static void arith_mul(void) | |
| { | |
| assert(stack_idx > 1); | |
| stack_idx--; | |
| stack[stack_idx - 1] *= stack[stack_idx]; | |
| } | |
| inline static void arith_div(void) | |
| { | |
| assert(stack_idx > 1); | |
| stack_idx--; | |
| assert(stack[stack_idx] != 0); | |
| stack[stack_idx - 1] /= stack[stack_idx]; | |
| } | |
| inline static void arith_mod(void) | |
| { | |
| assert(stack_idx > 1); | |
| stack_idx--; | |
| assert(stack[stack_idx] != 0); | |
| stack[stack_idx - 1] %= stack[stack_idx]; | |
| } | |
| inline static void heap_store(void) | |
| { | |
| int value = pop(); | |
| int addr = pop(); | |
| assert(0 <= addr && addr < (int) LENGTHOF(heap)); | |
| heap[addr] = value; | |
| } | |
| inline static void heap_read(void) | |
| { | |
| int addr = pop(); | |
| assert(0 <= addr && addr < (int) LENGTHOF(heap)); | |
| push(heap[addr]); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 空ファイル扱いされたのでコメントを追加 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment