문제 파일을 다운로드받고 압축을 풀어준다
1. x64bug 해석
본 함수의 코드들인데 여기에서 주목해야 할 점은 correct와 wrong을 출력해주는 부분이다
이 이전에 있는 함수에서 해당 문자열을 고를 반환값을 줬을 가능성이 높기 때문이다
call challo.7ff77c961000
따라서 위의 코드 속 함수 주소를 더블 클릭 해주면 우리가 해석해야하는 함수의 코드들이 나오게 된다
이 함수에서 쓰이는 어셈블리어 함수 종류
mov | 두 번째에서 첫 번째로 데이터 이동 | jmp | 무조건 분기 |
movzx | 길이가 일치하지 않아도 이동(빈 공간 0) | jae | 결과가 크거나 같으면 분기(부호화 안 된 수) |
movsxd | 길이가 일치하지 않아도 이동(빈 공간 1) | je | 결과 값 0이면 분기(이동) |
sub | 캐리 포함하지 않은 뺄셈 | lea | 오프셋(데이터 영역) 값을 레지스터로 로드 |
add | 캐리 포함하지 않은 덧셈 | xor | 배타논리합(값이 달라야 1) |
inc | 내용 1 증가 | ret | 스택에 push된 주소로 복귀(리턴) |
mov: 이전에 사용했던 rcx 속에 있는 수를 rsp+8에 저장해두고
sub: rsp에 18을 빼 메모리를 확장해준다
mov, jmp: rsp에 0을 넣고 무조건 분기를 이용해 해당 주소(7FF77C96101A)인 movsxd 명령어 위치로 이동한다
movsxd, cmp: rsp에 있는 0값을 rax에 넣고 cmp로 for문 반복 횟수인 18을 비교하기 시작한다
jae 명령어로 위에 cmp로 for문 속 증가하는 변수를 반복 횟수인 18과 비교해
jae: 현재 반복 횟수가 18보다 크거나 같으면 분기하도록 한다
movsxd: 아직 작다면 rsp에 있는 반복 횟수를 rax에 넣고
lea: rcx에 문자열이 나열돼 있는 7FF77C963000을 넣고
movzx: rcx와 현재 반복 횟수를 담고 있는 rax를 더해 n번째 정답 문자를 eax에 넣는다
movsxd: rsp에 있는 반복 변수를 rcx에 넣고
mov: rsp+20에 있는 입력받은 문자열 위치를 넣고
movzx: 입력받은 문자열의 n번째 문자를 ecx에 넣는다
xor: rsp에 있는 for문 반복 변수와 ecx에 있는 입력받은 문자를 xor 연산해 ecx에 넣는다
mov: rsp에 있는 반복 변수 edx에 넣고
lea: xor한 값과 mov한 값*2를 더해 ecx에 넣어준다
cmp: 위의 긴 연산들을 마친 ecx 값과 정답 문자 eax 값이 같은지 확인하고
je: cmp가 결과가 같다는 값으로 0을 반환하면 7FF77C961051(jmp 7FF77C961012)로 이동한다
즉, 들어온 값과 반복 횟수를 xor 하고
그 값에 반복 횟수 2배 값을 더했을 때 정답 문자열이 나와야 한다
2. Ida 해석
ida는 익숙한 C언어 형태로 디컴파일해줘서 x64dbg보다 훨씬 쉽게 해석할 수 있다
위의 코드를 봐도 correct를 프린트해주는 곳의 if문만 잘 보면 해결할 수 있을 것 같다는 생각이 든다
함수의 디컴파일 버전을 보니까 x64dbg보다 훨씬 이해하기 쉬운 형태를 보여주고 있다
byte_140003000에 있는 정답 문자열이 입력값과
반복 변수의 연산 결과값과 같아야 correct를 프린트한다는 걸 알 수 있다
정답 문자열 = (i xor 입력값) + 2 * i
입력값 = (정답 문자열 - 2 * i) xor i
정답 문자열이 있는 주소를 더블 클릭하면
Hex View-1창에 해당 위치에 있는 문자열들이 나열돼 있다
우리가 유추한 식을 이용해 c언어를 코딩해 정답을 알아보자
#include <stdio.h>
int main() {
unsigned char chars[] = { 0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66, 0x80, 0x78, 0x69, 0x69, 0x7B, 0x99, 0x6D, 0x88, 0x68, 0x94, 0x9F, 0x8D, 0x4D, 0xA5, 0x9D, 0x45 };
for (int k = 0; k < 24; k++) {
printf("%c", (chars[k] - (2 * k)) ^ k);
}
return 0;
}
정답: DH{I_am_X0_xo_Xor_eXcit1ng}
'dreaMhack > Reverse Engineering' 카테고리의 다른 글
[드림핵] rev_basic_5 풀이/어셈블리어 해석 (0) | 2022.03.24 |
---|---|
[드림핵] rev_basic_4 풀이/어셈블리어 해석 (0) | 2022.03.23 |
[드림핵] rev_basic_1 풀이/어셈블리어 해석 (0) | 2022.03.23 |
[드림핵] rev_basic_0 풀이/어셈블리어 해석 (0) | 2022.03.23 |
[드림핵] 리버싱 레지스터 용도 정리 (0) | 2022.03.23 |