Skip to content

Instantly share code, notes, and snippets.

@akku1139
Last active December 30, 2024 07:09
Show Gist options
  • Select an option

  • Save akku1139/7becfbf3b54af766feef38e7257a395f to your computer and use it in GitHub Desktop.

Select an option

Save akku1139/7becfbf3b54af766feef38e7257a395f to your computer and use it in GitHub Desktop.
ASUSN CTF 2 - Reversing - whitespace
#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]);
}
#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]);
}
# 空ファイル扱いされたのでコメントを追加
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment