리버싱 연습
abex crackme5
시리얼 타파

abex crackme5를 풀어보려고 한다.
시리얼을 입력해서 확인하는 메시지박스가 뜨는 간단한 프로그램이다.

아무거나 입력했더니 아니라고 한다.

올리디버거로 따라가 보려고 한다.

윈도우 메시지폼이 뜨는 것으로 보아서 vc등으로 개발 된 것 같기도 하다.
어셈으로만 이루어진 것 같다.

윈도우 메시지폼이 뜨고, Check 버튼이 있는 것을 보아 버튼이 눌렸을 때 무언가를 해 주는 이벤트 핸들러 함수에 검사하는 내용이 있을 것이라고 추측 할 수 있다.

올리에서 find all strings를 통해 틀렸을 때의 메시지와 맞았을 때의 메시지를 push하는 주소를 찾을 수 있었다.
따라가면 바로 위에 점프 분기문이 보이고, strcmp함수를 호출한 것으로 보아 텍스트창에 있는 문자열과 어떤 문자열을 비교해서 점프하는 것 같다.

점프만을 패치하는 것보다 본 분석에서는 실제로 맞춰야 하는 시리얼을 찾고자 함이므로 위로 올려본다.

위로 올렸을 때 함수의 프롤로그로 보이지는 않지만 시작지점이 보이고, 분기문도 보인다.

이 곳으로 점프를 뛰는 곳으로 올라갔을 때 call을 볼 수 있다.
DialogBoxParam 함수를 호출하는 것으로 보아 이 위치 자체가 윈도우 메시지박스의 이벤트 핸들러 함수인 것 같다.
항상 반복해가며 호출과 switch문(또는 if문)을 거쳐가며 각 메시지에 따라서 함수를 호출하거나 아무것도 하지 않게 된다.

실제로 bp를 걸고 실행하게 되면 창을 건들기만 해도 bp에 걸리게 된다.

다시 분기문쪽으로 와서,
65랑 비교해서 점프하지 않을 땐 리턴하는 곳으로 간다.
점프했을 때, 아래에서 GetDigItemText 함수를 호출하는데, 텍스트박스에서 문자열을 가져오는 함수인 것 같다.

메시지박스의 이벤트가 65일 때(Check 버튼을 누르는 이벤트일 때) 메시지박스의 문자열을 가져오게 한다.

GetDigItemText 함수를 호출한 뒤 GetVolumeInformationA 함수를 호출하는데, 이 함수는 하드드라이브의 정보를 가져온다는 함수라고 한다.
이 정보를 가져와서 시리얼에 반영하는지는 아직 모르겠다.

그 아래쪽은 좀 웃긴데, 갑자기 문자열을 복사한다. strcat로.
0040225c위치에 "4562-ABEX" 라는 문자열을 붙이게 한다.

처음엔 저 위치에 아무것도 없다가,
strcat 함수를 호출하고 나서 문자열이 붙여진 것을 알 수 있다.

그 아래에선, 반복문같이 보이는 곳이 있다. 시리얼을 만드는 주요 루틴중 하나일 것이다.
DL에 2를 복사하고, 40225c, 40225d, ... 에 1을 add하는 연산을 한다.
그 이후에 DL을 1 감소시키고 연산의 결과가 제로일 때 점프를 하지 않게 되면서 점프문을 빠져나간다.

근데 저 주소는 방금 문자열을 붙인 주소가 아닌가..?
반복문을 한 번 실행시켰을 때 차례로 add 연산을 하면서, "4562-ABEX"문자열의 1~4번째 문자의 아스키코드 값이 1 더해져서 4562 -> 5673으로 변한 것을 볼 수 있었다.

한번 더 실행시키면 6784가 되어야 할 것이다.
실제로 그렇게 실행이 된다.
반복문이 두 번 실행되는동안 DEC DL이 두 번 실행되면서 2에서 0이 되었고, 반복문을 빠져나오게 된다.
반복문을 나오면서 "4562-ABEX"는 "6784-ABEX"가 되었다.

그 아래부터 위와 비슷한 형태가 반복되는 듯이 보이는데, 빠르게 넘어가보겠다.
두 번째 strcat 호출 전에 아까의 "6784-ABEX"와 위의 "L2C-5781"이라는 문자열을 push하고 strcat 함수를 호출한다. 아마 두 문자열을 합치는 것 같다.

두 문자열이 합쳐진 결과는 두 번째로 넣었던 00402000주소에 들어가게 되었다.
스택에 인자가 들어가는 순서를 역으로 생각하면 될 것 같다. 첫 번째 인자에 복사해 주는 strcat 함수.
이어진 문자열의 위치가 00402000인것을 dump화면에서 확인할 수 있음과 동시에, 내가 넣은 문자열인 "abcd1234"를 push하는 것이 보인다.
내가 넣은 문자열과 방금 이어붙인 문자열을 push하고 strcmp 함수로 비교하는 것으로 보인다.
그 아래에선 비교한 결과값을 통해 맞았을 때나 틀렸을 때의 메시지박스를 띄우게 분기문과 메시지박스를 호출하는 곳이 다시 보인다.

이어붙인 문자열이 시리얼이라는 것을 알 수 있었다.

다시 실행시켜서 마지막에 이어붙인 시리얼을 입력했을 때 맞는것을 확인할 수 있었다.

댓글

이 블로그의 인기 게시물

scanf와 scanf_s

레나 리버싱 Tut.ReverseMe1 풀이 1

리버싱 연습