개발자는 파일의 크기를 줄이거나 분석하기 어렵게 하기 위해서 packer를 사용하여 응용프로그램을 packing한다. packer에는 여러 종류가 있는데 가장 기본적인 UPX 패커의 동작원리를 보면서 packer에 대해 이해해보자
패킹작업을 수행하면 위의 그림대로 code와 파일 복구를 위한 IAT등을 UPX1영역에 복사하고 복구를 위한 recovery code가 그 위에 작성되고 ep가 recovery code의 시작에 위치하게 된다. 패킹된 UPXcalc.exe 를 실행하면 recovery code가 실행된 후 원래 code가 실행된다.
UPXcalc.exe를 실행시 동작 과정을 보자. 실행시 ep는 recovery code의 시작(1번)에 위치한다. recovery code는 먼저 UPX0섹션을 모두 초기화 한다. 그리고 복사 해둔 원본 code를 복사한다.
이제부터는 IAT를 채워 넣을 차례다.
IAT는 하드에 파일로 존재할때랑 메모리에 로딩됬을 때 다른곳을 포인팅하고 있다. 하드에 있을때는 dll에서 사용하는 함수의 이름을 포인팅하고 있지만 메모리에 로딩되면 IAT는 dll안의 함수 시작주소를 직접 가리키게 된다.
UPXcalc.exe가 로딩될때는 UPX 의 import table을 보고 dll들을 로딩하였기 때문에 원본 코드가 사용하는 dll은 로딩이 안되있을수도 있다. 그렇기 때문에 packer(recovery code)는 직접 동적 로딩을 하여야한다. 백업해둔 name을 갖고 LoadLibrary()와 GetProcAddress()함수를 사용하여 원본 code가 사용하는 dll들을 동적 로딩하고 사용하는 함수의 시작주소를 IAT에 넣어 원본의 IAT를 복구한다.
※원본code는 이미 함수들의 정보가 포함된 컴파일된 기계어이므로 dll만 로딩해주면 원본code의 함수들이 정상 동작한다. (걍 코드로 dll을 동적로딩해서 함수의 주소값으로 참조하여 사용하려면 calling convection, parameters의 형과 개수, return value의 형이 필요하다)
이렇게 IAT까지 복구를 다 해주면 jmp문으로 원본code가 있는 곳으로 eip를 뛰게한 후 원본code를 실행하게 된다. 계산기가 실행된다!
0 개의 댓글:
댓글 쓰기