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=0; 20>iCnt2; ++iCnt2)
{
//--- Address Part Start
printf("= %08X ", vpData );
//--- Address Part End
//--- Hexa View Part Start
for(iCnt=0; 16>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=0; 16>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