Fixed x64 and MinGW32 crashes.

This commit is contained in:
Jason Hood 2010-12-22 18:47:45 +10:00
parent c1be7e4e7a
commit 1b3511ac1f
7 changed files with 51 additions and 20 deletions

View File

@ -5,6 +5,11 @@
I don't know of a method to retrieve the 32-bit address of a function in
64-bit code, so this is a simple workaround.
18 December, 2010: Initially I used GetProcAddress, but then I thought that
was silly, why don't I just return LoadLibraryW directly? That worked fine
for TDM64 and VC, but MinGW32 would return the address of the jump to the
function, not the function itself. Not so silly after all.
*/
#define WIN32_LEAN_AND_MEAN
@ -12,5 +17,6 @@
int main( void )
{
return (DWORD)LoadLibraryW;
return (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ),
"LoadLibraryW" );
}

4
ANSI.c
View File

@ -57,7 +57,7 @@
v1.31, 13 & 19 November, 2010:
fix multibyte conversion problems.
v1.32, 4, 12 & 16 December, 2010:
v1.32, 4 to 22 December, 2010:
test for lpNumberOfCharsWritten/lpNumberOfBytesWritten being NULL;
recognise DSR and xterm window title;
ignore sequences starting with \e[? & \e[>;
@ -908,7 +908,7 @@ void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi,
#ifdef _WIN64
DWORD len = GetModuleFileName( GetModuleHandleA( "ANSI64.dll" ),
dll, lenof(dll) );
if (type == 32 || type == -32)
if (type == 32)
{
dll[len-6] = '3';
dll[len-5] = '2';

View File

@ -43,14 +43,14 @@
VC compatibility (2008 Express for 32-bit, PSDK 2003 R2 for 64-bit);
explicitly use wide characters (stick with TCHAR, but not <tchar.h>).
v1.32, 4, 12 & 16 December, 2010:
v1.32, 4 to 22 December, 2010:
make -p more robust;
inject into GUI processes;
-i implies -p.
*/
#define PVERS L"1.32"
#define PDATE L"17 December, 2010"
#define PDATE L"22 December, 2010"
#include "ansicon.h"
#include <shellapi.h>
@ -95,6 +95,10 @@ BOOL Inject( LPPROCESS_INFORMATION ppi )
WCHAR dll[MAX_PATH];
int type;
#if (MYDEBUG > 0)
if (GetModuleFileNameEx( ppi->hProcess, NULL, dll, lenof(dll) ))
DEBUGSTR( L"%s", dll );
#endif
type = ProcessType( ppi );
if (type == 0)
return FALSE;
@ -103,7 +107,6 @@ BOOL Inject( LPPROCESS_INFORMATION ppi )
while (dll[len-1] != '\\')
--len;
#ifdef _WIN64
type = abs( type );
wsprintf( dll + len, L"ANSI%d.dll", type );
if (type == 32)
InjectDLL32( ppi, dll );
@ -303,7 +306,15 @@ int main( void )
CoInitialize( NULL );
do
{
Sleep( 10 );
// When I first tried doing this, it took a little while to
// succeed. Testing again shows it works immediately - perhaps the
// CoInitialize introduces enough of a delay. Still, play it safe
// and keep trying. And if you're wondering why I do it at all,
// ProcessType may detect GUI, even for a console process. That's
// fine after injection (including -p), but not here. We *need* to
// suspend our own execution whilst running the child, otherwise
// bad things happen (besides which, I want to restore the original
// attributes when the child exits).
if (GetModuleFileNameEx( pi.hProcess, NULL, name, lenof(name) ))
{
DWORD_PTR info;
@ -315,6 +326,7 @@ int main( void )
info );
break;
}
Sleep( 10 );
} while (GetExitCodeProcess( pi.hProcess, &rc ) &&
rc == STILL_ACTIVE);
CoUninitialize();

View File

@ -28,7 +28,7 @@ void InjectDLL64( LPPROCESS_INFORMATION, LPCTSTR );
// ========== Auxiliary debug function
#ifndef MYDEBUG
# define MYDEBUG 2 // 0 - no debugging
# define MYDEBUG 0 // 0 - no debugging
// 1 - use OutputDebugString
// 2 - use %temp%\ansicon.log
#endif

View File

@ -57,9 +57,9 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
if (LLW == 0)
{
HMODULE hKernel = GetModuleHandleA( "kernel32.dll" );
#ifdef _WIN64
#ifdef __MINGW64__
HMODULE hKernel = GetModuleHandleA( "kernel32.dll" );
#define GETPROC( proc ) proc = (T##proc)GetProcAddress( hKernel, #proc )
GETPROC( Wow64GetThreadContext );
GETPROC( Wow64SetThreadContext );
@ -90,7 +90,7 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
#else
LLW = (DWORD)LoadLibrary;
LLW = (DWORD)GetProcAddress( hKernel, "LoadLibraryW" );
#endif
}

View File

@ -1,5 +1,13 @@
/*
Test for a valid process.
Test for a valid process. This may sometimes detect GUI, even for a console
process. I think this is due to a DLL being loaded in the address space
before the main image. Ideally I could just use the base address directly,
but that doesn't seem easy to do for another process - there doesn't seem to
be a GetModuleHandle for another process. The CreateRemoteThread trick won't
work with 64-bit (exit code is DWORD) and setting it up to make it work
hardly seems worth it. There's GetModuleInformation, but passing in NULL just
returns a base of NULL, so that's no help. Since 64/32 is sufficient, let
ansicon.exe handle the difference between console/GUI.
*/
#include "ansicon.h"
@ -14,10 +22,10 @@ int ProcessType( LPPROCESS_INFORMATION pinfo )
{
IMAGE_DOS_HEADER dos_header;
SIZE_T read;
if (ReadProcessMemory( pinfo->hProcess, minfo.AllocationBase,
if (minfo.BaseAddress == minfo.AllocationBase &&
ReadProcessMemory( pinfo->hProcess, minfo.AllocationBase,
&dos_header, sizeof(dos_header), &read ))
{
DEBUGSTR( L" Base = %p", minfo.AllocationBase );
if (dos_header.e_magic == IMAGE_DOS_SIGNATURE)
{
IMAGE_NT_HEADERS nt_header;
@ -33,14 +41,16 @@ int ProcessType( LPPROCESS_INFORMATION pinfo )
{
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
{
DEBUGSTR( L" 32-bit %s", (gui) ? L"GUI" : L"console" );
return (gui) ? -32 : 32;
DEBUGSTR( L" %p: 32-bit %s",
minfo.AllocationBase, (gui) ? L"GUI" : L"console" );
return 32;
}
#ifdef _WIN64
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
{
DEBUGSTR( L" 64-bit %s", (gui) ? L"GUI" : L"console" );
return (gui) ? -64 : 64;
DEBUGSTR( L" %p: 64-bit %s",
minfo.AllocationBase, (gui) ? L"GUI" : L"console" );
return 64;
}
#endif
DEBUGSTR( L" Ignoring unsupported machine (0x%X)",

View File

@ -140,6 +140,8 @@
The 64-bit version can inject into a 32-bit process, but the 32-bit
version will not inject into a 64-bit process.
Building rubyinstaller on Win7 crashes (XP is fine).
===============
Version History
@ -147,11 +149,12 @@
Legend: + added, - bug-fixed, * changed.
1.32 - 16 December, 2010:
1.32 - 22 December, 2010:
- fixed crash due to NULL lpNumberOfBytesWritten/lpNumberOfCharsWritten;
- -p will test the parent process for validity;
* hook into GUI processes;
+ recognise DSR and xterm window title sequences.
+ recognise DSR and xterm window title sequences;
- fixed MinGW32 binaries (LLW was wrong).
1.31 - 19 November, 2010:
- fixed multibyte support (no extra junk with UTF-8 files);
@ -273,4 +276,4 @@
==============================
Jason Hood, 16 December, 2010.
Jason Hood, 22 December, 2010.