리버싱 핵심원리 책을 읽으면서 실습했다.
크랙미란, 리버싱 연습을 위해 일부러 디버깅/리버싱으로
프로그램을 고의로 수정해서 문제를 풀어나가게 하는 프로그램들인데
유명한 입문? 크랙미 프로그램인 abex crackme 2를 리버싱 실습을 하려고 한다.
abex2는 실행 시
이렇게 이름과 시리얼을 적는 곳과,
Chcek, About, Quit 버튼이 세 개 있고
이름과 시리얼을 적고 check 버튼을 눌러서 이름에 대한 시리얼이 맞는 지 비교해
적절한 출력을 내 주는 프로그램이다.
이름에 1234를 적고 시리얼에 hello를 적어서 check 버튼을 눌렀더니 아니라고 뜬다.
그리고 이름이 4글자 미만이면 이름을 4글자 이상 적으라고 나온다.
이름은 최소 4글자는 적어야 한다.
올리디버거로 열어보았다.
이전에 보던 곳과는 다른 곳에서 시작한다.
abex crackme 2는 비주얼 베이직으로 짜여있는 프로그램인데, 비주얼 베이직은
MSVBM이라는 비주얼 베이직 함수가 담겨있는 dll을 사용하고, 프로그램의 기본
main 함수가 아닌 버튼을 눌렀을 때 등의 버튼 이벤트 핸들러 함수 등에
사용자의 주요한 코드가 담겨있다고 한다.
실제로 ExeInfoPE로 살펴보았을 때 Visual Basic로 작성되어 있다는 것을 확인할 수 있었다.
크랙미란, 리버싱 연습을 위해 일부러 디버깅/리버싱으로
프로그램을 고의로 수정해서 문제를 풀어나가게 하는 프로그램들인데
유명한 입문? 크랙미 프로그램인 abex crackme 2를 리버싱 실습을 하려고 한다.
abex2는 실행 시
이렇게 이름과 시리얼을 적는 곳과,
Chcek, About, Quit 버튼이 세 개 있고
이름과 시리얼을 적고 check 버튼을 눌러서 이름에 대한 시리얼이 맞는 지 비교해
적절한 출력을 내 주는 프로그램이다.
이름에 1234를 적고 시리얼에 hello를 적어서 check 버튼을 눌렀더니 아니라고 뜬다.
그리고 이름이 4글자 미만이면 이름을 4글자 이상 적으라고 나온다.
이름은 최소 4글자는 적어야 한다.
올리디버거로 열어보았다.
abex crackme 2는 비주얼 베이직으로 짜여있는 프로그램인데, 비주얼 베이직은
MSVBM이라는 비주얼 베이직 함수가 담겨있는 dll을 사용하고, 프로그램의 기본
main 함수가 아닌 버튼을 눌렀을 때 등의 버튼 이벤트 핸들러 함수 등에
사용자의 주요한 코드가 담겨있다고 한다.
실제로 ExeInfoPE로 살펴보았을 때 Visual Basic로 작성되어 있다는 것을 확인할 수 있었다.
버튼을 눌렀을 때의 이벤트 핸들러를 쉽게 찾기 위해 틀렸을 때 나오는 메시지박스의 문자열을 찾아보기로 했다.
올리디버거의 Search for - All referenced strings를 통해 프로그램에 있는 모든 문자열들을 찾아 볼 수 있다.
아래로 조금 내리니 틀렸을 때의 메시지와 맞췄을 때의 메시지 문자열을 다 찾아볼 수 있다.
더블클릭해서 주소를 찾아가 보았다.
문자열들을 집어넣어주고 CALL을 하는 모습이 보인다.
아래를 조금 내려보니 메시지박스를 띄우는 함수를 호출하는 것 같다. 이 부분에 브레이크포인트를 걸고 테스트를 해 보겠다.
Check 버튼을 눌렀을 때 브레이크 포인트 실행 부분에서 메시지박스가 뜨는 것을 볼 수 있다.
이 근처에 분기문이 있다는 것을 유추해 볼 수도 있고,
책에서 나온 대로 위로 좀 올려서 함수의 처음 부분까지 따라가 볼 수도 있다.
책에서 나온 대로 실습해보겠다.
위로 좀 많이 올리니 함수 프롤로그처럼 보이는 시작 부분이 보였다.
시작 위치에 bp를 걸고 다시 check 버튼을 눌러 보겠다.
check 버튼을 눌렀을 때 bp에서 멈추게 된다. 이 함수?는 check 버튼의 이벤트 핸들러라고 생각하면 될 것 같다.
근데 함수 시작 부분에 화살표로 점프되어 오는 것이 보이는데, check 버튼의 이벤트 핸들러를 호출하는 위치를 찾을 수 있을까?
궁금해서 함수 처음 위치에 jump된 위치를 찾아가 보았다.
점프된 곳을 찾아가 보니 jmp문이 3개나 있었다. 일정 위치를 Arg.1(esp + 4)에서 뺀 값과 일정한 점프 위치를 사용해 버튼의 이벤트 핸들러로 점프하는 것 같다.
그럼 위의 jmp문들은 진짜로 각각 다른 버튼의 이벤트 핸들러인가.
bp를 걸고 테스트 해 보았다.
About 버튼을 눌렀을 때 중간의 점프문에서 bp가 걸리고,
Quit 버튼을 눌렀을 때 가장 위의 점프문에서 bp가 걸린다.
스택의 구조 때문에 프로그래밍 할 때 버튼의 정보가 담긴 구조체가 거꾸로 들어가는지
Quit, About, Check 순서대로 점프문이 있다.
아무튼 crackme2를 파훼하려면 다시 아까 그 위치로 가서 비교하는 분기문을 찾아보자.
아까 그 Check 버튼의 이벤트 핸들러 함수 위치에서 틀렸을 때 나오는 메시지 호출 위로 올리다 보면 맞았을 때 나오는 메시지 호출이 나오고 그 위로 좀 더 올리다 보니 분기문 하나가 나왔다.
JZ 00403408인데, 점프 위치가
아까 틀린 메시지가 나오는 위치였다. 이 분기문을 수정하면 시리얼이 맞게끔 패치시킬 수 있을 것 같다.
그 위에 비교를 위해서 연산하는 옵코드까지 싹 NOP(no operation code)로 바꿨다.
(뭘 어떻게 바꾸던 상관없을 것 같다. 점프문을 바꿔도 되고.)
그리고 다시 실행을 해 보았다.
Yes 메시지가 나오긴 나오는데, No 메시지도 나오게 된다.
이건 왜일까.
No 메시지가 나오는 곳에도 자세히 보니 점프문이 있었다.
이벤트 핸들러엔 아마도, if - else문이 아니라
1
2
3
4
5
6
7
8
9
10
|
if (serial == "시리얼")
{
MessageBox("Yes", ~);
}
if (serial == "시리얼")
{
MessageBox("No", ~);
}
| cs |
이렇게 if 두 식으로 이루어진 코드일 것 같다. 아무튼 이곳도 변경해 주면
(이 곳은 점프문을 바꿔서 아래로 내려가게 수정했다.)
Yes 메시지만 뜨고 No 메시지를 건너뛴 것을 볼 수 있다.
점프 분기문 두 군데를 패치하면 가장 쉽게 패치시킬 수 있다.
(이 곳은 점프문을 바꿔서 아래로 내려가게 수정했다.)
Yes 메시지만 뜨고 No 메시지를 건너뛴 것을 볼 수 있다.
점프 분기문 두 군데를 패치하면 가장 쉽게 패치시킬 수 있다.
'리버스 엔지니어링' 카테고리의 다른 글
리버싱 연습 - abex crackme2 (3) 시리얼 핵심 루틴 (0) | 2020.06.30 |
---|---|
리버싱 연습 - abex crackme2 (2) (0) | 2020.06.30 |
리버싱 공부 - 스택 프레임 기법 (0) | 2020.06.30 |
리버싱 공부 - 레지스터 (0) | 2020.06.30 |
리버싱 연습 - 점프에 관하여 (0) | 2020.06.30 |