일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 신경망
- 아파치
- 백준
- C언어
- 역전파
- 우분투
- 기울기
- AdaGrad
- Apache2
- flag
- 소프트맥스 함수
- 책
- Python Challenge
- PostgreSQL
- PICO CTF
- CTF
- 신경망 학습
- picoCTF
- 오차역전파법
- PHP
- 코딩
- 딥러닝
- 순전파
- Python
- 설치
- 리뷰
- 파이썬
- FastAPI
- HTML
- sgd
- Today
- Total
Story of CowHacker
어셈블리 chapter 2 본문
이번 글에서는 어셈블리의 기본 문법을 직접 실습해보는걸 쓸것이다.
먼저 이 실습을 하기 위해서는 32Bit의 운영체제가 준비 돼있어야한다.
일단 hello.asm라는 제목으로 vim파일을 하나 만든다.
nasm 이라고 the Netwide AsSeMbler라는 뜻을 가진 명령어를 쓴다. nasm -f의 옵션은 출력파일형식 설정을 하는 것이다. 뒤에 elf32는 파일 형식을 32bit로 출력 파일을 설정한다는 것이고 -g는 앞에 -felf32의 옵션을 디버깅 정보로 설정 해준다는 옵션이다.
그다음 ;를 써 명령어를 이어서 gcc ( GNU Compiler Collection ) 를 써줫다. -m32옵션은 hello.o 파일을 32bit로 컴파일 한다는 것이고 -o옵션은 앞에 오브젝트된 파일인 .o파일을 실행 파일인 hello.out 파일로 만들어주는 것이다.
정상적으로 컴파일된 파일이 만들어진걸 확인할수 있다.
gdb로 한번 hello.out 파일을 열어볼거다. 명령어는 gdb 파일명.out이다.
disassemble main 명령어로 gdb환경에서 main을 확인해본다.
레지스터 위치를 보기위해선 일단 프로그램이 실행이 된 상태여야 한다. 먼저 break main ( 약자로 b main으로 써줘도 된다. ) 명령어로 main문에 break를 걸어주고 나서 run을 쳐 실행후 다음 info reg 명령어로 확인 한다.
info reg로 레지스터 위치를 확인한다. 지금은 아직 젤 처음 구문인 push명령어를 실행하기 전단계에 위치 해있다.
일단 push eax의 명령어를 실행하기전에 스택 값을 먼저 본다. 그 이유는 스택의 변화값을 확인하기 위함인데 push eax;을 해석하면 eax의 값을 스택에 넣는다 라는 것이기에 넣기 전, 후 스택값을 확인해야하기 떄문이다.
ni 명령어를 통해 push의 구간을 실행한후 레지스터의 위치를 확인해본다.
push명령어가 실행된후 스택의 값을 확인해보니 eax의 값이 들어간걸 확인할수있다.
다음은 add의 기능을 확인해볼 꺼다 일단 ni 명령어를 통해 첫번쨰 add가 실행된걸 확인해본다.
아까 첫번쨰 add가 일어나기전 eax의 값은 b7fbcdbc였는데 지금은 거기에 10을 더한 b7fbcdc6인걸확인할수 있다.
한번 계산기를 로 10진수로 확인해본다.
바뀐 값도 같이 10진수로 확인해본다.
두개의 값을 빼보면 10이 나오는걸 확인할수있다.
다음 ni 명령어를 통해 두번쨰 add를 실행한후 레지스터 위치를 확인한다.
두번쨰 add를 한 값을 10진수로 확인해본다.
두번쨰 add한 값에서 전값을 뺴면 또 10이 나오는걸 확인할수있다.
이까지 add의 실행 과정을 확인해봤다.
다음 sub명령을 실행한후 레지스터 위치를 확인해본다.
한번 eax의 값을 확인해본다. 지금 b7fbcdcb로 바뀐걸 확인할수있다.
바뀐 값을 10진수로 확인해보니 3,086,732,747이다.
sub로 5를 뻇으니 당연히 5가 나오는것이 맞다.
mov를 한후 레지스터 위치를 확인한다.
여기서 x/x로 ebx의 값을 확인하니 Cannot access memory at address라는 구문이 보여 p/x 구문으로 확인을해보았다.
나중에 x/x 와 p/x 부분을 따로 한번 알아볼 예정이다. 간단히 하면 p : 변수 , x : 주소 이다 그리고 / 뒤 x는 16진법으로 본다는 것이다.
mov가 실행 되기전 ebx의 값은 0x0 인걸로 보인다.
mov 가 실행되고 난후 ebx의 값은 eax의 값으로 된걸 볼수있다. 지금은 eax의 값과 ebx의 값이 같아 push를 해도 차이점이 보이지 않는다... 끝부분에 바뀐 값으로 다시 실습하는 과정을 넣었다.
다음 push를 하기에 앞써 eax의 값을 확인한다.
스택의 값은 지금 b7fbcdbc인걸로 확인한다.
push를 한후 esp의 값을 보면 eax의 값이 들어간걸 알수있다.
inc를 하기전 eax의 값을 본다. 지금은 b7fbcddf인걸로 확인할수 있다.
inc를 실행후 eax값을 확인한다. 바뀐값을 빼기 해보면 1이 나오는걸 알수있다.
즉, inc의 명령어 대로 값을 1 올렸다는 얘기가 된다.
이번에는 dec를 실행후 eax의 값을 본다. 아까 inc를 하기전 값이 그대로 나온걸 확인할수있다.
이로써 dec실습까지 해보았다.
아까 lea할때 ebx와 eax가 값이 같아 차이가 없었던걸 지금은 ebx에 20 ( 10 진수 ) 을 더한후 lea를 해보는 과정이다 lea를 하기전 ebx와 eax 의 값을 본다.
lea실행후 eax의 주소가 바뀐걸 확인할수 있다.
'공부 > 어셈블리@_@' 카테고리의 다른 글
어셈블리 chapter 1 (0) | 2020.06.01 |
---|