📄 xdsloaddlg.cpp
字号:
CloseHandle( hProcess);
// Read the thread context
HANDLE hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, de.dwThreadId);
if( hThread == NULL)
{
TerminateProcess( pi.hProcess, 0);
AfxMessageBox( "OpenThread");
dlg->m_run.EnableWindow( TRUE);
return 0;
}
CONTEXT context;
context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
if( !GetThreadContext( hThread, &context))
{
CloseHandle( hThread);
TerminateProcess( pi.hProcess, 0);
AfxMessageBox( "GetThreadContext");
dlg->m_run.EnableWindow( TRUE);
return 0;
}
/*
I'm going to handle only these opcodes:
EC IN AL,DX
EE OUT DX,AL
66 ED IN AX,DX
66 EF OUT DX,AX
There are some others, i.e. double word IN and OUT and some privileged opcodes
other than IN/OUT, like PUSHF. You can find them on Internet.
*/
CString str;
int ipincr = 0;
if( opcodes[0] == 0x66 && opcodes[1] == 0xED) // IN AX,DX
{
ipincr = 2;
DWORD port = context.Edx & 0x0000FFFF;
if( bVerbose)
str.Format( "IN AX,0x%04X\r\n", port);
// TODO
if ((port >= XDS510(0x00) && port < XDS510(0x20)) ||
(port >= XDS510(0x400) && port < XDS510(0x410)) ||
port == XDS510(0x800))
{
context.Eax &= 0xFFFF0000;
context.Eax |= (unsigned)XDS510_read( port - XDS510_BASE) & 0x0000FFFF;
}
else
{
TRACE( "Direct I/O read attempted from port %x\n", port);
context.Eax |= 0x0000FFFF;
}
}
else if( opcodes[0] == 0x66 && opcodes[1] == 0xEF) // OUT DX,AX
{
ipincr = 2;
DWORD port = context.Edx & 0x0000FFFF;
if( bVerbose)
str.Format( "OUT 0x%04X,0x%04X\r\n", port, context.Eax & 0x0000FFFF);
// TODO
if ((port >= XDS510(0x00) && port < XDS510(0x20)) ||
(port >= XDS510(0x400) && port < XDS510(0x410)) ||
port == XDS510(0x800))
{
XDS510_write( port - XDS510_BASE, context.Eax & 0x0000FFFF);
}
else
{
TRACE( "Direct I/O write attempted to port %x\n", port);
}
}
/* else if( opcodes[0] == 0xEC) // IN AL,DX
{
ipincr = 1;
if( bVerbose)
str.Format( "IN AL,0x%04X\r\n", context.Edx & 0x0000FFFF);
// TODO
}
else if( opcodes[0] == 0xEE) // OUT DX,AL
{
ipincr = 1;
if( bVerbose)
str.Format( "OUT 0x%04X,0x%02X\r\n", context.Edx & 0x0000FFFF, context.Eax & 0x000000FF);
// TODO
}
*/
if( ipincr > 0)
{
if( bVerbose)
{
dlg->m_monitor.GetWindowText( oldtxt);
int nChars = oldtxt.GetLength();
if( nChars < CHAR_LIMIT)
{
dlg->m_monitor.SetSel( nChars, -1);
dlg->m_monitor.ReplaceSel( str);
}
}
// Advance EIP to the next instruction. This is enough to remove the exception
context.Eip += ipincr;
if( !SetThreadContext( hThread, &context))
{
CloseHandle( hThread);
TerminateProcess( pi.hProcess, 0);
AfxMessageBox( "SetThreadContext");
dlg->m_run.EnableWindow( TRUE);
return 0;
}
CloseHandle( hThread);
ContinueDebugEvent( de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
continue;
}
else // Opcode not handled
{
CloseHandle( hThread);
// Opcode dump
str.Format( "%04X (edx=%08X eax=%08X)\r\n",
opcodes[0] == 0x66 ? opcodes[0]<<8 | opcodes[1] : opcodes[0], context.Edx, context.Eax);
dlg->m_monitor.GetWindowText( oldtxt);
int nChars = oldtxt.GetLength();
if( nChars < CHAR_LIMIT)
{
dlg->m_monitor.SetSel( nChars, -1);
dlg->m_monitor.ReplaceSel( str);
}
// Continue for first chances (maybe someone can handle it...) or continuable exceptions
if( de.u.Exception.dwFirstChance ||
!(de.u.Exception.ExceptionRecord.ExceptionFlags & EXCEPTION_NONCONTINUABLE))
{
ContinueDebugEvent( de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
}
else
// Otherwise, game over.
{
TerminateProcess( pi.hProcess, 0);
AfxMessageBox( "Privileged instruction not handled, second-chance exception");
dlg->m_run.EnableWindow( TRUE);
return 0;
}
continue;
}
}
}
}
CString CXdsloadDlg::ExceptionString( DWORD code, BOOL* known)
{
if( known)
*known = TRUE;
switch( code)
{
case STATUS_WAIT_0 :
return CString( "WAIT_0");
case STATUS_ABANDONED_WAIT_0 :
return CString( "ABANDONED_WAIT_0");
case STATUS_TIMEOUT :
return CString( "TIMEOUT");
case STATUS_PENDING :
return CString( "PENDING");
case STATUS_SEGMENT_NOTIFICATION :
return CString( "SEGMENT_NOTIFICATION");
case STATUS_GUARD_PAGE_VIOLATION :
return CString( "GUARD_PAGE_VIOLATION");
case STATUS_DATATYPE_MISALIGNMENT :
return CString( "DATATYPE_MISALIGNMENT");
case STATUS_BREAKPOINT :
return CString( "BREAKPOINT");
case STATUS_SINGLE_STEP :
return CString( "SINGLE_STEP");
case STATUS_ACCESS_VIOLATION :
return CString( "ACCESS_VIOLATION");
case STATUS_IN_PAGE_ERROR :
return CString( "IN_PAGE_ERROR");
case STATUS_INVALID_HANDLE :
return CString( "INVALID_HANDLE");
case STATUS_NO_MEMORY :
return CString( "NO_MEMORY");
case STATUS_ILLEGAL_INSTRUCTION :
return CString( "ILLEGAL_INSTRUCTION");
case STATUS_NONCONTINUABLE_EXCEPTION :
return CString( "NONCONTINUABLE_EXCEPTION");
case STATUS_INVALID_DISPOSITION :
return CString( "INVALID_DISPOSITION");
case STATUS_ARRAY_BOUNDS_EXCEEDED :
return CString( "ARRAY_BOUNDS_EXCEEDED");
case STATUS_FLOAT_DENORMAL_OPERAND :
return CString( "FLOAT_DENORMAL_OPERAND");
case STATUS_FLOAT_DIVIDE_BY_ZERO :
return CString( "FLOAT_DIVIDE_BY_ZERO");
case STATUS_FLOAT_INEXACT_RESULT :
return CString( "FLOAT_INEXACT_RESULT");
case STATUS_FLOAT_INVALID_OPERATION :
return CString( "FLOAT_INVALID_OPERATION");
case STATUS_FLOAT_OVERFLOW :
return CString( "FLOAT_OVERFLOW");
case STATUS_FLOAT_STACK_CHECK :
return CString( "FLOAT_STACK_CHECK");
case STATUS_FLOAT_UNDERFLOW :
return CString( "FLOAT_UNDERFLOW");
case STATUS_INTEGER_DIVIDE_BY_ZERO :
return CString( "INTEGER_DIVIDE_BY_ZERO");
case STATUS_INTEGER_OVERFLOW :
return CString( "INTEGER_OVERFLOW");
case STATUS_PRIVILEGED_INSTRUCTION :
return CString( "PRIVILEGED_INSTRUCTION");
case STATUS_STACK_OVERFLOW :
return CString( "STACK_OVERFLOW");
case STATUS_CONTROL_C_EXIT :
return CString( "CONTROL_C_EXIT");
case STATUS_FLOAT_MULTIPLE_FAULTS :
return CString( "FLOAT_MULTIPLE_FAULTS");
case STATUS_FLOAT_MULTIPLE_TRAPS :
return CString( "FLOAT_MULTIPLE_TRAPS");
case STATUS_ILLEGAL_VLM_REFERENCE :
return CString( "ILLEGAL_VLM_REFERENCE");
default:
if( known)
*known = FALSE;
CString str;
str.Format( "Unknown (0x%08X)", code);
return str;
}
}
CString CXdsloadDlg::DebugEventString( DWORD code, BOOL *known)
{
if( known)
*known = TRUE;
switch( code)
{
case EXCEPTION_DEBUG_EVENT:
return CString( "EXCEPTION_DEBUG_EVENT");
case CREATE_THREAD_DEBUG_EVENT:
return CString( "CREATE_THREAD_DEBUG_EVENT");
case CREATE_PROCESS_DEBUG_EVENT:
return CString( "CREATE_PROCESS_DEBUG_EVENT");
case EXIT_THREAD_DEBUG_EVENT:
return CString( "EXIT_THREAD_DEBUG_EVENT");
case EXIT_PROCESS_DEBUG_EVENT:
return CString( "EXIT_PROCESS_DEBUG_EVENT");
case LOAD_DLL_DEBUG_EVENT:
return CString( "LOAD_DLL_DEBUG_EVENT");
case UNLOAD_DLL_DEBUG_EVENT:
return CString( "UNLOAD_DLL_DEBUG_EVENT");
case OUTPUT_DEBUG_STRING_EVENT:
return CString( "OUTPUT_DEBUG_STRING_EVENT");
case RIP_EVENT:
return CString( "RIP_EVENT");
default:
if( known)
*known = FALSE;
CString str;
str.Format( "Unknown (0x%08X)", code);
return str;
}
}
void CXdsloadDlg::OnCancel()
{
// TODO: Add extra cleanup here
CDialog::OnCancel();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -