이 문제는... 제목 보자마자 기억이 났다.
작년 여름방학 동아리 과제였는데 못 풀었었다. 풀이를 봐도 이해가 안 됐었는데 그때보다는 발전했을지! 검증해보자 :)
__int64 __fastcall main(int a1, char **a2, char **a3)
{
FILE *stream; // [rsp+10h] [rbp-30h]
__int64 table_len; // [rsp+18h] [rbp-28h]
FILE *input_file; // [rsp+20h] [rbp-20h]
__int64 size; // [rsp+28h] [rbp-18h]
void *input; // [rsp+30h] [rbp-10h]
char *ptr; // [rsp+38h] [rbp-8h]
if ( a1 != 3 )
{
fwrite("Usage : ./baseball <table filename> <input filename>\n", 1uLL, 0x35uLL, stderr);
exit(-1);
}
stream = fopen(a2[1], "rb");
if ( !stream )
{
fwrite("File not found\n", 1uLL, 0xFuLL, stderr);
exit(-1);
}
fseek(stream, 0LL, 2);
table_len = ftell(stream);
fseek(stream, 0LL, 0);
if ( table_len != 64 )
{
fwrite("Invalid table\n", 1uLL, 0xEuLL, stderr);
exit(-1);
}
fread(&table, 0x41uLL, 1uLL, stream);
fclose(stream);
input_file = fopen(a2[2], "rb");
if ( !input_file )
{
fwrite("File not found\n", 1uLL, 0xFuLL, stderr);
exit(-1);
}
fseek(input_file, 0LL, 2);
size = ftell(input_file);
if ( !size )
{
fwrite("Invalid input\n", 1uLL, 0xEuLL, stderr);
exit(-1);
}
fseek(input_file, 0LL, 0);
input = malloc(size + 1);
if ( !input )
{
fwrite("Allocation failed\n", 1uLL, 0x12uLL, stderr);
exit(-1);
}
memset(input, 0, size + 1);
fread(input, size, 1uLL, input_file);
fclose(input_file);
ptr = (char *)change(input, (unsigned int)size);
printf("%s", ptr);
free(input);
free(ptr);
return 0LL;
}
table 파일을 읽어서 table 변수에 저장
input 파일을 읽어서 input 변수에 저장
change 함수에 input과 size 전달 후 함수 결과 출력
_BYTE *__fastcall sub_1289(_BYTE *a1, int a2)
{
_BYTE *v3; // rax
_BYTE *v4; // rax
_BYTE *v5; // rax
_BYTE *v6; // rax
_BYTE *v7; // rax
_BYTE *ans; // [rsp+18h] [rbp-28h]
_BYTE *v9; // [rsp+18h] [rbp-28h]
_BYTE *v10; // [rsp+18h] [rbp-28h]
_BYTE *input; // [rsp+20h] [rbp-20h]
unsigned __int64 size; // [rsp+28h] [rbp-18h]
_BYTE *v13; // [rsp+30h] [rbp-10h]
_BYTE *input_end; // [rsp+38h] [rbp-8h]
size = (4 * a2 / 3 + 4) / 0x48uLL + 4 * a2 / 3 + 4 + 1;
if ( size < a2 )
return 0LL;
v13 = malloc(size);
if ( !v13 )
return 0LL;
input_end = &a1[a2];
input = a1;
ans = v13;
while ( input_end - input > 2 )
{
*ans = table[*input >> 2];
ans[1] = table[(input[1] >> 4) | (16 * *input) & 0x30];
ans[2] = table[(input[2] >> 6) | (4 * input[1]) & 0x3C];
v3 = ans + 3;
ans += 4;
*v3 = table[input[2] & 0x3F];
input += 3;
}
if ( input_end != input )
{
v4 = ans;
v9 = ans + 1;
*v4 = table[*input >> 2];
if ( input_end - input == 1 )
{
*v9 = table[(16 * *input) & 0x30];
v5 = v9 + 1;
v10 = v9 + 2;
*v5 = 61;
}
else
{
*v9 = table[(input[1] >> 4) | (16 * *input) & 0x30];
v6 = v9 + 1;
v10 = v9 + 2;
*v6 = table[(4 * input[1]) & 0x3C];
}
v7 = v10;
ans = v10 + 1;
*v7 = 61;
}
*ans = 0;
return v13;
}
python 정리
input = []
output = []
table = [] # size = 64
idx = 0
size = len(input)
while size - idx > 2:
output.append(table[input[idx] >> 2])
output.append(table[((input[idx+1] >> 4) | ((16 * input[idx]) & 0x30))])
output.append(table[((input[idx+2] >> 6) | ((4 * input[idx+1]) & 0x3c))])
output.append(table[input[idx+2] & 0x3f])
idx += 3
if size != idx:
output.append(table[input[idx] >> 2])
if size - idx == 1:
output.append(table[(16 * input[idx]) & 0x30])
output.append('=')
else:
output.append(table[((input[idx+1] >> 4) | ((16 * input[idx]) & 0x30))])
output.append(table[(4 * input[idx+1]) & 0x3C])
output.append('=')
우리의 목표는 table을 찾고 flag_out.txt를 역산하는 것이다.
f1 = open('D:\\code\\dh\\rev\\baseball\\text_in.txt', 'r')
f2 = open('D:\\code\\dh\\rev\\baseball\\text_out.txt', 'r')
input = f1.read()
output = f2.read()
table = [0 for i in range(64)]
size = len(input)
idx = 0
idx2 = 0
while size - idx > 2:
table[ord(input[idx]) >> 2] = output[idx2]
table[((ord(input[idx+1]) >> 4) | ((16 * ord(input[idx])) & 0x30))] = output[idx2+1]
table[((ord(input[idx+2]) >> 6) | ((4 * ord(input[idx+1])) & 0x3c))] = output[idx2+2]
table[ord(input[idx+2]) & 0x3f] = output[idx2+3]
idx += 3
idx2 += 4
if size != idx:
table[ord(input[idx]) >> 2] = output[idx2]
if size - idx == 1:
table[(16 * input[idx]) & 0x30] = output[idx2+1]
else:
table[((ord(input[idx+1]) >> 4) | ((16 * ord(input[idx])) & 0x30))] = output[idx2+1]
table[(4 * ord(input[idx+1])) & 0x3C] = output[idx2+2]
print(table)
table = [0, 'h', 's', 0, 'R', 'F', '/', 't', 'u', 'I', 0, 'W', '3', 'd', 0, 'Y', 'n', 'S', 'v', 'V', '7', 'O', 'U', 'Q', 'b', 'Z', 'c', 'N', '4', 'J', '2', 0, '1', 'G', 'L', '+', 'e', 'j', 'A', '8', 0, 'r', 0, 'l', 'p', 'g', '5', 'a', 'k', 0, 'B', 'o', '0', 'q', 'y', 'D', 'H', 'm', 0, 0, 'M', '9', 0, 'P']
output[0] = table[input 앞 6bit]
output[1] = table[input 뒤 4bit + input[1] 앞 4bit]
output[2] = table[input[1] 뒤 6bit + input[2] 앞 2bit]
output[3] = table[input[2] 뒤 6bit]
with open('D:\\code\\dh\\rev\\baseball\\flag_out.txt', 'r') as f:
output = f.read()
input = []
table = [0, 'h', 's', 0, 'R', 'F', '/', 't', 'u', 'I', 0, 'W', '3', 'd', 0, 'Y', 'n', 'S', 'v', 'V', '7', 'O', 'U', 'Q', 'b', 'Z', 'c', 'N', '4', 'J', '2', 0, '1', 'G', 'L', '+', 'e', 'j', 'A', '8', 0, 'r', 0, 'l', 'p', 'g', '5', 'a', 'k', 0, 'B', 'o', '0', 'q', 'y', 'D', 'H', 'm', 0, 0, 'M', '9', 0, 'P']
size = len(output)
idx = 0
while size - idx > 7:
input.append(((table.index(output[idx]) << 2) | (table.index(output[idx+1]) >> 4)) & 0xff)
input.append(((table.index(output[idx+1]) << 4) | (table.index(output[idx+2]) >> 2)) & 0xff)
input.append(((table.index(output[idx+2]) << 6) | (table.index(output[idx+3]))) & 0xff)
idx += 4
if size != idx:
if output[-1] == '=' and output[-2] == '=':
input.append((table.index(output[idx]) << 2) | (table.index(output[idx+1]) >> 4))
input.append((table.index(output[idx+1]) << 4) | (table.index(output[idx+2]) >> 2))
else:
input.append((table.index(output[idx]) << 2) | (table.index(output[idx+1]) >> 4))
for i in input:
print(chr(i),end='')
굉장히 말이 되는 문장이 나왔는데 (누가 봐도 플래그 같은데...) 왜 답이 아니라는 거지
아, = 갯수를 거꾸로 생각했다. ㅋㅋㅋㅋ
with open('D:\\code\\dh\\rev\\baseball\\flag_out.txt', 'r') as f:
output = f.read()
input = []
table = [0, 'h', 's', 0, 'R', 'F', '/', 't', 'u', 'I', 0, 'W', '3', 'd', 0, 'Y', 'n', 'S', 'v', 'V', '7', 'O', 'U', 'Q', 'b', 'Z', 'c', 'N', '4', 'J', '2', 0, '1', 'G', 'L', '+', 'e', 'j', 'A', '8', 0, 'r', 0, 'l', 'p', 'g', '5', 'a', 'k', 0, 'B', 'o', '0', 'q', 'y', 'D', 'H', 'm', 0, 0, 'M', '9', 0, 'P']
size = len(output)
idx = 0
while size - idx > 7:
input.append(((table.index(output[idx]) << 2) | (table.index(output[idx+1]) >> 4)) & 0xff)
input.append(((table.index(output[idx+1]) << 4) | (table.index(output[idx+2]) >> 2)) & 0xff)
input.append(((table.index(output[idx+2]) << 6) | (table.index(output[idx+3]))) & 0xff)
idx += 4
if size != idx:
if output[-1] == '=' and output[-2] == '=':
input.append(((table.index(output[idx]) << 2) | (table.index(output[idx+1]) >> 4)) & 0xff)
else:
input.append(((table.index(output[idx]) << 2) | (table.index(output[idx+1]) >> 4)) & 0xff)
input.append(((table.index(output[idx+1]) << 4) | (table.index(output[idx+2]) >> 2)) & 0xff)
for i in input:
print(chr(i),end='')
이전에는 풀이를 봐도 무슨 말인지 몰랐는데 이제는 바로 풀린다 ㅎㅎ
그래도 이전보다는 발전했다는 사실이 기분이 참 좋다.