-
[리버싱 핵심원리 study] 8장 abex' crackme#2 분석(2)Reverse Engineering 2020. 12. 3. 13:11
https://maple19out.tistory.com/8
지난 포스팅에 이어 이번에는 serial 생성 알고리즘을 살펴보겠다. abex' crackme#2 프로그램에서는 이름/시리얼을 입력하고 [Check] 버튼을 클릭한 후, 조건에 대한 검사를 통해 올바른 시리얼 키인지 아닌지를 판별한다. 즉, 이전에 찾았던 조건 분기 코드는 check button을 클릭했을 때 호출되는 함수의 내부에서 작동되었을 것이라고 예측할 수 있다.
1. 함수 시작 찾기
이전의 stack frame 관련 포스팅 내용을 바탕으로, 함수의 시작을 찾아보자. 스크롤을 올리다 보면 다음과 같은 명령어를 발견할 수 있다.
push ebp / mov ebp, esp 어디서 많이 보던 코드다. 바로 stack frame을 구성하기 위해 함수의 시작 부분에서 ebp를 새롭게 설정하는 부분이다. 즉, 해당 부분이 함수의 시작 부분임을 알 수 있다. 해당 부분을 기준으로 아래쪽으로 코드를 살펴보면서 name 문자열을 읽는 부분을 살펴보면 될 것 같다.
2. Name 문자열을 읽는 코드
해당 부분부터 디버깅을 진행하다 보면 다음과 같은 코드를 살펴볼 수 있다.
여기서 [ebp-88]주소에 어떤 것이 들어가 있는지 확인하기 위하여 해당 명령어에 위치한 상태에서 enter키를 눌러보자.
아직까지는 특별히 들어간 것이 없다. 이제 call까지 실행된 후의 값을 확인해보자.
위와 같이 Name 문자열이 ebp-88 부분에 들어간 것을 확인할 수 있다.
3. 암호화 루프
계속해서 디버깅을 하다보면 다음과 같은 Loop를 만나게 된다.
간단히 설명하자면 00403197의 test ax, ax를 통해 조건을 검사하고 0040319F부터 loop가 시작된다. 이후에 004032A0를 통해 다시 loop의 조건 검사 부분으로 jump 하게 된다. vbaVarForInit(), vbaVarForNext는 문자열 객체에서 한 글자씩 참조할 수 있도록 도와주는 역할을 하며, mov ebx, 4 부분은 loop count를 세팅해주는 역할을 한다.
4. 암호화 방법
디버깅을 진행하다 보면 위와 같은 부분을 발견할 수 있다. 우선 004031F6의 연산을 통해 Name 문자열에서 하나의 문자(UNICODE)를 가져온다. 'm'이 될 것이다. 004031F7에 의해서 'm'(UNICODE)를 'm'(ASCII CODE)로 변환한다. m은 아스키 값으로 109다. 이제 맨 아래의 call vbaVarAdd를 통해 어떻게 값이 변하는지 살펴보자.
또 내부적으로 VarAdd라는 것을 호출하는데 그에 앞서 [esp+4], [esp+C], [esp+14]의 주소 값을 argument로 넘기고 함수를 호출하고 있다. 이때의 스택에는 다음과 같은 값들이 저장되어 있다.
이제 VarAdd내부로 들어가 보자.
굉장히 복잡해 보이는데 핵심은 바로 766E9DAB의 add edx, eax부분이다. 이 부분을 통해 'm'(109)에 64h(100)라는 값이 더해지고 결과적으로 D1(109 + 100) 이 된다. 함수가 종료되면 edx 레지스터에는 D1이라는 값이 남게 된다. 결과적으로 암호화 알고리즘은 각 문자열에 64 hex 값을 더한 것이 serial key가 됨을 알 수 있다.
반응형'Reverse Engineering' 카테고리의 다른 글
[리버싱 핵심원리 study] 11장 Lena's Reversing for Newbies (0) 2020.12.23 [리버싱 핵심원리 study] 10장 함수 호출 규약 (0) 2020.12.04 [리버싱 핵심원리 study] 8장 abex' crackme#2 분석(1) (1) 2020.12.02 [리버싱 핵심원리 study] 7장 Stack Frame (0) 2020.12.01 [dreamhack.io study] x64dbg로 hello world 디버깅해보기 (0) 2020.11.26