본문 바로가기

Reversing/Introduction to reversing

abex crackme 5

프로그램 동작 방식

 

Delphi

  • 마이크로소프트 윈도우 응용프로그램을 위한 통합개발환경(고속개발도구)

 

  • serial을 입력하는 창

 

GetVolumeInformation() 함수

: 지정된 루트 디렉터리가 속한 파일 시스템 정보와 볼륨 정보를 가져오는 함수

 
BOOL GetVolumeInformationA(
  [in, optional]  LPCSTR  lpRootPathName,
  [out, optional] LPSTR   lpVolumeNameBuffer,
  [in]            DWORD   nVolumeNameSize,
  [out, optional] LPDWORD lpVolumeSerialNumber,
  [out, optional] LPDWORD lpMaximumComponentLength,
  [out, optional] LPDWORD lpFileSystemFlags,
  [out, optional] LPSTR   lpFileSystemNameBuffer,
  [in]            DWORD   nFileSystemNameSize
);
  • in은 입력변수, optional은 선택적으로 사용한다는 의미
  • out은 실행 결과가 저장될 변수를 지정하는 것

 

lpRootPathName은 입력 변수로, 선택적으로 사용할 수 있다. optional이므로 반드시 사용해야하는 것은 아니다.

nVolumeNameSize은 입력 변수지만 반드시 사용해야한다. 함수 사용시 nVolumeNameSize을 지정하지 않으면 오류가 발생한다.

lpVolumeNameBuffer는 함수 호출 시 변수 이름을 넣어주면, 함수가 실행되고 그 결과로 찾아낸 볼륨 이름을 지정한 변수에 담아준다.

 

 

  • 출력 값이 저장된 모든 변수에 0이 저장되어 있는 것을 알 수 있다.

 

  • GetVolumeInformation() 함수까지 실행시 출력 변수에 다양한 값이 저장되는 것을 확인할 수 있다.

 

디버깅 과정에서 다양한 윈도우 API를 만나게 되는데, 그 때 가장 먼저 해야하는 것이 MSDN에서 함수의 기능을 살펴보는 것

입력 값과 출력 값이 어디에 저장되고 이 값들이 이후 프로그램에서 어떻게 사용되는지 조사하면 해결의 실마리를 찾을 수 있다.

 

 

반복문을 통한 문자열 변경

반복문 구성 → 초깃값, 한계 값, 증가 값

 

 

004010AD

DL 레지스터에 2를 복사한다.

DL은 나중에 반복문의 종료를 체크하는 변수로 사용된다.

자바 코드에서 int i = 2와 같은 역할

 

 

004010AF ~ 004010C4

반복문이 수행하는 로직

 

 

004010CB

DL 레지스터를 하나씩 감소시킨다.

DEC 명령어는 차감하는 대상이 0이 되면 ZF를 1로 설정한다.

자바 코드에서 i--와 같은 역할

 

 

004010CD

ZF가 1이 아니면 주소 004010AF(반복문 수행 로직 처음 주소)로 점프한다.

DL 레지스터가 0이 되면 ZF가 1로 설정되고 반복문이 종료된다.

 

 

프로그램 구조 분석

핵심 프로그램 구조
 
 

① 파일 시스템 정보와 볼륨 정보를 가져와서 일련번호를 만들기 위한 입력 값으로 사용

 

 

② 파일 시스템 정보와 프로그램 내부에 들어 있는 문자열을 결합해서 만든 새로운 문자열을 반복문을 통해 다른 문자열로 변형

 

 

ADD DWORD PTR DS:[40225C], 1
ADD DWORD PTR DS:[40225D], 1
ADD DWORD PTR DS:[40225E], 1
ADD DWORD PTR DS:[40225F], 1
  • 연속된 메모리 주소의 값을 각각 1씩 더함.
  • 총 4개의 주소 (0x40225C ~ 0x40225F)에 대해 각각 +1 수행

⇒ 반복문을 2번 수행하므로, 결론적으로 4개의 주소에 대해 각각 +2를 수행하는 것

 

 

③ 앞에서 생성한 새로운 문자열을 가지고 프로그램 내부의 문자열과 결합해 일련번호를 생성함, 프로그램 내부에는 2가지의 문자열이 있고, 파일 시스템 정보와 결합하고 변형해서 일련변호를 생성

 

 

④ 생성한 일련번호와 사용자가 입력한 값이 일치하는 지 확인

 

 

문제 해결

  • 프로그램을 실행하면 일련번호를 입력하는 창이 나오는데, abcd를 입력하고 GetVolumeInformationA 함수를 실행시킨다.
  • 0040225C에 있는 데이터가 일련번호를 만드는 데 사용됨을 일련번호를 만드는 부분을 보면 알 수 있다.

 

  • 원래는 드라이브 이름이 저장되어야하는데 인식을 못하는 건지 아무것도 들어가있지 않다. 그래도 계속 진행하겠다.

 

  • 다음 코드를 실행시켜보면 0040225C에 들어있는 값 + 4562-ABEX0040225C에 저장된다.
  • 0040225C에 아무것도 들어가 있지 않았어서 0040225C 4562-ABEX라는 문자열이 저장되었다.

 

  • 다음 반복문은 0040225C부터 4개의 문자값에 해당하는 숫자를 1만큼 2번 증가시킨다.

 

  • 원래는 4562가 들어있었는데 2씩 증가하여 6784가 되었다.

 

  • 먼저 00402000에 L2C-5781이라는 문자열을 저장한다.
  • 다음 0040225C에 저장되어있는 앞에서 생성한 문자열을 00402000에 저장된 문자열에 붙인다.
  • 마지막으로 사용자가 입력한 문자열과 00402000에 저장된 문자열을 비교한다.

lstrcmpiA()함수는 두 개의 인수를 입력받는데, 함수 실행 결과는 EAX 레지스터에 저장되며 두 인자의 값이 같으면 0, 다르면 1이 입력된다.

 

 

 

  • 내 컴퓨터에서 생성되는 일련번호는 L2C-57816784-ABEX임을 알 수 있다.

'Reversing > Introduction to reversing' 카테고리의 다른 글

Lena Reversing tutorial 17 - Removing NAGs  (0) 2025.05.05
abex crackme 4  (0) 2025.05.05
abex crackme 3  (1) 2025.05.05
abex crackme 2  (0) 2025.05.05
abex crackme 1  (2) 2025.05.05