본문 바로가기

Reverse Engineering/Reversing 이론 설명

[MASM] 고급프로시저 (지역변수 선언, 스택 매개변수, 디렉터리)

1. 지역변수
    - 단일 프로시저 안에서 생성, 사용, 소멸되는 변수이다.
    - 지역 변수에 대한 제한된 엑세스는 디버깅할 때 도움을 준다.
    - 지역 벼수들은 메모리를 효과적으로 사용한다.
    - 같은 변수 이름은 이름 충돌을 일으키지 않는 한, 두 개 또는 그 이상의 프로시저들에서 나타낼 수 있다.
    - 지역 변수들은 실행 시 스택에서 생성한다.

LOCAL 디렉티브
    - LOCAL 디렉티브는 하나의 프로시저 내부에서 하나 또는 그 이상의 지역 변수들을 선언한다.
    - PROC 디렉티브 바로 다음 행에 위치해야 한다.
    - 지역 변수 사용시, 어셈블러에 의해 코드 생성 
  
- LOCAL 디렉티브에 의한 지역변수 선언
BubbleSort   PROC
      LOCAL   temp : DWORD, SwapFlag : BYTE
      ret
BubbleSort ENDP

- 어셈블러에 의한 코드 생성
BubbleSort:
      push ebp
      mov   ebp, esp
      add   esp, 0FFFFFFF8h
      mov   esp, ebp
      pop   ebp
      ret    

    - 지역 변수로 어떤 크기의 배열을 생성하려고 하면, 반드시 프로그램을 어셈블하기 전에 충분한 스택 공간을 따로 할당(allocate)해야 한다. 여기서는 [add   esp, 0FFFFFFF8h] 부분으로 이 코드는 [sub   esp, 00000008h] 와 같은 기능을 수행한다. esp에서 0x00000008의 공간을 따로 할당해서 지역변수를 선언하는데 사용한다.

2. 스택 매개변수
   
● argument와 parameter의 차이
    - 인수(argument)는 호출한 프로그램에 의해 프로시저로 전달되는 값이다
    - 매개변수(parameter)는 호출된 프로시저가 받는 값을 말한다.
    - 이 설명으로는 도대체 어떤 차이인지는 모르겠지만, 전달되는 값에 대해서 바라보는 관점에서의 차이인 것 같음.

INVOKE 디렉티브
    - INVOKE 디렉티브는 다중 인수를 전달할 수 있게 하는 Intel의 CALL명령에 대한 보다 더 강력한 대안이다.
    - INVOKE procedureName [,argumentList]
    - argumentList는 프로시저로 전달되는 인수들이 콤마로 분리된 일람이다.
    - CALL 명령은 인수들의 일람을 포함하지 않는다. 
    - INVOKE 디렉티브는 임의 개수의 인수를 허용하며, 각 인수들은 여러 소스 코드 행에 걸쳐 나타낼 수 있다.
   
 유형  
 즉시값
정수 수식
변수명
주소 수식
레지스터 명
ADDR name
10, 3000h, OFFSET myList, TYPE array
(10*20), COUNT
myList, array, myWord, myDword
[myList+2], [ebx+esi]
eax, bl, edi
ADDR myList 

    - ADDR 연산자는 INVOKE 디렉티브를 가지고 프로시저를 호출할 때, 포인터를 전달하기 위해 사용된다. 프로시저 인수로 주소를 전달하는 것을 참조에 의한 전달(passing by reference)이라 한다.

PROC 디렉티브
    - PROC 디렉티브는 매개변수 알람과 프로시저 이름을 선언한다.

PROTO 디렉티브
    - PROTO 디렉티브는 존재하는 프로시저의 프로토타입(prototype)을 만든다.
    - 프로토타입은 프로시저의 이름과 매개변수 일람을 선언한다. [프로시저를 선언한다.]
    - 프로토타입은 프로시저의 정의하기 전에 호출할 수 있게 해준다.
    - MASM은 INVOKE 문장에 의해 호출되는 각 프로시저에 대해 프로토타입을 요구한다.
    - 주의할 사항PROTO 디렉티브는 반드시 INVOKE 디렉티브 이전에 나타나야 한다.
    - 프로시저 순서 : PROTO -> INVOKE -> PROC -> ENDP
    - 단, 프로시저 구현은 INVOKE 문장 이전에 나올 수 있다. 이 경우, PROC 디렉티브는 프로토타입 역할을 한다.

값에 의한 전달 (passing by value; call by value)
    - 변수 값의 복사본이 프로시저로 전달될 때, 이것을 값에 의한 전달이라 한다.
    - 일반적으로, 호출된 프로시저에 의해 값이 변하지 않도록 인수들을 값에 의해 전달한다.
    - 변수의 복사본은 호출하는 프로그램에 의해 스택에 푸시되며, 호출된 프로시저는 스택으로부터 값을 가져와서 그 값을 이용한다.
    - 프로시저가 매개변수를 변경하더라도, 호출하는 프로그램에 있는 대응되는 인수 값에 접근할 수 없다.

참조에 의한 전달 (passing by reference; call by reference)
    - 변수의 주소가 프로시저로 전달될 때, 이것을 참조에 의한 전달이라한다.
    - 호출된 프로시저는 주어진 주소를 통해 변수의 내용을 변경할 수 있다.
    - 프로시저가 변수를 변경할 것으로 예상되는 경우에마, 쓰는 것이 좋다.