반응형
rev-basic-5
_int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x18; ++i )
{
if ( *(unsigned __int8 *)(a1 + i + 1) + *(unsigned __int8 *)(a1 + i) != byte_140003000[i] )
return 0i64;
}
return 1i64;
}
if문을 보면 인자로 받은 a1을 byte_140003000[i]
와 비교한다.
i
가-1< i < 0x18
일 때,a1[i+1] + a1[i] = byte_140003000[i]
가 성립하는 경우에만 flag이다.
byte_140003000[i]
을 확인하고 a1[i+1] + a1[i] = byte_140003000[i]
라는 조건이 성립하는 flag를 구해보자.
다음은 byte_140003000[32]
다.
.data:0000000140003000 ; unsigned __int8 byte_140003000[32]
.data:0000000140003000 byte_140003000 db 0ADh, 0D8h, 2 dup(0CBh), 9Dh, 97h, 0CBh, 0C4h, 92h
.data:0000000140003000 ; DATA XREF: sub_140001000+48↑o
.data:0000000140003000 db 0A1h, 0D2h, 0D7h, 0D2h, 0D6h, 0A8h, 0A5h, 0DCh, 0C7h
.data:0000000140003000 db 0ADh, 0A3h, 0A1h, 98h, 4Ch, 9 dup(0)
지금부터 byte_140003000를 arr이라고 표현하겠다.
arr에 있는 값을 이용해서 a1[i+1] + a1[i] = byte_140003000[i]
조건이 성립하는 a1[i]
를 구해야한다.
예를 들어 i=1
인 경우, a1[2] + a1[1] = arr[1] = AD
가 되는 것이다. 그러나 AD를 2가지의 16진수로 나누는 경우의 수는 엄청 많기 때문에 조건에 맞는 a1[1
을 구할 수 없다.
그렇다면 어떻게 a1[i]
을 구할 수 있을까?
- 마지막 자리부터 구하면 된다.
arr의 마지막에서 2번째인 24번째 인덱스 값이 "0"인 것을 확인하면 눈치챌 수 있다.
즉, a1[24] + a1[23] = arr[23] = 0
이라는 것 알 수 있고 a1[24] = a1[23] = 0
이라는 것을 알 수 있다.
- 이어서
a1[23] + a1[22] = arr[22] = 4C
임으로a1[22] = 4C
라는 것도 알 수 있다!
이런 방식으로 뒷자리부터 이어나가면서 a1[i]
를 인덱스 역순으로 하나씩 계산하면 flag를 구할 수 있다.
필자는 IDA python을 이용했다.
import idc
def extract_byte_array(start_address, length):
extracted_data = [0]
for i in range(length):
byte_value = idc.get_wide_byte(start_address + i)
extracted_data.append(byte_value)
return extracted_data
arr = extract_byte_array(0x140003000, 32)
result = list()
for i in range(0, len(arr)):
result.append(0)
for i in range(len(arr)-2, 0, -1):
result[i] = arr[i] - result[i+1]
for i in range(0, len(result)):
print(chr(result[i]), end='')
print()
반응형