(gdb) info reg

모든 register 정보 확인

 

 

(gdb) info reg $rsp

rsp의 register 정보 확인

 

 

(gdb) x/t $rsp

2진수로 register rsp의 메모리 확인

 

 

(gdb) x/o $rsp

8진수로 register rsp의 메모리 확인

 

 

(gdb) x/o 0x00000000004005bd

8진수로 메모리주소로 메모리확인

 

 

(gdb) x/d $rsp

10진수로 register rsp의 메모리 확인

 

 

(gdb) x/u $rsp

unsigned 10진수로 register rsp의 메모리 확인

 

 

(gdb) x/x $rsp

16진수로 register rsp의 메모리 확인

 

 

(gdb) x/c $rsp

문자열로 register rsp의 메모리 확인

 

 

(gdb) x/f $rsp

부동소수점으로 register rsp의 메모리 확인

 

 

(gdb) x/s $rsp

문자열로 register rsp의 메모리 확인

 

 

(gdb) x/bx $rsp

1byte 단위로 메모리 확인

 

 

(gdb) x/hx $rsp

2byte 단위로 메모리 확인

 

 

(gdb) x/wx $rsp

4byte 단위로 메모리 확인

 

 

(gdb) x/gx $rsp

8byte 단위로 메모리 확인(64bit 환경)

 

 

(gdb) x/10gx $rsp

현재 명령어 이후로 8byte 단위로 10개의 메모리 확인(64bit 환경)

 

 

 

 

출처 :

blog.naver.com/kjycracker/221677591285

'Reverse Engineering > gdb' 카테고리의 다른 글

lea, and, or, xor 명령어  (0) 2020.10.10
sub, add 명령어  (0) 2020.10.10
gdb - Segmentation Fault, 대괄호 [ ]  (0) 2020.10.07
gdb 명령어, 리틀엔디언 방식  (0) 2020.10.07
gdb 실행, 명령어  (0) 2020.10.07

lea 명령어와 mov 명령어 비교

[어셈블리어]

global main

section .text 
main: 
        mov     eax, 1 
        mov     ebx, 4 
        mov     ecx, 7 
        lea       eax, [eax+ecx] 
        lea       ebx, [ebx*4] 
        mov     eax, [eax+ecx]

 

 

- lea 명령어는 [ ] 대괄호 안의 값(여기서는 연산값)을 상수값으로 레지스터로 그대로 전달한다.

lea       eax, [eax+ecx]   결과.

 

<eax 값 출력>          

                               (16진수)  (10진수)

info reg $eax     :           0x8          8

 

 

lea       ebx, [ebx*4]   결과. 

 

<ebx 값 출력>

                               (16진수)  (10진수)

info reg $ebx     :           0x10         16

 

 

- mov 명령어는 [ ] 대괄호 안의 값(여기서는 연산값)을 주소값으로 보고 그 주소값에 있는 값을 레지스터로 전달한다.

mov     eax, [eax+ecx]   결과.

 

<ecx 값 출력>                 

info reg $ecx     :        

[ ] 대괄호 안의 값은 eax+ecx 즉, 8+7 = 15  16진수로 F다.

이를 주소형식으로 표현하면 0x0000000F 가 되는데

이 0x0000000F 주소값에 있는 값을 레지스터(ecx)로 전달하게 된다는 말이다.

 

하지만, 이 주소는 의미없는 주소이고 접근할 수 없는 주소다. 그래서 값이 제대로 출력되지 않는다.

 

 

and, or, xor 명령어

[어셈블리어]

global main

section .text
main:
        mov     eax, 0x33
        mov     ebx, 0x55
        mov     ecx, 0x42

        and     eax, ebx
        or       eax, ecx
        xor     eax, 0xac 

 

(16진수)         (2진수)

  0x33          00110011 

  0x55          01010101

  0x42          01000010

  0xac          10101100

 

 

and      eax, ebx   결과.

 

<eax 값 출력>         

                               (16진수)     (10진수)

info reg $eax     :           0x11          17

 

   00110011      (eax)

& 01010101      (ebx) 

   00010001          ->     17 (10진수)    0x11 (16진수)

 

 

 

 

or      eax, ecx   결과.

 

<eax 값 출력>         

                               (16진수)     (10진수)

info reg $eax     :           0x53          83

 

   00010001      (eax)

|  01000010      (ecx) 

   01010011          ->     83 (10진수)    0x53 (16진수)

 

 

 

 

xor      eax, 0xac   결과.

 

<eax 값 출력>         

                               (16진수)     (10진수)

info reg $eax     :           0xff          255

 

   01010011      (eax)

^ 10101100      (0xac) 

   11111111         ->     255 (10진수)    0xff (16진수)

 

 

 

'Reverse Engineering > gdb' 카테고리의 다른 글

gdb) 레지스터 값, 메모리값 확인 명령어  (0) 2020.11.20
sub, add 명령어  (0) 2020.10.10
gdb - Segmentation Fault, 대괄호 [ ]  (0) 2020.10.07
gdb 명령어, 리틀엔디언 방식  (0) 2020.10.07
gdb 실행, 명령어  (0) 2020.10.07

sub 명령어

[어셈블리 코드]

main:

            mov      eax,  esp                                    (1)

            sub       esp,  8                                        (2)

            mov      [eax],  dword 1                          (3)

            mov      [eax-4],  dword 2                       (4)

            sub       [eax-4],  dword 1                       (5)

 

[스택 주소]

(시작)

 

high

 

bffff0a0                       <-  esp                     처음엔 esp가 최상단 주소를 가리키고 있음.

bffff09c

bffff098

 

low

 

 

(1)        mov      eax,  esp   

 

high

 

bffff0a0                       <-  esp                     

                                 <-  eax                      esp가 가리키는 주소를 eax에도 할당.

bffff09c

bffff098

 

low

 

 

(2)        sub       esp,  8

 

high

 

bffff0a0                       <-  eax

bffff09c

bffff098                       <-  esp                       sub 명령어를 통해 esp가 가리키는 주소를 8만큼 내린다(빼준다).

                                         (즉, 주소 공간을 2개 만큼 아래로 확보한다는 말? 각 주소는 4크기 만큼의 차이가 있다.)

low

 

 

(3)        mov      [eax],  dword 1

 

high

 

bffff0a0                       <-  eax

bffff09c

bffff098                       <-  esp                     

 

low

 

 

<주소값 출력>

bffff0a0   :         0x00000001                           eax가 가리키는 주소에 1 값 할당.

                                             (dword는 4바이트이므로 주소 크기에 맞게 4바이트 만큼 확보하고 1값을 할당한 것.)

 

 

(4)        mov      [eax-4],  dword 2

 

high

 

bffff0a0                       <-  eax

bffff09c

bffff098                       <-  esp                     

 

low

 

 

<주소값 출력>

bffff09c   :         0x00000002                eax가 가리키는 주소(bffff0a0)에 4 만큼 뺀(내려간) 주소(bffff09c)에 2 값 할당.

                                             (dword는 4바이트이므로 주소 크기에 맞게 4바이트 만큼 확보하고 2값을 할당한 것.)

 

 

(5)        sub       [eax-4],  dword 1 

 

high

 

bffff0a0                       <-  eax

bffff09c

bffff098                       <-  esp                     

 

low

 

 

<주소값 출력>

bffff09c   :         0x00000001       

 

                                    eax가 가리키는 주소에 4 만큼 뺀(내려간) 주소(bffff09c)의 값(0x00000002)에서 1만큼을 sub

                                   (dword는 4바이트이므로 주소 크기에 맞게 4바이트 만큼 확보하고 1값을 뺸 것.)

 

 

add 명령어

[어셈블리 코드]

main:

            mov      eax,  esp                                    (1)

            add       esp,  8                                        (2)

            mov      [eax],  dword 1                          (3)

            mov      [eax+4],  dword 2                       (4)

            add       [eax+4],  dword 1                       (5)

 

[스택 주소]

(시작)

 

high

 

bffff0a8

bffff0a4

bffff0a0                       <-  esp                     처음엔 esp가 최상단 주소를 가리키고 있음.

bffff09c

bffff098

 

low

 

 

(1)        mov      eax,  esp   

 

high

 

bffff0a8

bffff0a4

bffff0a0                       <-  esp                     

                                 <-  eax                      esp가 가리키는 주소를 eax에도 할당.

bffff09c

bffff098

 

low

 

 

(2)        add       esp,  8

 

high

 

bffff0a8                       <-  esp

bffff0a4

bffff0a0                       <-  eax

bffff09c

bffff098                                               

 

low

 

 

                                             add 명령어를 통해 esp가 가리키는 주소를 8만큼 올린다(더한다).

                                            (즉, 주소 공간을 2개 만큼 위로 확보한다는 말? 각 주소는 4크기 만큼의 차이가 있다.)

 

 

(3)        mov      [eax],  dword 1

 

high

 

bffff0a8                       <-  esp

bffff0a4

bffff0a0                       <-  eax

bffff09c

bffff098                                            

 

low

 

 

<주소값 출력>

bffff0a0   :         0x00000001                           eax가 가리키는 주소에 1 값 할당.

                                             (dword는 4바이트이므로 주소 크기에 맞게 4바이트 만큼 확보하고 1값을 할당한 것.)

 

 

(4)        mov      [eax+4],  dword 2

 

high

 

bffff0a8                       <-  esp

bffff0a4

bffff0a0                       <-  eax

bffff09c

bffff098                       

 

low

 

 

<주소값 출력>

bffff0a4   :         0x00000002             eax가 가리키는 주소(bffff0a0)에 4 만큼 더한(올라간) 주소(bffff0a4)에 2 값 할당.

                                             (dword는 4바이트이므로 주소 크기에 맞게 4바이트 만큼 확보하고 2값을 할당한 것.)

 

 

(5)        add       [eax+4],  dword 1 

 

high

 

bffff0a8                       <-  esp

bffff0a4

bffff0a0                       <-  eax

bffff09c

bffff098                                      

 

low

 

 

<주소값 출력>

bffff0a4   :         0x00000001       

 

                                eax가 가리키는 주소에 4 만큼 더한(올라간) 주소(bffff0a4)의 값(0x00000002)에서 1만큼을 add

                                   (dword는 4바이트이므로 주소 크기에 맞게 4바이트 만큼 확보하고 1값을 더한 것.)

 

 

 

 

 

gdb 명령어) 

 

PUSH : 스택에 데이터를 삽입

 

ex) push word

     push dword

     push word

 

• push 명령어는 자동으로 ESP를 4 바이트 감소 시킴

 

 

 

POP : 스택에서 데이터를 꺼냄(현재 위치한 스택인듯?)

 

ex) pop eax

     pop ebx

 

• 스택에서 4 바이트를 꺼내와 지정한 레지스터에 삽입

• pop 명령어는 자동으로 ESP를 4 바이트 증가 시킴

 

 

 

 

Segmentation Fault

이 프로그램( a.out )을 실행하면 어떤 결과가 나올까요? Segmentation Fault

 

 

Segmentation Fault

 

• 프로그램이 허용되지 않은 메모리 영역에 접근을 시도하거나, 잘못된 방법으로 메모리 영역에 접근을 시도할 경우 발생한다.

 

 

발생 이유)

 

프로그래머가 생각하지 못한 사용자 입력값이 있었다?

• 그냥 프로그램을 잘못 짰다

• 프로그램에 문제가 있다는 의미

 

 

즉, 끝맽음을 제대로 하지 않은 것이다.

 

프로그램의 끝은 시스템 콜을 이용해야 함.

 

 

 

시스템 콜

<system calls list>

 

 

system calls list에 의하면,

 

eax 에 들어가는 값 1이 함수 코드번호이고 1번은 exit함수를 뜻한다.

ebx 에 들어가는 값 0은 인자로 들어가는 값이다.

 

즉, C언어 코드로 해석하면 exit(0)란 의미이다.

따라서 프로그램을 종료하겠다는 의미가 된다.

 

 

결국 이 프로그램( a.out )이 이제는 정상적으로 종료된다.

 

 

 

 

대괄호 [ ]의 사용.

 

어셈블리언어에서 대괄호( [ ] )는 포인터를 의미한다. 즉, 해당 값이 가리키는 주소를 의미한다.

 

 

위 코드에서의 사용 예를 보면,

mov      dword  [ebx],   0x10

 

16진수 0x10이라는 값을 ebx가 가리키는 주소에 4바이트 크기(dword)의 공간에다 넣어라. 하는 의미가 된다.

'Reverse Engineering > gdb' 카테고리의 다른 글

lea, and, or, xor 명령어  (0) 2020.10.10
sub, add 명령어  (0) 2020.10.10
gdb 명령어, 리틀엔디언 방식  (0) 2020.10.07
gdb 실행, 명령어  (0) 2020.10.07
gdb at&t 방식을 intel 방식으로 바꾸기  (0) 2020.10.07

q

: gdb 종료

 

r(run)

: 실행

 

 

주의)

b main+7                       이렇게 쓰면 gdb에서 'main+7' 자체를 함수로 인식해버린다. 저러한 함수는 없기에 제대로 실행 안됨.

b *main+7                     그래서 이렇게 main 앞에 *를 써주면, 나는 main에 break point를 두고 싶은데 main 함수에서 +7번째에 있는 부분에 break point를 두고싶다. 라는 의미로 적용되어 원하는 대로 사용 가능하다.

 

 

 

 

 

 

gdb 는 리틀 엔디언 방식.

 

x/x 사용 예)

 

x/bx   $esp   1바이트(byte) 단위로 출력하겠다.

 

x/4bx   $esp   1바이트(byte) 단위로 4번째 까지 출력하겠다.

 

x/wx   $esp   1워드(word) 단위로 출력하겠다. 즉, 4바이트 단위로 출력하겠다. (1워드 = 4바이트)

 

x/4wx   $esp   1워드(word) 단위로  4번째 까지 출력하겠다. 즉, 4바이트 단위로  4번째 까지 출력하겠다.

(1워드 = 4바이트)

 

( 사용 후 마지막으로 출력한 방식으로 계속 출력되므로 ( x/x 출력 할 때.)  다시 본래의 출력 방식인 4바이트 단위 출력으로 돌리려면 x/4wx 로 출력을 다시 해주면 된다. ) 

 

 

gdb 는 리틀 엔디언 방식이어서,

0x12345678이 0x78  0x56  0x34  0x12  순서로 뒤에 값 부터 출력 되는 것을 볼 수 있다.

'Reverse Engineering > gdb' 카테고리의 다른 글

lea, and, or, xor 명령어  (0) 2020.10.10
sub, add 명령어  (0) 2020.10.10
gdb - Segmentation Fault, 대괄호 [ ]  (0) 2020.10.07
gdb 실행, 명령어  (0) 2020.10.07
gdb at&t 방식을 intel 방식으로 바꾸기  (0) 2020.10.07

 

 

1. 이전에 어셈블리 코드로 만든 eaxm1-1.asm 파일을

 

목적코드 파일(오브젝트 파일)로 생성( .o 파일 )한다.

ex) nasm -f elf32 exam1-1.asm

 

exam1-1.o 목적코드 파일로 생성된다.

 

 

 

2. 목적코드 파일을 링크하여 실행파일( . exe 파일 )로 만들어 실행가능한 파일로 만들어준다.ex) ld --entry main exam1-1.o

 

a.out 이라는 실행파일이 생성된다.

( 실행파일 이름은 다른 이름으로 생성할 수도 있다. )

 

 

3. 생성된 a.out 실행파일을 gdb로 실행한다.

 

 

gdb 실행

: gdb -q a.out

-q 옵션) quite 옵션. gdb를 실행하실때 뜨는 안내문을 생략하고 gdb를 실행하는 옵션

 

 

 

 

gdb 명령어)

 

disas main

: main 의 것들을 디스어셈블해 보여주겠다.

 

x/x      <-  data 출력.                ex) x/x   $esp

                                                x/4x   $esp

                                                x/x   0xbffff098

x/s      <-  string 출력.

 

x/i       <-  instruction 출력.          ex) x/i   0x08048060

                                                  x/4i   0x08048060

 

break 명령어 : b                 

ex) b main

 

ni(next instruction) 명령어

: 다음 주소로 넘어간다.

 

info reg

: 해당 레지스터의 정보 값을 확인하겠다.

ex) info  reg  $esp

     info  reg  $eax

 

'Reverse Engineering > gdb' 카테고리의 다른 글

lea, and, or, xor 명령어  (0) 2020.10.10
sub, add 명령어  (0) 2020.10.10
gdb - Segmentation Fault, 대괄호 [ ]  (0) 2020.10.07
gdb 명령어, 리틀엔디언 방식  (0) 2020.10.07
gdb at&t 방식을 intel 방식으로 바꾸기  (0) 2020.10.07

+ Recent posts