진법 변환

study 2012.03.06 08:30

간단한 진법 변환에 대해서 알아보겠습니다. 

아주 기초적면서도 중요한 내용입니다만, 블로그에 제대로 소개한적이 없어서 이번에 제대로 정리해보겠습니다. 


일반적인 사람이 사용하는 진법은 10진법입니다. 컴퓨터는 내부적으로 2진법을 사용합니다. 리버싱에서는 16진법을 사용합니다. 따라서 리버서는 이 세 가지 진법체계(2, 10, 16)를 자유자재로 변환할 줄 알아야 합니다.

보통은 계산기를 사용하면 편합니다만 2진수 <-> 16진수 변환 과정은 리버싱에 자주 등장하기 때문에 암산으로 가능하도록 숙달하는 것이 좋습니다. 




기본 진법


 진 법 숫 자 설 명   
 2 (Binary)  0, 1  ON, OFF 1111(2), 1111b
 10 (Decimal)  0 ~ 9  사람이 익숙한 숫자 체계 15(10), 15d
 16 (Hexadecimal)  0 ~ 9, A ~ F  2진법을 1/4로 줄여서 보여줌  F(16), Fh

* 참고

16진수는 2진수를 1/4로 압축시켜 보여주는 효과가 있습니다. 즉, 4 자리의 2진수가 1 자리의 16진수로 간단히 표현됩니다. 

예) 15(10) = 1111(2) = F(16)




변환 방법


학창시절에 배웠던 진법 변환 방법의 기억을 되살려 보겠습니다.

#1. 2진수 <-> 10진수 

1) 9(10) -> 1001(2)



2) 1001(2) ->  9(10)


3) 30(10) -> 11110(2)



4) 11110(2) ->  30(10) 


변환 방법은 매우 간단합니다. 기억이 새록새록 나시죠?  


#2. 10진수 <-> 16진수

1) 123(10) -> 7B(16)


2) 7B(16) -> 123(10)


3) 500(10) -> 1F4(16)



4) 1F4(16) -> 500(10) 


여기까지는 변환 원리만 기억하시고 실제로는 계산기를 사용하시는것이 편리합니다.

리버서에게 중요한 것은 아래의 2진수 <-> 16진수 변환을 암산(수작업)으로 해내는 능력입니다.

#3. 2진수 <-> 16진수



<2진수 테이블>


위 테이블에서는 1 ~ 15 까지의 숫자를 각각 10, 16, 2 진수로 보여주고 있습니다. 

눈여겨 보실 내용은 4 자리의 2 진수를 1 자리의 16진수로 표현 가능하다는 것입니다.
'4 자리의 2 진수' 라는 말은 4 bit 라고 바꿔 말 할 수 있고, 8 bit(1 byte) 는 '8 자리의 2 진수' 이며 이는 2 자리의 16 진수입니다.

즉, 1 byte 는 2 자리의 16 진수로 간단히 표현(00 ~ FF)이 가능하다는 뜻입니다. 이런 특성 때문에 컴퓨터 공학에서는 16진수로 숫자를 표현하는 것이 편리합니다. (1 byte 로 저장할 수 있는 숫자를 10 진수로 표현하면 0 ~ 255 이며 세 자리수가 필요합니다.)

위의 테이블을 다 외우시면 물론 좋습니다만 처음에는 빨간색으로 표시한 2(0010), 4(0100), 8(1000), A(1010), C(1100)만 외우셔도 됩니다. 파란색으로 표시한 1(0001), F(1111)는 간단하니까 한번 보면 저절로 외워지고요. 나머지 숫자는 빨간색 숫자에서 계산하시면 됩니다. 계산 방법은 아래와 같습니다.


3(0011) = 2(0010) + 1(0001)
5(0101) = 4(0100) + 1(0001) 
6(0110) = 4(0100) + 2(0010)
7(0111) = 8(1000) - 1(0001)
9(1001) = 
8(1000) + 1(0001)
B(1011) = A(1010) + 1(0001)

D(1101) = C(1100) + 1(0001)
E(1110) = F(1111) - 1(0001) 


간단한 예제를 살펴보겠습니다.

변환 요령은 "16진수는 한 자리씩 끊고, 2진수는 네 자리씩 끊는다" 입니다. 그리고 위 테이블을 보면서 변환하시면 됩니다. (조금만 숙달되도 암산으로 가능해 집니다.)  

1) 7F(16) -> 01111111(2)


2) 3D6A921E(16) -> 00111101 01101010 10010010 00011110(2)


3) 10101100(2) -> AC(16)




진법 변환 활용


이러한 16진수 <-> 2진수 진법 변환을 왜 공부해야 할까요?

리버싱 분야에서 다양한 활용 예가 있습니다.

IA32 Instruction Table 을 해석을 위해 ModR/M, SIB, Group ID 등을 계산할 때 필요합니다.


<그림 - IA32 Instruction Format : 출처 Intel Manual>


<그림 - ModR/M Byte : 출처 Intel Manual>

EFLAGS 레지스터는 각 bit 가 flag 를 의미합니다. 이러한 bit flag 연산에 진법 변환이 필요합니다.


 <그림 - EFLAGS : 출처 Intel Manual> 

 Win32 API 의 파라미터 중에 Flag 를 bit 로 표시하는 경우가 많습니다.

HANDLE WINAPI CreateFile(

  __in      LPCTSTR lpFileName,

  __in      DWORD dwDesiredAccess,

  __in      DWORD dwShareMode,

  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,

  __in      DWORD dwCreationDisposition,

  __in      DWORD dwFlagsAndAttributes,

  __in_opt  HANDLE hTemplateFile

);


* 출처 : MSDN


CreateFile() API 의 6 번째 파라미터 dwFlagsAndAttributes 는 아래와 같이 bit flag 로 이루어져 있습니다.


<그림 -  dwFlagsAndAttributes 설명 일부 : 출처 MSDN>  

이외에도 디버깅을 하다보면 각종 bit 연산이 나타나는데 16진수 <-> 2진수 변환 방법을 알고 있으면 코드를 이해하는데 크게 도움이 됩니다.

지금까지 매우 기초적이면서도 중요한 진법 변환에 대하여 알아보았습니다. 잘 활용하시기 바랍니다.


개인적으로 백만년 만의 포스팅이네요. 이 포스팅을 시작으로 블로그 활동을 재개합니다. ^^~

* 얼마전 회사를 떠나서... 사회에 첫 발을 내디딘... 혹은 학교로 복귀한... 15기 인턴들 모두 화이팅~~~




ReverseCore
    이전 댓글 더보기
  1. 1 2018.02.01 22:56 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  2. 2018.02.02 06:03 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  3. 1 2018.02.02 20:01 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  4. 2018.02.03 19:05 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  5. 1 2018.02.03 19:38 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  6. 1 2018.02.04 15:11 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  7. 2018.02.05 07:31 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  8. 1 2018.02.05 19:19 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  9. 1 2018.02.07 18:05 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  10. 2018.02.08 07:38 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  11. 1 2018.02.08 17:51 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  12. 2018.02.10 00:28 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  13. 바이낸 2018.02.10 08:35 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  14. 1 2018.02.10 16:02 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  15. 1 2018.02.11 17:13 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  16. 2018.02.11 19:14 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  17. 1 2018.02.13 18:28 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  18. 2018.02.14 08:30 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  19. 1 2018.02.14 15:55 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다

  20. 1 2018.02.15 17:23 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다



지난주부터 "IA-32 Instruction" 챕터를 작업하는 중인데요, IA-32 Instruction 이란 쉽게 말해 아래 그림에서 빨간 박스로 표시된 부분을 말하는 것입니다.



디버거에 탑재된 Disassembler 가 저 Instruction 을 해석해서 우리가 익히 보는 (오른쪽의) Disassembly 코드를 만들어 내지요.

"IA-32 Instruction" 챕터를 작업하면서 제 노하우를 공개하였습니다. 그건 바로 Intel IA-32 Manual 에서 Instruction 을 해독하기 위해 필요한 Opcode Map(Opcode Table) 부분만 프린터로 출력한 것입니다. 저한테는 Opcode 매뉴얼인 셈이지요. (아래 그림 참고)



작업 중인 책 내용의 일부를 소개합니다. (참고 섹션 내용입니다.)

* 참고

위 출력물이 너덜너덜 해질 때쯤 여러분은 IA-32 Instruction 해석의 고수가 되어 있으실 겁니다. 저 또한 5년 동안 손 때묻은 저만의 출력물을 한 부 가지고 있습니다. 후배나 동료가 Instruction 해석에 관해서 물어오면 자랑스럽게 꺼내서 가르쳐 줍니다. 많이 참고하다 보면 어떤 내용이 대충 어느 페이지에 있다는 감이 생겨서 한번에 그곳을 펼칠 수 있습니다. (생활의 달인?)
제가 가장 존경하는 선배님도 이러한 출력물을 가지고 계셨습니다. 그 당시에도 매우 낡아 보였지요. 어찌 보면 이것이 리버서의 연륜(?)을 나타내는 하나의 척도로 볼 수 도 있겠습니다. 여러분께서도 꼭 자신만의 출력물을 한 부 만들어서 활용해 보시기 바랍니다.

이처럼 오랫동안 저랑 같이 작업한 제 손 때묻은 매뉴얼 이라서 어느덧 애정이 생겨 버렸습니다. (기술자들은 모두 그런 게 한두 개씩은 있잖아요? 자신과 오랫동안 함께 하면서 분신이 되어버린 도구 같은…)

최근 1~2년은 주로 각종 자동화 시스템의 개발/유지보수 업무를 하면서 Opcode 매뉴얼을 거의 꺼내 보지 못했었는데, 이번에 "IA-32 Instruction" 챕터를 쓰면서 다시 꺼내어 보니 감개가 무량하더군요. (그동안 소홀해서 미안해~ 이번 챕터는 다 니 덕이야~ 고마워~)

더불어 제게 처음 IA-32 Instruction 을 가르쳐 주시고(사실 개발, 분석을 다 가르쳐 주셨죠) 제가 가장 존경하는 선배님(형님)이 생각납니다. 지금은 외국에 계셔서 만나 뵙기는 힘듭니다만 오늘은 그분이 더 보고 싶네요. ^^~

  1. LinkC 2010.08.31 14:55 신고 댓글주소 | 수정 | 삭제 | 댓글

    Revercore님의 중후한 내공을 느낄 수 있는 멋진 메뉴얼이네요 :D

    이런 고수분들의 글을 보며 공부 할 수 있는 기연을 얻은 저도 운이 좋은 것 같습니다

    저도 글을 포스팅 하면서 느끼는 거지만, Core님의 글솜씨에 정말 감탄하고 있습니다

    그만큼 다음 챕터도, 앞으로 나올 책도 정말 너무 기대됩니다

    p.s 1시 0분 0초에 글을 포스팅하신 Core님의 내공에 한 번 더 감탄! XD

  2. 철이 2010.09.01 08:32 신고 댓글주소 | 수정 | 삭제 | 댓글

    아...저렇게 공부 하는거구나.

    여름은 잘 보내셨냐요? 이번 방학때 바다 공모전, 파일시스템 공부 했습니다.

    ㅎㅎ 휴학 하는데 더욱더 리버싱공부를 해야 겠습니다.

  3. SeHwa 2010.09.01 23:09 신고 댓글주소 | 수정 | 삭제 | 댓글

    책을 쓰고 계신가요? 왜인지 구입 의욕이 훅훅 나는 책이로군요.

  4. Ethobis 2010.09.10 17:45 신고 댓글주소 | 수정 | 삭제 | 댓글

    ㅋㅋㅋ 당장 인쇄했지만..
    보기가 어렵네요 무슨말인지 ㅠㅠ

    • reversecore 2010.09.14 00:08 신고 댓글주소 | 수정 | 삭제

      앗, 어떤 페이지를 인쇄하셨나요?

      윗글에는 제가 Opcode 챕터를 쓰는 과정에서의 에피소드를 적어놓은 것이구요... 실제적으로 어떻게 Opcode 를 해석하는지에 대한 내용은 책에 수록될 예정입니다. ^^

  5. Ethobis 2010.09.15 22:51 신고 댓글주소 | 수정 | 삭제 | 댓글

    Opcode 매뉴얼 페이지만 한 5장이었나 그렇게 인쇄했거든요 ㅎㅎ
    헥사값으로 어떻게읽고 어떤 오피코드인지 보는법이랑 당장에 오피코드 종류들도 그렇게 많이 알고있지 않아서 보기가 어렵네요 간단하게나마 보는 방법좀 알려주실수있나요 ㅋㅋ

    • reversecore 2010.09.16 23:16 신고 댓글주소 | 수정 | 삭제

      네, 그러셨군요.

      설명이 조금 길어서 댓글로는 어렵겠습니다.

      Instruction 해석은 One-byte Opcode Map 에서 시작합니다.
      가령 Instruction 의 첫바이트가 50 이라면...
      One-byte Opcode Map 의 5행 0열의 PUSH EAX 명령을 의미하는 것입니다. 추가적으로 Operand 형식을 볼줄 알아야 하는데 그것도 매뉴얼에 있습니다. 그리고 ModR/M, SIB 테이블을 읽을줄 알면 됩니다. (역시 매뉴얼에 있습니다.)

      알고보면 원리는 간단합니다. (블로그에 그 내용을 올리면 좋을 텐데 말이죠.)

  6. 보름♬달★콤 2010.09.24 14:42 신고 댓글주소 | 수정 | 삭제 | 댓글

    분석가는 아니고 개발자입니다.
    몇달 전 호기심에 어셈블리 디버거를 만들면서 디스어셈블리도 구현하다보니
    저역시 너덜너덜해진 ia32출력물을 가지게 되었네요^^;
    opcode map을 외우지는 못하지만 동작을 이해하느라 많이 보다보니 그렇게 되었지요.

    근데 opcode map을 보다보니 '틀린' 부분이 종종 있는 것 같던데..
    혼자 하다보니 확실한 지 몰라서.. 맞나요?

    • reversecore 2010.09.25 13:16 신고 댓글주소 | 수정 | 삭제

      안녕하세요~ ^^

      호기심에 디버거를 만드신다구요? @@~~
      정말 대단하십니다~~~

      과거 디버거의 동작원리를 처음 공부할때 간단히 debug.exe 비슷한 형태의 32bit 디버거를 구현해본 적이 있습니다. 꼬박 일주일 동안 밤낮으로 매달렸었는데요... 그 이후에 OllyDbg 개발자를 맘속으로 존경하게 되었습니다. 실력과 인간성 모두를 말이죠...

      보름달콤님께서 만드신 디버거를 보고싶네요~

      opcode map 의 어떤 부분을 말씀하시는 것인지요?
      저에게도 좀 알려 주시기 바랍니다.

      제가 알고 있는 것은 해마다 기존 내용을 조금씩 수정하고 있다는 것입니다. 예를 들어 문자열 복사 명령어 A4 의 경우 MOVS Xb, Yb 로 되어 있는데, 액면 그대로 해석하면 SRC 와 DST 가 반대로 되지요. MOVS 명령어 설명을 읽어보면 Operand 순서는 중요하지 않고 크기만 중요하다고 되어 있습니다. 순서(EDI<-ESI)는 결정 되어 있단 뜻이겠지요. 그런데 2004 년 판을 찾아보면 MOV Yb, Xb 로 정확히 나와 있습니다. 어느 순간 부터 지금처럼 바뀌어 버렸지요. 이런 부분들이 좀 어려움을 주는 것 같습니다.

    • 보름♬달★콤 2010.09.27 13:14 신고 댓글주소 | 수정 | 삭제

      아 맞아요.. 그런 부분이 저도 헷갈렸던 부분이기도 합니다.
      말씀하신 MOVS의 경우,
      instruction format으로 본다면 opcode외에 어떠한 operand도 갖지 않지만
      디스어셈블리 출력에 있어서는 operand를 표기해서 정확한 동작의 의미를 전달할 수 있게 하는 게 좋을 테고요
      그런 점에서 일반적인 src, dst가 뒤바뀐 opcode map의 표기를 그대로 따라야 하는지 등의 고민을 했었던 것 같습니다.

      map이 틀렸다고 생각했던 것들이 뭐였는지 잘 표시를 안해놓아서
      다 기억할 수는 없지만 방금 하나를 발견했네요.
      AF opcode의 경우, 어떤 경우든지 EDI(RDI)를 취하게 되는 것으로 보이는데
      opcode map에는 SCAS/W/D/Q rAX, Xv 로 표기가 되어 있습니다.
      틀린 게 아닌가요? 이런 부분이 몇몇 있었던 것 같습니다..

    • reversecore 2010.09.29 01:24 신고 댓글주소 | 수정 | 삭제

      네, AF 의 경우도 SCAS rAX, Xv 로 표시되어 있지만 실제는 Yv 로 표시해야 정확히 [EDI] 의미가 되지요. 2004년 판에는 Yv 로 되어 있네요. 또한 명령어 자체에 rAX 에 값을 입력하라는 의미가 내포되어 있으므로 Disassembly 코드에서 rAX 는 생략해 버리는 군요.

      역시 SCAS 명령의 설명을 찾아보면 아래와 같습니다.

      "Note that the documentation provided by this form can be misleading. That is, the memory operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword) but it does not have to specify the correct location. The location is always specified by ES:(E)DI."

      즉, Operand 의 크기가 중요하고 무조건 EDI 로 정해진다라고 되어 있지요.

      이런 문제들이 공통적으로 Operand 의 Addressing Method 가 X/Y 형식인 경우 발생하게 됩니다.

      말씀하신 대로 이런 내용을 잘 염두에 두고 Disassembly 코드를 만들어야 할것 같습니다. (참고로 AF Opcode 에 대해서 OllyDbg 와 WinDbg 가 동일한 Disassembly 코드를 만들어 내는 것을 확인했습니다.)

      감사합니다.

  7. 춤매 2011.01.07 22:40 신고 댓글주소 | 수정 | 삭제 | 댓글

    님 블로그를 가끔씩 눈팅하는데,
    책을 쓰실 정도로 실력도 있으신데 겸손하신 면도 있으시고..
    존경스럽습니다..

    • reversecore 2011.01.11 10:51 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      존경이라고 말씀하시면 제가 넘 부끄럽구요.

      책은 태어나서 첨으로 겁없이 도전하는 거랍니다.

      책을 쓰는 지금의 고통을 미리 알았더라면, 좀 더 신중하게 생각했을 겁니다. ^^

      감사합니다.

  8. 오늘도 2011.01.13 18:40 신고 댓글주소 | 수정 | 삭제 | 댓글

    좋은 책 빨리 부탁 드립니다.

  9. blackrus 2011.02.22 23:52 신고 댓글주소 | 수정 | 삭제 | 댓글

    제 싸이에 글좀 퍼가겠습니다 ㅠㅠ..
    실례가된다면 바로말씀해주세요
    물론 출처는 남기겠습니다 ㅎ

  10. blackrus 2011.02.25 00:23 신고 댓글주소 | 수정 | 삭제 | 댓글

    아 넵 ㅠ
    죄송합니다 ㅠ
    바로지울께요

  11. 오곡 2012.02.21 21:18 신고 댓글주소 | 수정 | 삭제 | 댓글

    정말 대단하십니다

    Portable Executable 개념을 발표하려고 검색하다가 들어오게 됐는데

    정말 대단하십니다...;;

    리버싱에 중요한 것도 오늘 알게 됐네요 감사합니다 ^^;;

    책 출판하신다고 했는데 꼭 사고 싶네요~

    화이팅~!

  12. 리버서워너비 2014.02.20 21:26 신고 댓글주소 | 수정 | 삭제 | 댓글

    죄송하지만 제가 구글링을 많이해봤는데도 저 위에 그림과 같은 글과 표를 가진 pdf 파일을 찾지 못하였습니다 ㅠㅠ 글쓴이님과 같은 것으로 공부하고싶은 마음때문에 그런데 링크좀 걸어주실수있으신지요.. 아님 만약 가능하다면 sgc109@naver.com 이 메일로 파일을 보내주시면 감사하겠습니다.





티스토리 툴바