📄 image.cpp
字号:
#include "pch.h"
#include "util.h"
#include "main.h"
#include "image.h"
Module::Module ( )
{
m_dwRefCount = 0 ;
}
Module::~Module ( )
{
Dispose ( ) ;
}
void Module::AddRef ( )
{
m_dwRefCount++ ;
}
void Module::Release ( )
{
m_dwRefCount-- ;
}
void Module::MakeInvalid ( )
{
m_bInvalid = TRUE ;
Dispose ( ) ;
}
void Module::Dispose ( )
{
// dispose content
int i , n = m_arFunction.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Function* f = ( Function* ) m_arFunction [ i ] ;
delete f ;
}
m_arFunction.RemoveAll ( ) ;
}
Export::Export ( )
{
m_bDynamic = FALSE ;
}
Export::~Export ( )
{
Dispose ( ) ;
}
void Export::MakeRoom ( )
{
// alloc memory for hooked item
int i , n = m_pModule->m_arFunction.GetSize ( ) ;
m_arHook.SetSize ( n ) ;
for ( i = 0 ; i < n ; i++ )
{
m_arHook [ i ] = FALSE ;
}
}
void Export::Dispose ( )
{
int i , n = m_arImport.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Export* p = ( Export* ) m_arImport [ i ] ;
delete p ;
}
m_arImport.RemoveAll ( ) ;
}
CImageFile::CImageFile ( )
{
m_pRoot = NULL ;
}
CImageFile::~CImageFile ( )
{
if ( m_pRoot != NULL )
delete m_pRoot ;
int i , n = m_arModule.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Module* p = ( Module* ) m_arModule [ i ] ;
delete p ;
}
}
Export* CImageFile::ParseModule ( LPCTSTR pFile , LPCTSTR pPath )
{
CString pn ;
Module* pm ;
Export* p ;
// create a node and set basic information
p = new Export ;
xSearchModule ( pFile , pPath , pn ) ;
int i , n = m_arModule.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
pm = ( Module* ) m_arModule [ i ] ;
if ( pm->m_strPath.CompareNoCase ( pn ) == 0 )
{
pm->AddRef ( ) ;
p->m_bRepeat = TRUE ;
p->m_pModule = pm ;
p->MakeRoom ( ) ;
return p;
}
}
pm = new Module ;
m_arModule.Add ( pm ) ;
pm->AddRef ( ) ;
pm->m_strShort = pFile ;
pm->m_strPath = pn ;
pm->m_strShort.MakeUpper ( ) ;
pm->m_strPath.MakeUpper ( ) ;
pm->m_bInvalid = FALSE ;
p->m_bRepeat = FALSE ;
p->m_pModule = pm ;
LOADED_IMAGE img ;
// load image file
if ( FALSE == xMapAndLoad ( pn , img ) )
{
pm->MakeInvalid ( ) ;
p->MakeRoom ( ) ;
return p ;
}
TRY
{
// parse PE file to get export information
IMAGE_DATA_DIRECTORY dd = img.FileHeader->\
OptionalHeader.DataDirectory [ IMAGE_DIRECTORY_ENTRY_EXPORT ] ;
PIMAGE_EXPORT_DIRECTORY ped = ( PIMAGE_EXPORT_DIRECTORY )
xFromRVA ( dd.VirtualAddress , img ) ;
Function* f ;
CHAR name [ MAX_PATH ] ;
DWORD *pn , *pf ;
WORD *po ;
int i , j , n1 , n2 , n3;
if ( ped != NULL )
{
n1 = ped->NumberOfFunctions ;
n2 = ped->NumberOfNames ;
pn = ( DWORD* ) xFromRVA ( ped->AddressOfNames , img ) ;
pf = ( DWORD* ) xFromRVA ( ped->AddressOfFunctions , img ) ;
po = ( WORD* ) xFromRVA ( ped->AddressOfNameOrdinals , img );
for ( i = 0 ; i < n1 ; i++ )
{
if ( pf [ i ] == 0 ) continue ;
// an exported function
f = new Function ;
f->m_wOrdinal = ( WORD ) ( ped->Base + i ) ;
f->m_dwEntry = pf [ i ] ;
for ( j = 0 ; j < n2 ; j++ )
{
if ( po [ j ] == i )
break ;
}
if ( j == n2 )
{
f->m_bHasName = FALSE ;
f->m_strName.Empty ( ) ;
}
else
{
f->m_bHasName = TRUE ;
f->m_strName = ( LPSTR ) xFromRVA ( pn [ j ] , img ) ;
if ( UnDecorateSymbolName ( f->m_strName , name , MAX_PATH , UNDNAME_COMPLETE ) )
f->m_strUnDecorateName = name ;
else f->m_strUnDecorateName = f->m_strName ;
}
// check for forward-function
if ( dd.VirtualAddress <= pf [ i ] &&
pf [ i ] < dd.VirtualAddress + dd.Size )
{
f->m_bForward = TRUE ;
f->m_strForward = ( LPSTR ) xFromRVA ( pf [ i ] , img ) ;
}
else
{
f->m_bForward = FALSE ;
f->m_strForward.Empty ( ) ;
}
n3 = pm->m_arFunction.Add ( f ) ;
// use map to accelerate
pm->m_mapOrdinal [ f->m_wOrdinal ] = ( void* ) n3 ;
if ( f->m_bHasName == TRUE )
{
pm->m_mapName [ f->m_strName ] = ( void* ) n3 ;
}
}
}
}
CATCH_ALL ( CException )
{
pm->MakeInvalid ( ) ; // format is invalid
}
END_CATCH_ALL ;
UnMapAndLoad ( &img ) ;
p->MakeRoom ( ) ;
return p ;
}
void CImageFile::ParseImage ( LPCTSTR pFile , LPCTSTR pPath )
{
CPtrList q ;
m_pRoot = ParseModule ( pFile , pPath ) ;
q.AddTail ( m_pRoot ) ;
while ( FALSE == q.IsEmpty ( ) )
{
ParseImage (
( Export* ) q.RemoveHead ( ) ,
pPath ,
q ) ;
}
}
void CImageFile::ParseImage ( Export* pExport , LPCTSTR pPath , CPtrList &q )
{
Module* pm = pExport->m_pModule ;
CString pn ;
if ( pExport->m_bRepeat == TRUE ||
pm->m_bInvalid == TRUE )
return ;
pn = pm->m_strPath ;
LOADED_IMAGE img ;
xMapAndLoad ( pn , img ) ;
CPtrList q2 ;
TRY
{
PIMAGE_IMPORT_DESCRIPTOR pid ;
PIMAGE_THUNK_DATA ptd ;
PIMAGE_IMPORT_BY_NAME pibn ;
Export* pi ;
WORD n , i ;
// parse PE file to get import information
pid = ( PIMAGE_IMPORT_DESCRIPTOR )
xFromRVA ( img.FileHeader->OptionalHeader.DataDirectory \
[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress , img ) ;
while ( pid != NULL && pid->FirstThunk )
{
pi = ParseModule ( ( LPSTR ) xFromRVA ( pid->Name , img ) , pPath ) ;
pi->m_dwTableBase = pid->FirstThunk ;
if ( pi->m_pModule->m_bInvalid == FALSE )
{
ptd = ( PIMAGE_THUNK_DATA ) xFromRVA (
pid->OriginalFirstThunk , img ) ;
if ( ptd == NULL )
{
ptd = ( PIMAGE_THUNK_DATA )
xFromRVA ( pid->FirstThunk , img ) ;
}
i = 0 ;
while ( ptd != NULL && ptd->u1.Ordinal != 0 )
{
if ( ptd->u1.Ordinal & 0x80000000 ) // by ordinal
{
n = ( WORD ) ( ptd->u1.Ordinal & 0xffff ) ;
n = ( WORD ) pi->m_pModule->m_mapOrdinal [ n ] ;
}
else // by name
{
pibn = ( PIMAGE_IMPORT_BY_NAME ) xFromRVA (
ptd->u1.Ordinal , img ) ;
n = ( WORD ) pi->m_pModule->m_mapName [ ( CString ) pibn->Name ] ;
}
pi->m_arExport.Add ( n ) ; // record by ordinal
pi->m_arPatch.Add ( i ) ;
ptd++ ;
i++ ;
}
}
q2.AddTail ( pi ) ;
pExport->m_arImport.Add ( pi ) ;
pid++ ;
}
}
CATCH_ALL ( CException )
{
// invalid format
q2.RemoveAll ( ) ;
pExport->Dispose ( ) ;
}
END_CATCH_ALL ;
UnMapAndLoad ( &img ) ;
q.AddTail ( &q2 ) ;
}
void CImageFile::Present ( CTreeCtrl& ctrl )
{
// show it to user
Present ( ctrl , m_pRoot , TVI_ROOT ) ;
}
void CImageFile::Present ( CTreeCtrl& ctrl , Export* pExport , HTREEITEM hParent )
{
HTREEITEM h ;
// set item information
int in =
!!pExport->m_pModule->m_bInvalid * 4 +
!!pExport->m_bDynamic * 2 +
!!pExport->m_bRepeat ;
h = ctrl.InsertItem ( pExport->m_pModule->m_strShort , in , in , hParent ) ;
ctrl.SetItemData ( h , ( DWORD ) pExport ) ;
int i , n = pExport->m_arImport.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Export* p = ( Export* ) pExport->m_arImport [ i ] ;
Present ( ctrl , p , h ) ;
}
}
void CImageFile::AddModule ( CTreeCtrl& ctrl ,
LPCTSTR pFile ,
LPCTSTR pPath )
{
CPtrList q ;
HTREEITEM h = ctrl.GetSelectedItem ( ) ;
Export* pp = ( Export* ) ctrl.GetItemData ( h ) ;
Export* p = ParseModule ( pFile , pPath ) ;
q.AddTail ( p ) ;
// parse and add a module to current dependency tree
while ( FALSE == q.IsEmpty ( ) )
{
ParseImage (
( Export* ) q.RemoveHead ( ) ,
pPath ,
q ) ;
}
p->m_bDynamic = TRUE ;
pp->m_arImport.Add ( p ) ;
Present ( ctrl , p , h ) ;
}
void CImageFile::RemoveModule ( CTreeCtrl& ctrl )
{
// remove a module from current dependency tree
HTREEITEM h = ctrl.GetSelectedItem ( ) , hp ;
Export *pp , *p = ( Export* ) ctrl.GetItemData ( h ) ;
hp = ctrl.GetParentItem ( h ) ;
pp = ( Export* ) ctrl.GetItemData ( hp ) ;
ctrl.DeleteItem ( h ) ;
p->m_pModule->Release ( ) ;
delete p ;
int i , n = pp->m_arImport.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Export* pi = ( Export* ) pp->m_arImport [ i ] ;
if ( pi == p )
{
pp->m_arImport.RemoveAt ( i ) ;
ResetModule ( ) ;
break ;
}
}
}
void CImageFile::ResetModule ( )
{
// remove all
int i , n = m_arModule.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Module* pm = ( Module* ) m_arModule [ i ] ;
if ( pm->m_dwRefCount == 0 )
{
m_arModule.RemoveAt ( i ) ;
delete pm ;
break ;
}
}
}
void CImageFile::GetHooked ( CPtrArray& ar )
{
RELEASE_PTR_ARRAY ( ar , Hooked ) ;
GetHooked ( ar , m_pRoot , NULL ) ;
}
void CImageFile::GetHooked ( CPtrArray& ar , Export* pExport1 , Export* pExport2 )
{
// get all selected for hooking
Hooked* ph ;
Function* f ;
Module *pm1 , *pm2 ;
BOOL* pt ;
int i , n ;
if ( pExport2 != NULL )
{
pm1 = pExport1->m_pModule ;
pm2 = pExport2->m_pModule ;
n = pExport1->m_arHook.GetSize ( ) ;
pt = new int [ n ] ;
for ( i = 0 ; i < n ; i++ )
{
pt [ i ] = -1 ;
}
n = pExport1->m_arExport.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
int n2 = pExport1->m_arExport [ i ] ;
pt [ pExport1->m_arExport [ i ] ] =
pExport1->m_arPatch [ i ] ;
}
n = pExport1->m_arHook.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
if ( pExport1->m_arHook [ i ] == FALSE ) continue ; // not selected
// insert hook item
f = ( Function* ) pm1->m_arFunction [ i ] ;
ph = new Hooked ;
ph->m_strImportPathName = pm2->m_strPath ;
ph->m_strImportName = pm2->m_strShort ;
ph->m_strExportPathName = pm1->m_strPath ;
ph->m_strExportName = pm1->m_strShort ;
ph->m_bHasName = f->m_bHasName ;
ph->m_strFunction = f->m_strName ;
ph->m_dwOrdinal = f->m_wOrdinal ;
if ( pt [ i ] != -1 )
{
ph->m_dwTableBase = pExport1->m_dwTableBase ;
ph->m_nIndex = pt [ i ] ;
}
else
{
ph->m_dwTableBase = 0 ;
}
ph->m_nHookedIndex = ar.Add ( ph ) ;
}
delete[] pt ;
}
n = pExport1->m_arImport.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
Export* p = ( Export* ) pExport1->m_arImport [ i ] ;
GetHooked ( ar , p , pExport1 ) ;
}
}
void CImageFile::SetImport ( CTreeCtrl& ctrl , BOOL bHook )
{
HTREEITEM h = ctrl.GetSelectedItem ( ) ;
Export* p ;
h = ctrl.GetChildItem ( h ) ;
while ( h != NULL )
{
p = ( Export* ) ctrl.GetItemData ( h ) ;
int i , n = p->m_arHook.GetSize ( ) ;
for ( i = 0; i < n ; i++ )
{
p->m_arHook [ i ] = bHook ;
}
if ( bHook == TRUE )
{
ctrl.SetItemState ( h, -1, TVIS_BOLD ) ;
}
else
{
ctrl.SetItemState ( h, 0, TVIS_BOLD ) ;
}
h = ctrl.GetNextItem ( h , TVGN_NEXT ) ;
}
}
void CImageFile::SetTree ( CTreeCtrl& ctrl , BOOL bHook )
{
HTREEITEM h = ctrl.GetSelectedItem ( ) ;
h = ctrl.GetChildItem ( h ) ;
while ( h != NULL )
{
SetTree ( ctrl , h , bHook ) ;
h = ctrl.GetNextItem ( h , TVGN_NEXT ) ;
}
}
void CImageFile::SetTree ( CTreeCtrl& ctrl , HTREEITEM h , BOOL bHook )
{
// refresh tree for displaying
Export* p = ( Export* ) ctrl.GetItemData ( h ) ;
int i , n = p->m_arHook.GetSize ( ) ;
for ( i = 0 ; i < n ; i++ )
{
p->m_arHook [ i ] = bHook ;
}
if ( bHook == TRUE )
{
ctrl.SetItemState ( h, -1, TVIS_BOLD ) ;
}
else
{
ctrl.SetItemState ( h, 0, TVIS_BOLD ) ;
}
h = ctrl.GetChildItem ( h ) ;
while ( h != NULL )
{
SetTree ( ctrl , h , bHook ) ;
h = ctrl.GetNextItem ( h , TVGN_NEXT ) ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -