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