ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 15 UPX 실행 압축된 notepad 디버깅
    리버싱 엔지니어링/리버싱 핵심 원리 2022. 3. 27. 02:31

     notepad.exe의 EP code 

    : notepad.exe를 OllyDbg로 open

    • 010073B2 주소에서 GetModuleHandleA() API 호출하여 notepad.exe 프로세스의 ImageBase를 구한다
      • ImageBase : PE 파일이 로딩되는 시작 주소
      • GetModeuleHandleA() : 인자로 모듈 이름(dll,exe)을 넘겨주면 해당 모듈의 핸들, 베이스 주소를 리턴한다
        • 성공시 핸들, 실패시 NULL 리턴
      • 인자를 NILL로 전달하면, 호출 프로세스(.exe 파일)를 만드는 데 사용된 파일에 대한 핸들을 반환.
      • 번외) GetModuleHandle(NULL)을 hinstance를 구한다고도 함
        • hinstance : 운영체제가 메모리에서 로드될 때 프로그램을 식별 위해 갖는 ID값
        • hinstance 핸들은 보통 메모리 상 올라가있는 시작주소 값을 갖고 있다.
    • 010073B4 주소에서 MZ 비교, 010073C0 주소에서 PE 시그니처 비교
      • MZ, PE 시그처란?
         
        • 리틀엔디언 표기법 주의!
        • 모든 PE 파일은 시작 부분에 DOS signature("MZ")가 존재 : 4D5A
          • 리틀엔디언 표기법으로 인해 코드내에서 5A45와 비교
        • (참고) e_ifanew : NT header의 옵셋 = 000000E0
        • PE signature(PE00) : 5045
          • 리틀엔디언 표기법으로 인해 코드내에서 4550와 비교

     

     notepad_upx.exe의 EP code 

    : notepad_upx.exe를 OllyDbg로 open

    파일이 압축된 경우 나오는 알림창. 아무거나 선택해서 넘어가기

     

    • 섹션 시작 주소(Image Base 고려)
      • 첫 번째 : 01001000
      • 두 번째 : 01011000
      • 세 번째 : 01016000

     

    • upx EP 코드

    • EP 주소는 01015330 이며, 두번째 섹션의 끝부분. 실제 압축된 원본코드의 EP 주소(0100739D) 위쪽으로 존재
    • PUSHAD 명령으로 EAX~EDI 레지스터 값을 스택에 저장
    • ESI와 EDI 레지스터를 각각 두번째 섹션 시작 주소(01011000)와 첫번째 시작주소(01001000)로 세팅
    • 디버깅 시, ESI와 EDI가 동시에 세팅되면 ESI가 가리키는 버퍼에서 EDI가 가리키는 버퍼로 메모리 복사가 일어날 것으로 예측 가능

     

    • 이 경우에서는 Sourece(ESI)로 부터 데이터를 읽어 압축해제 후 Destination(EDI)에 저장
    • UPX EP 코드를 전부 쫓아가(트레이싱) 원본 EP 코드를 찾아내는것
    •  리버싱에서는 원본 EP를 OEP(Original Entty Point)라고 한다. 

     

     UPX 파일 트레이싱 

     

    트레이싱할 때의 원칙 : "루프(loop)를 만나면 그 역할을 살펴본 후 탈출한다."

     

     OllyDbg 트레이스 명령어 

    명령어 단축키 설명
    Animate Into Ctrl+F7 Step Into 명령 반복(화면 표시 O)
    Animate Over Ctrl+F8 Step Over 명령 반복(화면 표시 O)
    Trace Into Ctrl+F11 Step Into 명령 반복(화면 표시 X)
    Trace Over Ctrl+F12 Step Over 명령 반복(화면 표시 X)
    • 애니메이트 명령어는 트레이싱 과정이 화면에 표시되어 속도가 느림
    • 트레이스 명령어는 미리 설정한 트레이스 조건에서 자동으로 멈출 수 있고, 로그를 남길 수 있음
    • UPX 파일 트레이싱 에서는 Animate Over[Ctrl+F8] 사용

     

     루프 #1 

    EP code에서 Animate Over[Ctrl+F8] 사용

    → 짧은 루프가 나타남, 트레이싱을 멈추고(Strp Into[F7]) 해당 루프 확인

    • 루프 회전수 ECX는 350 이상(루프 중간에 멈췄기 때문)
    • EDX에서 한바이트를 읽어 EDI에 쓰는 것
    • 실행 압축 파일 디버깅 시 이러한 루프를 만나면 루프를 빠져나와야함 
    • 루프 다음 주소인 010153E6에 BP 설치후 실행하여 루프 탈출

     

     루프#2 

    • 본격적인 디코딩(decoding) 루프 또는 압축해제 루프.
      • ESI가 가리키는 두번째 섹션(UPX1)의 주소에서 차례대로 값을 읽어서 적절한 연산을 거쳐 압축을 해제하여 EDI가 가리키는 첫번째 섹션(UPX0)의 주소에 값을 써줌
    • 사용되는 명령어들( AL(EAX)에는 압축해제된 데이터가 존재, EDI는 첫 번째 섹션의 주소 )

    • 이전과 동일하게 BP 설치 후 실행하여 루프 탈출 

     

     루프 #3 

    다시 트레이싱, 아래와 같은 루프 발견

    • 원본 코드의 CALL/JMP 명령어의 destination 주소를 복원해주는 코드
    • 01015434 주소에 BP 설치 후 탈출 

    +) 일반적으로 실행 압축파일은 원본 파일 코드, 데이터, 리소스 압축해제 과정이 끝나면 IAT*(Import Address Table)를 세팅하고 OEP로 이동 -> IAT 세팅만 하면 UPX 압축해제 코드 끝!

    *IAT : 프로그램이 어떤 라이브러리에서 어떤 함수를 사용하고 있는지를 기술한 테이블 

     

     루프 #4 

    다시 트레이싱하면, IAT 세팅하는 루프 발견 

    • 01015436 주소에서 EDI=01014000으로 세팅, 이곳은 두번째 섹션(UPX1)

    • 이곳에 notepad.exe에서 사용되는 API 문자열이 저장되어있음

    • GetProcAddress() 호출
      • GetProcAddress() : DLL에 있는 API 주소를 가져옴

    • API 시작주소를 얻어 EBX 레지스터가 가리키는 notepad.exe IAT 영역에 API 주소를 입력. 
    • 루프 탈출 후 실행하면, OEP로 점프하는 코드 발견(JMP 0110739D)

    ↓0110739D

     

     UPX의 OEP 빨리 찾는 방법 

    POPAD 명령어 이후의 JMP 명령어에 BP 설치

    • UPX 패커의 특징은 EP코드가 PUSHAD/POPAD로 둘러싸여 있는것
    • OEP 코드로 가는 JMP 명령어가 POPAD 바로 이후에 나탸난다.

    스택에 하드웨어 브레이크 포인트 설치

    1. PUSHAD 명령을 실행 후, ESP에 저장된 스택 주소로 이동
    2. 이동 후 하드웨어 BP 설치
    • BP가 설치된 명령어가 실행된 이후에 제어를 멈춘다
    1. 실행하면, 압축이 해제되면서 코드가 실행되고, POPAD가 호출되는 순간 제어가 멈춤.
    2. OEP로가는 JMP 명령어 발견 가능

    '리버싱 엔지니어링 > 리버싱 핵심 원리' 카테고리의 다른 글

    17 실행 파일에서 .reloc 섹션 제거하기  (0) 2022.03.27
    16 Base Relocation Table  (0) 2022.03.27
    14 실행 압축  (0) 2022.03.25
    13 PE File Format(5) - EAT  (0) 2022.03.24
    13 PE File Format(4) - IAT  (0) 2022.03.23

    댓글

Designed by Tistory.