2. Reversing (리버싱)/2) 개념 정리

[2025.05.17]리버싱난다_5주차 활동

snowryan 님의 블로그 2025. 5. 22. 00:34

참고강의- 유튜브 Fin 리버싱 강의 (18-23강), EAT(1,2), 프로그램 압축, 빠르게 OEP찾기, Relocation

 

[IAT]

실행파일이 다른 모듈에서 사용하는 함수를 가르키는 포인터 함수로 모든 함수의 리스트이다. txt파일로 정리하며 여러 배열이 존재한다. PE파일이 다른 DLL파일에서 사용하는 함수 참조할 때 사용하며 PE파일내 참조하고싶은 모든 함수의 주소로 채워짐 이후 프로그램이 함수를 호출할 때 IAT에 저장된 함수를 호출한다

[Library]

다른 프로그램에서 호출하도록 관련 함수와 기능을 모아둔 파일이다. 

[EAT]

라이브러리 파일에서 제공하는 함수를 다른 프로그램에 가져다 사용하게하는 핵심 메커니즘이다. EAT를 통해서만 library가 내보내는 시작 주소를 알 수있다. PE파일의 특정 구조체 정보를 가지고있다. PE파일이 내보는 함수의 개수와 주소만 있으므로 배열로 충분하다  PE파일이 제공하는 함수를 다른 프로세스에서 사용하게 내보내는 용도이다. PE파일이 내보내는 모든 함수 주소를 저장하고 다른 프로세스에서 함수를 호출할 때 EAT에서 찾아서 호출한다.

 

[EAT구조체]

NumberOfFunctions: export함수의 개수

NumberOfNames: export함수 중 이름을 가지는 함수

AddressOfFunctions: export함수의 주소배열

AddressOfNames: 함수 이름 주소배열

AddressOfNamesOrdinals Ordinal(고유번호) 배열(배열 원소개수= NumberofNames) RVA

 

 

[GetProcAddress() 작동원리]

1.    AddressOfNames 멤버를 이용해 함수 이름 배열로 간다

2.    함수 이름 배열에 문자열 주소가 저장되어 있으므로 문자열 비교를 이용하여 웑하는 함수의 이름을 찾는다( Array index= 인덱스 위치 0, str=string cmp)

3.    AddressOfNamesOrdinals 멤버를 이용해 ordinal 배열로 간다

4.    ordinal배열에서 array_index로 해당 고유번호인 ordinal값을 찾는다

5.    AddressOfFunctions 멤버를 이용해 함수 주소 배열인 EAT로 간다

6.    EAT에서 아까 구해놓은 ordinal값을 인덱스로 사용하여 원하는 함수의 시작주소를 얻는다 ordinal==index

 Ordinal != index일 때 AddressOfNamesOrdinals 배열 값이 ordinal==index가 아니더라도 GetProcAddress() 사용가능하다

 

INT:PE파일에서 참조하는 모든 DLL파일과 함수이름 포함한다

 

[인코딩] 원본-> 형태변환, 디코딩: 형태 변환상태-> 원본형태로 변환한다

[PE패커] 실행파일 압축기로 정확한 명칭은 Run-Time packer로 불린다

[패커]: 파일의 크기를 작게 만들어 리버싱을 조금 어렵게 만든다, 메모리에서 디코드 루프가 돌면 패킹이 풀린다.  

[메모리 덤프] 메모리 내용인 코드를 가져온다

[프로텍터] 리버싱을 매우 어렵게 만드는 압축기, anti-reversing으로 파일이 커짐

 

[소프트웨어 breakpoint]

중단점에서 멈추므로 처음부터 중단점까지만 실행이 됨, 디버깅을 편하기 하기위해 만들어짐

[하드웨어 breakpoint] c

cpu에서 중단점을 잡는것이고 4개까지만 중단점을 설정 할 수있다. 만약 EAX에 중단점을 걸었다면 프로그램이 종료될때 까지 모니터링을 하여 EAX에 참조되는 것에 중단점을 다시 걸어버린다. 항상 값을 모니터링 하는 것이다. 

pushad: 현재 EAX~EDI(ESP EBP)까지를 스택에 push

popad: EAX~EDI(ESP EBP)까지를 스택에 pop

대부분 pushad를 하면 popad가 실행된다 하나를 넣으면 반환하는 것이다 unpacking

하드웨어 중단점이 설정되어 있으면 OEP실행 

 

[데이터 압축]

컴퓨터 공학의 분야로 어떤 형태의 파일이나 데이터라도 내부 바이너리인 기계어로 되어있으며 적절한 압축알고리즘을 이용하여 프로그램의 크기를 줄여 보관과 전송을 용이하게 하는 것이 우리가 잘 아는 압축이다. 실행압축 exe파일

압축의 종류

1. 비손실 압축(모든 파일)

2.손실 압축 (모든 파일)

3.실행 압축 (exe 파일)

 

[PE relocation]: PE파일이 프로세스 가상 메모리에 로딩될 때 헤더의 IB주소에 로딩한다 만약 DLL일 경우 IB애 이미 다른 파일이 로딩되면 다른 비어있는 공간으로 재배치하는 것이다.  DLL,EXE,ASLR기능이 있다.

PE재배치 방법

1.하드코딩된 주소를 찾는다

2.값을 읽은 후 IB만큼 뺀다

3.실제로 로딩된 주소를 더한다

 

rev-basic4 문제풀이

test eax에 할당된 함수에 들어가보고 Hex값을 찾는다. ida로 decompile을 하여 c언어로 코드를 확인한다.

((x << 4) | (x >> 4)) == 0x24가 되는 x를 찾는 것이다. 

for x in range(256):
    if ((x << 4) & 0xFF) | (x >> 4) == 0x24:
        print(hex(x))

  • 이 함수는 x를 다음 방식으로 변형해서 비교: ((x << 4) | (x >> 4))
  • 입력된 바이트들이 위 연산의 결과와 일치하는지 검증하는 함수
  • 주어진 28바이트는 기준값 (byte_140003000[])이고, 역산하면 원래의 x값을 일부 구할 수 있다
  • 플래그값을 구하려면 위에 파이썬 코드로 역산하면 된다