diff --git a/ANSI.c b/ANSI.c index 6c09260..d6b8425 100644 --- a/ANSI.c +++ b/ANSI.c @@ -81,6 +81,9 @@ ignore the version within the core API DLL names; fix 32-bit process trying to identify 64-bit process; hook _lwrite & _hwrite. + + v1.52, 10 April, 2012: + use ansicon.exe to enable 32-bit to inject into 64-bit. */ #include "ansicon.h" @@ -913,7 +916,7 @@ API_DATA APIs[] = HMODULE hKernel; // Kernel32 module handle HINSTANCE hDllInstance; // Dll instance handle TCHAR hDllName[MAX_PATH]; // Dll file name -#ifdef _WIN64 +#if defined(_WIN64) || defined(W32ON64) LPTSTR hDllNameType; // pointer to process type within above #endif @@ -1212,6 +1215,30 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi, InjectDLL64( &child_pi, hDllName ); } #else +#ifdef W32ON64 + if (type == 64) + { + TCHAR args[64]; + STARTUPINFO si; + PROCESS_INFORMATION pi; + wcscpy( hDllNameType, L"CON.exe" ); + wsprintf( args, L"ansicon -P%lu:%lu", + child_pi.dwProcessId, child_pi.dwThreadId ); + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + if (CreateProcess( hDllName, args, NULL, NULL, FALSE, 0, NULL, NULL, + &si, &pi )) + { + WaitForSingleObject( pi.hProcess, INFINITE ); + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + } + else + DEBUGSTR( 1, L"Could not execute \"%s\"", hDllName ); + wcscpy( hDllNameType, L"32.dll" ); + } + else +#endif InjectDLL32( &child_pi, hDllName ); #endif if (!gui && !(dwCreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS))) @@ -1704,7 +1731,7 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) GetEnvironmentVariable( L"ANSICON_LOG", logstr, lenof(logstr) ); log_level = _wtoi( logstr ); prog = get_program_name( NULL ); -#ifdef _WIN64 +#if defined(_WIN64) || defined(W32ON64) hDllNameType = hDllName - 6 + #endif GetModuleFileName( hInstance, hDllName, lenof(hDllName) ); diff --git a/ansicon.c b/ansicon.c index 7196933..7b06956 100644 --- a/ansicon.c +++ b/ansicon.c @@ -60,9 +60,13 @@ 7 January, 2012: fixed installing into a piped CMD.EXE; added a log message indicating all imports have been processed. + + v1.52, 10 April, 2012: + fixed running "cmd" if "ComSpec" is not defined; + pass process & thread identifiers on the command line (for x86->x64). */ -#define PDATE L"24 February, 2012" +#define PDATE L"10 April, 2012" #include "ansicon.h" #include "version.h" @@ -194,6 +198,20 @@ int main( void ) *logstr = '\0'; GetEnvironmentVariable( L"ANSICON_LOG", logstr, lenof(logstr) ); log_level = _wtoi( logstr ); + +#ifdef _WIN64 + if (*arg == '-' && arg[1] == 'P') + { + swscanf( arg + 2, L"%u:%u", &pi.dwProcessId, &pi.dwThreadId ); + pi.hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); + pi.hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, pi.dwThreadId ); + Inject( &pi, &gui, arg ); + CloseHandle( pi.hThread ); + CloseHandle( pi.hProcess ); + return 0; + } +#endif + if (log_level && !(log_level & 8)) DEBUGSTR( 1, NULL ); // create a new file @@ -300,7 +318,11 @@ arg_out: { cmd = _wgetenv( L"ComSpec" ); if (cmd == NULL) - cmd = L"cmd"; + { + // CreateProcessW writes to the string, so can't simply point to "cmd". + static TCHAR cmdstr[] = L"cmd"; + cmd = cmdstr; + } arg = cmd; } diff --git a/makefile b/makefile index db84cf6..1ab6753 100644 --- a/makefile +++ b/makefile @@ -53,8 +53,8 @@ x64/ansicon.exe: x64/ansicon.o $(X64OBJS) x64/ansiconv.o x64/ANSI64.dll: x64/ANSI.o $(X64OBJS) x64/ansiv.o $(CC) -m64 $+ -s -o $@ -mdll -Wl,-shared -x64/ANSI32.dll: x86/ANSI32.dll - cmd /c "copy/y x86\ANSI32.dll x64\ANSI32.dll >nul" +x64/ANSI32.dll: x64/ANSI32.o x64/proctype32.o x86/injdll32.o x86/util.o x86/ansiv.o + $(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared x64/ANSI-LLW.exe: ANSI-LLW.c $(CC) -m32 $(CFLAGS) $< -s -o $@ @@ -68,6 +68,11 @@ x86/ansiv.o: ansi.rc x64/ansiconv.o: ansicon.rc x64/ansiv.o: ansi.rc +x64/ANSI32.o: ANSI.c + $(CC) -m32 -DW32ON64 $(CFLAGS) $< -c -o $@ +x64/proctype32.o: proctype.c + $(CC) -m32 -DW32ON64 $(CFLAGS) $< -c -o $@ + # Need two commands, because if the directory doesn't exist, it won't delete # anything at all. clean: diff --git a/makefile.vc b/makefile.vc index fd6cee5..00a9019 100644 --- a/makefile.vc +++ b/makefile.vc @@ -42,9 +42,9 @@ X64OBJS = x64\proctype.obj x64\injdll64.obj x64\injdll32.obj x64\util.obj all: ansicon$(BITS) -ansicon32: x86 x86\ansicon.exe x86\ANSI32.dll +ansicon32: x86 x86\ansicon.exe x86\ANSI32.dll x64\ANSI32.dll -ansicon64: x64 x64\ansicon.exe x64\ANSI64.dll x64\ANSI32.dll x64\ANSI-LLW.exe +ansicon64: x64 x64\ansicon.exe x64\ANSI64.dll x64\ANSI-LLW.exe x86: mkdir x86 @@ -53,9 +53,7 @@ x86\ansicon.exe: x86\ansicon.obj $(X86OBJS) x86\ansicon.res $(CC) /nologo /Fe$@ $** $(LIBS) x86\ANSI32.dll: x86\ANSI.obj $(X86OBJS) x86\ansi.res -!IF $(BITS) == 32 $(CC) /nologo /LD /Fe$@ $** $(LIBS) -!ENDIF x64: mkdir x64 @@ -66,8 +64,8 @@ x64\ansicon.exe: x64\ansicon.obj $(X64OBJS) x64\ansicon.res x64\ANSI64.dll: x64\ANSI.obj $(X64OBJS) x64\ansi.res $(CC) /nologo /LD /Fe$@ $** $(LIBS) $(LIBS64) -x64\ANSI32.dll: x86\ANSI32.dll - copy x86\ANSI32.dll x64\ANSI32.dll +x64\ANSI32.dll: x64\ANSI32.obj x64\proctype32.obj x86\injdll32.obj x86\util.obj x86\ansi.res + $(CC) /nologo /LD /Fe$@ $** $(LIBS) x64\ANSI-LLW.exe: ANSI-LLW.c $(CC) $(CFLAGS) /Fe$@ /Fo$*.obj $? $(LIBS64) @@ -81,5 +79,10 @@ injdll32.c: ansicon.h injdll64.c: ansicon.h proctype.c: ansicon.h +x64\ANSI32.obj: ANSI.c + $(CC) /DW32ON64 /c $(CFLAGS) /Fo$@ $? +x64\proctype32.obj: proctype.c + $(CC) /DW32ON64 /c $(CFLAGS) /Fo$@ $? + clean: -del $(DIR)\*.obj $(DIR)\*.res $(DIR)\*.lib $(DIR)\*.exp diff --git a/proctype.c b/proctype.c index 81213f9..f6a6e60 100644 --- a/proctype.c +++ b/proctype.c @@ -50,7 +50,7 @@ int ProcessType( LPPROCESS_INFORMATION pinfo, BOOL* gui ) { if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { - DEBUGSTR( 1, L" 32-bit %s (base = %p)", + DEBUGSTR( 1, L" 32-bit %s (base = %.8p)", (*gui) ? L"GUI" : L"console", minfo.AllocationBase ); return 32; } @@ -61,6 +61,13 @@ int ProcessType( LPPROCESS_INFORMATION pinfo, BOOL* gui ) (*gui) ? L"GUI" : L"console", minfo.AllocationBase ); return 64; } +#elif defined(W32ON64) + if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) + { + DEBUGSTR( 1, L" 64-bit %s", + (*gui) ? L"GUI" : L"console" ); + return 64; + } #endif DEBUGSTR( 1, L" Ignoring unsupported machine (0x%X)", nt_header.FileHeader.Machine ); @@ -80,8 +87,13 @@ int ProcessType( LPPROCESS_INFORMATION pinfo, BOOL* gui ) // address. If the pointer overflows, assume 64-bit and abort. if (ptr > ptr + minfo.RegionSize) { - DEBUGSTR( 1, L" Ignoring apparent 64-bit process." ); +#ifdef W32ON64 + DEBUGSTR( 1, L" Pointer overflow: assuming 64-bit console" ); + return 64; +#else + DEBUGSTR( 1, L" Ignoring apparent 64-bit process" ); return 0; +#endif } #endif } diff --git a/version.h b/version.h index b834aa6..a66bdcd 100644 --- a/version.h +++ b/version.h @@ -2,8 +2,8 @@ version.h - Version defines. */ -#define PVERS L"1.51" // wide string -#define PVERSA "1.51" // ANSI string (windres 2.16.91 didn't like L) -#define PVERE L"151" // wide environment string -#define PVEREA "151" // ANSI environment string -#define PVERB 1,5,1,0 // binary (resource) +#define PVERS L"1.52" // wide string +#define PVERSA "1.52" // ANSI string (windres 2.16.91 didn't like L) +#define PVERE L"152" // wide environment string +#define PVEREA "152" // ANSI environment string +#define PVERB 1,5,2,0 // binary (resource)