04 리버싱에 익숙해지기 - 1. abex crackme 세 번째 예제

HnBrd·2023년 7월 6일
1

리버싱 입문

목록 보기
4/4
post-thumbnail

1.1 프로그램 동작 방식

PE 구조를 살펴보는 데는 Detect It Easy 툴을 사용하면 된다

  • Detect It Easy는 다음과 같은 기능(정보)을 제공한다

    • PE 구조
    • 프로그램을 개발한 언어
      • 프로그램 개발한 언어를 알면 자주 사용되는 어려움에 직면했을 때 구글링에 도움을 준다
    • 패킹 여부
    • 파일을 직접 수정
  • 세 번째 예제 abexcm3.exe 를 열어서 알 수 있는 것은?

    • 델파이로 개발되었다

이제 실행해보자

  • 일련번호를 담은 파일을 생성하는 문제
    • 어떤 이름의 파일을 생성해야 하는가?
    • 생성한 파일을 규칙에 맞도록 변경해야 한다

1.2. 함수 호출 규약

  • 함수 호출 규약 ( = Calling Convention )이란?
    • 함수를 호출할 때 인자를 전달하는 방식에 대한 약속
    • 함수 실행이 끝나고 스택을 정리하는 방식에 대한 약속

함수 호출 규약의 3가지 방식

  1. cedcl

    • 인자가 오른쪽에서 왼쪽으로 순서대로 스택으로 전달
    • 함수가 종료될 때 호출자가 피호출자의 스택 프레임을 정리
      • 호출자 (= caller)가 ADD ESP 8를 통해 스택의 위치를 증가시켜 정리
    // [caller]
    PUSH 2
    PUSH 1
    CALL callee
    ADD ESP 8
  2. stdcall
    - 인자가 오른쪽에서 왼쪽으로 순서대로 스택으로 전달

    • 함수가 종료될 때 피호출자가 스스로 스택 프레임을 정리
      • 피호출자 (= callee)가 RETN 8
    // [caller]
    PUSH 2
    PUSH 1
    CALL callee
    ...
    
    // [callee]
    PUSH EBP
    MOV EBP, ESP
    ...
    POP EBP
    RETN 8
  1. fastcall
    - 인자가 오른쪽에서 왼쪽으로 순서대로 레지스터를 사용해서 전달
    - 스택 정리할 필요 없음
    - 피호출자 (= callee)가 RETN

    // [caller]
    MOV EDX 2
    MOV ECX 1
    CALL callee
    ...
    
    // [callee]
    PUSH EBP
    MOV EBP, ESP
    ...
    MOV DWORD PTR SS:[EBP-8], EDX
    MOV DWORD PTR SS:[EBP-4], ECX
    ...
    POP EBP
    RETN

1.3. 부호 있는 숫자의 표현

  • 음수를 2의 보수로 표현 한다
    • 2의 보수 = NOT 연산 후 1을 더하기


1.4. 프로그램 구조 분석

이제 abexcm3.exe 프로그램의 구조에 대해 분석

  • 엔트리 포인트 아래에 찾아야 할 오류 메시지를 모두 확인할 수 있다

분석으로 알아낼 수 있는 프로그램 실행 순서

  1. CreateFileA() 함수를 통해서 키를 담은 파일 abex.12c 가 있는지 확인해서 EAX 에 저장

  2. 파일이 없다면 "Hmmm, I can't find the file!" 메시지 부분으로 JMP

  3. 파일이 있다면 GetFileSize() 함수를 통해 파일 크기를 확인해서 EAX 에 저장

  • 파일이 유효하면 "Yep, keyfile found!"
  • 파일이 유효하지 않으면 "The found file is not a valid keyfile!"

1.5.문제 해결

  1. 프로그램 주석 영역을 살펴보면 CreateFileA() 함수 상단에 FileName = abex.12c
HANDLE CreateFileA(
  [in]           LPCSTR                lpFileName,
  [in]           DWORD                 dwDesiredAccess,
  [in]           DWORD                 dwShareMode,
  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  [in]           DWORD                 dwCreationDisposition,
  [in]           DWORD                 dwFlagsAndAttributes,
  [in, optional] HANDLE                hTemplateFile
);
  1. 메모장을 열어서 키를 담을 파일 abex.12c 를 생성하고, 내용은 대충 아무거나 10바이트 넣어본다

  2. 파일의 크기를 검사하는 부분에 BP를 걸고 실행

  3. 프로그램의 크기가 EAX 레지스터에 10 이라고 적힌 부분을 찾을 수 있고, 유효한 값은 16진수로 12 임을 알 수 있다

  4. abex.12c 에 문자를 더 입력해서 18 바이트 (= 16진수로 12 바이트) 로 만들어준다

  5. 실행하면 CMP 에서 ZF1 로 설정되어서 JNE 구문은 점프하지 않음

  6. 성공!

profile
잡식

0개의 댓글