Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

887 lines
27 KiB

#include <precomp.h>
#pragma hdrstop
#define MYOF_FLAGS (OF_READ | OF_SHARE_DENY_NONE)
int read_name(
int ifile,
LPSTR pch
) {
char length;
int rc;
rc = _lread( ifile, &length, sizeof(length) );
if ( rc != sizeof(length) ) {
PRINTF("Could not read name length\n");
*pch = '\0';
return( -1 );
}
rc = _lread( ifile, pch, length );
if ( rc != length ) {
PRINTF("Could not read name\n");
*pch = '\0';
return( -1 );
}
*(pch + length) = '\0';
return( (int)length );
}
BOOL FindExport(
LPSTR filename,
WORD segment,
WORD offset,
LPSTR sym_text,
int direction,
LONG *dist
) {
int iFile;
OFSTRUCT ofs;
int rc;
IMAGE_DOS_HEADER doshdr;
IMAGE_OS2_HEADER winhdr;
BYTE Table[65536];
BYTE bBundles;
BYTE bFlags;
BYTE *ptr;
WORD wIndex = 1;
int i;
int this_dist;
int wIndexBest = -1;
char myfilename[256];
#pragma pack(1)
typedef struct
{
BYTE bFlags;
UNALIGNED WORD wSegOffset;
} FENTRY, *PFENTRY;
typedef struct
{
BYTE bFlags;
UNALIGNED WORD wINT3F;
BYTE bSegNumber;
UNALIGNED WORD wSegOffset;
} MENTRY, *PMENTRY;
#pragma pack()
strcpy(myfilename, filename);
if (-1 == (iFile=OpenFile(myfilename, &ofs, MYOF_FLAGS))) {
PRINTF("Error reading file %s\n", filename);
strcpy(myfilename, filename);
strcat(myfilename, ".exe");
if (-1 == (iFile=OpenFile(myfilename, &ofs, MYOF_FLAGS))) {
PRINTF("Error reading file %s\n", myfilename);
strcpy(myfilename, filename);
strcat(myfilename, ".dll");
if (-1 == (iFile=OpenFile(myfilename, &ofs, MYOF_FLAGS))) {
PRINTF("Error reading file %s\n", myfilename);
return FALSE;
}
}
}
rc = _lread(iFile, &doshdr, sizeof(doshdr));
if (rc != sizeof(doshdr)) {
//PRINTF("Error reading DOS header\n");
goto Error;
}
if (doshdr.e_magic != IMAGE_DOS_SIGNATURE) {
//PRINTF("Error - no DOS EXE signature");
goto Error;
}
rc = _llseek(iFile, doshdr.e_lfanew, FILE_BEGIN);
if (rc == -1) {
//PRINTF("Error - could not seek - probably not Win3.1 exe\n");
goto Error;
}
rc = _lread(iFile, &winhdr, sizeof(winhdr));
if (rc != sizeof(winhdr)) {
//PRINTF("Error - could not read WIN header - probably not Win3.1 exe\n");
goto Error;
}
if (winhdr.ne_magic != IMAGE_OS2_SIGNATURE) {
//PRINTF("Error - not WIN EXE signature\n");
goto Error;
}
rc = _llseek(iFile, doshdr.e_lfanew+winhdr.ne_enttab, FILE_BEGIN);
if (rc == -1) {
//PRINTF("Error - could not seek to entry table\n");
goto Error;
}
rc = _lread(iFile, Table, winhdr.ne_cbenttab);
if (rc != winhdr.ne_cbenttab) {
//PRINTF("Error - could not read entry table\n");
goto Error;
}
ptr = Table;
while (TRUE) {
bBundles = *ptr++;
if (bBundles == 0)
break;
bFlags = *ptr++;
switch (bFlags) {
case 0: // Placeholders
wIndex += bBundles;
break;
case 0xff: // movable segments
for (i=0; i<(int)bBundles; ++i) {
PMENTRY pe = (PMENTRY )ptr;
if (pe->bSegNumber == segment) {
this_dist = (direction == BEFORE) ? offset - pe->wSegOffset
: pe->wSegOffset - offset;
if ( this_dist >= 0 && (this_dist < *dist || *dist == -1) ) {
// mark this as the best match so far
*dist = this_dist;
wIndexBest = wIndex;
}
}
ptr += sizeof(MENTRY);
wIndex++;
}
break;
default: // fixed segments
if ((int)bFlags != segment) {
ptr += (int)bBundles * sizeof(FENTRY);
wIndex += (int)bBundles;
} else {
for (i=0; i<(int)bBundles; ++i) {
PFENTRY pe = (PFENTRY)ptr;
this_dist = (direction == BEFORE) ? offset - pe->wSegOffset
: pe->wSegOffset - offset;
if ( this_dist >= 0 && (this_dist < *dist || *dist == -1) ) {
// mark this as the best match so far
*dist = this_dist;
wIndexBest = wIndex;
}
ptr += sizeof(FENTRY);
wIndex++;
}
}
break;
}
}
if (wIndexBest == -1) {
// no match found - error out
Error:
_lclose(iFile);
return FALSE;
}
// Success: match found
// wIndexBest = ordinal of the function
// segment:offset = address to look up
// *dist = distance from segment:offset to the symbol
// filename = name of .exe/.dll
// Look for the ordinal in the resident name table
rc = _llseek(iFile, doshdr.e_lfanew+winhdr.ne_restab, FILE_BEGIN);
if (rc == -1) {
//PRINTF("Error - unable to seek to residentname table\n");
goto Error;
}
rc = _lread(iFile, Table, winhdr.ne_modtab-winhdr.ne_restab);
if (rc != winhdr.ne_modtab-winhdr.ne_restab) {
//PRINTF("Error - unable to read entire resident name table\n");
goto Error;
}
ptr = Table;
while (*ptr) {
if ( *(UNALIGNED USHORT *)(ptr+1+*ptr) == (USHORT)wIndexBest) {
// found the matching name
*(ptr+1+*ptr) = '\0'; // null-terminate the function name
wsprintf(sym_text, "%s", ptr+1);
goto Finished;
}
ptr += *ptr + 3;
}
// Look for the ordinal in the non-resident name table
rc = _llseek(iFile, doshdr.e_lfanew+winhdr.ne_nrestab, FILE_BEGIN);
if (rc == -1) {
//PRINTF("Error - unable to seek to non-residentname table\n");
goto Error;
}
rc = _lread(iFile, Table, winhdr.ne_cbnrestab);
if (rc != winhdr.ne_cbnrestab) {
//PRINTF("Error - unable to read entire non-resident name table\n");
goto Error;
}
ptr = Table;
while (*ptr) {
if ( *(UNALIGNED USHORT *)(ptr+1+*ptr) == (USHORT)wIndexBest) {
// found the matching name
*(ptr+1+*ptr) = '\0'; // null-terminate the function name
wsprintf(sym_text, "%s", ptr+1);
goto Finished;
}
ptr += *ptr + 3;
}
// fall into error path - no match found
goto Error;
Finished:
_lclose(iFile);
return TRUE;
}
int read_symbol(
int ifile,
LPSTR pch,
LONG *offset
) {
int rc;
WORD word;
rc = _lread( ifile, (LPSTR)&word, sizeof(WORD) );
if ( rc != sizeof(WORD) ) {
PRINTF("Could not read symbol offset\n");
*pch = '\0';
*offset = 0L;
return(-1);
}
*offset = (LONG)word;
rc = read_name( ifile, pch );
return( rc );
}
BOOL FindSymbol(
WORD selector,
LONG offset,
LPSTR sym_text,
LONG *dist,
int direction,
int mode
) {
BOOL result;
int length;
int iFile;
char filename[256];
OFSTRUCT ofs;
LONG filesize;
LONG start_position;
LONG position;
WORD w1;
WORD num_syms;
WORD w3;
WORD w4;
WORD next_off;
#ifdef NEED_INDICES
WORD index;
char c2;
int nSubEtry;
#endif
char c1;
int rc;
int cnt;
LONG this_offset;
WORD r2;
WORD seg_num;
char b[12];
char name_buff[128];
LONG this_dist;
HEAPENTRY he = {0};
*dist = -1;
strcpy( sym_text, "[Unknown]" );
result = FALSE;
if ( mode == V86_MODE ) {
return FALSE;
// v86_addr = ((ULONG)selector << 4) + (ULONG)offset;
}
/*
** Search for selector in kernel heap
*/
he.Selector = selector;
while (FindHeapEntry(&he, FALSE)) {
{
strcpy(filename, he.FileName);
strcat(filename,".sym");
iFile = OpenFile( filename, &ofs, MYOF_FLAGS );
if ( iFile == -1 ) {
PRINTF("Could not open symbol file \"%s\"\n", filename );
// Open the .EXE/.DLL file and see if the address corresponds
// to an exported function.
result = FindExport(he.FileName,(WORD)(he.SegmentNumber+1),(WORD)offset,sym_text,direction,dist);
if (!result) {
// not found in any .dll/.exe's export table, so just print file name,
// segment number, and offset
wsprintf(sym_text,"%s(%X):%04X",he.OwnerName, he.SegmentNumber,offset);
*dist = 0;
result = TRUE;
}
continue;
}
rc = _lread( iFile, (LPSTR)&filesize, sizeof(filesize) );
if ( rc != sizeof(filesize) ) {
PRINTF("Could not read file size\n");
_lclose( iFile );
return( FALSE );
}
filesize <<= 4;
rc = _lread( iFile, (LPSTR)&w1, sizeof(w1) );
if ( rc != sizeof(w1) ) {
PRINTF("Could not read w1\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&num_syms, sizeof(num_syms) );
if ( rc != sizeof(num_syms) ) {
PRINTF("Could not read num_syms\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&w3, sizeof(w3) );
if ( rc != sizeof(w3) ) {
PRINTF("Could not read w3\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&w4, sizeof(w4) );
if ( rc != sizeof(w4) ) {
PRINTF("Could not read w4\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&next_off, sizeof(next_off) );
if ( rc != sizeof(next_off) ) {
PRINTF("Could not read next_off\n");
_lclose( iFile );
return( FALSE );
}
start_position = ((LONG)next_off) << 4;
rc = _lread( iFile, (LPSTR)&c1, sizeof(c1) );
if ( rc != sizeof(c1) ) {
PRINTF("Could not read c1\n");
_lclose( iFile );
return( FALSE );
}
read_name( iFile, name_buff );
#ifdef NEED_ABSOLUTES
#ifdef NEED_SYM4
rc = _lread( iFile, (LPSTR)&c2, sizeof(c2) );
if ( rc != sizeof(c2) ) {
PRINTF("Could not read c2\n");
_lclose( iFile );
return( FALSE );
}
#endif
cnt = num_syms;
while ( cnt ) {
length = read_symbol( lpOutputRoutine, iFile, name_buff, &
this_offset );
if ( length == 0 ) {
PRINTF("Error access symbols in file %s\n", filename );
break;
}
--cnt;
}
#ifdef NEED_INDICES
cnt = num_syms;
while ( cnt ) {
rc = _lread( iFile, (LPSTR)&index, sizeof(index) );
if ( rc != sizeof(index) ) {
PRINTF("Could not read index table entry\n");
_lclose( iFile );
return( FALSE );
}
PRINTF("Index: %04X\n", index );
--cnt;
}
#endif
#endif
position = start_position;
do {
rc = _llseek( iFile, position, FILE_BEGIN );
if ( rc == -1 ) {
PRINTF("Failed to seek to next record\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&next_off, sizeof(next_off) );
if ( rc != sizeof(next_off) ) {
PRINTF("Could not read next_off\n");
_lclose( iFile );
return( FALSE );
}
position = ((LONG)next_off) << 4;
rc = _lread( iFile, (LPSTR)&num_syms, sizeof(num_syms) );
if ( rc != sizeof(num_syms) ) {
PRINTF("Could not read num_syms\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&r2, sizeof(r2) );
if ( rc != sizeof(r2) ) {
PRINTF("Could not read r2\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&seg_num, sizeof(seg_num) );
if ( rc != sizeof(seg_num) ) {
PRINTF("Could not read seg_num\n");
_lclose( iFile );
return( FALSE );
}
if ( mode == PROT_MODE && seg_num != (WORD)(he.SegmentNumber+1) ) {
/*
** Skip reading of symbols for segments with the wrong seg_num
*/
continue;
}
cnt = 0;
while ( cnt < 12 ) {
rc = _lread( iFile, (LPSTR)&b[cnt], sizeof(b[0]) );
if ( rc != sizeof(b[0]) ) {
PRINTF("Could not read 12 byte b array\n");
_lclose( iFile );
return( FALSE );
}
cnt++;
}
read_name( iFile, name_buff );
cnt = num_syms;
while ( cnt ) {
length = read_symbol( iFile, name_buff,
&this_offset );
if ( length == 0 ) {
PRINTF("Error access symbols in file %s\n", filename );
break;
}
switch( mode ) {
case PROT_MODE:
switch( direction ) {
case BEFORE:
this_dist = offset - this_offset;
break;
case AFTER:
this_dist = this_offset - offset;
break;
}
break;
case V86_MODE:
#if 0
mod_addr = mod_offset + (ULONG)(seg_num << 4) + this_offset;
switch( direction ) {
case BEFORE:
this_dist = v86_addr - mod_addr;
break;
case AFTER:
this_dist = mod_addr - v86_addr;
break;
}
#endif
break;
}
if ( this_dist >= 0 && (this_dist < *dist || *dist == -1) ) {
*dist = this_dist;
strcpy( sym_text, name_buff );
result = TRUE;
}
--cnt;
}
#ifdef NEED_INDICES
cnt = num_syms;
while ( cnt ) {
rc = _lread( iFile, (LPSTR)&index, sizeof(index) );
if ( rc != sizeof(index) ) {
PRINTF("Could not read index table entry\n");
_lclose( iFile );
return( FALSE );
}
--cnt;
}
#endif
} while ( position != start_position && position != 0 );
_lclose( iFile );
}
}
return( result );
}
BOOL FindAddress(
WORD *selector,
LONG *offset,
LPSTR sym_text,
int mode
) {
int length;
int iFile;
char filename[256];
OFSTRUCT ofs;
LONG filesize;
LONG start_position;
LONG position;
WORD w1;
WORD num_syms;
WORD w3;
WORD w4;
WORD next_off;
#ifdef NEED_INDICES
WORD index;
#endif
char c1;
char c2;
int rc;
int cnt;
LONG this_offset;
WORD r2;
WORD seg_num;
char b[12];
char name_buff[128];
char name1[200];
HEAPENTRY he = {0};
strcpy(name1,sym_text);
_strupr(name1);
if (mode == V86_MODE) { //BUGBUG
return FALSE;
}
/*
** Search for selector in kernel heap
*/
while (FindHeapEntry(&he, FALSE)) {
{
strcpy(filename, he.FileName);
strcat(filename,".sym");
iFile = OpenFile( filename, &ofs, MYOF_FLAGS );
if ( iFile == -1 ) {
// PRINTF("Could not open symbol file \"%s\"\n", filename );
continue;
}
rc = _lread( iFile, (LPSTR)&filesize, sizeof(filesize) );
if ( rc != sizeof(filesize) ) {
PRINTF("Could not read file size\n");
_lclose( iFile );
return( FALSE );
}
filesize <<= 4;
rc = _lread( iFile, (LPSTR)&w1, sizeof(w1) );
if ( rc != sizeof(w1) ) {
PRINTF("Could not read w1\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&num_syms, sizeof(num_syms) );
if ( rc != sizeof(num_syms) ) {
PRINTF("Could not read num_syms\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&w3, sizeof(w3) );
if ( rc != sizeof(w3) ) {
PRINTF("Could not read w3\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&w4, sizeof(w4) );
if ( rc != sizeof(w4) ) {
PRINTF("Could not read w4\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&next_off, sizeof(next_off) );
if ( rc != sizeof(next_off) ) {
PRINTF("Could not read next_off\n");
_lclose( iFile );
return( FALSE );
}
start_position = ((LONG)next_off) << 4;
rc = _lread( iFile, (LPSTR)&c1, sizeof(c1) );
if ( rc != sizeof(c1) ) {
PRINTF("Could not read c1\n");
_lclose( iFile );
return( FALSE );
}
read_name( iFile, name_buff );
rc = _lread( iFile, (LPSTR)&c2, sizeof(c2) );
if ( rc != sizeof(c2) ) {
PRINTF("Could not read c2\n");
_lclose( iFile );
return( FALSE );
}
cnt = num_syms;
while ( cnt ) {
length = read_symbol( iFile, name_buff,
&this_offset );
if ( length == 0 ) {
PRINTF("Error access symbols in file %s\n", filename );
break;
}
--cnt;
}
#ifdef NEED_INDICES
cnt = num_syms;
while ( cnt ) {
rc = _lread( iFile, (LPSTR)&index, sizeof(index) );
if ( rc != sizeof(index) ) {
PRINTF("Could not read index table entry\n");
_lclose( iFile );
return( FALSE );
}
PRINTF("Index: %04X\n", index );
--cnt;
}
#endif
position = start_position;
do {
rc = _llseek( iFile, position, FILE_BEGIN );
if ( rc == -1 ) {
PRINTF("Failed to seek to next record\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&next_off, sizeof(next_off) );
if ( rc != sizeof(next_off) ) {
PRINTF("Could not read next_off\n");
_lclose( iFile );
return( FALSE );
}
position = ((LONG)next_off) << 4;
rc = _lread( iFile, (LPSTR)&num_syms, sizeof(num_syms) );
if ( rc != sizeof(num_syms) ) {
PRINTF("Could not read num_syms\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&r2, sizeof(r2) );
if ( rc != sizeof(r2) ) {
PRINTF("Could not read r2\n");
_lclose( iFile );
return( FALSE );
}
rc = _lread( iFile, (LPSTR)&seg_num, sizeof(seg_num) );
if ( rc != sizeof(seg_num) ) {
PRINTF("Could not read seg_num\n");
_lclose( iFile );
return( FALSE );
}
if ( mode == PROT_MODE &&
seg_num != (WORD)(he.SegmentNumber+1) ) {
/*
** Skip reading of symbols for segments with the wrong seg_num
*/
continue;
}
cnt = 0;
while ( cnt < 12 ) {
rc = _lread( iFile, (LPSTR)&b[cnt], sizeof(b[0]) );
if ( rc != sizeof(b[0]) ) {
PRINTF("Could not read 12 byte b array\n");
_lclose( iFile );
return( FALSE );
}
cnt++;
}
read_name( iFile, name_buff );
cnt = num_syms;
while ( cnt ) {
length = read_symbol( iFile, name_buff, &this_offset );
if ( length == 0 ) {
PRINTF("Error access symbols in file %s\n", filename );
break;
}
if ( _stricmp(name_buff,sym_text) == 0 ) {
switch( mode ) {
case PROT_MODE:
*selector = (WORD)(he.gnode.pga_handle | 1);
*offset = this_offset;
_lclose( iFile );
return( TRUE );
#if 0
case V86_MODE:
*selector = se[nEntry].selector + seg_num;
*offset = this_offset;
_lclose( iFile );
return( TRUE );
#endif
}
}
{
char name2[200];
strcpy(name2,name_buff);
_strupr(name2);
if ( strstr(name2,name1) != 0 ) {
switch( mode ) {
case PROT_MODE:
*selector = (WORD)(he.gnode.pga_handle | 1);
*offset = this_offset;
PRINTF("%04X:%04X = %s\n", *selector, *offset, name_buff );
break;
#if 0
case V86_MODE:
*selector = se[nEntry].selector + seg_num;
*offset = this_offset;
PRINTF("%04X:%04X = %s\n", *selector, *offset, name_buff );
break;
#endif
}
}
}
--cnt;
}
} while ( position != start_position && position != 0 );
_lclose( iFile );
}
}
return( FALSE );
}
VOID
ListNear(
) {
VDMCONTEXT ThreadContext;
WORD selector;
LONG offset;
CHAR sym_text[1000];
DWORD dist;
BOOL b;
int mode;
mode = GetContext( &ThreadContext );
if (!GetNextToken()) {
selector = (WORD) ThreadContext.SegCs;
offset = ThreadContext.Eip;
} else if (!ParseIntelAddress(&mode, &selector, &offset)) {
return;
}
if ( mode == PROT_MODE ) {
PRINTF( "#%04X:%04lX", selector, offset );
}
if ( mode == V86_MODE ) {
PRINTF( "&%04X:%04lX", selector, offset );
}
b = FindSymbol( selector, offset, sym_text, &dist, BEFORE, mode );
if ( !b ) {
PRINTF(" = Could not find symbol before");
} else {
if ( dist == 0 ) {
PRINTF(" = %s", sym_text );
} else {
PRINTF(" = %s + 0x%lx", sym_text, dist );
}
}
b = FindSymbol( selector, offset, sym_text, &dist, AFTER, mode );
if ( !b ) {
PRINTF(" = Could not find symbol after");
} else {
if ( dist == 0 ) {
PRINTF(" = %s", sym_text );
} else {
PRINTF(" = %s - 0x%lx", sym_text, dist );
}
}
PRINTF("\n");
}
VOID
EvaluateSymbol(
) {
VDMCONTEXT ThreadContext;
BOOL result;
WORD selector;
LONG offset;
int mode;
try {
mode = GetContext( &ThreadContext );
result = FindAddress( &selector, &offset, lpArgumentString, mode );
if ( result ) {
if ( mode == PROT_MODE ) {
PRINTF("Symbol %s = #%04X:%04X PROT_MODE\n", lpArgumentString, selector, offset );
}
if ( mode == V86_MODE ) {
PRINTF("Symbol %s = &%04X:%04X V86_MODE\n", lpArgumentString, selector, offset );
}
return;
}
if ( mode == PROT_MODE ) {
mode = V86_MODE;
} else {
if ( mode == V86_MODE ) {
mode = PROT_MODE;
}
}
result = FindAddress( &selector, &offset, lpArgumentString, mode );
if ( result ) {
if ( mode == PROT_MODE ) {
PRINTF("Symbol %s = #%04X:%04X PROT_MODE\n", lpArgumentString, selector, offset );
}
if ( mode == V86_MODE ) {
PRINTF("Symbol %s = &%04X:%04X V86_MODE\n", lpArgumentString, selector, offset );
}
return;
}
PRINTF("Could not find symbol %s\n", lpArgumentString );
} except (1) {
PRINTF("Exception 0x%08x in !bde.es, don't forget to thank Dave Hart for saving\n"
"your debugging bacon by adding a try/except block!\n"
"And while you're at it remind him to take out this caffeine-induced spew.\n",
GetExceptionCode());
}
}