Compare commits
10 Commits
86512f67f6
...
37f92009f6
Author | SHA1 | Date | |
---|---|---|---|
![]() |
37f92009f6 | ||
![]() |
0fc890dddd | ||
![]() |
0dd40f6d74 | ||
![]() |
d7a2d5e962 | ||
![]() |
a1bf74dff9 | ||
![]() |
eccbbe7a54 | ||
![]() |
0472db80b2 | ||
![]() |
06459edb69 | ||
![]() |
4e84582f02 | ||
![]() |
eec487abb6 |
168
ANSI.c
168
ANSI.c
@ -210,8 +210,25 @@
|
|||||||
scrolling will use the default attribute for new lines;
|
scrolling will use the default attribute for new lines;
|
||||||
workaround Windows 10 1803 console bug.
|
workaround Windows 10 1803 console bug.
|
||||||
|
|
||||||
v1.85, 22 August, 2018:
|
v1.85, 22 & 23 August, 2018:
|
||||||
fix creating the wrap buffer.
|
fix creating the wrap buffer;
|
||||||
|
always inject from ansicon.exe, even if it's GUI or excluded;
|
||||||
|
log CreateFile calls;
|
||||||
|
preserve last error.
|
||||||
|
|
||||||
|
v1.86, 4 November, 2018:
|
||||||
|
always unhook, even on terminate;
|
||||||
|
check the DLL still exists before adding to imports.
|
||||||
|
|
||||||
|
v1.87, 3 February, 2019:
|
||||||
|
some hooked functions are not imported, so myimport wasn't set;
|
||||||
|
add missing SetCurrentConsoleFontEx to list of hooks.
|
||||||
|
|
||||||
|
v1.88, 1 March, 2019:
|
||||||
|
a detached process has no console handle (fixes set_ansicon).
|
||||||
|
|
||||||
|
v1.89, 29 April, 2019:
|
||||||
|
an eight-digit window handle would break my custom printf.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ansicon.h"
|
#include "ansicon.h"
|
||||||
@ -236,6 +253,7 @@ DWORD orgmode; // original mode
|
|||||||
CONSOLE_CURSOR_INFO orgcci; // original cursor state
|
CONSOLE_CURSOR_INFO orgcci; // original cursor state
|
||||||
HANDLE hHeap; // local memory heap
|
HANDLE hHeap; // local memory heap
|
||||||
HANDLE hBell, hFlush;
|
HANDLE hBell, hFlush;
|
||||||
|
BOOL ansicon; // are we in ansicon.exe?
|
||||||
|
|
||||||
#define CACHE 5
|
#define CACHE 5
|
||||||
struct Cache
|
struct Cache
|
||||||
@ -524,26 +542,14 @@ void get_state( void )
|
|||||||
csbix.cbSize = sizeof(csbix);
|
csbix.cbSize = sizeof(csbix);
|
||||||
if (GetConsoleScreenBufferInfoX( hConOut, &csbix ))
|
if (GetConsoleScreenBufferInfoX( hConOut, &csbix ))
|
||||||
{
|
{
|
||||||
Info.dwSize = csbix.dwSize;
|
|
||||||
ATTR = csbix.wAttributes;
|
|
||||||
WIN = csbix.srWindow;
|
|
||||||
arrcpy( pState->o_palette, csbix.ColorTable );
|
arrcpy( pState->o_palette, csbix.ColorTable );
|
||||||
|
ATTR = csbix.wAttributes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arrcpy( pState->o_palette, legacy_palette );
|
arrcpy( pState->o_palette, legacy_palette );
|
||||||
if (!GetConsoleScreenBufferInfo( hConOut, &Info ))
|
if (!GetConsoleScreenBufferInfo( hConOut, &Info ))
|
||||||
{
|
ATTR = 7;
|
||||||
DEBUGSTR( 1, "Failed to get screen buffer info (%u) - assuming defaults",
|
|
||||||
GetLastError() );
|
|
||||||
ATTR = 7;
|
|
||||||
WIDTH = 80;
|
|
||||||
HEIGHT = 300;
|
|
||||||
WIN.Left = 0;
|
|
||||||
WIN.Right = 79;
|
|
||||||
TOP = 0;
|
|
||||||
BOTTOM = 24;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
arrcpy( pState->x_palette, xterm_palette );
|
arrcpy( pState->x_palette, xterm_palette );
|
||||||
|
|
||||||
@ -563,7 +569,10 @@ void get_state( void )
|
|||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL, OPEN_EXISTING, 0, NULL );
|
NULL, OPEN_EXISTING, 0, NULL );
|
||||||
if (!GetConsoleScreenBufferInfo( hConOut, &Info ))
|
if (!GetConsoleScreenBufferInfo( hConOut, &Info ))
|
||||||
|
{
|
||||||
|
RtlZeroMemory( &Info, sizeof(Info) );
|
||||||
ATTR = 7;
|
ATTR = 7;
|
||||||
|
}
|
||||||
if (pState->sgr.reverse)
|
if (pState->sgr.reverse)
|
||||||
{
|
{
|
||||||
*a++ = '-';
|
*a++ = '-';
|
||||||
@ -2794,6 +2803,10 @@ BOOL HookAPIOneMod(
|
|||||||
hook->myimport = &pThunk->u1.Function;
|
hook->myimport = &pThunk->u1.Function;
|
||||||
DEBUGSTR( 3, " %s%s", sp, hook->name );
|
DEBUGSTR( 3, " %s%s", sp, hook->name );
|
||||||
}
|
}
|
||||||
|
else if (hook->myimport == 0)
|
||||||
|
{
|
||||||
|
patch = hook->newfunc;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Don't hook if our import already points to the module being
|
// Don't hook if our import already points to the module being
|
||||||
@ -3003,7 +3016,7 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
|
|||||||
|
|
||||||
name = get_program( app, child_pi->hProcess, wide, lpApp, lpCmd );
|
name = get_program( app, child_pi->hProcess, wide, lpApp, lpCmd );
|
||||||
DEBUGSTR( 1, "%S (%u)", name, child_pi->dwProcessId );
|
DEBUGSTR( 1, "%S (%u)", name, child_pi->dwProcessId );
|
||||||
if (search_env( L"ANSICON_EXC", name ))
|
if (!ansicon && search_env( L"ANSICON_EXC", name ))
|
||||||
{
|
{
|
||||||
DEBUGSTR( 1, " Excluded" );
|
DEBUGSTR( 1, " Excluded" );
|
||||||
type = 0;
|
type = 0;
|
||||||
@ -3011,7 +3024,7 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = ProcessType( child_pi, &base, &gui );
|
type = ProcessType( child_pi, &base, &gui );
|
||||||
if (gui && type > 0)
|
if (!ansicon && gui && type > 0)
|
||||||
{
|
{
|
||||||
if (!search_env( L"ANSICON_GUI", name ))
|
if (!search_env( L"ANSICON_GUI", name ))
|
||||||
{
|
{
|
||||||
@ -3022,6 +3035,17 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
|
|||||||
}
|
}
|
||||||
if (type > 0)
|
if (type > 0)
|
||||||
{
|
{
|
||||||
|
#if defined(_WIN64) || defined(W32ON64)
|
||||||
|
if (type == 32)
|
||||||
|
*(PDWORD)DllNameType = 0x320033/*L'23'*/;
|
||||||
|
else
|
||||||
|
*(PDWORD)DllNameType = 0x340036/*L'46'*/;
|
||||||
|
#endif
|
||||||
|
if (GetFileAttributes( DllName ) == INVALID_FILE_ATTRIBUTES)
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
if (type > 0)
|
||||||
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
if (type == 64)
|
if (type == 64)
|
||||||
{
|
{
|
||||||
@ -3110,7 +3134,9 @@ BOOL WINAPI MyCreateProcessA( LPCSTR lpApplicationName,
|
|||||||
lpStartupInfo,
|
lpStartupInfo,
|
||||||
&child_pi ))
|
&child_pi ))
|
||||||
{
|
{
|
||||||
DEBUGSTR( 1, " Failed (%u)", GetLastError() );
|
DWORD err = GetLastError();
|
||||||
|
DEBUGSTR( 1, " Failed (%u)", err );
|
||||||
|
SetLastError( err );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3148,7 +3174,9 @@ BOOL WINAPI MyCreateProcessW( LPCWSTR lpApplicationName,
|
|||||||
lpStartupInfo,
|
lpStartupInfo,
|
||||||
&child_pi ))
|
&child_pi ))
|
||||||
{
|
{
|
||||||
DEBUGSTR( 1, " Failed (%u)", GetLastError() );
|
DWORD err = GetLastError();
|
||||||
|
DEBUGSTR( 1, " Failed (%u)", err );
|
||||||
|
SetLastError( err );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3219,8 +3247,10 @@ FARPROC WINAPI MyGetProcAddress( HMODULE hModule, LPCSTR lpProcName )
|
|||||||
HMODULE WINAPI MyLoadLibraryA( LPCSTR lpFileName )
|
HMODULE WINAPI MyLoadLibraryA( LPCSTR lpFileName )
|
||||||
{
|
{
|
||||||
HMODULE hMod = LoadLibraryA( lpFileName );
|
HMODULE hMod = LoadLibraryA( lpFileName );
|
||||||
DEBUGSTR( 2, "LoadLibraryA %s", lpFileName );
|
DWORD err = GetLastError();
|
||||||
|
DEBUGSTR( 2, "LoadLibraryA %\"s", lpFileName );
|
||||||
HookAPIAllMod( Hooks, FALSE, TRUE );
|
HookAPIAllMod( Hooks, FALSE, TRUE );
|
||||||
|
SetLastError( err );
|
||||||
return hMod;
|
return hMod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3228,8 +3258,10 @@ HMODULE WINAPI MyLoadLibraryA( LPCSTR lpFileName )
|
|||||||
HMODULE WINAPI MyLoadLibraryW( LPCWSTR lpFileName )
|
HMODULE WINAPI MyLoadLibraryW( LPCWSTR lpFileName )
|
||||||
{
|
{
|
||||||
HMODULE hMod = LoadLibraryW( lpFileName );
|
HMODULE hMod = LoadLibraryW( lpFileName );
|
||||||
DEBUGSTR( 2, "LoadLibraryW %S", lpFileName );
|
DWORD err = GetLastError();
|
||||||
|
DEBUGSTR( 2, "LoadLibraryW %\"S", lpFileName );
|
||||||
HookAPIAllMod( Hooks, FALSE, TRUE );
|
HookAPIAllMod( Hooks, FALSE, TRUE );
|
||||||
|
SetLastError( err );
|
||||||
return hMod;
|
return hMod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3242,8 +3274,10 @@ HMODULE WINAPI MyLoadLibraryExA( LPCSTR lpFileName, HANDLE hFile,
|
|||||||
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
|
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
|
||||||
LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
|
LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
|
||||||
{
|
{
|
||||||
DEBUGSTR( 2, "LoadLibraryExA %s", lpFileName );
|
DWORD err = GetLastError();
|
||||||
|
DEBUGSTR( 2, "LoadLibraryExA %\"s", lpFileName );
|
||||||
HookAPIAllMod( Hooks, FALSE, TRUE );
|
HookAPIAllMod( Hooks, FALSE, TRUE );
|
||||||
|
SetLastError( err );
|
||||||
}
|
}
|
||||||
return hMod;
|
return hMod;
|
||||||
}
|
}
|
||||||
@ -3257,8 +3291,10 @@ HMODULE WINAPI MyLoadLibraryExW( LPCWSTR lpFileName, HANDLE hFile,
|
|||||||
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
|
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
|
||||||
LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
|
LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
|
||||||
{
|
{
|
||||||
DEBUGSTR( 2, "LoadLibraryExW %S", lpFileName );
|
DWORD err = GetLastError();
|
||||||
|
DEBUGSTR( 2, "LoadLibraryExW %\"S", lpFileName );
|
||||||
HookAPIAllMod( Hooks, FALSE, TRUE );
|
HookAPIAllMod( Hooks, FALSE, TRUE );
|
||||||
|
SetLastError( err );
|
||||||
}
|
}
|
||||||
return hMod;
|
return hMod;
|
||||||
}
|
}
|
||||||
@ -3612,6 +3648,55 @@ WINAPI MyFreeLibrary( HMODULE hModule )
|
|||||||
// Add GENERIC_READ access to enable retrieving console info.
|
// Add GENERIC_READ access to enable retrieving console info.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void log_CreateFile( HANDLE h, LPCVOID name, BOOL wide, DWORD access,
|
||||||
|
DWORD dwDesiredAccess, DWORD dwCreationDisposition )
|
||||||
|
{
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
|
||||||
|
static char log[] = "CreateFile%s: %*s, %s, %s, %\"s";
|
||||||
|
LPCSTR acc, op;
|
||||||
|
char state[32];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (access != dwDesiredAccess)
|
||||||
|
acc = "w->r/w";
|
||||||
|
else if (access == (GENERIC_READ | GENERIC_WRITE) ||
|
||||||
|
(access & (FILE_READ_DATA | FILE_WRITE_DATA)) == (FILE_READ_DATA |
|
||||||
|
FILE_WRITE_DATA))
|
||||||
|
acc = "r/w";
|
||||||
|
else if (access == GENERIC_WRITE ||
|
||||||
|
access & (FILE_WRITE_DATA | FILE_APPEND_DATA))
|
||||||
|
acc = "write";
|
||||||
|
else if (access == GENERIC_READ ||
|
||||||
|
access & FILE_READ_DATA)
|
||||||
|
acc = "read";
|
||||||
|
else
|
||||||
|
acc = "access";
|
||||||
|
|
||||||
|
switch (dwCreationDisposition)
|
||||||
|
{
|
||||||
|
case CREATE_ALWAYS: op = "create"; break;
|
||||||
|
case CREATE_NEW: op = "new"; break;
|
||||||
|
case OPEN_ALWAYS: op = "open"; break;
|
||||||
|
case OPEN_EXISTING: op = "existing"; break;
|
||||||
|
case TRUNCATE_EXISTING: op = "truncate"; break;
|
||||||
|
default: op = "unknown"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
len = ac_sprintf( state, "failed (%u)", err );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state[0] = 'o';
|
||||||
|
state[1] = 'k';
|
||||||
|
len = 2;
|
||||||
|
}
|
||||||
|
log[sizeof(log) - 2] = wide ? 'S' : 's';
|
||||||
|
DEBUGSTR( 1, log, wide ? "W" : "A", len, state, op, acc, name );
|
||||||
|
|
||||||
|
SetLastError( err );
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
WINAPI MyCreateFileA( LPCSTR lpFileName, DWORD dwDesiredAccess,
|
WINAPI MyCreateFileA( LPCSTR lpFileName, DWORD dwDesiredAccess,
|
||||||
DWORD dwShareMode,
|
DWORD dwShareMode,
|
||||||
@ -3619,6 +3704,10 @@ WINAPI MyCreateFileA( LPCSTR lpFileName, DWORD dwDesiredAccess,
|
|||||||
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
|
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
|
||||||
HANDLE hTemplateFile )
|
HANDLE hTemplateFile )
|
||||||
{
|
{
|
||||||
|
LPCSTR name = lpFileName;
|
||||||
|
DWORD access = dwDesiredAccess;
|
||||||
|
HANDLE h;
|
||||||
|
|
||||||
if (dwDesiredAccess == GENERIC_WRITE)
|
if (dwDesiredAccess == GENERIC_WRITE)
|
||||||
{
|
{
|
||||||
PDWORD con = (PDWORD)lpFileName;
|
PDWORD con = (PDWORD)lpFileName;
|
||||||
@ -3629,9 +3718,13 @@ WINAPI MyCreateFileA( LPCSTR lpFileName, DWORD dwDesiredAccess,
|
|||||||
dwDesiredAccess |= GENERIC_READ;
|
dwDesiredAccess |= GENERIC_READ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CreateFileA( lpFileName, dwDesiredAccess, dwShareMode,
|
h = CreateFileA( lpFileName, dwDesiredAccess, dwShareMode,
|
||||||
lpSecurityAttributes, dwCreationDisposition,
|
lpSecurityAttributes, dwCreationDisposition,
|
||||||
dwFlagsAndAttributes, hTemplateFile );
|
dwFlagsAndAttributes, hTemplateFile );
|
||||||
|
if (log_level & 32)
|
||||||
|
log_CreateFile( h, name, FALSE, access,
|
||||||
|
dwDesiredAccess, dwCreationDisposition );
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
@ -3641,6 +3734,10 @@ WINAPI MyCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess,
|
|||||||
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
|
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
|
||||||
HANDLE hTemplateFile )
|
HANDLE hTemplateFile )
|
||||||
{
|
{
|
||||||
|
LPCWSTR name = lpFileName;
|
||||||
|
DWORD access = dwDesiredAccess;
|
||||||
|
HANDLE h;
|
||||||
|
|
||||||
if (dwDesiredAccess == GENERIC_WRITE)
|
if (dwDesiredAccess == GENERIC_WRITE)
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
@ -3660,9 +3757,13 @@ WINAPI MyCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess,
|
|||||||
dwDesiredAccess |= GENERIC_READ;
|
dwDesiredAccess |= GENERIC_READ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CreateFileW( lpFileName, dwDesiredAccess, dwShareMode,
|
h = CreateFileW( lpFileName, dwDesiredAccess, dwShareMode,
|
||||||
lpSecurityAttributes, dwCreationDisposition,
|
lpSecurityAttributes, dwCreationDisposition,
|
||||||
dwFlagsAndAttributes, hTemplateFile );
|
dwFlagsAndAttributes, hTemplateFile );
|
||||||
|
if (log_level & 32)
|
||||||
|
log_CreateFile( h, name, TRUE, access,
|
||||||
|
dwDesiredAccess, dwCreationDisposition );
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
@ -3770,7 +3871,8 @@ void set_ansicon( PCONSOLE_SCREEN_BUFFER_INFO pcsbi )
|
|||||||
hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
|
hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL, OPEN_EXISTING, 0, NULL );
|
NULL, OPEN_EXISTING, 0, NULL );
|
||||||
GetConsoleScreenBufferInfo( hConOut, &csbi );
|
if (!GetConsoleScreenBufferInfo( hConOut, &csbi ))
|
||||||
|
RtlZeroMemory( &csbi, sizeof(csbi) );
|
||||||
CloseHandle( hConOut );
|
CloseHandle( hConOut );
|
||||||
pcsbi = &csbi;
|
pcsbi = &csbi;
|
||||||
}
|
}
|
||||||
@ -3883,6 +3985,7 @@ HookFn Hooks[] = {
|
|||||||
HOOK( APIConsole, SetConsoleScreenBufferSize ),
|
HOOK( APIConsole, SetConsoleScreenBufferSize ),
|
||||||
HOOK( APIConsole, SetConsoleTextAttribute ),
|
HOOK( APIConsole, SetConsoleTextAttribute ),
|
||||||
HOOK( APIConsole, SetConsoleWindowInfo ),
|
HOOK( APIConsole, SetConsoleWindowInfo ),
|
||||||
|
HOOK( APIConsole, SetCurrentConsoleFontEx ),
|
||||||
HOOK( APIConsole, WriteConsoleOutputA ),
|
HOOK( APIConsole, WriteConsoleOutputA ),
|
||||||
HOOK( APIConsole, WriteConsoleOutputW ),
|
HOOK( APIConsole, WriteConsoleOutputW ),
|
||||||
HOOK( APIConsole, WriteConsoleOutputAttribute ),
|
HOOK( APIConsole, WriteConsoleOutputAttribute ),
|
||||||
@ -3927,6 +4030,7 @@ void OriginalAttr( PVOID lpReserved )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We also want to restore the original attributes for ansicon.exe.
|
// We also want to restore the original attributes for ansicon.exe.
|
||||||
|
ansicon =
|
||||||
org = (pNTHeader->OptionalHeader.MajorImageVersion == 20033 && // 'AN'
|
org = (pNTHeader->OptionalHeader.MajorImageVersion == 20033 && // 'AN'
|
||||||
pNTHeader->OptionalHeader.MinorImageVersion == 18771); // 'SI'
|
pNTHeader->OptionalHeader.MinorImageVersion == 18771); // 'SI'
|
||||||
}
|
}
|
||||||
@ -4040,7 +4144,6 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
|
|||||||
if (lpReserved == NULL)
|
if (lpReserved == NULL)
|
||||||
{
|
{
|
||||||
DEBUGSTR( 1, "Unloading" );
|
DEBUGSTR( 1, "Unloading" );
|
||||||
HookAPIAllMod( Hooks, TRUE, FALSE );
|
|
||||||
if (winmm != NULL)
|
if (winmm != NULL)
|
||||||
FreeLibrary( winmm );
|
FreeLibrary( winmm );
|
||||||
}
|
}
|
||||||
@ -4048,6 +4151,7 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
|
|||||||
{
|
{
|
||||||
DEBUGSTR( 1, "Terminating" );
|
DEBUGSTR( 1, "Terminating" );
|
||||||
}
|
}
|
||||||
|
HookAPIAllMod( Hooks, TRUE, FALSE );
|
||||||
if (orgattr != 0)
|
if (orgattr != 0)
|
||||||
{
|
{
|
||||||
hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
|
hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Copyright (C) 2005-2018 Jason Hood
|
Copyright (C) 2005-2019 Jason Hood
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the author be held liable for any damages
|
warranty. In no event will the author be held liable for any damages
|
||||||
|
33
ansicon.c
33
ansicon.c
@ -93,11 +93,13 @@
|
|||||||
v1.84, 7 May, 2018:
|
v1.84, 7 May, 2018:
|
||||||
import the DLL.
|
import the DLL.
|
||||||
|
|
||||||
v1.85, 22 August, 2018:
|
v1.85, 22 & 23 August, 2018:
|
||||||
use IsConsoleHandle for my_fputws, to distinguish NUL.
|
use IsConsoleHandle for my_fputws, to distinguish NUL;
|
||||||
|
don't load into the parent if already loaded;
|
||||||
|
add log level 32 to log CreateFile.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PDATE L"22 August, 2018"
|
#define PDATE L"29 April, 2019"
|
||||||
|
|
||||||
#include "ansicon.h"
|
#include "ansicon.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@ -219,10 +221,10 @@ void RemoteLoad( LPPROCESS_INFORMATION ppi, LPCTSTR app, BOOL unload )
|
|||||||
if (_wcsicmp( me.szModule, L"kernel32.dll" ) == 0)
|
if (_wcsicmp( me.szModule, L"kernel32.dll" ) == 0)
|
||||||
{
|
{
|
||||||
proc = me.modBaseAddr;
|
proc = me.modBaseAddr;
|
||||||
if (!unload || param)
|
if (param)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (unload)
|
else
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
if (_wcsicmp( me.szModule, DllNameType - 4 ) == 0)
|
if (_wcsicmp( me.szModule, DllNameType - 4 ) == 0)
|
||||||
@ -247,6 +249,11 @@ void RemoteLoad( LPPROCESS_INFORMATION ppi, LPCTSTR app, BOOL unload )
|
|||||||
DEBUGSTR( 1, " Unable to locate ANSICON's DLL" );
|
DEBUGSTR( 1, " Unable to locate ANSICON's DLL" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (!unload && param != NULL)
|
||||||
|
{
|
||||||
|
DEBUGSTR( 1, " ANSICON already loaded" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
rva = GetProcRVA( L"kernel32.dll", (unload) ? "FreeLibrary"
|
rva = GetProcRVA( L"kernel32.dll", (unload) ? "FreeLibrary"
|
||||||
@ -864,25 +871,25 @@ L"http://ansicon.adoxa.vze.com/\n"
|
|||||||
L"\n"
|
L"\n"
|
||||||
L"Process ANSI escape sequences in " WINTYPE L" console programs.\n"
|
L"Process ANSI escape sequences in " WINTYPE L" console programs.\n"
|
||||||
L"\n"
|
L"\n"
|
||||||
L"ansicon [-l<level>] [-i] [-I] [-u] [-U] [-m[<attr>]] [-p[u]]\n"
|
L"ansicon [-lLEVEL] [-i] [-I] [-u] [-U] [-m[ATTR]] [-p[u]]\n"
|
||||||
L" [-e|E string | -t|T [file(s)] | program [args]]\n"
|
L" [-e|E STRING | -t|T [FILE...] | PROGRAM [ARGS]]\n"
|
||||||
L"\n"
|
L"\n"
|
||||||
L" -l\t\tset the logging level (1=process, 2=module, 3=function,\n"
|
L" -l\t\tset the logging level (1=process, 2=module, 3=function,\n"
|
||||||
L" \t\t +4=output, +8=append) for program (-p is unaffected)\n"
|
L" \t\t +4=output, +8=append, +16=imports, +32=files) for PROGRAM\n"
|
||||||
L" -i\t\tinstall - add ANSICON to CMD's AutoRun entry (also implies -p)\n"
|
L" -i\t\tinstall - add ANSICON to CMD's AutoRun entry (also implies -p)\n"
|
||||||
L" -u\t\tuninstall - remove ANSICON from the AutoRun entry\n"
|
L" -u\t\tuninstall - remove ANSICON from the AutoRun entry\n"
|
||||||
L" -I -U\t\tuse local machine instead of current user\n"
|
L" -I -U\t\tuse local machine instead of current user\n"
|
||||||
L" -m\t\tuse grey on black (\"monochrome\") or <attr> as default color\n"
|
L" -m\t\tuse grey on black (\"monochrome\") or ATTR as default color\n"
|
||||||
L" -p\t\thook into the parent process\n"
|
L" -p\t\thook into the parent process\n"
|
||||||
L" -pu\t\tunhook from the parent process\n"
|
L" -pu\t\tunhook from the parent process\n"
|
||||||
L" -e\t\techo string\n"
|
L" -e\t\techo STRING\n"
|
||||||
L" -E\t\techo string, don't append newline\n"
|
L" -E\t\techo STRING, don't append newline\n"
|
||||||
L" -t\t\tdisplay files (\"-\" for stdin), combined as a single stream\n"
|
L" -t\t\tdisplay files (\"-\" for stdin), combined as a single stream\n"
|
||||||
L" -T\t\tdisplay files, name first, blank line before and after\n"
|
L" -T\t\tdisplay files, name first, blank line before and after\n"
|
||||||
L" program\trun the specified program\n"
|
L" PROGRAM\trun the specified program\n"
|
||||||
L" nothing\trun a new command processor, or display stdin if redirected\n"
|
L" nothing\trun a new command processor, or display stdin if redirected\n"
|
||||||
L"\n"
|
L"\n"
|
||||||
L"<attr> is one or two hexadecimal digits; please use \"COLOR /?\" for details.\n"
|
L"ATTR is one or two hexadecimal digits; please use \"COLOR /?\" for details.\n"
|
||||||
L"It may start with '-' to reverse foreground and background (but not for -p)."
|
L"It may start with '-' to reverse foreground and background (but not for -p)."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef INVALID_FILE_ATTRIBUTES
|
||||||
|
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||||
|
#endif
|
||||||
#ifndef LOAD_LIBRARY_AS_IMAGE_RESOURCE
|
#ifndef LOAD_LIBRARY_AS_IMAGE_RESOURCE
|
||||||
#define LOAD_LIBRARY_AS_IMAGE_RESOURCE 0x20
|
#define LOAD_LIBRARY_AS_IMAGE_RESOURCE 0x20
|
||||||
#endif
|
#endif
|
||||||
|
31
readme.txt
31
readme.txt
@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
ANSICON
|
ANSICON
|
||||||
|
|
||||||
Copyright 2005-2018 Jason Hood
|
Copyright 2005-2019 Jason Hood
|
||||||
|
|
||||||
Version 1.85. Freeware
|
Version 1.89. Freeware
|
||||||
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
@ -102,6 +102,7 @@ Usage
|
|||||||
4 Log console output (add to any of the above)
|
4 Log console output (add to any of the above)
|
||||||
8 Append to the existing file (add to any of the above)
|
8 Append to the existing file (add to any of the above)
|
||||||
16 Log all imported modules (add to any of the above)
|
16 Log all imported modules (add to any of the above)
|
||||||
|
32 Log CreateFile (add to any of the above)
|
||||||
|
|
||||||
The log option will not work with '-p'; set the environment variable
|
The log option will not work with '-p'; set the environment variable
|
||||||
ANSICON_LOG (to the number) instead. The variable is only read once when a
|
ANSICON_LOG (to the number) instead. The variable is only read once when a
|
||||||
@ -339,9 +340,27 @@ Version History
|
|||||||
|
|
||||||
Legend: + added, - bug-fixed, * changed.
|
Legend: + added, - bug-fixed, * changed.
|
||||||
|
|
||||||
1.85 - 22 August, 2018:
|
1.89 - 29 April, 2019:
|
||||||
|
- fix occasional freeze on startup (bug converting 8-digit window handle).
|
||||||
|
|
||||||
|
1.88 - 1 March, 2019:
|
||||||
|
- fix ANSICON environment variable when there is no console.
|
||||||
|
|
||||||
|
1.87 - 3 February, 2019:
|
||||||
|
- fix crash when some programs start (bug during hooking);
|
||||||
|
- properly hook SetCurrentConsoleFontEx.
|
||||||
|
|
||||||
|
1.86 - 4 November, 2018:
|
||||||
|
- check the DLL exists before importing it (allows renaming to update);
|
||||||
|
- unhook on terminate, as well (fixes issues with Vista and MinGW).
|
||||||
|
|
||||||
|
1.85 - 23 August, 2018:
|
||||||
- fix wrap issues with a buffer bigger than the window;
|
- fix wrap issues with a buffer bigger than the window;
|
||||||
- fix -e et al when redirecting to NUL.
|
- fix -e et al when redirecting to NUL;
|
||||||
|
- prevent -p from injecting when already injected;
|
||||||
|
- fix running directly via ansicon (hook even if it's GUI or excluded);
|
||||||
|
- preserve last error;
|
||||||
|
+ add log level 32 to monitor CreateFile.
|
||||||
|
|
||||||
1.84 - 11 May, 2018:
|
1.84 - 11 May, 2018:
|
||||||
- close the flush handles on detach;
|
- close the flush handles on detach;
|
||||||
@ -631,5 +650,5 @@ Distribution
|
|||||||
in LICENSE.txt.
|
in LICENSE.txt.
|
||||||
|
|
||||||
|
|
||||||
============================
|
===========================
|
||||||
Jason Hood, 22 August, 2018.
|
Jason Hood, 29 April, 2019.
|
||||||
|
32
util.c
32
util.c
@ -593,7 +593,7 @@ int ac_sprintf( char* buf, const char* fmt, ... )
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*buf++ = (unsigned)(num / power) % 10 + '0';
|
*buf++ = num / power % 10 + '0';
|
||||||
power /= 10;
|
power /= 10;
|
||||||
} while (power);
|
} while (power);
|
||||||
}
|
}
|
||||||
@ -609,7 +609,7 @@ int ac_sprintf( char* buf, const char* fmt, ... )
|
|||||||
// * BUF is big enough;
|
// * BUF is big enough;
|
||||||
// * FMT is valid;
|
// * FMT is valid;
|
||||||
// * width is only for X, is only 2 and the number is not bigger than that;
|
// * width is only for X, is only 2 and the number is not bigger than that;
|
||||||
// * X, d & u are 32-bit unsigned decimal, a digit less than maximum;
|
// * X, d & u are 32-bit unsigned decimal;
|
||||||
// * c is not output if NUL;
|
// * c is not output if NUL;
|
||||||
// * no other type is used;
|
// * no other type is used;
|
||||||
// * return value is not used.
|
// * return value is not used.
|
||||||
@ -638,9 +638,15 @@ int ac_wprintf( wchar_t* buf, const char* fmt, ... )
|
|||||||
}
|
}
|
||||||
else if (t == 'X')
|
else if (t == 'X')
|
||||||
{
|
{
|
||||||
int bits = 4;
|
int bits;
|
||||||
while (num >> bits)
|
if (num & 0xF0000000)
|
||||||
bits += 4;
|
bits = 32;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bits = 4;
|
||||||
|
while (num >> bits)
|
||||||
|
bits += 4;
|
||||||
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
bits -= 4;
|
bits -= 4;
|
||||||
@ -654,14 +660,20 @@ int ac_wprintf( wchar_t* buf, const char* fmt, ... )
|
|||||||
}
|
}
|
||||||
else // (t == 'd' || t == 'u')
|
else // (t == 'd' || t == 'u')
|
||||||
{
|
{
|
||||||
int power = 10;
|
unsigned power;
|
||||||
while (num / power)
|
if (num >= 1000000000)
|
||||||
power *= 10;
|
power = 1000000000;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
power = 1;
|
||||||
|
while (num / (power * 10))
|
||||||
|
power *= 10;
|
||||||
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
*buf++ = num / power % 10 + '0';
|
||||||
power /= 10;
|
power /= 10;
|
||||||
*buf++ = (int)(num / power) % 10 + '0';
|
} while (power);
|
||||||
} while (power != 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
version.h
10
version.h
@ -2,11 +2,11 @@
|
|||||||
version.h - Version defines.
|
version.h - Version defines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PVERS L"1.85" // wide string
|
#define PVERS L"1.89" // wide string
|
||||||
#define PVERSA "1.85" // ANSI string (windres 2.16.91 didn't like L)
|
#define PVERSA "1.89" // ANSI string (windres 2.16.91 didn't like L)
|
||||||
#define PVERE L"185" // wide environment string
|
#define PVERE L"189" // wide environment string
|
||||||
#define PVEREA "185" // ANSI environment string
|
#define PVEREA "189" // ANSI environment string
|
||||||
#define PVERB 1,8,5,0 // binary (resource)
|
#define PVERB 1,8,9,0 // binary (resource)
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
# define BITS L"64"
|
# define BITS L"64"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user