보안 따라잡기/리버스 엔지니어링 따라잡기
2. 기계어와 디컴파일러
Ggiant
2022. 10. 2. 12:42
컴파일러는 우리가 프로그래밍 언어로 소스코드를 작성하면 이를 기계어로 번역합니다.
여기서 기계어는 2진수로 표현되어 CPU는 이를 해석하고 처리합니다.
기계어는 주로 명령을 나타내는 OP 코드와 그 명령의 피 연산자인 오퍼랜드로 정의 됩니다.
OP 코드의 길이는 ISA에 의해 정의되며 x86의 경우 4byte의 크기를 가집니다.
문제는 OP코드와 오퍼랜드가 2진수로 이루어져 있기 때문에 우리가 보고 해석하기 힘들다는 것입니다.
때문에 우리는 디컴파일 과정을 거쳐 기계어를 사람이 볼 수 있는 형태로 만듭니다.
우리가 기계어를 해석해야하는 경우는 여러 경우가 있지만, 대표적인 경우는 디버깅입니다.
디버깅은 프로그램을 만들때 그 오류를 찾아 해결하는 과정인데, 이때 기계어를 분석하여 프로그램이 어떻게 흘러가는지 파악해 오류를 고쳐나갈 수 있습니다. 디버깅을 할때는 디버거라는 프로그램을 사용하는데, 이러한 프로그램은 보통 낮은 수준의 디컴파일 과정(보통 기계어와 어셈블리어를 1대 1로 대응하는)을 통해 기계어를 어셈블리 수준까지 보여줄 수 있습니다.
여기서 또 문제가 생기는데, 디버거마다 표현 방식이 달라 어떤 디버거를 쓰다가 다른 디버거를 쓰면 문법이 잘 이해가지 않을 때도 있습니다. 따라서 시간이 된다면 여러 디버거를 사용해보면서 표현 방식을 익히는 것도 필요합다.
보통 리버싱을 공부 할때 가장 많은 시간을 들이는 것이 패턴 파악입니다. 우리가 함수, if문, 반복문을 사용하면 대부분의 경우 비슷한 기계어 패턴이 나타납니다. 이것을 통해 "이것이 무슨 기능을 하는 함수구나" "여기까지가 한 분기구나" 등의 정보를 분석해 본래의 프로그램을 흉내낼 수 있습니다.