#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 }, { 0, 0 } };
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 );
while( 1 ) { 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();
while( 1 ) { 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 ) { if( 0 == *( m_uCp + m_count ) ) { printf( "." ); } else if( 32 > *( m_uCp + m_count ) ) { printf( "*" ); } else if( 127 < *( 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; while( 1 ) { 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]-159, 160 ); 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" ); } } |