- rev-basic-32022년 10월 23일
- satorare
- 작성자
- 2022.10.23.:17
IDA로 디컴파일링된 메인 함수 라인 8에서 조건문의 인수로 들어가는 함수 sub_140001000의 리턴값에 따라 Correct와 Wrong으로 결과가 나뉩니다.
해당 함수의 동작을 한 번 살펴봅시다.
조건문을 결정짓는 sub_140001000 함수 내부 또 하나의 조건문이 보입니다.
여기서 인수로 들어가는 연산을 한 번 살펴보겠습니다.
byte_140003000[i] != (i ^ al[i]) + 2 * i
>> 여기서 ^는 XOR연산입니다
>> *(al + i)는 배열 포인터를 i만큼 이동시킨다는 의미로 al[i]입니다
>> al은 해당 함수의 배열 파라미터입니다
즉, "al[i]와 i를 XOR 연산 한 값에 2 * i를 더한 값이 byte_140003000[i] 과 같냐? (단, i<24)"는 말입니다.
만약 같다면 sub_140001000()은 1을 리턴하고, 같지 않다면 0을 리턴하게됩니다.
그럼 이제 그 비교대상인 byte_14003000[] 배열을 살펴보겠습니다.
배열 byte_140003000[32] >> n1 dup(n2)은 n2라는 배열의 요소가 n1번 연속적으로 존재한다는 뜻입니다. 즉 2 dup(69h)는 Hex값 69가 연속적으로 2번 있다고 보시면 되고, 8 dup(0)은 Hex값 0이 연속적으로 8번 있다고 보시면 됩니다.
위의 Hex값을 모두 Decimal로 바꾸면 다음과 같습니다.
byte_140003000 = {73, 96, 103, 116, 99, 103, 66, 102, 128, 120, 105, 105, 123, 153, 109, 136, 104, 148, 159, 141, 77, 165, 157, 69, 0, 0, 0, 0, 0, 0, 0, 0}
>> 뒤의 8개의 0은 무시하셔도 됩니다. 반복문의 반복 횟수가 24번까지이므로 총 24바이트까지의 값만 보면 되기 때문입니다.
저희는 이 배열을 토대로 역연산을 진행하여 byte_140003000[i] != (i ^ al[i]) + 2 * i) 를 만족하는 문자열 al을 구해야합니다.
byte_140003000[i] 를 P라 하고, al[i] 를 Q라 한다면
P = i ^ Q + (2 * i)
이것은 다시
P - (2 * i) = i ^ Q
여기서
1. XOR은 대수의 결합법칙이 성립합니다. (A ^ (B ^ C) = (A ^ B) ^ C)
2. XOR은 각 원소에 대하여 유일한 역원이 존재합니다. 이 때 역원은 자기자신입니다. (A ^ A = 0)
3. XOR은 어떤 원소 A에 대하여 A ^ Z = A을 만족하는 항등원 Z = 0이 존재합니다. (A ^ 0 = A)
위 세 가지 성질을 이용하면 다음과 같이 정리할 수 있습니다.
P -(2 * i) = i ^ Q ... 양변에 ^ i를 추가합니다.
(P -(2 * i)) ^ i = (i ^ Q) ^ i ... 우변에 1번(결합법칙)을 적용합니다.
(P -(2 * i)) ^ i = Q ^ (i ^ i) ... 우변에 2번(유일한 역원의 존재)을 적용합니다
(P- (2 * i)) ^ i = Q ^ 0 ... 우변에 3번(항등원의 존재)을 적용합니다.
∴ Q = (P- (2 * i)) ^ i
즉,
al[i] = (byte_140003000[i] - 2 * i) ^ i
입니다.
replit으로 아래와 같이 키값을 역연산하는 코드를 짜보았습니다.
replit으로 작성한 역연산 코드 이를 실행하면 다음과 같이 키값 문자열이 출력됩니다.
정답은 직접 입력해서 보시길 바랍니다 'bin' 카테고리의 다른 글
4. 소유권 이해하기 (0) 2022.10.26 rev-basic-5 (0) 2022.10.25 rev-basic-4 (0) 2022.10.24 러스트 프로그래밍 가이드 연습문제 1 ~ 3 (0) 2022.10.23 3. 보편적인 프로그래밍 개념 (0) 2022.10.23 다음글이전글이전 글이 없습니다.댓글