본문 바로가기
코스웨어/14년 스마트컨트롤러

2014.08.06 업무보고 출석번호 6번 김용우

by 알 수 없는 사용자 2014. 8. 6.
728x90
반응형

※ 이전에 정리한 Assembly의 마지막 부분을 풀이한 내용이다. 좀더 확실하게 정리를 해보자.


▶아래의 그림을 보면 조금 복잡할 수도 있지만 순서대로 Stack Memory의 내용을 비교해서 보면 쉽게 이해할 수 있다.

→ 먼저 main함수의 EBP를 기준으로 구조체 변수가 생성이 된것을 알 수 있다. 그리고 바로 주소값을 인자로 stst함수를 호출한다.

함수영역으로 가기전에 Stack Memory에 위의 그림과 같이 구조체 Status의 주소값을 저장해둔다. 아래는 main.asm의 소스코드중 일부를 가져온것이다.

Status의 값을 넣는 과정을 첨부했다.

lea eax, DWORD PTR _status$[ebp]            ;_status$ = -20 을 의미

push eax

→ 함수를 호출하면서 return Address값을 Stack메모리에 저장하고 Entry Code로 EBP값을 저장한뒤 ESP값이랑 EBP값을 셋팅해준다.


→ 이제 본격적으로 함수의 내용을 수행하는데 push EBX와 pop EBX를 통해 EBX값을 기억해둔다.


→ 이제 비워둔 EBX의 레지스터에 &status의 값을 저장해두자.(&status의 주소값을 통해서 구조체 안에 있는 변수들에 각각 레지스터의 상태 값을 저장하기위함이다.)


→EAX부터 EDX까지 위의 그림과 같은 방식으로 상태 값을 저장하는데 여기서 문제는 EBX가 현재 주소값을 저장하고 있기때문에 나머지의 값을 저장한뒤 EAX에 push해둔 EBX의 값을 가져와서 저장한뒤에 EBX를 통해서 EBX의 값을 삽입한다.


→이로써 상태 레지스터의 값을 구조체 변수들에 저장을 한뒤 main함수에서 출력하고 프로그램을 종료하는 것이다.




※이번시간에는 pushad로 Stack Memory에 저장된 값을 불러와서 구조체에 저장하는 방식으로 소스코드를 작성해보자.


→앞서 풀이한 내용과 아주 흡사하기 때문에 어렵지 않다. 노트에 메모리의 구조에 대해서 그림을 그려가면서 해보면 아주 쉽게 풀이가 될 것이다.





;procedure structrue example

;Author: Ryuwoo

;Date : 2014.08.06



.386

.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD


PUBLIC _STST


.CODE ; program code


_STST PROC NEAR32

push  EBP ; Entry Code

mov EBP, ESP


;mov EAX, 1

;mov ECX, 2

;mov EDX, 3

;mov EBX, 4

;mov ESI, 5

;mov EDI, 6


pushfd

pushad



mov EAX, [EBP+8] ; EBX에 &status의 값 삽입

mov EBX, [EBP-8] ; EAX

mov [EAX], EBX


mov EBX, [EBP-12] ; ECX

mov [EAX+4], EBX


mov EBX, [EBP-16] ; EDX

mov [EAX+8], EBX


mov EBX, [EBP-20] ; EBX

mov [EAX+12], EBX


mov EBX, EBP ; ESP

add EBX, 4

mov [EAX+16], EBX


mov EBX, [EBP-28] ; EBP

mov [EAX+20], EBX


mov EBX, [EBP-32] ; ESI

mov [EAX+24], EBX


mov EBX, [EBP-36] ; EDI

mov [EAX+28], EBX


mov EBX, EBP ; EIP (return Address Value)

add EBX, 4

mov EBX, [EBX]

mov [EAX+32], EBX


mov EBX, [EBP-4] ; EFL

mov [EAX+36], EBX



popad

popfd


mov ESP, EBP ; Exit Code

pop EBP

ret ; return(== pop EIP)


_STST ENDP


END


→전체적인 그림은 앞선 내용과 동일하기에 그림 첨부없이 설명하도록 하겠다.

먼저 함수호출할때 전달되는 인자가 status의 주소값이므로 주소값을 찾아오도록 해야한다.

호출된 함수로 들어가서 제일 처음 pushad를 통해 현재 각각의 레지스터의 상태들을 한번에 저장해둔다.


※현재 소스는 주석처리가 되어있지만 처음 코딩을 할때 저장된 레지스터의 값들을 제대로 호출하는지 알수 없을 때 아래에 주석처리된 코드를 통해서 구조체에 저장되는 값들이 정확한 값이 맞는지 확인해보자.

;mov EAX, 1

;mov ECX, 2

;mov EDX, 3

;mov EBX, 4

;mov ESI, 5

;mov EDI, 6


→ 여기서 pushad를 통해서 저장되는 레지스터의 값들이 어떠한 순서를 가지는지 알아야한다.

아래의 그림을 보면 pushad가 저장되는 순서를 알 수 있다.


→ 이제 본격적으로 레지스터의 상태값을 구조체에 넣어볼텐데 필자는 기억하는 주소값을 이번에는 EAX로 한다. EAX에 저장된 주소값을 통해서  ECX, EDX, EBX, ESI, EDI의 레지스터의 값들은 따로 변하거나 수정된 부분이 없으므로 바로 EAX에 저장된 주소값에 각각 해당하는 레지스터 구조체 위치에 바로 넣었다. 


→그럼 이제 남은 EAX와 ESP , EBP를  구조체에 넣어주자.

먼저 선언한 구조체의 변수 순서를 확인해보자. 

현재 구조체의 주소값을 EAX에 저장해두었기 때문에 EAX에 저장하는 레지스터의 값을 메모리에서 찾아서 저장해두되지만 그렇게 mov명령을 쓰면 메모리에서 메모리로 값을 이동하게 되는 것이므로 명령수행이 불가능하다. 따라서 EBX에 그 값을 불러와서 EAX에 저장해야하는데 아래의 소스코드와 같이 한다.

mov EBX, [EBP-20] ; ESP

mov [EAX+16], EBX


mov EBX, [EBP-24] ; EBP

mov [EAX+20], EBX


→전체적인 내용이 앞선 소스코드의 내용을 응용한 것이므로 그렇게 어렶지는 않을 것이다.



#include <stdio.h>


typedef struct _context
{
  unsigned int EAX;
  unsigned int ECX;
  unsigned int EDX;
  unsigned int EBX;
  unsigned int ESP;
  unsigned int EBP;
  unsigned int ESI;
  unsigned int EDI;
  unsigned int EIP;
  unsigned int EFL;
}Context;

extern void STST(Context*);

int main()
{
  Context status;
  STST(&status);
  printf("EAX : %08X \n", status.EAX);
  printf("ECX : %08X \n", status.ECX);
  printf("EDX : %08X \n", status.EDX);
  printf("EBX : %08X \n", status.EBX);
  printf("ESP : %08X \n", status.ESP);
  printf("EBP : %08X \n", status.EBP);
  printf("ESI : %08X \n", status.ESI);
  printf("EDI : %08X \n", status.EDI);
  printf("EIP : %08X \n", status.EIP);
  printf("EFL : %08X \n", status.EFL);
  return 0;
}


;procedure structrue example

;Author: Ryuwoo

;Date : 2014.08.05



.386

.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD


PUBLIC _STST


.CODE ; program code


_STST PROC NEAR32

push  EBP ; Entry Code

mov EBP, ESP


;mov EAX, 1

;mov ECX, 2

;mov EDX, 3

;mov EBX, 4

;mov ESI, 5

;mov EDI, 6


pushfd

pushad



mov EAX, [EBP+8] ; EBX에 &status의 값 삽입

mov EBX, [EBP-8] ; EAX

mov [EAX], EBX


mov EBX, [EBP-12] ; ECX

mov [EAX+4], EBX


mov EBX, [EBP-16] ; EDX

mov [EAX+8], EBX


mov EBX, [EBP-20] ; EBX

mov [EAX+12], EBX


mov EBX, EBP ; ESP

add EBX, 4

mov [EAX+16], EBX


mov EBX, [EBP-28] ; EBP

mov [EAX+20], EBX


mov EBX, [EBP-32] ; ESI

mov [EAX+24], EBX


mov EBX, [EBP-36] ; EDI

mov [EAX+28], EBX


mov EBX, EBP ; EIP (return Address Value)

add EBX, 4

mov EBX, [EBX]

mov [EAX+32], EBX


mov EBX, [EBP-4] ; EFL

mov [EAX+36], EBX



popad

popfd


mov ESP, EBP ; Exit Code

pop EBP

ret ; return(== pop EIP)


_STST ENDP


END



정리 다해놓고 글올려놨는데 마치기 10분전에 문제가 수정되었네요 하하하하하.... 얼추 수정해놨습니다. 전체적인 글은 내일 수정하도록하겠습니다.

마지막에 수정된 문제로 작성한 소스코드 올려놨습니다^^







728x90