Index

문제
실행 파일(exe)이 주어지고, 실행하면 사용자 입력을 받고 프로그램이 종료된다.
문제풀이

문제의 main 함수이다. sub_140001000함수로 사용자가 입력한 값을 넘긴다.

for 문 안의 if 조건문을 false 반환을 받으면 된다. 먼저, byte_140003000 배열의 값을 확인하자.

F2로 브레이크 포인터를 걸고 F9로 실행시켰다. 프로그램이 실행되면서 0x7ff74a853000 배열에 문자가 저장된 걸 확인할 수 있다.
if ( (i ^ (unsigned __int8)__ROL1__(*(_BYTE *)(a1 + i), i & 7)) != byte_140003000[i] )위에서 얻은 값을 if 조건문에 맞게 역연산해주면 된다. 지저분한 식을 깔끔하게 바꿔보자.
if ( (i ^ __ROL1__(a1[i], i & 7)) != byte_140003000[i] )__ROL1__()이라는 함수가 사용된다. 어셈블리어를 함께 보자.

i & 7이 연산된 cl과 a1[i]값을 가진 al이 rol이라는 명령어로 처리된다.
rol은 Rotate Left로 왼쪽으로 시프트연산을 하는 shl과 비슷한 역할이지만, 크기를 넘어서는 비트를 다시 하위 1비트로 밀면서 들어가진다.
오른쪽 방향으로 Rotate Right를 하는 ror도 있다. 역시 shr과 비슷한 역할이지만, 최하위 비트 아래로 내려가는 비트를 상위 1비트로 밀면서 들어간다.
즉, 정해진 크기의 큐가 있다면, 기준점을 잡고 원형 큐 처럼 돌아가면서 시프트되는 연산이다.
문제 조건문에서는 마지막에 xor연산을 수행하니, 결과 값에서 다시 i값으로 xor연산을 수행한다. 이후 ROL이 되어서 결과를 만든 것이니, xor한 결과 값과 i & 7로 ROR연산을 수행한다.
파이썬 풀이 코드
str = [0x52, 0xdf, 0xb3, 0x60, 0xf1, 0x8b, 0x1c, 0xb5, 0x57, 0xd1, 0x9f, 0x38, 0x4b, 0x29, 0xd9, 0x26, 0x7f, 0xc9, 0xa3, 0xe9, 0x53, 0x18, 0x4f, 0xb8, 0x6a, 0xcb, 0x87, 0x58, 0x5b, 0x39, 0x1e]
def ror(x, y): #1byte ror
shr = x >> y
under = x << (8-y)
under &= 255
return shr|under
for i in range(0, len(str)):
xor_i = i^str[i]
print(chr(ror(xor_i, (i & 7))), end='')ror함수에서 먼저, 첫번째 인자 x를 두번째 인자 y로 shr 연산을 진행한다. 이후, x에서 8-y만큼 반대로 shl 연산을 진행한다. 두개의 값을 or 연산을 하면 로테이트 된 비트 값이 나오면서 ror연산이 마무리된다. 이때, shl 연산을 한 결과 값은 1byte만 사용될 수 있도록 255(0xff)와 and연산한다.
실행 결과

Uploaded by N2T

