diff --git a/ANSI.c b/ANSI.c index a58714a..6f4bff3 100644 --- a/ANSI.c +++ b/ANSI.c @@ -56,6 +56,9 @@ v1.31, 13 November, 2010: fix multibyte conversion problems. + + v1.32, 4 December, 2010: + test for lpNumberOfCharsWritten/lpNumberOfBytesWritten being NULL. */ #ifndef UNICODE @@ -76,9 +79,9 @@ // ========== Auxiliary debug function -//#define MYDEBUG 0 // no debugging +#define MYDEBUG 0 // no debugging //#define MYDEBUG 1 // use OutputDebugString -#define MYDEBUG 2 // use %temp%\ansicon.log +//#define MYDEBUG 2 // use %temp%\ansicon.log #if (MYDEBUG > 0) #if (MYDEBUG > 1) @@ -135,7 +138,7 @@ void DEBUGSTR( LPTSTR szFormat, ... ) // sort of OutputDebugStringf } #if (MYDEBUG > 1) { - FILE* file = fopen( tempfile, "a" ); + FILE* file = fopen( tempfile, "at" ); // _fmode might be binary if (file != NULL) { fwprintf( file, L"%s\n", szFormat ); @@ -877,7 +880,8 @@ ParseAndPrintString( HANDLE hDev, } } FlushBuffer(); - *lpNumberOfBytesWritten = nNumberOfBytesToWrite - i; + if (lpNumberOfBytesWritten != NULL) + *lpNumberOfBytesWritten = nNumberOfBytesToWrite - i; return( i == 0 ); } @@ -888,69 +892,14 @@ ParseAndPrintString( HANDLE hDev, void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi, DWORD dwCreationFlags ) { - char* ptr = 0; - MEMORY_BASIC_INFORMATION minfo; - BOOL con = FALSE; -#ifdef _WIN64 - BOOL x86 = FALSE; -#endif - - while (VirtualQueryEx( pinfo->hProcess, ptr, &minfo, sizeof(minfo) )) - { - IMAGE_DOS_HEADER dos_header; - SIZE_T read; - if (ReadProcessMemory( pinfo->hProcess, minfo.AllocationBase, - &dos_header, sizeof(dos_header), &read )) - { - if (dos_header.e_magic == IMAGE_DOS_SIGNATURE) - { - IMAGE_NT_HEADERS nt_header; - if (ReadProcessMemory( pinfo->hProcess, (char*)minfo.AllocationBase + - dos_header.e_lfanew, &nt_header, - sizeof(nt_header), &read )) - { - if (nt_header.Signature == IMAGE_NT_SIGNATURE) - { - if (nt_header.OptionalHeader.Subsystem == - IMAGE_SUBSYSTEM_WINDOWS_CUI) - { - if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) - { - con = TRUE; -#ifdef _WIN64 - x86 = TRUE; - } - else if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) - { - con = TRUE; -#endif - } - else - { - DEBUGSTR( L" Ignoring unsupported machine (%x)", - nt_header.FileHeader.Machine ); - } - } - else - { - DEBUGSTR( L" Ignoring non-console subsystem (%u)", - nt_header.OptionalHeader.Subsystem ); - } - break; - } - } - } - } - ptr += minfo.RegionSize; - } - - if (con) + int type = ProcessType( pinfo ); + if (type != 0) { WCHAR dll[MAX_PATH]; #ifdef _WIN64 DWORD len = GetModuleFileName( GetModuleHandleA( "ANSI64.dll" ), dll, lenof(dll) ); - if (x86) + if (type == 32) { dll[len-6] = '3'; dll[len-5] = '2'; @@ -965,6 +914,11 @@ void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi, InjectDLL32( pinfo, dll ); #endif } + else + { + DEBUGSTR( L" Unsupported process type" ); + } + if (lpi) memcpy( lpi, pinfo, sizeof(PROCESS_INFORMATION) ); @@ -1117,7 +1071,8 @@ WINAPI MyWriteConsoleA( HANDLE hCon, LPCVOID lpBuffer, buf = malloc( len * sizeof(WCHAR) ); if (buf == NULL) { - *lpNumberOfCharsWritten = 0; + if (lpNumberOfCharsWritten != NULL) + *lpNumberOfCharsWritten = 0; return (nNumberOfCharsToWrite == 0); } MultiByteToWideChar( cp, 0, lpBuffer, nNumberOfCharsToWrite, buf, len ); @@ -1163,7 +1118,7 @@ WINAPI MyWriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, DWORD Mode; if (GetConsoleMode( hFile, &Mode ) && (Mode & ENABLE_PROCESSED_OUTPUT)) { - DEBUGSTR( L"\\WriteFile: %lu \"%.*S\"", nNumberOfBytesToWrite, nNumberOfBytesToWrite, lpBuffer ); + DEBUGSTR( L"WriteFile->" ); return MyWriteConsoleA( hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, diff --git a/ansi.rc b/ansi.rc index 3604dac..3aedb28 100644 --- a/ansi.rc +++ b/ansi.rc @@ -13,8 +13,8 @@ #endif 1 VERSIONINFO -FILEVERSION 1,3,1,0 -PRODUCTVERSION 1,3,1,0 +FILEVERSION 1,3,2,0 +PRODUCTVERSION 1,3,2,0 FILEOS VOS_NT FILETYPE VFT_DLL { @@ -25,12 +25,12 @@ FILETYPE VFT_DLL VALUE "Comments", "http://ansicon.adoxa.cjb.net/" VALUE "CompanyName", "Jason Hood" VALUE "FileDescription", "ANSI Console" - VALUE "FileVersion", "1.31" + VALUE "FileVersion", "1.32" VALUE "InternalName", "ANSI" BITS VALUE "LegalCopyright", "Freeware" VALUE "OriginalFilename", "ANSI" BITS ".dll" VALUE "ProductName", "ANSICON" - VALUE "ProductVersion", "1.31" + VALUE "ProductVersion", "1.32" } } diff --git a/ansicon.c b/ansicon.c index 8b103be..3e0f90e 100644 --- a/ansicon.c +++ b/ansicon.c @@ -42,10 +42,13 @@ use LLW to fix potential Unicode path problems; VC compatibility (2008 Express for 32-bit, PSDK 2003 R2 for 64-bit); explicitly use wide characters (stick with TCHAR, but not ). + + v1.32, 4 December, 2010: + make -p more robust. */ -#define PVERS L"1.31" -#define PDATE L"15 November, 2010" +#define PVERS L"1.32" +#define PDATE L"4 December, 2010" #ifndef UNICODE # define UNICODE @@ -70,11 +73,9 @@ int _CRT_glob = 0; #ifdef _WIN64 -# define InjectDLL InjectDLL64 -# define BITS L"64" +# define BITS L"64" #else -# define InjectDLL InjectDLL32 -# define BITS L"32" +# define BITS L"32" #endif @@ -82,30 +83,43 @@ int _CRT_glob = 0; #define AUTORUN L"AutoRun" -void help( void ); +void help( void ); void display( LPCTSTR, BOOL ); LPTSTR skip_spaces( LPTSTR ); LPTSTR skip_arg( LPTSTR ); -void process_autorun( TCHAR ); +void process_autorun( TCHAR ); -BOOL find_proc_id( HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe ); -BOOL GetParentProcessInfo( LPPROCESS_INFORMATION ppi ); +BOOL find_proc_id( HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe ); +BOOL GetParentProcessInfo( LPPROCESS_INFORMATION ppi ); // Find the name of the DLL and inject it. -void Inject( LPPROCESS_INFORMATION ppi ) +BOOL Inject( LPPROCESS_INFORMATION ppi ) { DWORD len; - TCHAR dll[MAX_PATH]; + WCHAR dll[MAX_PATH]; + int type; + + type = ProcessType( ppi ); + if (type == 0) + return FALSE; len = GetModuleFileName( NULL, dll, lenof(dll) ); while (dll[len-1] != '\\') --len; - lstrcpy( dll + len, L"ANSI" BITS L".dll" ); - - InjectDLL( ppi, dll ); +#ifdef _WIN64 + swprintf( dll + len, L"ANSI%d.dll", type ); + if (type == 32) + InjectDLL32( ppi, dll ); + else + InjectDLL64( ppi, dll ); +#else + wcscpy( dll + len, L"ANSI32.dll" ); + InjectDLL32( ppi, dll ); +#endif + return TRUE; } @@ -210,7 +224,11 @@ int main( void ) pi.hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId ); pi.hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, pi.dwThreadId ); SuspendThread( pi.hThread ); - Inject( &pi ); + if (!Inject( &pi )) + { + _putws( L"ANSICON: parent process type is not supported." ); + rc = 1; + } ResumeThread( pi.hThread ); CloseHandle( pi.hThread ); CloseHandle( pi.hProcess ); diff --git a/ansicon.rc b/ansicon.rc index deb2999..d87cde3 100644 --- a/ansicon.rc +++ b/ansicon.rc @@ -7,8 +7,8 @@ #include 1 VERSIONINFO -FILEVERSION 1,3,1,0 -PRODUCTVERSION 1,3,1,0 +FILEVERSION 1,3,2,0 +PRODUCTVERSION 1,3,2,0 FILEOS VOS_NT FILETYPE VFT_APP { @@ -19,12 +19,12 @@ FILETYPE VFT_APP VALUE "Comments", "http://ansicon.adoxa.cjb.net/" VALUE "CompanyName", "Jason Hood" VALUE "FileDescription", "ANSI Console" - VALUE "FileVersion", "1.31" + VALUE "FileVersion", "1.32" VALUE "InternalName", "ansicon" VALUE "LegalCopyright", "Freeware" VALUE "OriginalFilename", "ansicon.exe" VALUE "ProductName", "ANSICON" - VALUE "ProductVersion", "1.31" + VALUE "ProductVersion", "1.32" } } diff --git a/injdll.h b/injdll.h index 171f3a6..7f02ca7 100644 --- a/injdll.h +++ b/injdll.h @@ -14,6 +14,7 @@ #define WIN32_LEAN_AND_MEAN #include +BOOL ProcessType( LPPROCESS_INFORMATION ); void InjectDLL32( LPPROCESS_INFORMATION, LPCTSTR ); void InjectDLL64( LPPROCESS_INFORMATION, LPCTSTR ); diff --git a/injdll32.c b/injdll32.c index 34790b4..f7dbff3 100644 --- a/injdll32.c +++ b/injdll32.c @@ -59,7 +59,7 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll ) { #ifdef _WIN64 #ifdef __MINGW64__ - extern HMODULE hKernel; + HMODULE hKernel = GetModuleHandleA( "kernel32.dll" ); #define GETPROC( proc ) proc = (T##proc)GetProcAddress( hKernel, #proc ) GETPROC( Wow64GetThreadContext ); GETPROC( Wow64SetThreadContext ); diff --git a/makefile b/makefile index 6f0d86a..8cf2c2d 100644 --- a/makefile +++ b/makefile @@ -15,7 +15,7 @@ x86/%v.o: %.rc windres -U _WIN64 -F pe-i386 $< $@ x64/%.o: %.c - $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ + $(CC) -m64 -c $(CFLAGS) $(CPPFLAGS) $< -o $@ x64/%v.o: %.rc windres $< $@ @@ -29,20 +29,20 @@ ansicon64: x64 x64/ansicon.exe x64/ANSI64.dll x64/ANSI32.dll x64/ANSI-LLW.exe x86: mkdir x86 -x86/ansicon.exe: x86/ansicon.o x86/injdll32.o x86/ansiconv.o +x86/ansicon.exe: x86/ansicon.o x86/proctype.o x86/injdll32.o x86/ansiconv.o $(CC) -m32 $+ -s -o $@ -x86/ANSI32.dll: x86/ANSI.o x86/injdll32.o x86/ansiv.o +x86/ANSI32.dll: x86/ANSI.o x86/proctype.o x86/injdll32.o x86/ansiv.o $(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared x64: mkdir x64 -x64/ansicon.exe: x64/ansicon.o x64/injdll64.o x64/ansiconv.o - $(CC) $+ -s -o $@ +x64/ansicon.exe: x64/ansicon.o x64/proctype.o x64/injdll64.o x64/injdll32.o x64/ansiconv.o + $(CC) -m64 $+ -s -o $@ -x64/ANSI64.dll: x64/ANSI.o x64/injdll64.o x64/injdll32.o x64/ansiv.o - $(CC) $+ -s -o $@ -mdll -Wl,-shared +x64/ANSI64.dll: x64/ANSI.o x64/proctype.o x64/injdll64.o x64/injdll32.o x64/ansiv.o + $(CC) -m64 $+ -s -o $@ -mdll -Wl,-shared x64/ANSI32.dll: x86/ANSI32.dll cp -p x86/ANSI32.dll x64/ANSI32.dll diff --git a/makefile.vc b/makefile.vc index 1face60..3b1413d 100644 --- a/makefile.vc +++ b/makefile.vc @@ -43,10 +43,10 @@ ansicon64: x64 x64\ansicon.exe x64\ANSI64.dll x64\ANSI32.dll x64\ANSI-LLW.exe x86: mkdir x86 -x86\ansicon.exe: x86\ansicon.obj x86\injdll32.obj x86\ansicon.res +x86\ansicon.exe: x86\ansicon.obj x86\proctype.obj x86\injdll32.obj x86\ansicon.res $(CC) /nologo /Fe$@ $** $(LIBS) -x86\ANSI32.dll: x86\ANSI.obj x86\injdll32.obj x86\ansi.res +x86\ANSI32.dll: x86\ANSI.obj x86\proctype.obj x86\injdll32.obj x86\ansi.res !IF $(BITS) == 32 $(CC) /nologo /LD /Fe$@ $** $(LIBS) !ENDIF @@ -54,10 +54,10 @@ x86\ANSI32.dll: x86\ANSI.obj x86\injdll32.obj x86\ansi.res x64: mkdir x64 -x64\ansicon.exe: x64\ansicon.obj x64\injdll64.obj x64\ansicon.res +x64\ansicon.exe: x64\ansicon.obj x64\proctype.obj x64\injdll64.obj x64\injdll32.obj x64\ansicon.res $(CC) /nologo /Fe$@ $** $(LIBS) bufferoverflowu.lib -x64\ANSI64.dll: x64\ANSI.obj x64\injdll64.obj x64\injdll32.obj x64\ansi.res +x64\ANSI64.dll: x64\ANSI.obj x64\proctype.obj x64\injdll64.obj x64\injdll32.obj x64\ansi.res $(CC) /nologo /LD /Fe$@ $** $(LIBS) bufferoverflowu.lib x64\ANSI32.dll: x86\ANSI32.dll diff --git a/proctype.c b/proctype.c new file mode 100644 index 0000000..cf84f7f --- /dev/null +++ b/proctype.c @@ -0,0 +1,64 @@ +/* + Test for a valid process. +*/ + +#define WIN32_LEAN_AND_MEAN +#include + + +int ProcessType( LPPROCESS_INFORMATION pinfo ) +{ + MEMORY_BASIC_INFORMATION minfo; + char* ptr = 0; + int type = 0; + + while (VirtualQueryEx( pinfo->hProcess, ptr, &minfo, sizeof(minfo) )) + { + IMAGE_DOS_HEADER dos_header; + SIZE_T read; + if (ReadProcessMemory( pinfo->hProcess, minfo.AllocationBase, + &dos_header, sizeof(dos_header), &read )) + { + if (dos_header.e_magic == IMAGE_DOS_SIGNATURE) + { + IMAGE_NT_HEADERS nt_header; + if (ReadProcessMemory( pinfo->hProcess, (char*)minfo.AllocationBase + + dos_header.e_lfanew, &nt_header, + sizeof(nt_header), &read )) + { + if (nt_header.Signature == IMAGE_NT_SIGNATURE) + { + if (nt_header.OptionalHeader.Subsystem == + IMAGE_SUBSYSTEM_WINDOWS_CUI) + { + if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) + { + type = 32; +#ifdef _WIN64 + } + else if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) + { + type = 64; +#endif + } + else + { + //DEBUGSTR( L" Ignoring unsupported machine (%x)", + // nt_header.FileHeader.Machine ); + } + } + else + { + //DEBUGSTR( L" Ignoring non-console subsystem (%u)", + // nt_header.OptionalHeader.Subsystem ); + } + break; + } + } + } + } + ptr += minfo.RegionSize; + } + + return type; +}