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

131001 화 어셈블리 조유진

by 알 수 없는 사용자 2013. 10. 1.
728x90
반응형

사진


틀린 명령어 입력시 명령어 목록을 보여줌



프로그램이 메모리에 적재되지 않은 경우



프로그램 적재



적재 프로그램 실행 전 데이터 영역



적재한 프로그램 실행 직후 데이터 영역




main.exe



#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <windows.h>
#include <winnt.h>

#define MAX_PROGRAM_SIZE  0x10000  // 64KB
#define SECTION_SIZE  512

#define  MEMORY_START    0
#define  MEMORY_END    1
#define  CODE    2
#define  DATA    3
#define  STACK    4

typedef  struct _command
{
  const unsigned char *ucpCommand;
  const unsigned char *ucpDetail;
  void( *fp )();
} COMMAND;

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

void ChaseAddress( unsigned char * _uCp, int _iSize );
void DrawHeader();

void STST( CONTEXT_INFO *stpReg );  // CPU의 정보를 메모리에 저장
void LDST( CONTEXT_INFO *stpReg );  // 메모리에 저장된 CPU 정보를 재등록

unsigned char MD( int * );  // Memory Display Function By Assembly
void MM( int *, char);  // Memory Modify Function By Assembly

void PrintRegister( CONTEXT_INFO *stpReg );
void ClearMemory();

void Command();

void ViewCode();
void ViewData();
void ViewStack();
void OpenExcutable();
void Exit();
void ViewRegister();
void Go();

unsigned char ucMemory[MAX_PROGRAM_SIZE * 2];

static unsigned char *ucpPoint[5];  // 메모리 공간을 구분하는 변수. 이곳에서만 쓰이기 때문에 static
unsigned int uiLoadFlag = 0;

CONTEXT_INFO  stOldReg;

COMMAND stCommand[] =
{
  { "CODE""코드 영역을 봅니다", ViewCode },
  { "DATA""데이터 영역을 봅니다", ViewData },
  { "STACK""스택 영역을 봅니다", ViewStack },
  { "REGVIEW""레지스터를 봅니다", ViewRegister },
  { "LOAD""실행 파일을 메모리에 적재합니다", OpenExcutable },
  { "CLEAR""메모리를 비웁니다", ClearMemory },
  { "GO""적재한 실행 파일을 실행합니다", Go },
  { "EXIT""종료합니다", Exit },
  { 00 }
};

int main()
{
  int a = 0x12345678;

  ucpPoint[MEMORY_START]  = ucMemory;
  ucpPoint[MEMORY_END]  = ucMemory + sizeof( ucMemory );

  ucpPoint[CODE]  = ( unsigned char * )( ( int )( ucMemory+MAX_PROGRAM_SIZE ) & 0xFFFF0000 );
  ucpPoint[DATA]  = ucpPoint[CODE] + 0x2000;
  ucpPoint[STACK]  = ucMemory+0x10000;

  printf( "Start of memory\t: 0x%08X\n", ucpPoint[MEMORY_START] );
  printf( "End of memory\t: 0x%08X\n", ucpPoint[MEMORY_END] );
  printf( "CODE\t: 0x%08X\n", ucpPoint[CODE] );
  printf( "DATA\t: 0x%08X\n", ucpPoint[DATA] );
  printf( "STACK\t: 0x%08X\n", ucpPoint[STACK] );

  STST( &stOldReg );

  while1 )
  {
    Command();
  }

  //printf( "0x%08X : %02X\n", &a, MD( &a ) );
  
  //MM( &a, 0xFF );

  //printf( "0x%08X : %02X\n", &a, MD( &a ) );
  //printf( "0x%08X : %08X\n", &a, a );

  //ChaseAddress( ( unsigned char * )&a, 4 );

  //PrintRegister( &stOldReg );

  //STST( &stReg );
  //PrintRegister( &stReg );

  return 0;
}

void PrintRegister( CONTEXT_INFO *stpReg )
{
  printf( "┌──────RegisterStatus──────┐\n" );
  printf( "│EAX : 0x%08X\t", stpReg->eax );
  printf( "ECX : 0x%08X│\n", stpReg->ecx );
  printf( "│EDX : 0x%08X\t", stpReg->edx );
  printf( "EBX : 0x%08X│\n", stpReg->ebx );
  printf( "│ESP : 0x%08X\t", stpReg->esp );
  printf( "EBP : 0x%08X│\n", stpReg->ebp );
  printf( "│ESI : 0x%08X\t", stpReg->esi );
  printf( "EDI : 0x%08X│\n", stpReg->edi );
  printf( "│EIP : 0x%08X\t", stpReg->eip );
  printf( "EFL : 0x%08X│\n", stpReg->efl );
  printf( "└───────────────────┘\n\n" );
}

void ChaseAddress( unsigned char * _uCp, int _iSize )
{
  unsigned char *m_uCp = _uCp;
  
  int m_count=0;
  int i=0;
  int m_bytes = 0;

  printf( "\n" );
  DrawHeader();

  while1 )
  {
    if( ( i % 22 == 0 )&&( i != 0 ) )
    {
      printf( "<Press any key to view more... <q> to exit>" );
      if( getch() == 'q' )
      {
        break;
      }
      putchar( '\n' );
      DrawHeader();
    }

    printf( "  %08X  ", m_uCp );  
    for( m_count=0; m_count<=15; m_count++ )
    {
      if( m_bytes < _iSize )
      {
        printf( "%02X", MD( ( int * )(m_uCp + m_count) ) );
        if( m_count != 15 )
        {
          putchar(' ');
        }
        m_bytes = m_bytes + 1;
      }
      else
      {
        printf( "  " );
        if( m_count != 15 )
        {
          putchar(' ');
        }
      }
    }
    
    printf( "  " );

    for( m_count=0; m_count<=15; m_count++ )
    {
      if( m_uCp + m_count < _uCp+_iSize )
      {
        if0 == *( m_uCp + m_count ) )
        {
          printf( "." );
        }
        else if32 > *( m_uCp + m_count )  )
        {
          printf( "*" );
        }
        else if127 < *( m_uCp + m_count )  )
        {
          printf( "*" );
        }
        else
        {
          printf( "%c", MD( ( int * )(m_uCp + m_count) ) );
        }
      }
      else
      {
        printf( " " );
      }
    }
    if( m_bytes == _iSize )
    {
      printf( "\n\n<End of memory.>\n" );
      break;
    }
    putchar( '\n' );
    i = i + 1;
    m_uCp = m_uCp + 16;
  }
  printf( "\n\n" );
}

void DrawHeader()
{
  int i;

  printf( "  Address                          HEX                             ASCII\n" );
  printf( "            " );
  for( i=0; i<=15; i++ )
  {
    printf( "%02X", i );
    if( i != 15 )
    {  putchar(' ');
    }
  }
  printf( "  " );
  for( i=0; i<=15; i++ )
  {
    printf( "%1X", i );
  }
  printf( "\n" );
}

void Command()
{
  int i;
  int iRet;

  unsigned char ucCommand[30];

  fflush( stdin );
  printf( "COMMAND> " );
  iRet = read( 0, ucCommand, 30 );
  ucCommand[iRet-1= 0;

  for( i=0; i<iRet-1; i++ )
  {
    ucCommand[i] = toupper( ucCommand[i] );
  }

  i = 0;
  while1 )
  {
    if( stCommand[i].fp == 0 )
    {
      printf( "오류 : 없는 명령어 입니다!\n\n<명령어 목록>\n" );

      for( i=0; stCommand[i].fp!=0; i++ )
      {
        printf( "%s\t: %s\n", stCommand[i].ucpCommand, stCommand[i].ucpDetail );
      }
      putchar( '\n' );
      break;
    }

    if( strcmp( stCommand[i].ucpCommand, ucCommand ) == 0 )
    {
      (stCommand[i].fp)();
      break;
    }
    i++;
  }
}

void ViewCode()
{
  ChaseAddress( ucpPoint[CODE], ucpPoint[DATA]-ucpPoint[CODE] );
  return;
}
void ViewData()
{
  ChaseAddress( ucpPoint[DATA], ucpPoint[DATA]-ucpPoint[CODE] );
  return;
}
void ViewStack()
{
  ChaseAddress( ucpPoint[MEMORY_END]-159160 );
  return;
}
void ViewRegister()
{
  CONTEXT_INFO stContext;

  STST( &stContext );
  PrintRegister( &stContext );
  return;
}
void Exit()
{
  exit( 0 );
  return;
}

void OpenExcutable()
{
  int iFd = 0;  // File descripter
  int iRet;
  unsigned int uiTotalCount = 0;
  unsigned int iCount = 0;

  unsigned char *ucpCursor;
  unsigned char *ucpCodeStart;

  unsigned char ucFileName[30];

  IMAGE_DOS_HEADER *stpDOSHeader;
  IMAGE_NT_HEADERS *stpNTHeader;

  printf( "파일 이름<실행파일> : " );

  iRet = read( 0, ucFileName, 30 );
  ucFileName[iRet-1= 0;

  iFd = open( ucFileName, O_RDONLY );

  if( iFd < 0 )
  {
    printf( "\n파일을 열 수 없습니다...\n\n" );
    return;
  }

  ClearMemory();

  iRet = read( iFd, ucMemory, MAX_PROGRAM_SIZE );

  if( iRet < 0 )
  {
    printf( "\n파일을 읽을 수 없습니다...\n\n" );
    close( iFd );
    return;
  }

  stpDOSHeader = ( IMAGE_DOS_HEADER* )ucMemory;

  printf( "파일을 열었습니다.\n" );

  if( stpDOSHeader->e_magic != 0x5A4D )
  {
    printf( "올바른 파일 형식이 아닙니다. 실행 파일을 입력해 주시기 바랍니다.\n\n" );
    close( iFd );
    return;
  }

  stpNTHeader = ( IMAGE_NT_HEADERS* )( ucMemory + stpDOSHeader->e_lfanew -1 );

  printf( "%d\n", stpNTHeader->OptionalHeader.SizeOfInitializedData );

  uiTotalCount = stpNTHeader->OptionalHeader.SizeOfHeaders;
  iRet = lseek( iFd, stpNTHeader->OptionalHeader.SizeOfHeaders, SEEK_SET );

  ClearMemory();

  if( iRet < 0 )
  {
    printf( "파일 적재 오류!\n" );
    close( iFd );
    return;
  }

  iRet = read( iFd, ucpPoint[CODE], SECTION_SIZE );
  if( iRet < 0 )
  {
    printf( "코드 영역 적재 오류!\n" );
    close( iFd );
    return;
  }
  uiTotalCount = uiTotalCount + iRet;

  iRet = read( iFd, ucpPoint[DATA], SECTION_SIZE );
  if( iRet < 0 )
  {
    printf( "데이터 영역 적재 오류!\n" );
    close( iFd );
    return;
  }
  uiTotalCount = uiTotalCount + iRet;

  printf( "총 읽어들인 바이트 수 : %d bytes\n", uiTotalCount );

  close( iFd );

  uiLoadFlag = 1;

  return;
}

void ClearMemory()
{
  printf( "메모리를 초기화합니다...\n" );
  memset( ucpPoint[CODE], 0, ucpPoint[MEMORY_END]-ucpPoint[CODE] );

  uiLoadFlag = 0;
}

void Go()
{
  CONTEXT_INFO stNewReg = { 0, };

  if( uiLoadFlag )
  {
    stNewReg.eax = ( int )&stOldReg;
    stNewReg.eip = ( int )ucpPoint[CODE];
    stNewReg.esp = ( int )(ucpPoint[MEMORY_END]+4);  // PUSH는 이동하고 값을 넣으므로...

    LDST( &stNewReg );

    printf( "Kernel Panic\n" );
  }
  else
  {
    printf( "프로그램을 적재하시기 바랍니다...\n" );
  }
}


728x90