Close the handles opened by CreateProcess.

Prevent the block when directly running a GUI process.
File logging improvements (on by default, this time).
This commit is contained in:
Jason Hood 2010-12-16 16:00:56 +10:00
parent dd4e45686b
commit be7672b92e
8 changed files with 81 additions and 55 deletions

57
ANSI.c
View File

@ -57,10 +57,11 @@
v1.31, 13 & 19 November, 2010: v1.31, 13 & 19 November, 2010:
fix multibyte conversion problems. fix multibyte conversion problems.
v1.32, 4 & 12 December, 2010: v1.32, 4, 12 & 16 December, 2010:
test for lpNumberOfCharsWritten/lpNumberOfBytesWritten being NULL; test for lpNumberOfCharsWritten/lpNumberOfBytesWritten being NULL;
recognise DSR and xterm window title; recognise DSR and xterm window title;
ignore sequences starting with \e[? & \e[>. ignore sequences starting with \e[? & \e[>;
close the handles opened by CreateProcess.
*/ */
#include "ansicon.h" #include "ansicon.h"
@ -347,10 +348,8 @@ BOOL HookAPIAllMod( PHookFn Hooks, BOOL restore )
// ========== Print Buffer functions // ========== Print Buffer functions
#define BUFFER_SIZE 256 int nCharInBuffer;
LPCTSTR ChBuffer;
int nCharInBuffer = 0;
TCHAR ChBuffer[BUFFER_SIZE];
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// FlushBuffer() // FlushBuffer()
@ -366,18 +365,14 @@ void FlushBuffer( void )
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// PushBuffer( char c ) // PushBuffer( LPCTSTR s )
// Adds a character in the buffer and flushes the buffer if it is full. // Adds a character in the "buffer".
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void PushBuffer( TCHAR c ) void PushBuffer( LPCTSTR s )
{ {
ChBuffer[nCharInBuffer++] = c; if (nCharInBuffer++ == 0)
if (nCharInBuffer >= BUFFER_SIZE) ChBuffer = s;
{
FlushBuffer();
DEBUGSTR( L"flush" );
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -799,19 +794,19 @@ ParseAndPrintString( HANDLE hDev,
) )
{ {
DWORD i; DWORD i;
LPTSTR s; LPCTSTR s;
if (hDev != hConOut) // reinit if device has changed if (hDev != hConOut) // reinit if device has changed
{ {
hConOut = hDev; hConOut = hDev;
state = 1; state = 1;
} }
for (i = nNumberOfBytesToWrite, s = (LPTSTR)lpBuffer; i > 0; i--, s++) for (i = nNumberOfBytesToWrite, s = (LPCTSTR)lpBuffer; i > 0; i--, s++)
{ {
if (state == 1) if (state == 1)
{ {
if (*s == ESC) state = 2; if (*s == ESC) state = 2;
else PushBuffer( *s ); else PushBuffer( s );
} }
else if (state == 2) else if (state == 2)
{ {
@ -929,11 +924,18 @@ void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi,
#endif #endif
} }
if (lpi)
memcpy( lpi, pinfo, sizeof(PROCESS_INFORMATION) );
if (!(dwCreationFlags & CREATE_SUSPENDED)) if (!(dwCreationFlags & CREATE_SUSPENDED))
ResumeThread( pinfo->hThread ); ResumeThread( pinfo->hThread );
if (lpi)
{
memcpy( lpi, pinfo, sizeof(PROCESS_INFORMATION) );
}
else
{
CloseHandle( pinfo->hProcess );
CloseHandle( pinfo->hThread );
}
} }
@ -1288,10 +1290,6 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
if (dwReason == DLL_PROCESS_ATTACH) if (dwReason == DLL_PROCESS_ATTACH)
{ {
#if (MYDEBUG > 1)
DEBUGSTR( NULL ); // create a new file
#endif
hDllInstance = hInstance; // save Dll instance handle hDllInstance = hInstance; // save Dll instance handle
DEBUGSTR( L"hDllInstance = %p", hDllInstance ); DEBUGSTR( L"hDllInstance = %p", hDllInstance );
@ -1309,11 +1307,18 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
OriginalAttr(); OriginalAttr();
DisableThreadLibraryCalls( hInstance ); DisableThreadLibraryCalls( hInstance );
} }
else if (dwReason == DLL_PROCESS_DETACH && lpReserved == NULL) else if (dwReason == DLL_PROCESS_DETACH)
{
if (lpReserved == NULL)
{ {
DEBUGSTR( L"Unloading" ); DEBUGSTR( L"Unloading" );
HookAPIAllMod( Hooks, TRUE ); HookAPIAllMod( Hooks, TRUE );
} }
else
{
DEBUGSTR( L"Terminating" );
}
}
return( bResult ); return( bResult );
} }

View File

@ -43,13 +43,14 @@
VC compatibility (2008 Express for 32-bit, PSDK 2003 R2 for 64-bit); VC compatibility (2008 Express for 32-bit, PSDK 2003 R2 for 64-bit);
explicitly use wide characters (stick with TCHAR, but not <tchar.h>). explicitly use wide characters (stick with TCHAR, but not <tchar.h>).
v1.32, 4 & 12 December, 2010: v1.32, 4, 12 & 16 December, 2010:
make -p more robust; make -p more robust;
inject into GUI processes again. inject into GUI processes again;
don't block when directly running a GUI process.
*/ */
#define PVERS L"1.32" #define PVERS L"1.32"
#define PDATE L"12 December, 2010" #define PDATE L"16 December, 2010"
#include "ansicon.h" #include "ansicon.h"
#include <shellapi.h> #include <shellapi.h>
@ -169,6 +170,10 @@ int main( void )
} }
} }
#if (MYDEBUG > 1)
DEBUGSTR( NULL ); // create a new file
#endif
option = (argc > 1 && argv[1][0] == '-'); option = (argc > 1 && argv[1][0] == '-');
if (option && (towlower( argv[1][1] ) == 'i' || if (option && (towlower( argv[1][1] ) == 'i' ||
towlower( argv[1][1] ) == 'u')) towlower( argv[1][1] ) == 'u'))
@ -288,10 +293,15 @@ int main( void )
ZeroMemory( &si, sizeof(si) ); ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si); si.cb = sizeof(si);
if (CreateProcess( NULL, cmd, NULL,NULL, TRUE, 0, NULL,NULL, &si, &pi )) if (CreateProcess( NULL, cmd, NULL,NULL, TRUE, 0, NULL,NULL, &si, &pi ))
{
if (ProcessType( &pi ) > 0)
{ {
SetConsoleCtrlHandler( (PHANDLER_ROUTINE)CtrlHandler, TRUE ); SetConsoleCtrlHandler( (PHANDLER_ROUTINE)CtrlHandler, TRUE );
WaitForSingleObject( pi.hProcess, INFINITE ); WaitForSingleObject( pi.hProcess, INFINITE );
} }
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
else else
{ {
*skip_arg( cmd ) = '\0'; *skip_arg( cmd ) = '\0';

View File

@ -20,17 +20,17 @@
#define lenof(array) (sizeof(array)/sizeof(*(array))) #define lenof(array) (sizeof(array)/sizeof(*(array)))
BOOL ProcessType( LPPROCESS_INFORMATION ); int ProcessType( LPPROCESS_INFORMATION );
void InjectDLL32( LPPROCESS_INFORMATION, LPCTSTR ); void InjectDLL32( LPPROCESS_INFORMATION, LPCTSTR );
void InjectDLL64( LPPROCESS_INFORMATION, LPCTSTR ); void InjectDLL64( LPPROCESS_INFORMATION, LPCTSTR );
// ========== Auxiliary debug function // ========== Auxiliary debug function
//#define MYDEBUG 1 // use OutputDebugString
//#define MYDEBUG 2 // use %temp%\ansicon.log
#ifndef MYDEBUG #ifndef MYDEBUG
# define MYDEBUG 0 // no debugging # define MYDEBUG 2 // 0 - no debugging
// 1 - use OutputDebugString
// 2 - use %temp%\ansicon.log
#endif #endif
#if (MYDEBUG > 0) #if (MYDEBUG > 0)

View File

@ -75,7 +75,18 @@ void DEBUGSTR( LPTSTR szFormat, ... ) // sort of OutputDebugStringf
FILE* file = fopen( tempfile, "at" ); // _fmode might be binary FILE* file = fopen( tempfile, "at" ); // _fmode might be binary
if (file != NULL) if (file != NULL)
{ {
fwprintf( file, L"%s\n", szFormat ); TCHAR path[MAX_PATH];
LPTSTR prog, ext;
GetModuleFileName( NULL, path, lenof(path) );
prog = wcsrchr( path, '\\' );
if (prog != NULL)
++prog;
else
prog = path;
ext = wcsrchr( prog, '.' );
if (ext != NULL)
*ext = '\0';
fwprintf( file, L"%s: %s\n", prog, szFormat );
fclose( file ); fclose( file );
} }
} }

View File

@ -66,7 +66,7 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
// Assume if one is defined, so is the other. // Assume if one is defined, so is the other.
if (Wow64GetThreadContext == 0) if (Wow64GetThreadContext == 0)
{ {
DEBUGSTR( "Failed to get pointer to Wow64GetThreadContext.\n" ); DEBUGSTR( L"Failed to get pointer to Wow64GetThreadContext.\n" );
return; return;
} }
#endif #endif
@ -82,7 +82,7 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
if (!CreateProcess( (LPCTSTR)code, NULL, NULL, NULL, FALSE, 0, NULL, NULL, if (!CreateProcess( (LPCTSTR)code, NULL, NULL, NULL, FALSE, 0, NULL, NULL,
&si, &pi )) &si, &pi ))
{ {
DEBUGSTR( "Failed to execute \"%s\".\n", (LPCTSTR)code ); DEBUGSTR( L"Failed to execute \"%s\".\n", (LPCTSTR)code );
return; return;
} }
WaitForSingleObject( pi.hProcess, INFINITE ); WaitForSingleObject( pi.hProcess, INFINITE );

View File

@ -14,13 +14,13 @@ CFLAGS = -O2 -Wall
X86OBJS = x86/proctype.o x86/injdll32.o x86/debugstr.o X86OBJS = x86/proctype.o x86/injdll32.o x86/debugstr.o
X64OBJS = x64/proctype.o x64/injdll64.o x64/injdll32.o x64/debugstr.o X64OBJS = x64/proctype.o x64/injdll64.o x64/injdll32.o x64/debugstr.o
x86/%.o: %.c x86/%.o: %.c ansicon.h
$(CC) -m32 -c $(CFLAGS) $(CPPFLAGS) $< -o $@ $(CC) -m32 -c $(CFLAGS) $(CPPFLAGS) $< -o $@
x86/%v.o: %.rc x86/%v.o: %.rc
windres -U _WIN64 -F pe-i386 $< $@ windres -U _WIN64 -F pe-i386 $< $@
x64/%.o: %.c x64/%.o: %.c ansicon.h
$(CC) -m64 -c $(CFLAGS) $(CPPFLAGS) $< -o $@ $(CC) -m64 -c $(CFLAGS) $(CPPFLAGS) $< -o $@
x64/%v.o: %.rc x64/%v.o: %.rc
@ -61,13 +61,6 @@ x86/ansiv.o: ansi.rc
x64/ansiconv.o: ansicon.rc x64/ansiconv.o: ansicon.rc
x64/ansiv.o: ansi.rc x64/ansiv.o: ansi.rc
ansicon.c: ansicon.h
ANSI.c: ansicon.h
debugstr.c: ansicon.h
injdll32.c: ansicon.h
injdll64.c: ansicon.h
proctype.c: ansicon.h
clean: clean:
-rm x86/*.o -rm x86/*.o
-rm x64/*.o -rm x64/*.o

View File

@ -26,14 +26,21 @@ int ProcessType( LPPROCESS_INFORMATION pinfo )
{ {
if (nt_header.Signature == IMAGE_NT_SIGNATURE) if (nt_header.Signature == IMAGE_NT_SIGNATURE)
{ {
BOOL gui = (nt_header.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
if (nt_header.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI || if (nt_header.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI ||
nt_header.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) gui )
{ {
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
return 32; {
DEBUGSTR( L" 32-bit %s", (gui) ? L"GUI" : L"console" );
return (gui) ? -32 : 32;
}
#ifdef _WIN64 #ifdef _WIN64
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
return 64; {
DEBUGSTR( L" 64-bit %s", (gui) ? L"GUI" : L"console" );
return (gui) ? -64 : 64;
}
#endif #endif
DEBUGSTR( L" Ignoring unsupported machine (0x%X)", DEBUGSTR( L" Ignoring unsupported machine (0x%X)",
nt_header.FileHeader.Machine ); nt_header.FileHeader.Machine );

View File

@ -147,7 +147,7 @@
Legend: + added, - bug-fixed, * changed. Legend: + added, - bug-fixed, * changed.
1.32 - 12 December, 2010: 1.32 - 16 December, 2010:
- fixed crash due to NULL lpNumberOfBytesWritten/lpNumberOfCharsWritten; - fixed crash due to NULL lpNumberOfBytesWritten/lpNumberOfCharsWritten;
- -p will test the parent process for validity; - -p will test the parent process for validity;
* hook into GUI processes; * hook into GUI processes;
@ -273,4 +273,4 @@
============================== ==============================
Jason Hood, 12 December, 2010. Jason Hood, 16 December, 2010.