20140822 (다른 프로그램 실행 분석 프로그램 작성)

125일차









------------------------------

실행 파일 분석 프로그램 작성

------------------------------
















소스


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <windows.h>

#define  MAX_PROGRAM_SIZE  0x10000

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

static unsigned char * Mem;    // 동적 메모리 시작 주소
static unsigned char * Mem_End;  // 동적 메모리 끝 주소
static unsigned char * code;    // 프로그램 저장공간의 시작 위치 - Code
int File_DS;      // 저수준 파일의 데스크립터

extern void STST(Context *);  // Reg 상태 저장
extern void LDST(Context *);
extern void MM(void *, unsigned char);// Memory 수정
extern unsigned char MD(void *);  // Memory 보기

void load();
void HexaView(void *);
void Print_Register(Context *);
void Memory_Clear();

int main()
{
  Context status;
  unsigned int uiNum;

  Mem = malloc(MAX_PROGRAM_SIZE*2);

  if(0 == Mem)
  {
    printf("동적 할당을 받을 수 없습니다.\n");
    printf("프로그램을 종료합니다.\n");
    return 0;
  }
  else
  {
    code = (unsigned char *)(((unsigned int)Mem + MAX_PROGRAM_SIZE) & 0xFFFF0000);
    Mem_End = Mem + MAX_PROGRAM_SIZE*2 - 1;
    printf("Dynamic Memory area\t: 0x%08X to 0x%08X (128KBytes)\n", Mem, Mem_End);
  }

  printf("Code Start Address\t: 0x%08X\n", code);

  STST(&status);
  Print_Register(&status);

  load();
  HexaView(code);

  printf("1: 프로그램 재시작, 2 : 프로그램 종료\n");
  printf("선택하세요 : ");
  scanf("%d"&uiNum);

  if(uiNum == 1)
  {
    LDST(&status);
  }

  free(Mem);

  return 0;
}

void load()
{
  int Read_Num;
  int Header_Size;
  unsigned int uiSection_Size;
  IMAGE_DOS_HEADER * stpDH;
  IMAGE_NT_HEADERS * stpPH;
  IMAGE_FILE_HEADER * stpFH;
  IMAGE_OPTIONAL_HEADER32 * stpOH;  

  File_DS = open("t1.exe", O_RDONLY);

  if(File_DS < 0)
  {
    printf("파일 열기 실패.\n");
    return;
  }


  Read_Num = read(File_DS, Mem, MAX_PROGRAM_SIZE*2);

  if(0 >= Read_Num)
  {
    printf("파일 읽기 실패(1).\n");
    close(File_DS);
    return;
  }

  stpDH = (IMAGE_DOS_HEADER *)Mem;
  stpPH = (IMAGE_NT_HEADERS *)(Mem + stpDH->e_lfanew-1);
  stpFH = (IMAGE_FILE_HEADER *)( ((char *)(stpPH)) + 4 );
  stpOH = (IMAGE_OPTIONAL_HEADER32 *)( ((char *)(stpFH)) + sizeof(IMAGE_FILE_HEADER));

  Header_Size = stpOH->SizeOfHeaders;  // Header size
  uiSection_Size = stpOH->FileAlignment;    // Section size

  Memory_Clear();    // Memory clear

  lseek(File_DS, Header_Size, SEEK_SET);  // 파일 포인터 위치 이동
  Read_Num = read(File_DS, code, uiSection_Size);

  if(0 >= Read_Num)
  {
    printf("파일 읽기 실패(2).\n");
    close(File_DS);
    return;
  }

  close(File_DS);
}

void HexaView(void * vpData)
{  
  int iCnt;
  int iCnt2;
  
  printf("===============================================================================\n");
  printf("= ADDRESS                         HEXA                             ASCII      =\n");
  printf("=-----------------------------------------------------------------------------=\n");
  
  for(iCnt2=020>iCnt2; ++iCnt2)
  {

//---  Address Part Start

    printf("= %08X  ", vpData );

//---  Address Part End

  

//--- Hexa View Part Start

    for(iCnt=016>iCnt; ++iCnt)
    {
      if(7 == iCnt)
      {
        printf("%02X  ", (*((unsigned char *)vpData)) );
      }
      else
      {
        printf("%02X ", (*((unsigned char *)vpData)) );
      }
      ++((unsigned char *)vpData);
    }

//--- Hexa View Part End




//---   ASCII Part Start

    ((unsigned char *)vpData) = ((unsigned char *)vpData) - iCnt;
    for(iCnt=016>iCnt; ++iCnt)
    {
      if(0x20 <= (*((unsigned char *)vpData)) && 0x80 > (*((unsigned char *)vpData)))
      {
        printf("%c", (*((unsigned char *)vpData)));
      }
      else
      {
        printf(".");
      }
      ++((unsigned char *)vpData);
    }
    printf(=\n");

//---   ASCII Part End



  }  
  printf("===============================================================================\n");

  return ;
}

void Print_Register(Context * 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\n", status->EFL);
}

void Memory_Clear()
{
  unsigned char * ucData;

  ucData = Mem;

  while(1)
  {
    MM(ucData, 0x00);
    ++ucData;

    if(ucData > Mem_End)
    {
      break;
    }
  }
}







외부 함수 Asm 코드


.386
.MODEL FLAT
.STACK 4096

PUBLIC  _LDST
PUBLIC  _STST
PUBLIC  _MM
PUBLIC  _MD

.CODE
_LDST   PROC   NEAR32   ; LoaD STatus Procedure Start
  push  ebp    ; Entry Code
  mov  ebp, esp    ; Entry Code

  add  esp, 12    ; load EFL
  popfd

  pop  eax    ; load EIP
  mov  [esp-16], eax

  popad      ; load Reg
  
  mov  esp, ebp    ; Exit Code
  pop  ebp    ; Exit Code
  ret      ; Exit Code
_LDST   EndP     ; LoaD STatus Procedure End


_STST  PROC  NEAR32
  push  ebp    ; Entry Code
  mov  ebp, esp    ; Entry Code


  pushfd      ; save temp EFL

  add  esp, 56

  pushad      ; save Reg

  mov  eax, [ebp+4]  ; save EIP
  push  eax

  mov  eax, [ebp-4]  ; save EFL
  push  eax


  mov  esp, ebp    ; Exit Code
  pop  ebp    ; Exit Code
  ret      ; Exit Code
_STST  ENDP


_MM   PROC   NEAR32    ; Memory Modify
  push  ebp    ; Entry Code
  mov  ebp, esp    ; Entry Code

  mov  al, [ebp+12]
  mov  esp, [ebp+8]
  mov  [esp], al
  
  mov  esp, ebp    ; Exit Code
  pop  ebp    ; Exit Code
  ret      ; Exit Code
_MM   EndP      ; Memory Modify


_MD   PROC   NEAR32    ; Memory Display
  push  ebp    ; Entry Code
  mov  ebp, esp    ; Entry Code

  mov  esp, [ebp+8]
  mov  al, [esp]
  
  mov  esp, ebp    ; Exit Code
  pop  ebp    ; Exit Code
  ret      ; Exit Code
_MD   EndP      ; Memory Display

END

설정

트랙백

댓글