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
|
||||
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
4
ANSI.c
@ -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';
|
||||
|
20
ansicon.c
20
ansicon.c
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
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"
|
||||
@ -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)",
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user