📄 accmap.c
字号:
error_exit:
if( pMem )
UnmapViewOfFile( pMem );
if( hFileMap )
CloseHandle( hFileMap );
return( bSuccess );
#undef BUFSIZE
}
/*
* AddLib - a new library has loaded
*/
void AddLib( BOOL is_16, IMAGE_NOTE *im )
{
lib_load_info *lli;
ModuleTop++;
lli = LocalAlloc( LMEM_FIXED, ModuleTop*sizeof( lib_load_info ) );
memset( lli, 0, ModuleTop*sizeof( lib_load_info ) );
memcpy( lli, moduleInfo, ( ModuleTop - 1 ) *sizeof( lib_load_info ) );
LocalFree( moduleInfo );
moduleInfo = lli;
lli = &moduleInfo[ModuleTop - 1];
#ifndef WOW
(void)im, (void)is_16; // Unused
#else
if( is_16 ) {
lli->is_16 = TRUE;
lli->has_real_filename = TRUE;
lli->file_handle = 0;
lli->base = 0;
lli->newly_loaded = TRUE;
lli->newly_unloaded = FALSE;
strcpy( lli->filename, im->FileName );
strcpy( lli->modname, im->Module );
} else
#endif
{
lli->is_16 = FALSE;
lli->has_real_filename = FALSE;
/*
* for a 32-bit DLL, we make up a fake name to tell the debugger
* when the debugger asks to open this fake name, we return the
* saved file handle
*/
lli->file_handle = DebugEvent.u.LoadDll.hFile;
lli->base = DebugEvent.u.LoadDll.lpBaseOfDll;
lli->modname[0] = 0;
if ( NameFromHandle( lli->file_handle, lli->filename) ) {
lli->has_real_filename = TRUE;
} else if( NameFromProcess( lli, DebugeePid, lli->filename ) ) {
lli->has_real_filename = TRUE;
} else if( !GetModuleName( lli->file_handle, lli->filename ) ) {
lastLib++;
strcpy( lli->filename, libPrefix );
ultoa( lastLib, &lli->filename[sizeof( libPrefix ) - 1], 16 );
strcat( lli->filename, ".dll" );
}
FillInExceptInfo( lli );
lli->newly_loaded = TRUE;
lli->newly_unloaded = FALSE;
}
}
void DelLib( void )
{
unsigned i;
for( i = 0; i < ModuleTop; ++i ) {
if( moduleInfo[i].base == DebugEvent.u.UnloadDll.lpBaseOfDll ) {
moduleInfo[i].newly_unloaded = TRUE;
moduleInfo[i].base = NULL;
moduleInfo[i].code_size = 0;
if( moduleInfo[i].file_handle != INVALID_HANDLE_VALUE ) {
CloseHandle( moduleInfo[i].file_handle );
moduleInfo[i].file_handle = INVALID_HANDLE_VALUE;
}
break;
}
}
}
void DelProcess( BOOL closeHandles )
{
unsigned i;
for( i = 0; i < ModuleTop; ++i ) {
if( closeHandles ) {
CloseHandle( moduleInfo[i].file_handle );
moduleInfo[i].file_handle = INVALID_HANDLE_VALUE;
}
moduleInfo[i].base = NULL;
moduleInfo[i].code_size = 0;
}
}
/*
* force16SegmentLoad - force a wow app to access its segment so that it
* will be loaded into memory.
*/
#ifdef WOW
#define INS_BYTES 7
static void force16SegmentLoad( thread_info *ti, WORD sel )
{
static char getMemIns[INS_BYTES] = {
0x8e, 0xc0, 0x26, 0xa1, 0x00, 0x00, 0xcc
};
static char origBytes[INS_BYTES];
static BOOL gotOrig;
auto CONTEXT con;
auto CONTEXT oldcon;
if( !UseVDMStuff ) {
return;
}
if( !gotOrig ) {
gotOrig = TRUE;
ReadMem( WOWAppInfo.segment, WOWAppInfo.offset, origBytes, INS_BYTES );
}
WriteMem( WOWAppInfo.segment, WOWAppInfo.offset, getMemIns, INS_BYTES );
MyGetThreadContext( ti, &con );
oldcon = con;
con.Eax = sel;
con.Eip = WOWAppInfo.offset;
con.SegCs = WOWAppInfo.segment;
MySetThreadContext( ti, &con );
DebugExecute( STATE_IGNORE_DEBUG_OUT | STATE_IGNORE_DEAD_THREAD |
STATE_EXPECTING_FAULT, NULL, FALSE );
MySetThreadContext( ti, &oldcon );
WriteMem( WOWAppInfo.segment, WOWAppInfo.offset, origBytes, INS_BYTES );
}
#endif
unsigned ReqMap_addr( void )
{
int i;
HANDLE handle;
DWORD bytes;
pe_object obj;
WORD seg;
map_addr_req *acc;
map_addr_ret *ret;
header_info hi;
lib_load_info *lli;
WORD stack;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
seg = acc->in_addr.segment;
switch( seg ) {
case MAP_FLAT_CODE_SELECTOR:
case MAP_FLAT_DATA_SELECTOR:
seg = 0;
break;
default:
--seg;
break;
}
lli = &moduleInfo[acc->handle];
#ifdef WOW
if( lli->is_16 ) {
LDT_ENTRY ldt;
WORD sel;
thread_info *ti;
/*
* much simpler for a WOW app. We just ask for the selector that
* maps to the given segment number.
*/
ti = FindThread( DebugeeTid );
pVDMGetModuleSelector( ProcessInfo.process_handle,
ti->thread_handle, seg, lli->modname, &sel );
pVDMGetThreadSelectorEntry( ProcessInfo.process_handle,
ti->thread_handle, sel, &ldt );
if( !ldt.HighWord.Bits.Pres ) {
/*
* if the segment is not present, then we make the app load it
*/
force16SegmentLoad( ti, sel );
}
ret->out_addr.segment = sel;
ret->out_addr.offset = 0;
} else
#endif
{
/*
* for a 32-bit app, we get the PE header. We can look the up the
* object in the header and determine if it is code or data, and
* use that to assign the appropriate selector (either FlatCS
* or FlatDS).
*/
handle = lli->file_handle;
if( !GetEXEHeader( handle, &hi, &stack ) ) {
return( 0 );
}
if( hi.sig == EXE_PE ) {
for( i = 0; i < hi.peh.num_objects; i++ ) {
ReadFile( handle, &obj, sizeof( obj ), &bytes, NULL );
if( i == seg ) {
break;
}
}
if( i == hi.peh.num_objects ) {
return( 0 );
}
if( obj.flags & ( PE_OBJ_CODE | PE_OBJ_EXECUTABLE ) ) {
ret->out_addr.segment = FlatCS;
} else {
ret->out_addr.segment = FlatDS;
}
ret->out_addr.offset = ( DWORD ) lli->base + obj.rva;
} else {
return( 0 );
}
}
addSegmentToLibList( acc->handle, ret->out_addr.segment,
ret->out_addr.offset );
ret->out_addr.offset += acc->in_addr.offset;
ret->lo_bound = 0;
ret->hi_bound = ~( addr48_off ) 0;
return( sizeof( *ret ) );
}
/*
* AccGetLibName - get lib name of current module
*/
unsigned ReqGet_lib_name( void )
{
get_lib_name_req *acc;
get_lib_name_ret *ret;
char *name;
unsigned i;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
name = GetOutPtr( sizeof( *ret ) );
ret->handle = 0;
for( i = 0; i < ModuleTop; ++i ) {
if( moduleInfo[i].newly_unloaded ) {
ret->handle = i;
name[0] = '\0';
moduleInfo[i].newly_unloaded = FALSE;
return( sizeof( *ret ) );
} else if( moduleInfo[i].newly_loaded ) {
ret->handle = i;
strcpy( name, moduleInfo[i].filename );
moduleInfo[i].newly_loaded = FALSE;
/*
* once the debugger asks for a lib name, we also add it to our lib
* list. This list is used to dump the list of all DLL's, and their
* selectors
*/
addModuleToLibList( i );
return( sizeof( *ret ) + strlen( name ) + 1 );
}
}
return( sizeof( *ret ) );
}
/*
* GetMagicalFileHandle - check if name is already opened by NT
*/
HANDLE GetMagicalFileHandle( char *name )
{
DWORD i;
for( i = 0; i < ModuleTop; i++ ) {
if( !stricmp( name, moduleInfo[i].filename ) ) {
if( moduleInfo[i].has_real_filename ) {
return( NULL );
} else {
return( moduleInfo[i].file_handle );
}
}
}
return( NULL );
}
/*
* IsMagicalFileHandle - test if a handle is one given by NT
*/
BOOL IsMagicalFileHandle( HANDLE h )
{
DWORD i;
for( i = 0; i < ModuleTop; i++ ) {
if( moduleInfo[i].file_handle == h ) {
return( TRUE );
}
}
return( FALSE );
}
#if 0
static lib_list_info *currInfo;
static int currSeg;
/*
* formatSel - format a selector for display
*/
static void formatSel( char *buff, int verbose )
{
thread_info *ti;
LDT_ENTRY ldt;
DWORD base;
DWORD limit;
DWORD off;
WORD seg;
seg = currInfo->segs[currSeg].segment;
off = currInfo->segs[currSeg].offset;
if( currInfo->is_16 ) {
wsprintf( buff, "%04x", seg );
} else {
wsprintf( buff, "%04x:%08lx", seg, off );
}
if( verbose ) {
ti = FindThread( DebugeeTid );
GetThreadSelectorEntry( ti->thread_handle, seg, &ldt );
base = off + ( DWORD ) ldt.BaseLow +
( ( DWORD ) ldt.HighWord.Bytes.BaseMid << 16L ) +
( ( DWORD ) ldt.HighWord.Bytes.BaseHi << 24L );
buff = &buff[strlen( buff )];
limit = 1 + ( DWORD ) ldt.LimitLow +
( ( DWORD ) ldt.HighWord.Bits.LimitHi << 16L );
if( ldt.HighWord.Bits.Granularity ) {
limit *= 0x1000L;
}
if( currInfo->is_16 ) {
wsprintf( buff, " - base:%08lx size:%04x", base, limit );
} else {
wsprintf( buff, " - base:%08lx size:%08lx", base, limit );
}
}
}
/*
* DoListLibs - format up lib list info. This is called repeatedly by
* the debugger to dump all DLL's and their segments
*/
int DoListLibs( char *buff, int is_first, int want_16, int want_32,
int verbose, int sel )
{
BOOL done;
sel = sel;
verbose = verbose;
if( is_first ) {
currInfo = listInfoHead;
currSeg = -1;
}
done = FALSE;
while( !done ) {
if( currInfo == NULL ) {
return( FALSE );
}
if( ( currInfo->is_16 && want_16 )
|| ( !currInfo->is_16 && want_32 ) ) {
done = TRUE;
if( currSeg == -1 ) {
wsprintf( buff, "%s (%s):", currInfo->modname,
currInfo->filename );
} else {
formatSel( buff, verbose );
}
} else {
currSeg = currInfo->segcount - 1;
}
if( currSeg == currInfo->segcount - 1 ) {
currInfo = currInfo->next;
currSeg = -1;
} else {
currSeg++;
}
}
return( TRUE );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -