/* * CheckIsModuleWin32App - check if a given module handle is a win32 app */ bool CheckIsModuleWin32App( HMODULE hmod, WORD *win32ds, WORD *win32cs, DWORD *win32initialeip ) { GLOBALENTRY ge; winext_data wedata; int segnum; *win32cs = *win32ds = 0; ge.dwSize = sizeof( GLOBALENTRY ); if( !GlobalEntryModule( &ge, hmod, 1 ) ) { return( false ); } ReadMem( (WORD)ge.hBlock, 0, (LPVOID) &wedata, sizeof( wedata ) ); if( memcmp( wedata.sig, win386Sig, sizeof( win386Sig) ) == 0 || memcmp( wedata.sig, win386Sig2, sizeof( win386Sig2) ) == 0 ) { if( memcmp( wedata.new_sig, win386Sig, sizeof( win386Sig ) ) == 0 ) { segnum = 2; } else { segnum = 3; } if( !GlobalEntryModule( &ge, hmod, segnum ) ) { return( false ); } ReadMem( (WORD)ge.hBlock, wedata.dataseg_off, (LPVOID)win32ds, sizeof( WORD ) ); ReadMem( (WORD)ge.hBlock, wedata.stacksize_off, (LPVOID)win32initialeip, sizeof( DWORD ) ); ReadMem( (WORD)ge.hBlock, wedata.codeinfo_off + 4, (LPVOID)win32cs, sizeof( WORD ) ); return( true ); } return( false ); } /* CheckIsModuleWin32App */
/* * DIPCliMapAddr * Possibilites: * 1) We are mapping segments for a 32-bit extended app. In this case, * we return the segment:offset returned by CheckIsModuleWin32App * 2) We are mapping a segment for a 16-bit app that is NOT a load * on call segment. In this case, GlobalEntryModule works and * we return the value we obtain from it * 3) We are mapping a segment for a 16-bit app that IS a load * on call segment. In this case, GlobalEntryModule FAILS (stupid * f*cking Windows) and so we have to go find it ourselves using * horkyFindSegment. */ void DIGCLIENT DIPCliMapAddr( addr_ptr *addr, void *info ) { GLOBALENTRY ge; LPVOID ptr; WORD sel; WORD cs,ds; DWORD off; DEBUGOUT( "mapaddr" ); info = info; if( CheckIsModuleWin32App( DTModuleEntry.hModule, &ds, &cs, &off ) ) { addr->segment = cs; addr->offset = off; } else { ge.dwSize = sizeof( ge ); if( !GlobalEntryModule( &ge, DTModuleEntry.hModule, addr->segment ) ) { addr->segment = horkyFindSegment( DTModuleEntry.hModule, addr->segment ); } ptr = GlobalLock( ge.hBlock ); GlobalUnlock( ge.hBlock ); sel = FP_SEG( ptr ); if( sel == NULL ) { sel = (WORD)ge.hBlock + 1; } addr->segment = sel; addr->offset = 0; } }
BOOL MyGlobalEntryModule( GLOBALENTRY *ge, HMODULE hmod, WORD seg ) { ge->dwSize = sizeof( GLOBALENTRY ); return( GlobalEntryModule( ge, hmod, seg ) ); } /* MyGlobalEntryModule */
/* * FlagWin32AppAsDebugged - check if a given module handle is a Win32 application */ void FlagWin32AppAsDebugged( HMODULE hmod ) { GLOBALENTRY ge; winext_data wedata; ge.dwSize = sizeof( GLOBALENTRY ); if( !GlobalEntryModule( &ge, hmod, 1 ) ) { return; } ReadMem( (WORD)ge.hBlock, 0, (LPVOID)&wedata, sizeof( wedata ) ); if( !memcmp( wedata.sig, win386Sig, sizeof( win386Sig ) ) ) { WriteMem( (WORD)ge.hBlock, 0, win386Sig2, 4 ); } } /* FlagWin32AppAsDebugged */
/* * ReqMap_addr * * Access request to map a segment number to a selector. * Possibilites: * 1) We are mapping segments for a 32-bit extended app. In this case, * we return the segment:offset returned by CheckIsModuleWin32App * 2) We are mapping a segment for a 16-bit app that is NOT a load * on call segment. In this case, GlobalEntryModule works and * we return the value we obtain from it * 3) We are mapping a segment for a 16-bit app that IS a load * on call segment. In this case, GlobalEntryModule FAILS (stupid * f*cking Windows) and so we have to go find it ourselves using * horkyFindSegment. Once horkyFindSegment is done, GlobalEntryModule * will give the right answer, and we return the value we obtain from it. */ trap_retval ReqMap_addr( void ) { GLOBALENTRY ge; LPVOID ptr; WORD sel; WORD cs,ds; DWORD off; int module; addr_seg in_seg; map_addr_req *acc; map_addr_ret *ret; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); ret->out_addr = acc->in_addr; ret->lo_bound = 0; ret->hi_bound = ~(addr48_off)0; module = acc->handle; in_seg = acc->in_addr.segment; if( CheckIsModuleWin32App( moduleIDs[ module ], &ds, &cs, &off ) ) { Out((OUT_MAP,"is 32 bit module")); if( in_seg == MAP_FLAT_DATA_SELECTOR ) { ret->out_addr.segment = ds; } else { ret->out_addr.segment = cs; } ret->out_addr.offset = off; } else { switch( in_seg ) { case MAP_FLAT_CODE_SELECTOR: case MAP_FLAT_DATA_SELECTOR: in_seg = 1; break; } ge.dwSize = sizeof( ge ); if( !GlobalEntryModule( &ge, moduleIDs[ module ], in_seg ) ) { if( horkyFindSegment( module, in_seg ) ) { if( !GlobalEntryModule( &ge, moduleIDs[ module ], in_seg ) ) { Out((OUT_MAP,"GlobalEntry 2nd time failed" )); return( sizeof( *ret ) ); } } else { Out(( OUT_MAP,"Well I'll be! horkyFindSegment failed" )); return( sizeof( *ret ) ); } } ptr = GlobalLock( ge.hBlock ); GlobalUnlock( ge.hBlock ); sel = FP_SEG( ptr ); if( sel == NULL ) { sel = (WORD)ge.hBlock + 1; } ret->out_addr.segment = sel; ret->out_addr.offset = 0; } ret->out_addr.offset += acc->in_addr.offset; if( module == 0 ) { Out(( OUT_MAP,"in=%4.4x:%8.8lx out=%4.4x:%8.8lx", acc->in_addr.segment, acc->in_addr.offset, ret->out_addr.segment, ret->out_addr.offset )); } return( sizeof( *ret ) ); }