📄 debug.cpp
字号:
}
if ( ( DWORD ) addr & 0xffff0000 ) // by name
{
CString fn ;
ReadString ( addr , fn ) ;
n = LocateHookedByName ( pm1 , pm2 , fn ) ;
}
else // by ordinal
{
n = LocateHookedByOrdinal ( pm1 , pm2 ,
( WORD ) ( ( DWORD ) addr & 0xffff ) ) ;
}
pThread->m_stDelay.AddTail ( n ) ;
}
}
void CDebugControl::PostDispatch ( Thread* pThread )
{
CMainApp* p = ( CMainApp* ) AfxGetApp ( ) ;
Breakpoint* pb = ( Breakpoint* )
pThread->m_stBreakpoint.RemoveTail ( ) ;
if ( ( DWORD ) pb & 0x80000000 ) // in stub code
{
OnStubNotifyPost ( pThread , ( WORD ) ( ( DWORD ) pb & 0x80000000 ) ) ;
}
else
{
if ( p->m_pfnLoadLibraryExW == pb->m_lpAddress ) // after loading a module
{
SnapModule ( ) ;
}
else if ( p->m_pfnGetProcAddress == pb->m_lpAddress ) // after get a procedure pointer
{
WORD n = pThread->m_stDelay.RemoveTail ( ) ;
if ( n != ( WORD ) -1 )
{
LPVOID addr = ( LPVOID ) GetRegister ( pThread , EAX ) ;
Hooked* ph = ( Hooked* ) m_arHooked [ n ] ;
CString msg , fn ;
if ( ph->m_bHasName == FALSE )
{
fn.Format ( "(%d)" , ph->m_dwOrdinal ) ;
}
else fn = ph->m_strFunction ;
if ( IsPageExecutable ( addr ) == TRUE )
{
// get it a stub code pointer
WriteDWord (
( LPVOID ) ( ( DWORD ) m_lpMem + n * 8 + 2 ) ,
( DWORD ) addr - ( ( DWORD ) m_lpMem + n * 8 + 6 ) ) ;
SetRegister ( pThread , EAX , ( DWORD ) m_lpMem + n * 8 ) ;
msg.Format (
IDS_EXTRA_HOOK_SUCCESS ,
ph->m_strImportName ,
fn ,
ph->m_strExportName ) ;
m_pDancerDoc->m_pRecordManager->AddExtraMsg ( msg , 0 ) ;
}
else
{
msg.Format (
IDS_EXTRA_HOOK_FAILED ,
ph->m_strImportName ,
fn ,
ph->m_strExportName ) ;
m_pDancerDoc->m_pRecordManager->AddExtraMsg ( msg , 1 ) ;
}
}
}
else if ( p->m_pfnIsDebuggerPresent == pb->m_lpAddress )
{
// reset return value
SetRegister ( pThread , EAX , 0 ) ;
}
}
}
void CDebugControl::SuspendThreadExcept ( Thread* pThread )
{
int i , n = m_arThread.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Thread* p = ( Thread* ) m_arThread [ i ] ;
if ( p != pThread )
{
SuspendThread ( p->m_hThread ) ;
}
}
}
void CDebugControl::ResumeThreadExcept ( Thread* pThread )
{
int i , n = m_arThread.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Thread* p = ( Thread* ) m_arThread [ i ] ;
if ( p != pThread )
{
ResumeThread ( p->m_hThread ) ;
}
}
}
BOOL CDebugControl::IsPageExecutable ( LPVOID lpAddress )
{
MEMORY_BASIC_INFORMATION mbi ;
// query memory attribute
VirtualQueryEx (
m_hProcess ,
lpAddress ,
&mbi ,
sizeof ( MEMORY_BASIC_INFORMATION ) );
return ( mbi.Protect == PAGE_EXECUTE ) ||
( mbi.Protect == PAGE_EXECUTE_READ ) ||
( mbi.Protect == PAGE_EXECUTE_READWRITE ) ||
( mbi.Protect == PAGE_EXECUTE_WRITECOPY ) ;
}
// install hooks
void CDebugControl::PatchModule ( Module2* pModule )
{
int i , n = m_arHooked.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Hooked* p = ( Hooked* ) m_arHooked [ i ] ;
if ( p->m_dwTableBase == 0 )
continue ;
if ( pModule->m_strPathName.CompareNoCase ( p->m_strImportPathName ) != 0 )
continue ;
// found a proper module
LPVOID entry = ( LPVOID )
( ( DWORD ) pModule->m_lpBase + p->m_dwTableBase + p->m_nIndex * 4 ) ;
LPVOID addr = ( LPVOID ) ReadDWord ( entry ) ;
CString msg , fn ;
// show patch information
if ( p->m_bHasName == FALSE )
{
fn.Format ( "(%d)" , p->m_dwOrdinal ) ;
}
else fn = p->m_strFunction ;
if ( IsPageExecutable ( addr ) == TRUE )
{
// can be patched
WriteDWord (
( LPVOID ) ( ( DWORD ) m_lpMem + i * 8 + 2 ) ,
( DWORD ) addr - ( ( DWORD ) m_lpMem + i * 8 + 6 ) ) ;
WriteDWord (
entry ,
( DWORD ) m_lpMem + i * 8 ) ;
msg.Format (
IDS_EXTRA_HOOK_SUCCESS ,
p->m_strImportName ,
fn ,
p->m_strExportName ) ;
m_pDancerDoc->m_pRecordManager->AddExtraMsg ( msg , 0 ) ;
}
else
{
msg.Format (
IDS_EXTRA_HOOK_FAILED ,
p->m_strImportName ,
fn ,
p->m_strExportName ) ;
m_pDancerDoc->m_pRecordManager->AddExtraMsg ( msg , 1 ) ;
}
}
}
void CDebugControl::OnStubNotify ( Thread* pThread , DWORD dwIndex )
{
// no need to notify
CMainApp* pp = ( CMainApp* ) AfxGetApp ( ) ;
if ( pp->m_appOption.m_bDisplay == FALSE &&
pp->m_appOption.m_bDumpFile == FALSE )
{
pThread->m_stDispatch.AddTail ( ( Record* ) NULL ) ;
return ;
}
// notify
Hooked* ph = ( Hooked* ) m_arHooked [ dwIndex ] ;
Dispatch* p = new Dispatch ;
if ( pp->m_appOption.m_bGetRegister == TRUE ) // need register information
{
p->m_pReg = new Register ;
GetAllRegister ( pThread , p->m_pReg ) ;
}
if ( ph->m_pType != NULL )
{
p->m_pParamBlock = ph->m_pType->Construct (
this , ( LPVOID ) ( GetRegister ( pThread , ESP ) + 4 ) , 0 ) ;
p->m_pType = ph->m_pType ;
}
else
{
p->m_pParamBlock = NULL ;
}
// start a dispatch information
p->m_bHasName = ph->m_bHasName ;
p->m_strFunction = ph->m_strFunction ;
p->m_wOrdinal = ( WORD ) ph->m_dwOrdinal ;
p->m_strImportName = ph->m_strImportName ;
p->m_strImportPathName = ph->m_strImportPathName ;
p->m_strExportName = ph->m_strExportName ;
p->m_strExportPathName = ph->m_strExportPathName ;
p->m_dwDepth = pThread->m_dwDepth++ ;
p->m_bExport = ( ph->m_dwTableBase != 0 ) ;
Record* pr = m_pDancerDoc->m_pRecordManager->AddHookMsg ( p ) ;
pThread->m_stDispatch.AddTail ( pr ) ;
}
// call returned
void CDebugControl::OnStubNotifyPost ( Thread* pThread , DWORD dwIndex )
{
pThread->m_dwDepth-- ;
Record* p = ( Record* ) pThread->m_stDispatch.RemoveTail ( ) ;
if ( p != NULL )
{
Type* pt = p->m_pDispatch->m_pType ;
if ( p->m_pDispatch->m_bWillDeleted == FALSE ) // not required to be deleted
{
p->m_pDispatch->m_dwReturn = GetRegister ( pThread , EAX ) ;
CMainApp* pp = ( CMainApp* ) AfxGetApp ( ) ;
if ( pp->m_appOption.m_bGetRegister == TRUE )
{
p->m_pDispatch->m_pRegPost = new Register ;
GetAllRegister ( pThread , p->m_pDispatch->m_pRegPost ) ;
}
if ( pt != NULL )
{
LPVOID addr = ( LPVOID ) p->m_pDispatch->m_dwReturn ;
ParamType* pp = &pt->m_arParam [ 0 ] ;
if ( pp->m_dwPointerDepth > 0 )
{
for ( DWORD i = 1 ; i < pp->m_dwPointerDepth ; i++ )
addr = ( LPVOID ) ReadDWord ( addr ) ;
p->m_pDispatch->m_pParamBlockPost =
pp->m_pType->Construct ( this , addr , pp->m_dwPointerDepth ) ;
}
else
{
// get paramter information
CString s ;
ParamBlock* pb ;
pb = p->m_pDispatch->m_pParamBlockPost = new ParamBlock ;
ParamType* ppt = &pt->m_arParam [ 0 ] ;
pb->m_bFunction = ppt->m_pType->m_bFunction ;
pb->m_bStruct = ppt->m_pType->m_bStruct ;
pb->m_pBlock = new BYTE [ 4 ] ;
* ( DWORD* ) pb->m_pBlock = p->m_pDispatch->m_dwReturn ;
pb->m_dwSize = 4 ;
pb->m_strMsg = pp->m_pType->m_strName + " - " ;
for ( DWORD i = 0 ; i < pb->m_dwSize ; i++ )
{
s.Format ( "%02X" , pb->m_pBlock [ i ] ) ;
pb->m_strMsg += s ;
if ( i != pb->m_dwSize - 1 )
pb->m_strMsg += ' ' ;
}
}
}
m_pDancerDoc->m_pRecordManager->CompleteMsg ( p->m_pDispatch ) ;
return ;
}
else // required to be deleted
{
delete p ;
}
}
}
WORD CDebugControl::LocateHookedByName ( Module2* pModule1 ,
Module2* pModule2 ,
const CString& strName )
{
int i , n = m_arHooked.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Hooked* p = ( Hooked* ) m_arHooked [ i ] ;
if ( p->m_strImportPathName.CompareNoCase ( pModule1->m_strPathName ) == 0 &&
p->m_strExportPathName.CompareNoCase ( pModule2->m_strPathName ) == 0 )
{
if ( p->m_strFunction.Compare ( strName ) == 0 )
return i ;
}
}
return -1 ;
}
WORD CDebugControl::LocateHookedByOrdinal ( Module2* pModule1 ,
Module2* pModule2 ,
WORD wOrdinal )
{
int i , n = m_arHooked.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Hooked* p = ( Hooked* ) m_arHooked [ i ] ;
if ( p->m_strImportPathName.CompareNoCase ( pModule1->m_strPathName ) == 0 &&
p->m_strExportPathName.CompareNoCase ( pModule2->m_strPathName ) == 0 )
{
if ( p->m_dwOrdinal == wOrdinal )
return i ;
}
}
return -1 ;
}
LPVOID CDebugControl::GetReturnAddress ( Thread* pThread )
{
return ( LPVOID )
ReadDWord ( ( LPVOID ) GetRegister ( pThread , ESP ) ) ;
}
// pause debugging
void CDebugControl::Pause ( )
{
m_bPause = !m_bPause ;
if ( m_bPause == TRUE ) SuspendThreadExcept ( NULL ) ;
else ResumeThreadExcept ( NULL ) ;
}
void CDebugControl::NotifyCreateThread ( DWORD dwID , LPVOID lpAddress )
{
CString msg ;
msg.Format ( IDS_DEBUG_CREATE_THREAD , dwID , lpAddress ) ;
m_pDancerDoc->m_pRecordManager->AddDebugMsg ( msg , 0 ) ;
}
// helpers for decoder
BYTE CALLBACK CDebugControl::_ReadByte ( HANDLE hControl , LPVOID lpAddress )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
return p->ReadByte ( lpAddress ) ;
}
WORD CALLBACK CDebugControl::_ReadWord ( HANDLE hControl , LPVOID lpAddress )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
return p->ReadWord ( lpAddress ) ;
}
DWORD CALLBACK CDebugControl::_ReadDWord ( HANDLE hControl , LPVOID lpAddress )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
return p->ReadDWord ( lpAddress ) ;
}
BOOL CALLBACK CDebugControl::_ReadBlock ( HANDLE hControl , LPVOID lpAddress , LPVOID lpBuf , DWORD dwSize )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
return p->ReadBlock ( lpAddress , lpBuf , dwSize ) ;
}
void CALLBACK CDebugControl::_RegisterDecoder ( HANDLE hControl , LPCSTR lpTypeName ,
LPPROC_DECODE_ROUTINE lpDecodeRoutine )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
int i , n = p->m_pTypeManager->m_arTypeSet.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
TypeSet* ps = ( TypeSet* ) p->m_pTypeManager->m_arTypeSet [ i ] ;
CString tn = lpTypeName ;
Type* p = ( Type* ) ps->Query ( tn ) ;
p->m_pfnUserDecoder = lpDecodeRoutine ;
}
}
void CALLBACK CDebugControl::_OutputString ( HANDLE hControl , LPCSTR lpString )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
CString msg = lpString ;
p->m_pDancerDoc->m_pRecordManager->AddExtraMsg ( msg , 0 ) ;
}
DWORD CALLBACK CDebugControl::_ReadString ( HANDLE hControl , LPVOID lpAddress , LPVOID lpBuf )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
DWORD addr = ( DWORD ) lpAddress ;
CHAR ch ;
CString str ;
str.Empty ( ) ;
for ( ; ; )
{
if ( FALSE == p->ReadBlock ( ( LPVOID ) addr , &ch , 1 ) )
{
break ;
}
if ( ch == 0 ) break ;
str += ch ;
addr++ ;
}
lstrcpy ( ( CHAR* ) lpBuf , str ) ;
return lstrlen ( ( CHAR* ) lpBuf ) ;
}
DWORD CALLBACK CDebugControl::_ReadStringW ( HANDLE hControl , LPVOID lpAddress , LPVOID lpBuf )
{
CDebugControl* p = ( CDebugControl* ) hControl ;
DWORD addr = ( DWORD ) lpAddress , size = 0 ;
WCHAR ch , buf [ MAX_PATH ] ;
for ( ; ; )
{
if ( FALSE == p->ReadBlock ( ( LPVOID ) addr , &ch , 2 ) )
{
break ;
}
if ( ( DWORD ) ch == 0 ) break ;
buf [ size++ ] = ch ;
addr += 2 ;
}
buf [ size ] = 0 ;
WideCharToMultiByte (
CP_ACP ,
0 ,
buf ,
-1 ,
( CHAR* ) lpBuf ,
MAX_PATH ,
NULL ,
NULL ) ;
return lstrlen ( ( CHAR* ) lpBuf ) ;
}
void CDebugControl::GetAllRegister ( Thread* pThread , Register* pr )
{
CONTEXT cnt ;
cnt.ContextFlags = CONTEXT_FULL ;
GetThreadContext ( pThread->m_hThread , &cnt ) ;
pr->Eax = cnt.Eax ;
pr->Ebx = cnt.Ebx ;
pr->Ecx = cnt.Ecx ;
pr->Edx = cnt.Edx ;
pr->Ebp = cnt.Ebp ;
pr->Esp = cnt.Esp ;
pr->Esi = cnt.Esi ;
pr->Edi = cnt.Edi ;
pr->Flags = cnt.EFlags ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -