#include <stdio.h> #include <windows.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <WinNT.h>
#define MAX_PROGRAM_SIZE 0x10000 // 64Kbyte #define SECTION_SIZE 512
typedef struct _CONTEXT1 { int efl; int eip; int edi; int esi; int ebp; int esp; int ebx; int edx; int ecx; int eax; }CONTEXT1;
void PrintCODE(void); void PrintDATA(void); void PrintSTACK(void); void EXIT(void); void HELP(void); void PrintLOAD(void); void Clear_mem(void); void GO(void);
typedef struct _CmdMap { void *vpCmd; void (*fp)(void); }CmdMap;
CmdMap stCmdList[] = { {"CODE" , PrintCODE}, {"DATA" , PrintDATA}, {"STACK", PrintSTACK}, {"LOAD" , PrintLOAD}, {"HELP" , HELP}, {"EXIT" , EXIT}, {"MC", Clear_mem}, {"GO", GO}, {0,0} };
static unsigned char sucMem[MAX_PROGRAM_SIZE*2]; // 128Kbyte , 동적할당 시작위치 static unsigned char *sucMem_end; // 동적할당 끝 위치 static unsigned char *sucCODE; // CODE 의 시작위치 static unsigned char *sucDATA; // DATA 의 시작위치 static unsigned char *sucSTACK; // STACK 의 시작위치 static unsigned char Load_Flag; // 로드유무 표시 static unsigned char Display_Flag; // 메모리값 출력시 계속해서 // 출력하는 경우를 위해 static int iFd; // 파일 입출력을 위한 파일디스크립션 static CONTEXT1 stat_old; // 기존의 레지스터값 저장
void HexaView(unsigned char *, unsigned int); void PrintReg(CONTEXT1 *); void STST(CONTEXT1 *); void LDST(CONTEXT1 *);
void Command(void * vpCmd);
//int ASKY(); // 반환값 받기 unsigned char MD(void *); // Momory Display Function By Assembly void MM(void *, char); // Momory Modify Function By Assembly
CONTEXT1 stOldreg;
int main() { int A = 0x12345678; static unsigned char ucBuff[31]; static unsigned char ucCnt = 0; int iRet;
sucMem_end = sucMem + sizeof(sucMem); sucCODE = (unsigned char *)(((unsigned int)sucMem+MAX_PROGRAM_SIZE) & 0xFFFF0000); sucDATA = sucCODE + 0x2000; sucSTACK = (unsigned char *)sucCODE + MAX_PROGRAM_SIZE-1;
printf("Memory Start Add : %08x\n", sucMem); printf("Memory End Add : %08x\n", sucMem_end); printf("Memory Code Add : %08x\n", sucCODE); printf("Memory DATA Add : %08x\n", sucDATA); printf("Memory Stack Add : %08x\n", sucSTACK); //HexaView((unsigned char *)&A , 159); printf("-------------------- 초기화 상태 --------------------\n"); PrintReg(&stOldreg); STST(&stOldreg); printf("-------------------- 저장 상태 ----------------------\n"); PrintReg(&stOldreg); while(1) { printf("\n>"); iRet = read(0,ucBuff,sizeof(ucBuff)); for(ucCnt=0 ; ucCnt < iRet-1 ; ++ucCnt) { ucBuff[ucCnt] = toupper((int)ucBuff[ucCnt]); } ucBuff[ucCnt]= '\0';
Command(ucBuff); }
getchar();
LDST(&stOldreg); // STST로 가게해줌. while 문 역할 // 메모리안에 있는 정보를 CPU 로 옮겨준다.
return 0; }
void Clear_mem() { unsigned int uiCnt;
for(uiCnt=0 ; uiCnt < (int)sucMem_end - (int)sucCODE ; ++uiCnt) { *(sucCODE+uiCnt) = 0; } return; }
void PrintLOAD() { IMAGE_DOS_HEADER *stpDOS;// windows.h -> 구조체 IMAGE_DOS_HEADER IMAGE_NT_HEADERS *stpNT; // NT Header IMAGE_FILE_HEADER *stpFH; // File Header IMAGE_OPTIONAL_HEADER *stpOH; // Optional Header unsigned char File_Name[255]; // 파일이름 임시저장 int Total_Read=0; int Read_Num=0; int Header_Size; int iRet; unsigned int uiCnt;
Clear_mem();
printf("\n읽어들일 파일이름을 입력하세요 : "); iRet = read(0,File_Name,sizeof(File_Name)); for(uiCnt=0 ; uiCnt < iRet-1 ; ++uiCnt) { File_Name[uiCnt] = toupper((int)File_Name[uiCnt]); } File_Name[uiCnt]= '\0';
iFd = open( File_Name , O_RDONLY | O_BINARY);
if( 0 > iFd ) { printf("File Open Error\n"); return; }
iRet = read(iFd , sucCODE , SECTION_SIZE);
if( 0 > iFd ) { printf("File was Readed\n"); close(iFd); return; } else { stpDOS = (IMAGE_DOS_HEADER *)sucCODE; stpNT = (IMAGE_NT_HEADERS *)(sucCODE + (stpDOS->e_lfanew)); stpFH = (IMAGE_FILE_HEADER *)((unsigned char *)stpNT + sizeof(stpNT->Signature)); stpOH = (IMAGE_OPTIONAL_HEADER *)((unsigned char *)stpFH + sizeof(IMAGE_FILE_HEADER)); Header_Size = stpOH->SizeOfHeaders; Clear_mem(); }
if( 0 > lseek(iFd, Header_Size, SEEK_SET) ) { printf("파일의 헤더정보 Skip 실패!!\n"); printf("파일을 적재할 수 없습니다..\n"); close(iFd); } else { Read_Num = read(iFd, sucCODE, SECTION_SIZE); // Code 영역에 SECTION_SIZE 만큼 읽어들임 }
if( 0 > Read_Num ) { printf("파일이 존재하지만 읽을 수 없습니다.\n"); close(iFd); return; } else { Total_Read = Total_Read + Read_Num; Read_Num = read(iFd, sucDATA, SECTION_SIZE); // DATA 영역에 SECTION_SIZE 만큼 } // 읽어 들임
close(iFd);
if(0 > Read_Num) { printf("파일이 존재하지만 읽을 수 없습니다.\n"); return; } else { Total_Read = Total_Read + Read_Num; iFd = 0; Load_Flag = 1; printf("파일을 성공적으로 메모리에 적재하였습니다.\n"); printf("읽어 들인 파일의 크기는 [%d]Bytes입니다.\n\n", Total_Read); }
return; }
void GO(void) { CONTEXT1 stNewreg = {0,};
stNewreg.eax = (int)&stOldreg; stNewreg.eip = (int)sucCODE; stNewreg.esp = (int)(sucSTACK+4); // 메모리 끝의 한칸 아래 집어줌 Push 할때를 대비 LDST(&stNewreg); printf("Kernel Panic\n"); }
void PrintCODE() { printf("\nCODE Field\n\n"); HexaView(sucCODE,160); }
void PrintDATA() { printf("\nDATA Field\n\n"); HexaView(sucDATA,160); }
void PrintSTACK() { printf("\nSTACK Field\n\n"); HexaView(sucSTACK-159,160); }
/*void PrintLOAD() { int iRet; int fd; int *ip; unsigned char ucBuff[31]; unsigned int uiCnt = 0; unsigned char ucBuff_Mem[MAX_PROGRAM_SIZE];
printf("\n읽어들일 파일이름을 입력하세요 : "); iRet = read(0,ucBuff,sizeof(ucBuff)); for(uiCnt=0 ; uiCnt < iRet-1 ; ++uiCnt) { ucBuff[uiCnt] = toupper((int)ucBuff[uiCnt]); } ucBuff[uiCnt]= '\0';
fd = open( ucBuff , O_RDONLY | O_BINARY);
iRet = read(fd , ucBuff_Mem , sizeof(ucBuff_Mem));
for(uiCnt=0 ; uiCnt < iRet ; uiCnt++) { MM(sucCODE+uiCnt,ucBuff_Mem[uiCnt]); }
close(fd); }*/
void PrintReg(CONTEXT1 *stpReg) { 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 EXIT() { exit(0); }
void HELP() { printf("CODE : CODE Area Display\n"); printf("DATA : DATA Area Display\n"); printf("STACK : STACK Area Display\n"); printf("HELP : Help massage Display\n"); printf("EXIT : EXIT Program\n"); printf("MC : Memory Clear\n"); printf("LOAD : Program Load\n"); }
void Command(void * vpCmd) { CmdMap *stpCmd = stCmdList;
while(1) { if( 0 == stpCmd->fp ) // 함수 포인터 { break; }
if( 0 == My_strcmp( vpCmd , stpCmd->vpCmd ) ) { // 함수 포인터를 이용한 함수 호출 (stpCmd->fp)(); break; } ++stpCmd; }
return; }
int My_strcmp(void *vpSrc, void *vpDst) { while(1) { if( 0 == *((unsigned char *)vpSrc) ) { break; }
if( 0 == *((unsigned char *)vpDst) ) { break; }
if( *((unsigned char *)vpSrc) != *((unsigned char *)vpDst) ) { break; }
vpSrc = ((unsigned char *)vpSrc) + 1; vpDst = ((unsigned char *)vpDst) + 1; }
return ( *((unsigned char *)vpSrc) - *((unsigned char *)vpDst) ); // 동일한 문자열일때(참일때) 반환값이 0 이 반환 // 동일하지 않으면(거짓일때) 0 이 아닌 값이 반환 }
void HexaView(unsigned char *ucP, unsigned int isize) { int iCnt; int iloop; unsigned int iSizeNum;
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"); if( 0 == 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 if( 32 > MD(ucP+iCnt)) { printf("."); } else if( 127 < MD(ucP+iCnt)) { printf("."); } else { printf("%c", MD(ucP+iCnt)); } } putchar('\n'); ucP = ucP + 16;
}
if( iSizeNum != 0 ) { 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-1 ; iCnt++ ) { if(0 == MD(ucP+iCnt)) { printf("."); } else if( 32 > MD(ucP+iCnt)) { printf("."); } else if( 127 < MD(ucP+iCnt)) { printf("."); } else { printf("%c", MD(ucP+iCnt)); } } putchar('\n');
} } |