==================================Outline====================================
함수의 호출과 작동 원리
----------------------------------------------------------------------------
'Initialize'라는 함수를 만들 수 디버깅 모드를 활용하여 각 레지스터들의 변화를 살펴보자.
우선 살펴보아야 할 메모리의 주소 값들을 보존시켜둔다.
EIP = 0040103E
ESP = 0012FF8C
ESP - 10h = 0012FF7C(스택 레지스터의 변화를 알아보기 위한 설정이다)
Initialize = 00401010
함수 호출
EIP는 명령어를 가리키는 레지스터이다. 00401043h 주소로 이동하면 ‘Initialize’의 주소로 이동하게 된다.
'call Initialize'를 해석 아래와 같다.
push ‘return address'(eip)
jmp Initialize
ret은 개념상 아래와 같다.
pop eip
eip에 간접적으로 값을 넣을 수 있는 방법은 두 가지인데 ‘call' 혹은 ’ret'명령어를 사용하는 것이다.
//cracking - 조건문을 조작하여 eip를 원하는 위치로 점프 시킨다.
return문 다음에 숫자를 적을 수도 있다. 이 경우는 나중에 배운다.
‘PUBLIC’ 명령어를 사용하면 다른 파일에서 접근이 가능해진다.
'PUBLIC'을 사용하지 않으면 기본적으로 외부에서 접근이 불가능하다.
‘extern’ 다른 파일에서 만들어진 함수를 호출하는 기능을 한다.
'NEAR32'는 4giga byte내에 코드가 존재한다는 뜻이다.
스택을 사용하는 변수들(지역변수들)
//6.3까지 배우고 나서부터는 C언어와 혼용하여 어셈블리를 배운다.
C에서는 함수를 사용할 때 인자를 입력하여 그 값을 달리하는 것이 가능하였다. CPU레지스터에는 용량의 한계가 있기 때문에 stack을 활용하면 된다. ARM core를 사용할 때 함수의 인자 4개 이상 만들게 되면 메모리에 값을 넣어야 하기 때문에 속도가 느려진다.
_stdcall: 함수의 인자를 좌측에서 우측으로 스택에 쌓는다.
_cdecl: 함수의 인자를 우측에서 좌측으로 쌓는다.(기본)
//주소보안 옵션 해제 - /DYNAMICBASE:NO
//asm파일 생성 옵션 - /Fa
//makfile에서 ‘@’은 명령어를 화면 창에 표시하지 않는 것이다.
push 300 ; 0000012cH
push 200 ; 000000c8H
push 100 ; 00000064H
call _smart
add esp, 12 ; 0000000cH
300, 200, 100순서임으로 _cdecl 형식임을 알 수 있다.
함수의 호출이 끝나면 stack은 다시 원래의 자리로 돌아와야 한다. 함수 내에 있던 지역변수는 함수가 종료됨으로써 사라지기 때문이다.
_cdecl call에서는 함수를 호출한 함수에서 스택의 값을 되돌려주는 것이다. 반면에 _stdcall은 호출된 함수 자체에서 사용한 변수를 스택에서 삭제한다.
aseeembly에서는 'ret'문을 사용하지 않으면 함수가 종료되지 않는다. C언어에서도 return을 삽입하는 습관을 들이자.
//소스
<main.c> |
'Busan IT > Assembly' 카테고리의 다른 글
pushad를 활용한 레지스터 출력 (0) | 2015.10.12 |
---|---|
Procedure 필수코드, C의 obj파일과 asm의 obj파일 합치기 (0) | 2015.10.06 |
pop, pushad 명령어 (0) | 2015.10.02 |
확장/반복문, Procedures (0) | 2015.10.01 |
조건문의 사용 (4) | 2015.09.30 |