Fixed x64 and MinGW32 crashes.
This commit is contained in:
parent
c1be7e4e7a
commit
1b3511ac1f
@ -5,6 +5,11 @@
|
|||||||
|
|
||||||
I don't know of a method to retrieve the 32-bit address of a function in
|
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.
|
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
|
#define WIN32_LEAN_AND_MEAN
|
||||||
@ -12,5 +17,6 @@
|
|||||||
|
|
||||||
int main( void )
|
int main( void )
|
||||||
{
|
{
|
||||||
return (DWORD)LoadLibraryW;
|
return (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ),
|
||||||
|
"LoadLibraryW" );
|
||||||
}
|
}
|
||||||
|
4
ANSI.c
4
ANSI.c
@ -57,7 +57,7 @@
|
|||||||
v1.31, 13 & 19 November, 2010:
|
v1.31, 13 & 19 November, 2010:
|
||||||
fix multibyte conversion problems.
|
fix multibyte conversion problems.
|
||||||
|
|
||||||
v1.32, 4, 12 & 16 December, 2010:
|
v1.32, 4 to 22 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[>;
|
||||||
@ -908,7 +908,7 @@ void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi,
|
|||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
DWORD len = GetModuleFileName( GetModuleHandleA( "ANSI64.dll" ),
|
DWORD len = GetModuleFileName( GetModuleHandleA( "ANSI64.dll" ),
|
||||||
dll, lenof(dll) );
|
dll, lenof(dll) );
|
||||||
if (type == 32 || type == -32)
|
if (type == 32)
|
||||||
{
|
{
|
||||||
dll[len-6] = '3';
|
dll[len-6] = '3';
|
||||||
dll[len-5] = '2';
|
dll[len-5] = '2';
|
||||||
|
20
ansicon.c
20
ansicon.c
@ -43,14 +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 & 16 December, 2010:
|
v1.32, 4 to 22 December, 2010:
|
||||||
make -p more robust;
|
make -p more robust;
|
||||||
inject into GUI processes;
|
inject into GUI processes;
|
||||||
-i implies -p.
|
-i implies -p.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PVERS L"1.32"
|
#define PVERS L"1.32"
|
||||||
#define PDATE L"17 December, 2010"
|
#define PDATE L"22 December, 2010"
|
||||||
|
|
||||||
#include "ansicon.h"
|
#include "ansicon.h"
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
@ -95,6 +95,10 @@ BOOL Inject( LPPROCESS_INFORMATION ppi )
|
|||||||
WCHAR dll[MAX_PATH];
|
WCHAR dll[MAX_PATH];
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
#if (MYDEBUG > 0)
|
||||||
|
if (GetModuleFileNameEx( ppi->hProcess, NULL, dll, lenof(dll) ))
|
||||||
|
DEBUGSTR( L"%s", dll );
|
||||||
|
#endif
|
||||||
type = ProcessType( ppi );
|
type = ProcessType( ppi );
|
||||||
if (type == 0)
|
if (type == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -103,7 +107,6 @@ BOOL Inject( LPPROCESS_INFORMATION ppi )
|
|||||||
while (dll[len-1] != '\\')
|
while (dll[len-1] != '\\')
|
||||||
--len;
|
--len;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
type = abs( type );
|
|
||||||
wsprintf( dll + len, L"ANSI%d.dll", type );
|
wsprintf( dll + len, L"ANSI%d.dll", type );
|
||||||
if (type == 32)
|
if (type == 32)
|
||||||
InjectDLL32( ppi, dll );
|
InjectDLL32( ppi, dll );
|
||||||
@ -303,7 +306,15 @@ int main( void )
|
|||||||
CoInitialize( NULL );
|
CoInitialize( NULL );
|
||||||
do
|
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) ))
|
if (GetModuleFileNameEx( pi.hProcess, NULL, name, lenof(name) ))
|
||||||
{
|
{
|
||||||
DWORD_PTR info;
|
DWORD_PTR info;
|
||||||
@ -315,6 +326,7 @@ int main( void )
|
|||||||
info );
|
info );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Sleep( 10 );
|
||||||
} while (GetExitCodeProcess( pi.hProcess, &rc ) &&
|
} while (GetExitCodeProcess( pi.hProcess, &rc ) &&
|
||||||
rc == STILL_ACTIVE);
|
rc == STILL_ACTIVE);
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
|
@ -28,7 +28,7 @@ void InjectDLL64( LPPROCESS_INFORMATION, LPCTSTR );
|
|||||||
// ========== Auxiliary debug function
|
// ========== Auxiliary debug function
|
||||||
|
|
||||||
#ifndef MYDEBUG
|
#ifndef MYDEBUG
|
||||||
# define MYDEBUG 2 // 0 - no debugging
|
# define MYDEBUG 0 // 0 - no debugging
|
||||||
// 1 - use OutputDebugString
|
// 1 - use OutputDebugString
|
||||||
// 2 - use %temp%\ansicon.log
|
// 2 - use %temp%\ansicon.log
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,9 +57,9 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
|
|||||||
|
|
||||||
if (LLW == 0)
|
if (LLW == 0)
|
||||||
{
|
{
|
||||||
|
HMODULE hKernel = GetModuleHandleA( "kernel32.dll" );
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#ifdef __MINGW64__
|
#ifdef __MINGW64__
|
||||||
HMODULE hKernel = GetModuleHandleA( "kernel32.dll" );
|
|
||||||
#define GETPROC( proc ) proc = (T##proc)GetProcAddress( hKernel, #proc )
|
#define GETPROC( proc ) proc = (T##proc)GetProcAddress( hKernel, #proc )
|
||||||
GETPROC( Wow64GetThreadContext );
|
GETPROC( Wow64GetThreadContext );
|
||||||
GETPROC( Wow64SetThreadContext );
|
GETPROC( Wow64SetThreadContext );
|
||||||
@ -90,7 +90,7 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
|
|||||||
CloseHandle( pi.hProcess );
|
CloseHandle( pi.hProcess );
|
||||||
CloseHandle( pi.hThread );
|
CloseHandle( pi.hThread );
|
||||||
#else
|
#else
|
||||||
LLW = (DWORD)LoadLibrary;
|
LLW = (DWORD)GetProcAddress( hKernel, "LoadLibraryW" );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
proctype.c
24
proctype.c
@ -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"
|
#include "ansicon.h"
|
||||||
@ -14,10 +22,10 @@ int ProcessType( LPPROCESS_INFORMATION pinfo )
|
|||||||
{
|
{
|
||||||
IMAGE_DOS_HEADER dos_header;
|
IMAGE_DOS_HEADER dos_header;
|
||||||
SIZE_T read;
|
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 ))
|
&dos_header, sizeof(dos_header), &read ))
|
||||||
{
|
{
|
||||||
DEBUGSTR( L" Base = %p", minfo.AllocationBase );
|
|
||||||
if (dos_header.e_magic == IMAGE_DOS_SIGNATURE)
|
if (dos_header.e_magic == IMAGE_DOS_SIGNATURE)
|
||||||
{
|
{
|
||||||
IMAGE_NT_HEADERS nt_header;
|
IMAGE_NT_HEADERS nt_header;
|
||||||
@ -33,14 +41,16 @@ int ProcessType( LPPROCESS_INFORMATION pinfo )
|
|||||||
{
|
{
|
||||||
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
|
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
|
||||||
{
|
{
|
||||||
DEBUGSTR( L" 32-bit %s", (gui) ? L"GUI" : L"console" );
|
DEBUGSTR( L" %p: 32-bit %s",
|
||||||
return (gui) ? -32 : 32;
|
minfo.AllocationBase, (gui) ? L"GUI" : L"console" );
|
||||||
|
return 32;
|
||||||
}
|
}
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
|
if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
|
||||||
{
|
{
|
||||||
DEBUGSTR( L" 64-bit %s", (gui) ? L"GUI" : L"console" );
|
DEBUGSTR( L" %p: 64-bit %s",
|
||||||
return (gui) ? -64 : 64;
|
minfo.AllocationBase, (gui) ? L"GUI" : L"console" );
|
||||||
|
return 64;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DEBUGSTR( L" Ignoring unsupported machine (0x%X)",
|
DEBUGSTR( L" Ignoring unsupported machine (0x%X)",
|
||||||
|
@ -140,6 +140,8 @@
|
|||||||
The 64-bit version can inject into a 32-bit process, but the 32-bit
|
The 64-bit version can inject into a 32-bit process, but the 32-bit
|
||||||
version will not inject into a 64-bit process.
|
version will not inject into a 64-bit process.
|
||||||
|
|
||||||
|
Building rubyinstaller on Win7 crashes (XP is fine).
|
||||||
|
|
||||||
|
|
||||||
===============
|
===============
|
||||||
Version History
|
Version History
|
||||||
@ -147,11 +149,12 @@
|
|||||||
|
|
||||||
Legend: + added, - bug-fixed, * changed.
|
Legend: + added, - bug-fixed, * changed.
|
||||||
|
|
||||||
1.32 - 16 December, 2010:
|
1.32 - 22 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;
|
||||||
+ 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:
|
1.31 - 19 November, 2010:
|
||||||
- fixed multibyte support (no extra junk with UTF-8 files);
|
- fixed multibyte support (no extra junk with UTF-8 files);
|
||||||
@ -273,4 +276,4 @@
|
|||||||
|
|
||||||
|
|
||||||
==============================
|
==============================
|
||||||
Jason Hood, 16 December, 2010.
|
Jason Hood, 22 December, 2010.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user