ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [x86 vs x64] Memory Address
    System hacking training/Knowledge 2018. 3. 19. 22:18

    오늘은 x86과 x64에 대해 전반적으로 정리를 하겠다.


    추후 x86의 BOF, RTL, ROP 등 64 bit환경에서의 공격 기법에 대해서도 포스팅하겠다.


    x86 vs x64하면 가장 먼저 떠오르는 것은 메모리 주소 체계일것이다.


    x86의 메모리 주소 체계는 이러하다.


    [x86] Memory Address (windows 기준)


    0x0000 0000 - 0xffff ffff


    0x0000 0000 - 0x7fff ffff (User Section, Ring3)

    0x8000 0000 - 0xffff ffff (Kernel Section, Ring0)


    0x0000 0000 부터 0xffff ffff 까지 사용할 수 있는 주소 공간이 있고,

    이는 unsigned int의 범위 0 ~ 4294967295와 동일하다.

    (따라서 32bit computer에서 0 ~ 4294967295까지 사용할 수 있는 주소 공간이 있다.)


    바로 x64의 메모리 주소 체계에 대해 알아보자.


    x64의 메모리 주소 체계는 이러하다.


    [x64] Memory Address


    0x0000 0000 0000 0000 - 0xffff ffff ffff ffff


    0x0000 0000 0000 0000 - 0x0000 7fff ffff ffff (User Section, 48bit)

    0xffff 8000 0000 0000 - 0xffff ffff ffff ffff (Kernel Section)


    이 둘을 비교했을 때 조금 다른 점이 보인다.


    64bit 메모리 주소 체계임에도 User Section에서 앞의 2byte (16bit)를 사용하지 않는것이다.


    이는 주소를 계산하는데 필요없는 시간이 낭비가 되기 때문에 사용하지 않는다.

    x86에서 x64로 넘어오면서 2배의 주소공간을 가지게 되었지만

    그정도의 주소공간을 필요로 하는 프로그램은 아직은 없기 때문에 앞의 2byte를 사용하지 않는다.


    그리고

    0x0000 7fff ffff ffff 에서 7이 8로 넘어갈때 (Kernel Section)

    운영체제에서는 바로 앞의 4byte 0x0000를  0xffff 로 세팅하여

    0xffff 8000 0000 0000가 Kernel Section이 된다.


    따라서

    64bit 주소체계에서는 User Section은 16bit를 제외한 48byte를 사용하게 된다. 




    자, 이제 x86 bof와 x64 bof의 차이점을 알아보자.


    예를 들어



    이런 스택 구조를 가진 바이너리가 존재한다고 하자.

    (여기서 SFP는 제외한다.)

    여기서 offset은 0x100이고, bof를 하기 위해서 buf를 0x100 byte 채우고, ret를 우리가 원하는 주소로 덮어주면 된다.


    따라서 페이로드를 구성하면 이와같다.


    [x86 bof] vs [x64 bof]


    <x86 bof> : stack의 크기 4byte

    payload = "A" * 0x100 + "변조할 return address (4 byte)"



    <x64 bof> : stack의 크기 8byte

    payload = "A" * 0x100 + "변조할 return address (6 byte)"


    32bit 와 64bit 주소체계에서 bof를 하기 위해 어떻게 다른지 대충 보일것이다.


    return address 부분을 보면 6 byte를 덮어줘야된다는 것이 보이는데


    만약 x86에서 bof 할때 처럼 생각하여 return address 부분에 8byte 를 덮어준다면

    segmentation fault가 뜨는것은 당연할 것이고, core를 분석해보면 주소가 제대로 들어가지 않은것을 확인 할 수 있는데


    이는 User Section 즉, 우리가 사용할 수 있는 주소중 가장 큰 주소가 0x0000 7fff ffff ffff 임에도 불구하고

    더 큰 주소의 범위로 이동하려 하였기때문이다.

    (예를 들어 BBBBBBBB로 덮어쓴다고 가정하면 0x4242424242424242로 덮어지기 때문에 위의 User Section의 주소범위를 벗어날 것이다.)


    x64 bof에 대한 자세한 내용은 따로 포스팅을 할 예정이다.


    일단은 x86에서와 다르게 x64에서는 주소가 6byte가 들어가야 bof가 성공한다는 것까지만 알고 넘어가자




    이번에는 스택과 레지스터에 대해 알아보자


    x86과 x64의 스택은 이러한 차이를 보인다.


    스택 한칸의 크기가 x86은 4byte이고, x64는 8byte라는 차이가 있다.


    이는 곧 레지스터 또한 x86은 4byte, x64는 8byte라는 것을 의미하는데


    AX를 예로들면



    AX 는 AL 과 AH로 이뤄져있고, 총 16byte이다.

    여기서 더 확장된 개념이 EAX인데 2배로 커졌다.

    RAX역시 EAX에서 2배 커졌기 때문에 총 RAX는 64bit의 크기를 가진다.




    마지막으로 함수 호출 규약에 대한 차이는

    x86은 Cdecl과 Fastcall을 혼용하여 사용하는 반면

    x64는 Fastcall만을 사용한다는 점이 다르다.


    이에 따라 함수의 인자를 Cdecl에서는 스택을 이용하여 push하여 넘겨주는 반면

    Fastcall은 레지스터를 이용하여 mov하여 넘겨주는 차이가 있다.


    하지만 Fastcall에서도 인자를 넘길때 6개보다 인자가 많으면 스택을 이용한다는 점은 참고해야한다.


    이상 x86과 x64의 기본적인 차이에 대해 알아보았다.

    반응형

    'System hacking training > Knowledge' 카테고리의 다른 글

    FPO (Frame Pointer Overflow)  (0) 2018.04.26
    x64 BOF(Buffer Overflow)  (0) 2018.04.18
    ELF Memory Protection - RELRO  (2) 2018.03.07
    ELF Technique - ROP  (2) 2018.03.05
    ELF Technique - GOT Overwrite  (0) 2018.02.28
Designed by Tistory.