📄 show16.c
字号:
SELECTOROF(lpMODULE->ne_sssp),
OFFSETOF(lpMODULE->ne_sssp) );
if ( lpMODULE->ne_cModules )
{
LPWORD lpModuleList = MAKELP(hModule, lpMODULE->ne_modRefTab);
lbprintf( HWndDetails, "imported modules:");
for ( i=0; i < lpMODULE->ne_cModules; i++ )
{
GetModuleName( lpModuleList[i], szBuffer, sizeof(szBuffer) );
lbprintf( HWndDetails, " + %s", szBuffer );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_HMODULE,
lpModuleList[i] );
}
}
// The fields in this "if" statement are only present for the
// pseudo Win32 modules
if ( lpMODULE->ne_flags & MODFLAGS_WIN32 )
{
lbprintf( HWndDetails, "Win32 Base Addr: %08lX",
lpMODULE->ne_Win32BaseAddr1 );
assert ( lpMODULE->ne_Win32BaseAddr1 == lpMODULE->ne_Win32BaseAddr2 );
lbprintf( HWndDetails, "Win32 Resource Addr: %08lX",
lpMODULE->ne_Win32ResourceAddr );
}
lbprintf( HWndDetails, "alignment: %u bytes", 1 << lpMODULE->ne_align );
lbprintf( HWndDetails, "OtherFlags: %02X", lpMODULE->ne_flagsother );
lbprintf( HWndDetails, "ImportedNames2: %04X",
lpMODULE->ne_importedNamesTab2 );
lbprintf( HWndDetails, "ImportedNames3: %04X",
lpMODULE->ne_importedNamesTab3 );
lbprintf( HWndDetails, "SwapArea: %lXh bytes",
lpMODULE->ne_swaparea * 16L );
// These fields should be 0. If they aren't, we want to know
// about them PRONTO! There may be useful information in them.
assert ( !lpMODULE->ne_cres );
}
void ShowSegmentTableDetails(HMODULE hModule)
{
LPMODULE lpMODULE = MAKELP( hModule, 0 );
LPSEGMENT_RECORD pSeg;
char szBuffer[260];
char szModuleName[32];
unsigned i;
if ( !IsModule(hModule) )
return;
if ( lpMODULE->ne_cseg == 0 ) // Make sure there's something to see...
return;
GetModuleName( hModule, szModuleName, sizeof(szModuleName) );
wsprintf(szBuffer, "Segments for module %04X (%s)",
hModule, szModuleName);
SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
// The array of segment records starts right after the 40h NE header.
pSeg = (LPSEGMENT_RECORD)MAKELP( hModule, lpMODULE->ne_segtab );
lbprintf( HWndDetails, "SEG HNDL TYPE SIZE" );
for ( i=0; i < lpMODULE->ne_cseg; i++ )
{
lbprintf( HWndDetails, "%02X: %04X %s %04X bytes",
i+1, pSeg->handle, pSeg->flags & 1 ? "DATA" : "CODE",
pSeg->alloc_size );
pSeg++;
}
}
void ShowEntryTableDetails(HMODULE hModule)
{
LPMODULE lpMODULE = MAKELP( hModule, 0 );
LPENTRY_BUNDLE_HEADER lpBundleHdr;
LPENTRY lpEntry;
char szBuffer[260];
char szModuleName[32];
unsigned i;
if ( !IsModule(hModule) )
return;
if ( lpMODULE->ne_npEntryTable == 0 )
return;
lpBundleHdr = MAKELP( hModule, lpMODULE->ne_npEntryTable );
// Are there any entries to show???
if ( lpBundleHdr->lastEntry == lpBundleHdr->firstEntry )
return;
GetModuleName( hModule, szModuleName, sizeof(szModuleName) );
wsprintf(szBuffer, "Entry table for module %04X (%s)",
hModule, szModuleName);
SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
while ( TRUE )
{
unsigned cEntries = lpBundleHdr->lastEntry - lpBundleHdr->firstEntry;
lpEntry = (LPENTRY)(lpBundleHdr+1); // Entries start after bundle hdr
for ( i=0; i < cEntries; i++ )
{
lbprintf( HWndDetails, "%3u: %02X:%04X %s %s",
lpBundleHdr->firstEntry + 1 + i,
lpEntry->segNumber, lpEntry->offset,
lpEntry->segType == 0xFF ? "MOVEABLE" : "FIXED",
lpEntry->flags & 1 ? "EXPORTED" : "" );
lpEntry++;
}
if ( lpBundleHdr->nextBundle == 0 )
break;
lpBundleHdr = MAKELP( hModule, lpBundleHdr->nextBundle );
}
}
void ShowResourceDetails(HMODULE hModule)
{
LPMODULE lpMODULE = MAKELP( hModule, 0 );
LPRESOURCE_TYPE lpRsrcType, lpRsrcEnd;
LPRESOURCE_INFO lpRsrcInfo;
LPBYTE lpName;
char szBuffer[260];
char szModuleName[32];
unsigned i;
if ( !IsModule(hModule) )
return;
if ( lpMODULE->ne_rsrcTab == lpMODULE->ne_resNamesTab )
return;
GetModuleName( hModule, szModuleName, sizeof(szModuleName) );
wsprintf(szBuffer, "Resources for module %04X (%s)",
hModule, szModuleName);
SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
// Get a pointer to the first resource type header. The "+2" skips
// past the alignment WORD at the beginning
lpRsrcType = MAKELP( hModule, lpMODULE->ne_rsrcTab + 2);
lpRsrcEnd = MAKELP( hModule, lpMODULE->ne_resNamesTab );
while ( lpRsrcType < lpRsrcEnd )
{
if ( lpRsrcType->ID == 0 )
break;
if ( lpRsrcType->ID & 0x8000 ) // A predefined standard resource
{
lbprintf( HWndDetails, "%s - Handler: %04X:%04X",
GetResourceTypeName( lpRsrcType->ID ),
HIWORD(lpRsrcType->function),
LOWORD(lpRsrcType->function) );
}
else // A named resource
{
lpName = MAKELP(hModule, lpMODULE->ne_rsrcTab + lpRsrcType->ID );
memcpy( szBuffer, lpName+1, *lpName );
szBuffer[*lpName] = 0;
lbprintf( HWndDetails, "NamedResource %s - Handler: %04X:%04X",
szBuffer,
HIWORD(lpRsrcType->function),
LOWORD(lpRsrcType->function) );
}
lpRsrcInfo = (LPRESOURCE_INFO)(lpRsrcType+1);
for ( i = 0; i < lpRsrcType->count; i++ )
{
// If it's a named resource, so retrieve the string. The
// ID value is an offset within the resource table.
if ( !(lpRsrcInfo->ID & 0x8000) )
{
lpName = MAKELP(hModule, lpMODULE->ne_rsrcTab
+ lpRsrcInfo->ID );
memcpy( szBuffer, lpName+1, *lpName );
szBuffer[*lpName] = 0;
}
else // An integer ID resource
wsprintf(szBuffer, "%u", lpRsrcInfo->ID);
lbprintf( HWndDetails,
" offs: %04X len: %04Xh ID: %s hndl: %04X",
lpRsrcInfo->offset, lpRsrcInfo->length,
szBuffer, lpRsrcInfo->handle );
lpRsrcInfo++; // Point at next resource of this type
}
lpRsrcType = (LPRESOURCE_TYPE) // Point at next resource type
((LPBYTE)lpRsrcType + sizeof(RESOURCE_TYPE)
+ (lpRsrcType->count * sizeof(RESOURCE_INFO)));
}
}
void ShowResidentNamesDetails(HMODULE hModule)
{
LPMODULE lpMODULE = MAKELP( hModule, 0 );
LPBYTE lpNameEntry;
char szBuffer[260];
char szModuleName[32];
if ( !IsModule(hModule) )
return;
GetModuleName( hModule, szModuleName, sizeof(szModuleName) );
wsprintf(szBuffer, "Resident names for module %04X (%s)",
hModule, szModuleName);
SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
lpNameEntry = MAKELP( hModule, lpMODULE->ne_resNamesTab );
// Each entry is as follows:
// BYTE - length of string that follows
// char[?] - the name. Size is given by previous field
// WORD - the export ordinal for this function
while ( TRUE )
{
if ( *lpNameEntry == 0 ) // A 0-length terminates the table
break;
memcpy(szBuffer, lpNameEntry+1, *lpNameEntry);
szBuffer[ *lpNameEntry ] = 0;
lbprintf( HWndDetails, "%03u %s",
*(LPWORD)(lpNameEntry + *lpNameEntry + 1), szBuffer );
lpNameEntry += (*lpNameEntry + 3);
}
}
void ShowNonResidentNamesDetails(HMODULE hModule)
{
LPMODULE lpMODULE = MAKELP( hModule, 0 );
LPBYTE lpNameEntry, lpNRNTable;
char szBuffer[260];
char szModuleName[32];
HFILE hFile = HFILE_ERROR;
if ( !IsModule(hModule) )
return;
// Open up the file, seek to the non-resident names, allocate
// memory for the buffer, and read the table in. Does error checking.
if ( !GetModuleFileName(hModule, szBuffer, sizeof(szBuffer)) )
return;
hFile = _lopen( szBuffer, READ );
if ( HFILE_ERROR == hFile )
return;
if ( HFILE_ERROR==_llseek(hFile, lpMODULE->ne_nonResNamesTab, SEEK_SET))
goto done;
lpNRNTable = malloc( lpMODULE->ne_cbNonResNamesTab );
if ( !lpNRNTable )
goto done;
if ( _lread(hFile, lpNRNTable, lpMODULE->ne_cbNonResNamesTab)
!= lpMODULE->ne_cbNonResNamesTab )
goto done;
lpNameEntry = lpNRNTable;
GetModuleName( hModule, szModuleName, sizeof(szModuleName) );
wsprintf(szBuffer, "Non-resident names for module %04X (%s)",
hModule, szModuleName);
SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
// Each entry has the same format as the resident names table
while ( TRUE )
{
if ( *lpNameEntry == 0 ) // A 0-length terminates the table
break;
memcpy(szBuffer, lpNameEntry+1, *lpNameEntry);
szBuffer[ *lpNameEntry ] = 0;
lbprintf( HWndDetails, "%03u %s",
*(LPWORD)(lpNameEntry + *lpNameEntry + 1), szBuffer );
lpNameEntry += (*lpNameEntry + 3);
}
done:
// Clean up things we created
if ( HFILE_ERROR != hFile )
_lclose( hFile );
if ( lpNRNTable )
free( lpNRNTable );
}
void lbprintf(HWND hWnd, char * format, ...)
{
char szBuffer[512];
va_list argptr;
va_start(argptr, format);
vsprintf(szBuffer, format, argptr);
va_end(argptr);
SendMessage( hWnd, LB_ADDSTRING, 0, (LPARAM)szBuffer );
}
// Records the type (module, task, etc...) of the line that was just
// added to the specified listbox window, along with the value.
void RecordListboxLineTypeAndValue(HWND hWnd, WORD type, WORD value)
{
unsigned lastIndex = (WORD)SendMessage( hWnd, LB_GETCOUNT, 0, 0 );
if ( !lastIndex )
return;
lastIndex--; // Index is 0 based
SendMessage( hWnd, LB_SETITEMDATA, lastIndex, MAKELONG(value, type) );
}
BOOL RetrieveListboxLineTypeAndValue(HWND hWnd, WORD *type, WORD *value)
{
DWORD itemData;
unsigned index = (WORD)SendMessage( hWnd, LB_GETCURSEL, 0, 0 );
itemData = SendMessage( hWnd, LB_GETITEMDATA, index, 0 );
if ( !itemData && itemData == (DWORD)LB_ERR )
return FALSE;
*type = HIWORD( itemData );
*value = LOWORD( itemData );
return TRUE;
}
char *ResourceTypes[] =
{
"",
"Cursor", // 1
"Bitmap", // 2
"Icon", // 3
"Menu", // 4
"Dialog", // 5
"String Table", // 6
"Font Directory", // 7
"Font", // 8
"Accelerator", // 9
"RC Data", //10
"Error Table", //11
"Group Cursor", //12
"Unknown", //13
"Group Icon", //14
"Name Table", //15
"Version info" //16
};
LPSTR GetResourceTypeName(WORD id)
{
static char szBuffer[64];
if ( (id & 0x8000) == 0 )
return "NamedResource";
id &= 0x7FFF; // Turn off high bit
if ( (id >= 1) && (id <= 16) )
return ResourceTypes[id];
if ( id == 0xCC )
return "TrueType Font";
wsprintf( szBuffer, "Unknown_%u", id );
return szBuffer;
}
BOOL IsModule(HMODULE hModule)
{
LPMODULE lpMODULE = MAKELP( hModule, 0 );
if ( IsBadReadPtr( lpMODULE, 2) )
return FALSE;
return lpMODULE->ne_signature == 0x454E; // Is 'NE' signature there?
}
BOOL IsA32BitHMODULE(WORD selector)
{
LPMODULE lpMODULE;
__asm {
lar AX, [selector]
jc false
cmp ah, 0F3h // Present, ring 3, writeable, accessed data segment
jne false;
}
lpMODULE = MAKELP( selector, 0 );
if ( IsBadReadPtr(lpMODULE, sizeof(MODULE)) ) // Is the seg big enough?
return FALSE;
if ( lpMODULE->ne_signature != 0x454E ) // look for NE signature
return FALSE;
if ( GetSelectorBase(selector) < 0x80000000LU ) // IMTE is in system
return FALSE; // memory > 2GB
if ( lpMODULE->ne_align != 0 ) // alignment is always 1 in 32 bit
return FALSE; // modules
if ( lpMODULE->ne_cseg != 0 ) // No segments in 32 bit modules
return FALSE;
if ( lpMODULE->ne_usage != 1 ) // Usage will always be 1
return TRUE;
if ( lpMODULE->ne_flags == 0x8010 ) // Are DLL and Win32 flags set?
return TRUE;
false:
return FALSE;
}
LPSTR GetTaskModuleName(HTASK hTask)
{
LPTDB lpTDB = MAKELP( hTask, 0 );
static char szBuffer[10];
if ( !IsTask(hTask) )
return "<unknown TDB>";
memcpy( szBuffer, lpTDB->TDB_ModName, 8 );
szBuffer[8] = 0;
return szBuffer;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -