어셈블리어와 악성코드

스택(Stack), PUSH, POP

YaluStar 2018. 11. 20. 10:12

스택(Stack), PUSH, POP



스택(Stack)

나중에 들어온 것이 먼저 나간다LIFO(Last In First Out) 방식입니다.

먼저 들어온 것이 나중에 나가는 FILO(First In Last Out) 방식이라고도 할 수 있습니다.

말의 차이일 뿐 크게 신경쓸 필요는 없습니다.


스택데이터를 넣는 것을 PUSH, 스택에서 값을 빼는 것을 POP이라고 하며, 일반적으로 TOP으로 명명되는 현재 스택 포인터가 사용됩니다.


PUSH가 될 때마다 스택 포인터가 하나씩 증가되고 POP이 될 때마다 스택 포인터가 하나씩 감소합니다.





실습 환경

VMware Workstation 15 Player (FREE 버전)

Windows XP Professional SP3 (32Bit)


CMD창을 열어 debug 명령어를 입력합니다.

-a 100

:0100 JMP 0106

:0102 MOV AX, 0002

:0105 RET

:0106 MOV AX, 0001

:0109 CALL 0102

:010C CMP AX, 0002





JMP 0106 명령어0106 주소로 이동합니다.

MOV AX, 0001 명령어가 먼저 실행되어 AX=0001이 되고 이어서 CALL 0102 명령어가 실행됩니다. 이 때 SP 레지스터의 값이 FFEE 였는데, CALL 명령어를 수행하면 SP=FFEC로 변경됩니다. 그리고 0102 주소로 이동하게 됩니다.


SP=FFEC로 값이 감소하게 되는 이유는 CALL 명령어를 수행하게 되면 나중에 CALL 명령어의 수행을 완료한 후에 돌아오기 위한 Return 주소 값을 메모리에 저장하기 때문에 SP의 값이 감소하게 됩니다.


0102 주소로 이동한 후 MOV AX, 0002 명령어를 수행하여 AX=0002 값이 됩니다.





이어서 RET 명령어를 통해 CALL 함수의 다음 명령어가 있는 위치로 나오게 됩니다.

이 때 CALL 함수 실행 전에 메모리에 저장했던 Return 주소 값을 추출하게 되어 바뀌었던 SP=FFEC의 값이 다시 SP=FFEE 값으로 돌아오게 됩니다.

그리고 CALL 명령어 다음에 있던 010C 주소에 있는 CMP AX, 0002 명령어를 실행하게 됩니다.




실행 순서를 정리하면 JMP 0106 -> MOV AX, 0001 -> CALL 0102 -> MOV AX, 0002 -> RET -> CMP AX, 0002가 됩니다.





PUSH (Push on Stack)

스택에 값을 넣는다.

ESP의 값이 4만큼 줄어들고 이 위치에 새로운 값이 채워진다.


사용하는 양식총 6가지가 있습니다.

PUSH reg16

PUSH mem 16

PUSH imm16

PUSH reg32

PUSH mem32

PUSH imm32




POP(Pop from Stack)

ESP 레지스터가 가리키고 있는 위치의 스택 공간에 4Byte 만큼을 Destination 피연산자에 복사하고 ESP 레지스터의 값에 4를 더합니다.


사용하는 양식은 PUSH와 거의 같지만 상수를 사용하지는 않습니다.

POP reg16

POP mem16

POP reg32

POP mem32



실습 환경

VMware Workstation 15 Player (FREE 버전)

Windows XP Professional SP3 (32Bit)


CMD창을 열어 debug 명령어를 입력합니다.

-a 100

MOV AX, 1234

MOV BX, 5678

PUSH AX

PUSH BX

POP AX

POP BX





MOV 명령어로 AX와 BX에 각각 1234, 5678 값을 넣어줍니다.

그리고 PUSH AX 명령어를 통해 AX에 들어있는 1234 값을 스택에 저장합니다.

스택에 저장하게 되어 SP의 값이 FFEE에서 FFEC로 감소하였습니다.

이어서 PUSH BX 명령어도 사용하여 BX에 들어있는 5678 값도 스택에 저장합니다.






BX의 값을 스택에 저장하여 SP의 값이 FFEA로 감소합니다.


이번에는 POP을 이용하여 스택에 저장되어 있는 값을 추출해보겠습니다.

POP AX 명령어를 이용하여 마지막에 저장했던 BX의 5678값이 추출이 되어 AX=5678로 값이 변경됩니다.

스택에서 값이 빠져나감으로써 SP의 값이 FFEC로 증가합니다.

한번더 POP BX 명령어를 이용하였더니 처음에 스택에 저장한 1234 값이 추출이 되어 BX=1234로 변경됩니다.

스택포인트(SP) 값도 처음 상태인 FFEE 값으로 돌아옵니다.







이상으로 스택(Stack), PUSH, POP에 대하여 알아보았습니다.

감사합니다.


반응형