CPU는 mov eax, 0x100 같은 명령을 그대로 알아듣지 못합니다. 그래서 CPU가 알 수 있는 2진수 형태의 기계어로 변환해서 실행을 하게 됩니다.

오늘은 그 CPU가 실행하는 기계어를 사람이 알아볼 수 있는 어셈블리 형태로 해석하는 방법을 알아보겠습니다.

먼저 인텔 CPU 매뉴얼이 필요합니다(이건 인텔 웹사이트에서 받으세요. 이번 글에서는 Volume 2A: Instruction Set Reference, A-M를 보면 됩니다). 각 기계어가 의미하는 뜻을 알아보려면 매뉴얼을 봐야 합니다. 이 글에서는 mov 명령을 예로 들면서 설명하겠습니다.

B8 00 01 00 00   mov         eax, 100h

mov 명령을 인텔 매뉴얼에서 찾아보면 다음과 같이 B8입니다.

mov 명령도 B8만 있는 것이 아니고 뒤에 오는 오퍼랜드의 종류에 따라서 여러 가지가 있습니다. 이것은 인텔 매뉴얼 Instruction Set Reference의 mov 부분에 목록이 나와 있습니다. 그런데 mov 도표에 보면 B8+라고 되어 있는데 이+는 목적지 오퍼랜드의 종류에 따라 바뀐다는 것을 뜻합니다. 이 순서는 eax, ecx, edx, ebx, esp, ebp, esi, edi 순으로 지정되어 있는데 mov eax는 B8, ecx는 B9, edx는 BA, … edi는 BF가 됩니다.

그런데 mov 명령 중에서도 뒤에 오퍼랜드가 eax, ecx등 여러 가지로 바뀌는데도 기계어는 똑같은 경우가 있습니다. 이것은 레지스터에 주소의 값을 대입하는 경우인데, ModR/M 바이트를 보고 판별합니다.

ModR/M 바이트는 3부분으로 구성되어 있는데, Mod 2비트, Reg/Opcode 3비트, R/M 3비트로 구성되어 있습니다. 이것은 인텔 매뉴얼 Instruction Set Reference의 앞부분을 보면 32Bit Addressing Forms with the ModR/M Byte라고 표 형태로 되어 있습니다.

8B 07            mov         eax, [edi]

위의 예에서 mov는 8B이고 eax, [edi] 부분은 07입니다. 이것은 ModR/M 표에서 찾으면 되는데, 첫 번째 오퍼랜드는 세로줄이며, 두 번째 오퍼랜드는 가로줄입니다. eax 줄에서 [edi]를 찾으면 07이 나옵니다(이 경우에는 목적지가 레지스터기 때문에 mov가 8B입니다. 목적지가 메모리주소가 될 경우 mov는 89로 바뀌고, 표에서 찾을 때에도 첫 번째 오퍼랜드는 가로줄이 되고 두 번째 오퍼랜드는 세로줄이 됩니다. 그렇기 때문에 오퍼랜드의 종류와 방향에 따라 명령어의 기계어가 바뀌게 됩니다).

8B 59 04         mov         ebx, [ecx+4]

이것 역시 mov는 8B이고 ebx, [ecx+] 부분은 59입니다. 4는 그 바로 뒤에 나오고 있습니다. 이걸 ModR/M 표에서 찾으면 ebx 줄에서 [ecx]+disp8에 있습니다. +disp8+4와 같은 오프셋을 뜻합니다. 8은 8비트 숫자를 나타냅니다. +disp32는 32비트 오프셋이겠죠.

8B 0C 50         mov         ecx, [eax+edx*2]

이번에 것을 찾아보면 ecx 줄에 [eax+edx*2]라는 것이 없을 겁니다. 이런 경우는 [--][--]를 찾으면 됩니다. 이건 0C인데 eax+ebx*2는 어디에 있느냐? 50이 바로 eax+ebx*2를 뜻합니다. 이것은 ModR/M 표에서는 안나오고 ModR/M 바로 뒤에 보면 32Bit Addressing Forms with the SIB Byte 표에 나와 있습니다. eax 줄에서 edx*2를 찾으면 50이 나옵니다.

이 표를 찾는 것만 알고 있으면 어떤 기계어가 나와도 인텔 매뉴얼에서 다 찾을 수 있을 것입니다.

관련글


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.