#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); void PrintReg(void);
typedef struct _CmdMap { void *vpCmd; void (*fp)(void); }CmdMap;
CmdMap stCmdList[] = { {"CODE" , PrintCODE}, {"DATA" , PrintDATA}, {"STACK", PrintSTACK}, {"LOAD" , PrintLOAD}, {"HELP" , HELP}, {"Q" , EXIT}, {"MC", Clear_mem}, {"GO", GO}, {"R", PrintReg}, {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; // 파일 입출력을 위한 파일디스크립션
void HexaView(unsigned char *, unsigned int); void STST(CONTEXT1 *); void LDST(CONTEXT1 *);
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[255]; static unsigned char ucCnt = 0; int iRet; CmdMap *stpCmd; 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(); STST(&stOldreg); printf("-------------------- 저장 상태 ----------------------\n"); PrintReg();
while(1) { fflush(stdin); putchar('\n'); putchar('>'); putchar(' '); iRet = read(0,ucBuff,sizeof(ucBuff));
ucBuff[iRet-1] = 0;
for(ucCnt=0 ; 0 != ucBuff[ucCnt] ; ++ucCnt) { ucBuff[ucCnt] = toupper((int)ucBuff[ucCnt]); } if(0 == strcmp(ucBuff,"Q") ) { break; }
stpCmd = stCmdList;
while(1) { if(0 == (stpCmd->fp) ) { printf("명령어를 찾을수 없습니다.\n"); break; } if(0 == strcmp(ucBuff, (stpCmd->vpCmd)) ) {
(stpCmd->fp)(); break; } ++stpCmd; } }
return 0; }
void Clear_mem() { unsigned int uiCnt;
for(uiCnt=0 ; uiCnt < (int)sucMem_end - (int)sucCODE ; ++uiCnt) { *(sucCODE+uiCnt) = 0; }
Load_Flag = 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,};
if( 0 == Load_Flag ) { printf("외부 프로그램이 적재되어 있지 않습니다.\n"); printf("Load 명령을 사용하여 프로그램을 적재하시길 바랍니다.\n"); return; }
stNewreg.eax = (int)&stOldreg; stNewreg.eip = (int)sucCODE; stNewreg.esp = (int)(sucSTACK); // 메모리 끝의 한칸 아래 집어줌 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 PrintReg() { printf("EAX VALUE : 0x%08x ECX VALUE : 0x%08x\n", stOldreg.eax, stOldreg.ecx); printf("EDX VALUE : 0x%08x EBX VALUE : 0x%08x\n", stOldreg.edx, stOldreg.ebx); printf("ESP VALUE : 0x%08x EBP VALUE : 0x%08x\n", stOldreg.esp, stOldreg.ebp); printf("ESI VALUE : 0x%08x EDI VALUE : 0x%08x\n", stOldreg.esi, stOldreg.edi); printf("EIP VALUE : 0x%08x EFL VALUE : 0x%08x\n", stOldreg.eip, stOldreg.efl); }
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"); printf("Go : Loaded Program Excute\n"); printf("R : Memory Status\n"); }
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');
} }
|