Enable 32-bit to inject into 64-bit.

This commit is contained in:
Jason Hood 2012-04-10 15:39:58 +10:00
parent 6fc87e3a06
commit 4d2dec15d3
6 changed files with 88 additions and 19 deletions

31
ANSI.c
View File

@ -81,6 +81,9 @@
ignore the version within the core API DLL names; ignore the version within the core API DLL names;
fix 32-bit process trying to identify 64-bit process; fix 32-bit process trying to identify 64-bit process;
hook _lwrite & _hwrite. hook _lwrite & _hwrite.
v1.52, 10 April, 2012:
use ansicon.exe to enable 32-bit to inject into 64-bit.
*/ */
#include "ansicon.h" #include "ansicon.h"
@ -913,7 +916,7 @@ API_DATA APIs[] =
HMODULE hKernel; // Kernel32 module handle HMODULE hKernel; // Kernel32 module handle
HINSTANCE hDllInstance; // Dll instance handle HINSTANCE hDllInstance; // Dll instance handle
TCHAR hDllName[MAX_PATH]; // Dll file name TCHAR hDllName[MAX_PATH]; // Dll file name
#ifdef _WIN64 #if defined(_WIN64) || defined(W32ON64)
LPTSTR hDllNameType; // pointer to process type within above LPTSTR hDllNameType; // pointer to process type within above
#endif #endif
@ -1212,6 +1215,30 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
InjectDLL64( &child_pi, hDllName ); InjectDLL64( &child_pi, hDllName );
} }
#else #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 ); InjectDLL32( &child_pi, hDllName );
#endif #endif
if (!gui && !(dwCreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS))) 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) ); GetEnvironmentVariable( L"ANSICON_LOG", logstr, lenof(logstr) );
log_level = _wtoi( logstr ); log_level = _wtoi( logstr );
prog = get_program_name( NULL ); prog = get_program_name( NULL );
#ifdef _WIN64 #if defined(_WIN64) || defined(W32ON64)
hDllNameType = hDllName - 6 + hDllNameType = hDllName - 6 +
#endif #endif
GetModuleFileName( hInstance, hDllName, lenof(hDllName) ); GetModuleFileName( hInstance, hDllName, lenof(hDllName) );

View File

@ -60,9 +60,13 @@
7 January, 2012: 7 January, 2012:
fixed installing into a piped CMD.EXE; fixed installing into a piped CMD.EXE;
added a log message indicating all imports have been processed. 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 "ansicon.h"
#include "version.h" #include "version.h"
@ -194,6 +198,20 @@ int main( void )
*logstr = '\0'; *logstr = '\0';
GetEnvironmentVariable( L"ANSICON_LOG", logstr, lenof(logstr) ); GetEnvironmentVariable( L"ANSICON_LOG", logstr, lenof(logstr) );
log_level = _wtoi( 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)) if (log_level && !(log_level & 8))
DEBUGSTR( 1, NULL ); // create a new file DEBUGSTR( 1, NULL ); // create a new file
@ -300,7 +318,11 @@ arg_out:
{ {
cmd = _wgetenv( L"ComSpec" ); cmd = _wgetenv( L"ComSpec" );
if (cmd == NULL) 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; arg = cmd;
} }

View File

@ -53,8 +53,8 @@ x64/ansicon.exe: x64/ansicon.o $(X64OBJS) x64/ansiconv.o
x64/ANSI64.dll: x64/ANSI.o $(X64OBJS) x64/ansiv.o x64/ANSI64.dll: x64/ANSI.o $(X64OBJS) x64/ansiv.o
$(CC) -m64 $+ -s -o $@ -mdll -Wl,-shared $(CC) -m64 $+ -s -o $@ -mdll -Wl,-shared
x64/ANSI32.dll: x86/ANSI32.dll x64/ANSI32.dll: x64/ANSI32.o x64/proctype32.o x86/injdll32.o x86/util.o x86/ansiv.o
cmd /c "copy/y x86\ANSI32.dll x64\ANSI32.dll >nul" $(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared
x64/ANSI-LLW.exe: ANSI-LLW.c x64/ANSI-LLW.exe: ANSI-LLW.c
$(CC) -m32 $(CFLAGS) $< -s -o $@ $(CC) -m32 $(CFLAGS) $< -s -o $@
@ -68,6 +68,11 @@ 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
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 # Need two commands, because if the directory doesn't exist, it won't delete
# anything at all. # anything at all.
clean: clean:

View File

@ -42,9 +42,9 @@ X64OBJS = x64\proctype.obj x64\injdll64.obj x64\injdll32.obj x64\util.obj
all: ansicon$(BITS) 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: x86:
mkdir x86 mkdir x86
@ -53,9 +53,7 @@ x86\ansicon.exe: x86\ansicon.obj $(X86OBJS) x86\ansicon.res
$(CC) /nologo /Fe$@ $** $(LIBS) $(CC) /nologo /Fe$@ $** $(LIBS)
x86\ANSI32.dll: x86\ANSI.obj $(X86OBJS) x86\ansi.res x86\ANSI32.dll: x86\ANSI.obj $(X86OBJS) x86\ansi.res
!IF $(BITS) == 32
$(CC) /nologo /LD /Fe$@ $** $(LIBS) $(CC) /nologo /LD /Fe$@ $** $(LIBS)
!ENDIF
x64: x64:
mkdir 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 x64\ANSI64.dll: x64\ANSI.obj $(X64OBJS) x64\ansi.res
$(CC) /nologo /LD /Fe$@ $** $(LIBS) $(LIBS64) $(CC) /nologo /LD /Fe$@ $** $(LIBS) $(LIBS64)
x64\ANSI32.dll: x86\ANSI32.dll x64\ANSI32.dll: x64\ANSI32.obj x64\proctype32.obj x86\injdll32.obj x86\util.obj x86\ansi.res
copy x86\ANSI32.dll x64\ANSI32.dll $(CC) /nologo /LD /Fe$@ $** $(LIBS)
x64\ANSI-LLW.exe: ANSI-LLW.c x64\ANSI-LLW.exe: ANSI-LLW.c
$(CC) $(CFLAGS) /Fe$@ /Fo$*.obj $? $(LIBS64) $(CC) $(CFLAGS) /Fe$@ /Fo$*.obj $? $(LIBS64)
@ -81,5 +79,10 @@ injdll32.c: ansicon.h
injdll64.c: ansicon.h injdll64.c: ansicon.h
proctype.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: clean:
-del $(DIR)\*.obj $(DIR)\*.res $(DIR)\*.lib $(DIR)\*.exp -del $(DIR)\*.obj $(DIR)\*.res $(DIR)\*.lib $(DIR)\*.exp

View File

@ -50,7 +50,7 @@ int ProcessType( LPPROCESS_INFORMATION pinfo, BOOL* gui )
{ {
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) 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 ); (*gui) ? L"GUI" : L"console", minfo.AllocationBase );
return 32; return 32;
} }
@ -61,6 +61,13 @@ int ProcessType( LPPROCESS_INFORMATION pinfo, BOOL* gui )
(*gui) ? L"GUI" : L"console", minfo.AllocationBase ); (*gui) ? L"GUI" : L"console", minfo.AllocationBase );
return 64; 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 #endif
DEBUGSTR( 1, L" Ignoring unsupported machine (0x%X)", DEBUGSTR( 1, L" Ignoring unsupported machine (0x%X)",
nt_header.FileHeader.Machine ); 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. // address. If the pointer overflows, assume 64-bit and abort.
if (ptr > ptr + minfo.RegionSize) 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; return 0;
#endif
} }
#endif #endif
} }

View File

@ -2,8 +2,8 @@
version.h - Version defines. version.h - Version defines.
*/ */
#define PVERS L"1.51" // wide string #define PVERS L"1.52" // wide string
#define PVERSA "1.51" // ANSI string (windres 2.16.91 didn't like L) #define PVERSA "1.52" // ANSI string (windres 2.16.91 didn't like L)
#define PVERE L"151" // wide environment string #define PVERE L"152" // wide environment string
#define PVEREA "151" // ANSI environment string #define PVEREA "152" // ANSI environment string
#define PVERB 1,5,1,0 // binary (resource) #define PVERB 1,5,2,0 // binary (resource)