본문 바로가기

2. Reversing (리버싱)

[2024.09.28] 리버씽씽이_2주차 활동

 

 

2주차에는 유튜브 리버싱 강의를 4강~7강까지 학습하였다.

 

https://www.youtube.com/playlist?list=PLY12b4RRLcSdsxgVvTW3mnNzMjVrd8JhO

 

리버싱 강의

리버싱에 대해 공부합시다.

www.youtube.com

 

 

 

<레지스터>

목표: IA-32 Register에 대해 배워보자

 

     1. CPU 레지스터

         : CPU 내부에 있는 저장공간

              CPU 내부에 있기에 데이터 연산속도가 매우 빠름(용량이 매우 작음)

 

     2. 범용 레지스터(General Register): 일반적인 레지스터

         - IA-32 4byte(reg size: 4byte)

 

     범용 레지스터(General Register)의 종류

 

      -  EAX: 결과값을 저장하거나 피연산자를 축적

      -  EBX: 메모리 주소를 저장하기 위한 용도

      -  ECX: 반복문을 사용할 때 ECX loop count -1 감소

      -  EDX: 입출력 연산에 사용

        위의 4개의 레지스터는 산술 명령어에서 상수/변수 값이 저장되는 용도

 

      -  ESI, EDI: 문자열이나 각종 반복 데이터를 처리, 데이터를 복사할 때 사용

      -  EBP: 함수의 시작 주소 값 저장

      -  ESP: 스택 메모리 주소 저장

       위의 4개의 레지스터는 메모리 주소를 저장하는 포인터로 사용

 

      -  EIP: CPU가 처리할 명령어 주소

         Ex) 0x123 mov eax, 1(Hex) EIP = 0x123

           다음 명령어가 실행될 때 0x123 주소에 있는 명령어가 실행됨

     

      *참고 사항 (용량)

  • EAX: 4byte
  • AX: 2byte
  • AH(High): 1byte
  • AL(Low): 1byte       다른 레지스터도 동일함

      3. Flag Register

         - 명령어의 실행 여부를 결정. (실행 조건)

         - 명령어 수행에 따라 true(1), false(0)로 설정됨

         - 32개의 개수가 있음.

         

         1) Zero Flag(ZF): 연산 명령 후에 결과 값이 0이 되면 ZF가 1(true)로 설정됨

         Ex) mov eax, 1

                mov ebx, 1

                sub eax, ebx

                  eax가 0이므로 ZF = 1

 

          2) Oveflow Flag(OF): 부호가 있는 수(signed integer)의 오버플로우가 발생했을 때, 1로 설정됨

                                                     MSB(최상위 비트)가 변경되었을 때 1로 설정됨

 

          3) Carry Flag(CF): 부호가 없는 수(unsigned integer)의 오버플로우가 발생했을 때 1로 설정됨

 

<스택>

 

            스택(Stack): 메모리 내부에 스택 존재함

 

            스택의 역할

          1) 함수 내의 로컬 변수가 임시저장

          2) 함수 호출 시 매개변수(파라미터) 전달

          3) 복귀 주소 저장

 

            스택의 특징

            -  FILO(First In, Last Out), LIFO(Last In, First Out) 구조

            -  스택에서 ESP(스택 포인터)는 움직이고, EBP(ESP 값을 저장)는 움직이지 않음

    

<스택 프레임(Stack Frame)>

 

            1. 스택 프레임(Stack Frame)

                : EBP를 사용하여 스택 내의 변수나 파라미터 복귀 주소에 접근하는 기법

 

            Ex) Assembly code

            push ebp                               ; 함수 시작 EBP 값을 스택에 넣음(EBP 백업)

            mov ebp, esp                        ; ESP의 값을 EBP에 넣음(ESP 백업)

            .                                            ; 함수 로직

            .                                            ; ESP는 변경 가능함 (EBP에 백업함)

            mov esp, ebp                        ; ESP 복원

            pop ebp                                ; EBP 복원

            return                                    ; 함수 종료

 

               esp 값이 변해도 ebp를 기준으로 해당 변수나 매개변수, 복귀 주소에 안전하게 접근 가능

               스택에 값이 저장되는 것은 보안상 취약할 수 있음

               스택만 수정하면 주소 조작 등이 가능해지기 때문

 

<크랙미 실습>

목표: HDD를 CD-ROM으로 인식시키기 위해서는 GetDriveTypeA의 리턴값이 무엇이 되어야 하는가?

 

실습순서

(CodeEngn Basic RCE L01)

 

  1. 01.exe 파일을 실행했을 때 위의 메시지와 오류가 출력됨
  2. x32dbg에서 exe 파일을 열어서 구조를 확인, 에러 코드 뒤에 있는 “YEAH” 구문이 실행되면 목표 달성

               

01.exe 파일: cmp로 EAX와 ESI를 비교한 후 error 구문 혹은 성공 구문으로 이동하는 프로그램

   cmp로 EAX와 ESI를 비교했을 때 둘이 같지 않아 ZF가 0   error 구문 실행됨

 

     -  cmp: if문. 결과값이 0이거나 1임

     -  je: jmp equal, cmp로 비교하여 같으면 jmp

     -  jz: jmp zero, 값이 0일 때, jmp

     -  jmp: 조건 없이 jump

       if Zero flag != 1, je/jz가 실행 안됨

 

 

    1)    치트엔진

실행시키고 싶은 코드에서 change register at this location 클릭

EIP(CPU가 실행할 명령어)를 해당 주소값으로 변경하면 “YEAH” 구문으로 이동

메모리 변조되어 성공

 

    2)    x32dbg

je -> jmp로 변경하여 조건 없이 0x0040103D push 0로 이동함

 

메모리 변조됨

 

이외의 방법은 cmp를 바꾸어 비교할 값을 같게 만들기, cmp로 비교하는 두 값 ESP, ESI를 동일한 값이 되게 하기가 있음