프로그램은 실행하면서 많은 함수를 호출한다. 함수가 호출되고 호출받은 함수가 실행되려면 레지스터와 스택을 사용해야 한다. 버퍼오버플로우 공격을 공부하면서 호출된 함수가 어떻게 esp (스택을 관리하는 레지스터)를 백업하는지 어떻게 스택을 독립적으로 사용하는지 알 수 있었다. 이번에는 프로그램의 흐름과 레지스터의 백업을 알아본다.
위의 그림을 보면 main() 함수에서 func() 함수를 호출하였다. main()함수를 콜러(호출함)라고하고 func()함수를 콜리(호출당함)라고 한다.
main()함수는 실행하면서 레지스터를 사용한다. 그리고 func()함수가 모두 실행되고 다시 main()함수로 되돌아왔을 때에 func()가 호출되기 이전의 레지스터의 값을 갖고 있어야 한다. 이 때 콜러가 저장하고 보존되도록 신경써야 하는 레지스터를 caller-saved-register라 하고 callee는 이 레지스터들을 자유롭게 사용할 수 있다.
콜러가 저장하는 레지스터 (caller-saved-register)
콜러가 사용하기전 반드시 백업해야 하는 레지스터, 콜리는 사용 가능
값이 보존되지 않아도 되는 경우는 백업하지 않을수 있다.
값이 보존되지 않아도 되는 경우는 백업하지 않을수 있다.
EAX, ECX, EDX
콜리가 저장하는 레지스터 (callee-saved-register)
콜리가 사용하기전 반드시 백업해야 하는 레지스터, 콜러는 사용 가능
콜리 입장에서는 콜러가 백업을 필요로하는 레지스터가 무엇인지 모르기 때문에 무조건 백업해야한다.
콜리 입장에서는 콜러가 백업을 필요로하는 레지스터가 무엇인지 모르기 때문에 무조건 백업해야한다.
EBX, ESI, EDI, EBP
많은 도움이 되었습니다 감사합니다
답글삭제