Assembly

2013.09.25_ HexaView 응용해서 스택구조확인

성엽이 2013. 9. 25. 19:18


 0925_MEMtoCPU.c Source

 #include <stdio.h>


typedef struct  _Context
{
  int  efl;
  int  eip;
  int  edi;
  int  esi;
  int  ebp;
  int  esp;
  int  ebx;
  int  edx;
  int  ecx;
  int  eax;
}CONTEXT;

void HexaView(unsigned char *, unsigned int);
void PrintReg(CONTEXT *);
void STST(CONTEXT *);
void LDST(CONTEXT *);

//int ASKY();      // 반환값 받기
unsigned char   MD(void *);  // Momory Display Function By Assembly
void     MM(void *, char);  // Momory Modify Function By Assembly


int main()
{
  int A = 0x12345678;
  CONTEXT  stpReg = {0,};

  //MD(&A) => 78을 반환해주기
  printf("A의 값 : %08x\n", A);
  printf("A의 주소 : %08x, 값 : %x\n"&A, MD(&A) );
  
  //MM(&A, 0xFF);  // => 78 자리에 FF 넣기
  MM(&A, 0xFF);
  printf("A의 주소 : %08x, A의 반환값 수정 : %08x\n",&A, A);
  
  HexaView((unsigned char *)&A , 159);   // 16개에 한줄씩이기때문에 159하면 맨마지막 하나만 출력이 안됨, 실행화면에서 확인가능

  //printf("%d\n", ASKY());  
  PrintReg(&stpReg);
  STST(&stpReg);
  PrintReg(&stpReg);
  getchar();

  LDST(&stpReg);  // STST로 가게해줌. while 문 역할
      // 메모리안에 있는 정보를 CPU 로 옮겨준다.

  printf("Kernel Panic\n");

  return 0;
}

void PrintReg(CONTEXT *stpReg)
{
  printf("------------------------------------------------\n");
  printf("EAX VALUE : 0x%08x   ECX VALUE : 0x%08x\n", stpReg->eax, stpReg->ecx);
  printf("EDX VALUE : 0x%08x   EBX VALUE : 0x%08x\n", stpReg->edx, stpReg->ebx);
  printf("ESP VALUE : 0x%08x   EBP VALUE : 0x%08x\n", stpReg->esp, stpReg->ebp);
  printf("ESI VALUE : 0x%08x   EDI VALUE : 0x%08x\n", stpReg->esi, stpReg->edi);
  printf("EIP VALUE : 0x%08x   EFL VALUE : 0x%08x\n", stpReg->eip, stpReg->efl);
}

void HexaView(unsigned char *ucP, unsigned int isize)
{
  int iCnt;
  int iloop;
  unsigned int iSizeNum;   // 출력하고 싶은 Byte 만큼 쓰기위해 갯수를 저장 

  iSizeNum = 0;
  
  printf("----------------------------------------"
     "----------------------------------\n");
  printf("Address  \t\t\tHexa\t\t\t      ASCII\n"); 
  printf("\t ");

  
  for(iCnt=0 ; iCnt <= 15 ; iCnt++)
  {
    printf("%02X ", iCnt);
  }

  putchar('\n');

  printf("----------------------------------------"
     "----------------------------------\n");
  
  if0 == isize%16 )
  {
    isize = isize / 16;  
  }
  else
  {
    iSizeNum = isize%16;
    isize = (isize/16);    
  }
  
  for(iloop=0; iloop < isize ; iloop++)
  {
    printf("%08X ", ucP); 
  
    for( iCnt=0 ; iCnt <= 15 ; iCnt++)
    {
      printf("%02X ", MD(ucP+iCnt));
    }
  
    for( iCnt=0 ; iCnt <= 15 ; iCnt++ )
    {
      if(0 == MD(ucP+iCnt))
      {
        printf(".");
      }
      else if32 > MD(ucP+iCnt))
      {
        printf(".");
      }
      else if127 < MD(ucP+iCnt))
      {
        printf(".");      
      }
      else
      {
        printf("%c", MD(ucP+iCnt)); 
      }
    }
  
    putchar('\n');
    ucP = ucP + 16;


  }

  if( iSizeNum != 0 )    // 출력하고 싶은 Byte 만큼만 출력하기 위해서 사용
  {
    printf("%08X ", ucP); 
  
    for( iCnt=0 ; iCnt <= iSizeNum-1 ; iCnt++)
    {
      printf("%02X ", MD(ucP+iCnt));
    }
    
    for( iCnt=0 ; iCnt <= 15-iSizeNum ; iCnt++ )
    {
      printf("   ");
    }    
    

    for( iCnt=0 ; iCnt <= iSizeNum ; iCnt++ )
    {
      if(0 == MD(ucP+iCnt))
      {
        printf(".");
      }
      else if32 > MD(ucP+iCnt))
      {
        printf(".");
      }
      else if127 < MD(ucP+iCnt))
      {
        printf(".");      
      }
      else
      {
        printf("%c", MD(ucP+iCnt)); 
      }
    }
  
    putchar('\n');

  }  
}



 0925_Monitor.asm 

 .386

.MODEL FLAT

PUBLIC  _STST  ; Store Status
PUBLIC  _LDST  ; Load Status
;PUBLIC  _ASKY  
PUBLIC  _MD
PUBLIC  _MM

.CODE

_STST  PROC  NEAR32

; Entry Code ) ------------------------------------
  PUSH  EBP   ; establish stack frame
  MOV  EBP,ESP
; -------------------------------------------------

;  PUSH EFL  
  pushfd

;  Trap Flag set 임의 제거
  mov  eax, [ebp-4]
  and  eax, 0FFFFFEFFh
  mov  [ebp-4], eax

;  &context 위치 가리킴
  mov  esp,  [ebp+8]

;  EAX 로 이동
  add  esp,  40

  pushad

;  EIP(return Address) 대입
  push  [ebp+4]

;  EFL 대입
  push  [ebp-4]

;   esp 위치 조정
  add  esp, 24
  mov  eax, ebp
  add  eax, 8
  push  eax
  
  push  [ebp]
  
; Exit Code ) ------------------------------------
  MOV  ESP,EBP ; restore ESP if local variables used
  POP  EBP   ; restore EBP
  RET     ; return
; ------------------------------------------------

; Store Status
_STST  ENDP


; Load Status
_LDST  PROC  NEAR32
  
  MOV  ESP, [ESP+4]  ; CONTEXT 주소로 ESP를 옮김 , ESP = &CONTEXT
  POPFD      ; EFL 을 CPU 로 , EFL = CONTEXT.EFL

  POP  EAX    ; EIP 백업 (EAX Reg 에다가) , EAX = Old EIP
  
  MOV  EBX, ESP  ; EBX 에 ESP 를 백업 , Current ESP Backup
    
  MOV  ESP, [ESP+12]  ; 뽑아왔던 ESP 넣음 , ESP = Old ESP
  PUSH  EAX    ; Old EIP 넣음 , SAVE Old EIP

  MOV  ESP, EBX  ; ESP = Current ESP 
  
  POPAD      ; PUSHAD 와 반대순서로 CPU에 올라가고, ESP는 무시

  MOV  ESP, [ESP-20]  ; ESP를 Return Address 로 돌려주기
  SUB  ESP, 4    
  
  RET     return

_LDST  ENDP


; 반환값 넣는 방법
;_ASKY  PROC  NEAR32

; Entry Code ) ------------------------------------
;  PUSH  EBP   ; establish stack frame
;  MOV  EBP,ESP
; -------------------------------------------------
  

;  MOV  EAX, 100  ; 반환값은 EAX에


; Exit Code ) -------------------------------------
;  MOV  ESP,EBP ; restore ESP if local variables used
;  POP  EBP   ; restore EBP
;  RET     ; return
; -------------------------------------------------

;_ASKY  ENDP


_MD  PROC  NEAR32

; Entry Code ) ------------------------------------
  PUSH  EBP   ; establish stack frame
  MOV  EBP,ESP
; -------------------------------------------------
  
  MOV  EAX, [EBP+8]  ; EAX = &A
  MOV  EAX, [EAX]  ; EAX = *(&A)
  
; Exit Code ) -------------------------------------
  MOV  ESP,EBP ; restore ESP if local variables used
  POP  EBP   ; restore EBP
  RET     ; return
; -------------------------------------------------

_MD  ENDP


_MM  PROC  NEAR32

; Entry Code ) ------------------------------------
  PUSH  EBP   ; establish stack frame
  MOV  EBP,ESP
; -------------------------------------------------
  
  PUSH  EBX    ; EBX Back up
  MOV  EAX, [EBP+8]  ; EAX = &A
  MOV  BL, [EBP+12]  ; BL = 0xFF
  MOV  [EAX], BL   ; *(&A) = 0xFF
  POP  EBX

; Exit Code ) -------------------------------------
  MOV  ESP,EBP ; restore ESP if local variables used
  POP  EBP   ; restore EBP
  RET     ; return
; -------------------------------------------------

_MM  ENDP


END




 실행화면

 


▶ MD 함수 스택 ( 변수안에 1Byte 만 바꾸기 위한 함수 )

▶ MM 함수 스택 ( 변수 안에 1Byte 만 출력 )


※ ESP 는 움직이는게 아니다. 기준점인 EBP 에서부터 위치를 조종해줘야 한다.