728x90

위와 같은 exe 파일 하나가 있고 메세지 박스에는 Wrong이 적혀있다. 임의의 값 혹은 아무값을 입력하지 않고도 Check를 누르면 프로그램이 종료되고, 

WinDbg로 trace해보면, Access violation 오류로 종료되는 것을 확인할 수 있다.

 

어떤 함수가 이를 일으키는지 확인해보자.

 

우선, exe 파일 시작인 winmain에선 DialogBoxParamA를 호출하여, 대화 박스를 호출하고, 4번째 인자는 대화 상자 프로시저에 대한 포인터이므로, 이 부분을 디버깅하면

이와 같은 사실(주석 확인)을 알 수 있었다.

우리가 박스에 입력하여(10진수로) check 버튼을 누르면, 그 값이 dword_4084D0에 16진수 값으로 저장된다.

 

 

그리고 함수를 살펴보면, 

else if ( (unsigned __int16)a4 == 0x3EB )     // 메세지 입력하면 항상 여기로
  {
    dword_4084D0 = GetDlgItemInt(hDlg, 1002, 0, 0);
    sub_40466F(a1);
    sub_404689();
    *(_DWORD *)sub_40466F = -1013972794;
    sub_40466F(&loc_40469F);
    sub_40466F(v6);
    *(_DWORD *)sub_40466F = 1768;
    return 1;
  }

현재, dword_4084d0에 사용자가 입력한 값이 들어간 상태이다. 

이후, 

1. sub_40466f를 a1을 인자로 실행

edi에 있는 a1은 0x00110F02, 무슨 값인진 모른다.

'sub_40466f' 함수

해당 함수는, 사용자가 입력한 값에 어떠한 hex값을 더한 후, inc 연산까지 하고 return 하는 함수이다.

현재 a1인자가 어떤 역할을 하는지 모르겠고, 이는 ida가 해석한 것이니 잘못 표현됐을 가능성을 열어두고 넘어가자.

 

 

2. sub_404689 함수 실행

'sub_404689' 함수

해당 함수 또한 사용자가 입력한 값을 inc하고 return하는 연산이다.

 

 

3. sub_40466f 함수 포인터 지정

sub_40466f 함수 포인터에 0c39000c6 mov 한 후, sub_40466f call, 즉 opcode "c6 00 90 c3"(리틀엔디안에 따라 역순으로) 을 실행하는것이며, 

https://shell-storm.org/online/Online-Assembler-and-Disassembler/?opcodes=c6+00+90+c3&arch=x86-32&endianness=little&baddr=0x00000000&dis_with_addr=True&dis_with_raw=True&dis_with_ins=True#disassembly

해당 opcode는 eax레지스터에 있는 주소에 0x90 바이트 (nop)를 삽입하고, ret를 한다.

 

해당 text영역과 stack view를 연동시켜보면, 

 

스택에 이전에 넣은 opcode가 있는것을 확인할 수 있고, opcode 내용대로  

eax에 있는 60160a9d 주소에 0x90 바이트 쓰기를 하다 엑세스 위반을 한 것을 알 수 있다.

 

이제 사용자의 입력이 처리되는 과정을 동적 디버깅으로 확인해보겠다.

 

사용자 입력에 1을 입력하면, 

GetDIgItemInt의 결과값, 즉 사용자 입력값인 1이 eax에 들어있는 것이 보이고, 해당 값을 dword_4084d0에 저장한다.

이후 sub_40466f 함수를 실행하면, 

loc_40467a를 호출하고, 

현재 eip가 코드로 정의되지 않은(정의는 ida가 함) 부분을 가르키고 있고, 이를 즉각 변환해준다고 한다.

dword_406014+2에 619060eb를 저장하고, inc를 두번 실행하여 (스택에 해당 주소를 넣었는지 두번 실행되는걸 동적 디버깅중 확인하였다) 현재 dword_4084d0의 값이 (사용자 입력 1) + 1 + 1 = 3인걸 확인하였다.

이후 계속 실행하면, 

또 함수를 생성해준다고 하고, 

위와 같은 연산을 한다. 또한, dword_4084d0 값을 확인해보면 

이와 같이 값이 바뀌었는데, ida에서 보여주지 못한 부분이 있다 생각하고 추측하면, 

이전에 mov로 dword_406014+2에 저장한 619060eb와 관련이 있다 생각한다.

이전 inc연산을 두번 함

최종적으로, eax가 사용자가 입력한 1에 601605d0을 더한 값이 되는것을 확인했다.

디버깅을 하면서, ida가 잡지 못한 부분이 있어 (619060eb를 저장하는 부분) 확실하지 않지만, 사용자의 입력이 덧셈으로만 조작된다 가정하면 

사용자 입력 + 601605d0 = EAX이다.

 

최종적으로, 우린 correct의 출력을 막는 401071을 nop로 씌우면 되므로, eax값을 401071로 만들어야 한다.

 

사용자 입력 + 0x601605d0 = 0x401071

사용자 입력 = 0x401071 - 0x601605d0 = FFFFFFFFA02A0AA1

32비트 프로그램이므로, 뒤의 4바이트만 주소에 들어가면 되므로, 

a02a0aa1을 넣어주면, 뒤 4바이트가 401071이 되는것을 확인하였고, 사용자는 정수로 입력해야 하므로 (GetDIgItemInt이므로) 이를 정수로 변환하면, 

2687109793 을 입력하면 된다.

정답!

 

728x90

'reversing > reversing.kr' 카테고리의 다른 글

[reversing.kr] Music Player  (1) 2024.02.15
[reversing.kr] Easy Keygen  (0) 2021.04.14
[reversing.kr] Easy_CrackMe  (0) 2020.11.29

+ Recent posts