본문 바로가기

프로젝트/디스어셈블러 만들기

IA-32 opcode map-1

일단 지금 하고 있는것이 기계어-> 어셈블리어로 변환시키는 방법이므로 intel이 어떻게 기계어 구조를 만들었

는지를 알기 위해서 Intel에서 제공해준 공식 메뉴얼을 봐봤습니다.


이 메뉴얼은 intel공식 홈페이지를 가서 메뉴얼 다운로드를 하면 나옵니다.


먼저 인텔 기계어의 가장 기본적인 구조입니다.

1)Instruction Prefixes: 1바이트로 Opcode를 보조하는 역할을 합니다.(선택적: 없어도 됨)

2) Opcode : 1,2,3 바이트로 어떤 명령어인지를 알려줍니다.

3) ModR/M : 1바이트로 각각의 bit가 Mod, Reg/Opcode,R/M으로 되있으며 Opcode가 원하는 그 어셈블리어에서 명령어 뒤에 나오는 값이 라고 생각하면 됩니다.(선택적)

4) SIB : 1바이트로 각각의 bit가 Scale,Index,Base로 되있으며 ModR/M을 보조하는데 쓰입니다.(선택적)

5) Displacement : 1,2,4바이트로 Memory Address의 Displacement를 나타냅니다.(Memory Address가 있을때만 쓰니까 선택적)

6) Immediate : Immediate(즉각적)이라고 해석되야하지만 이곳에서는 상수를 뜻합니다. 이 이유는 조금 있다가 Addressing Method를 설명할때 보여드리겠습니다.



그럼 한번 Opcode Map이 어떤것인지 살펴보겠습니다.

이렇게 생겼는데요 기계어의 앞부분을 행으로, 뒷부분을 열로 해서 이 테이블을 읽으면 됩니다.

저희가 읽을 값은 6A라는 값인데요 여기서 6A를  찾아보면 push Ib라고 써있습니다.

이것으로 봤을때 6A는 push라는 명령어를 가리킨다고 보면 되겠습니다.

그다음에 Ib에 대해서 살펴봐야 하는데요 이것을 보기 위해서 Addressing Method와 Operand Type에 대해서 살펴봐야 합니다.



이부분은 Operand Type입니다.

아까 저희가 찾으려는 값이 Ib인데 여기에 I는 없으므로 여기서 찾을것은 b라고 생각됩니다.

그래서 b를 읽어보면 바로 byte라고 나와있네요. 그럼 push lb라는것은 I(아직은 모르는)b(바이트)를 stack에 push한다는 뜻임을 알 수 있습니다.

그다음에는 I를 찾기 위해서 Addressing Method를 찾아보겠습니다.



바로 이부분이 Addressing Method인데요 이곳에서 I를 찾아보면 바로 Immediate data라고 나와있네요.

그 오른쪽 뜻을 읽어보면 "피연산자의 값은 명령의 다음 바이트로 인코딩됩니다" 라고 뜻만 읽으면 이렇게 되는데요 이것이 바로 값=byte로 상수라는 뜻입니다.

그러면 이제 push Ib는 바로 1byte크기의 상수를 push하는 명령이라고 볼 수 있습니다.


이렇게 intel 메뉴얼을 이용해서 기계어를 읽을 수 있습니다.


그럼 이제 이 지식들을 이용해서 이 위의 기계어를 전부 어셈블리어로 변환시켜보겠습니다.



저번 소스에서 기계어->어셈블리어로 변형시키는 소스를 넣고 프로그램을 돌려보면


이렇게 됩니다. 일단 call,jmp부분들은 memory부분이라 완성시키지 못해서 적당히만 출력해 봤습니다.


다시 한번 올리디버거랑 봐도 call부분에 대한 것 빼고는 완전 똑같을 정도로 어느정도 디스어셈블러를 만드는데 성공한 것 같습니다.

다음번에는 메모리구조와 data부분을 참조하여 memory address와 call부분들을 완성시키는 포스팅을 하겠습니다.


여기까지 읽어주셔서 감사합니다.

'프로젝트 > 디스어셈블러 만들기' 카테고리의 다른 글

EP찾기  (0) 2013.08.06
디스어셈블러 원리 파악  (0) 2013.07.19