Exemplo n.º 1
0
/* get_SharedInfo()
Return the address of Microsoft's SHAREDINFO structure (aka gSharedInfo) or die.

x86 only, for now.
*/
SHAREDINFO *get_SharedInfo( void )
{
	static DWORD SharedInfo;
	
	int i = 0;
	char *p = NULL;
	void *User32InitializeImmEntryTable = NULL;
	
	
	if( SharedInfo )
		return (SHAREDINFO *)SharedInfo;
	
#ifdef _MSC_VER
#pragma warning(push)  
#pragma warning(disable:4054) /* function pointer cast as data pointer */
#endif
	
	User32InitializeImmEntryTable = 
		(void *)GetProcAddress( LoadLibraryA( "user32" ), "User32InitializeImmEntryTable" );
	
#ifdef _MSC_VER
#pragma warning(pop)
#endif
	
	if( !User32InitializeImmEntryTable )
	{
		MSG_FATAL_GLE( "GetProcAddress() failed." );
		printf( "Failed to get address of User32InitializeImmEntryTable() in user32.dll\n" );
		exit( 1 );
	}
	
	/* This is my C implementation of the algorithm to find SharedInfo created by 
	(alex ntinternals org), originally implemented in asm in EnumWindowsHooks.c
	http://www.ntinternals.org/
	
	This works on XP, Vista, Win7 x86. To be sure an alternate way would be to check the different 
	win32k pdb files and find the addresses there.
	*/
	p = (char *)User32InitializeImmEntryTable;
	for( i = 0; i < 127; ++i )
	{
		if( ( *p++ == 0x50 ) && ( *p == 0x68 ) )
		{
			*( (char *)&SharedInfo + 0 ) = *++p;
			*( (char *)&SharedInfo + 1 ) = *++p;
			*( (char *)&SharedInfo + 2 ) = *++p;
			*( (char *)&SharedInfo + 3 ) = *++p;
			break;
		}
	}
	
	if( !SharedInfo )
	{
		MSG_FATAL( "Failed to get address of SharedInfo. The magic number wasn't found." );
		exit( 1 );
	}
	
	return (SHAREDINFO *)SharedInfo;
}
Exemplo n.º 2
0
/* init_global_prog_store()
Initialize the global program store by storing command line arguments, OS version, etc.

This function must only be called from the main thread.
For now there is only one program store implemented and it's a global store (G->prog).
*/
void init_global_prog_store( 
	int argc,   // in
	char **argv   // in deref
)
{
	unsigned offsetof_cHandleEntries = 0;
	
	FAIL_IF( !G );   // The global store must exist.
	
	FAIL_IF( G->prog->init_time );   // Fail if this store has already been initialized.
	
	
	/* get_SharedInfo() or die.
	This function loads user32.dll and must be called before any other pointer to GUI related info 
	is initialized.
	*/
	G->prog->pSharedInfo = get_SharedInfo();
	
	
	G->prog->argc = argc;
	G->prog->argv = argv;
	
	/* point pszBasename to this program's basename */
	if( argc && argv[ 0 ][ 0 ] )
	{
		char *clip = NULL;
		
		clip = strrchr( argv[ 0 ], '\\' );
		if( clip )
			++clip;
		
		G->prog->pszBasename = ( clip && *clip ) ? clip : argv[ 0 ];
	}
	else
		G->prog->pszBasename = "<unknown>";
	
	
	/* main thread id */
	G->prog->dwMainThreadId = GetCurrentThreadId();
	
	/* operating system version and platform */
	G->prog->dwOSVersion = GetVersion();
	G->prog->dwOSMajorVersion = (BYTE)G->prog->dwOSVersion;
	G->prog->dwOSMinorVersion = (BYTE)( G->prog->dwOSVersion >> 8 );
	G->prog->dwOSBuild = 
		( G->prog->dwOSVersion < 0x80000000 ) ? ( G->prog->dwOSVersion >> 16 ) : 0;
	
	/* the name of this program's window station */
	if( !get_user_obj_name( &G->prog->pwszWinstaName, GetProcessWindowStation() ) )
	{
		MSG_FATAL_GLE( "get_user_obj_name() failed." );
		printf( "Failed to get this program's window station name.\n" );
		printf( "If you can reproduce this error contact [email protected]\n" );
		exit( 1 );
	}
	
	
	/* Determine the offset of cHandleEntries in SERVERINFO.
	In NT4 the offset is 4 but this program isn't for NT4 so ignore.
	In Win2k and XP the offset is 8.
	In Vista and Win7 the offset is 4.
	*/
	offsetof_cHandleEntries = ( G->prog->dwOSMajorVersion >= 6 ) ? 4 : 8;
	
	offsetof_cHandleEntries = 8;

	/* The first member of SHAREDINFO is pointer to SERVERINFO.
	Add offsetof_cHandleEntries to the SERVERINFO pointer to get the address of cHandleEntries.
	*/
	G->prog->pcHandleEntries = 
		(volatile DWORD *)( (char *)G->prog->pSharedInfo->psi + offsetof_cHandleEntries );
	
	
	/* G->prog has been initialized */
	GetSystemTimeAsFileTime( (FILETIME *)&G->prog->init_time );
	return;
}