Remove ANSI-LLW.exe for good; tweak makefiles & doc; release v1.62.

This commit is contained in:
Jason Hood 2013-07-19 00:14:54 +10:00
parent d77831ce12
commit 1fc43d46c3
14 changed files with 561 additions and 608 deletions

View File

@ -1,23 +0,0 @@
; ANSI-LLW.asm - Output the 32-bit address of LoadLibraryW.
;
; Jason Hood, 1 February, 2013.
;
; A FASM (flatassembler.net) version of the C code, which virus scanners didn't
; like for some reason.
format PE Console 4.0
include 'win32a.inc'
mov eax, [LoadLibraryW]
ret
data import
library kernel32,'KERNEL32.DLL'
import kernel32,\
LoadLibraryW,'LoadLibraryW'
end data

View File

@ -1,22 +0,0 @@
/*
ANSI-LLW.c - Output the 32-bit address of LoadLibraryW.
Jason Hood, 13 November, 2010 (LLA version 5 September, 2010).
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
#include <windows.h>
int main( void )
{
return (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ),
"LoadLibraryW" );
}

3
ANSI.c
View File

@ -98,6 +98,9 @@
v1.61, 14 February, 2013:
go back to using ANSI-LLW.exe for 64->32 injection.
v1.62, 17 & 18 July, 2013:
another method to obtain LLW for 64->32 injection.
*/
#include "ansicon.h"

View File

@ -1,240 +0,0 @@
MinGW-w64 runtime licensing
***************************
This program or library was built using MinGW-w64 and statically
linked against the MinGW-w64 runtime. Some parts of the runtime
are under licenses which require that the copyright and license
notices are included when distributing the code in binary form.
These notices are listed below.
========================
Overall copyright notice
========================
Copyright (c) 2009, 2010 by the mingw-w64 project
This license has been certified as open source. It has also been designated
as GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying
copyright notice, this list of conditions, and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission
from the copyright holders.
4. The right to distribute this software or to use it for any purpose does
not give you the right to use Servicemarks (sm) or Trademarks (tm) of
the copyright holders. Use of them is covered by separate agreement
with the copyright holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of
any change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
========================================
getopt, getopt_long, and getop_long_only
========================================
Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Sponsored in part by the Defense Advanced Research Projects
Agency (DARPA) and Air Force Research Laboratory, Air Force
Materiel Command, USAF, under agreement number F39502-99-1-0512.
* * * * * * *
Copyright (c) 2000 The NetBSD Foundation, Inc.
All rights reserved.
This code is derived from software contributed to The NetBSD Foundation
by Dieter Baron and Thomas Klausner.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
===============================================================
gdtoa: Converting between IEEE floating point numbers and ASCII
===============================================================
The author of this software is David M. Gay.
Copyright (C) 1997, 1998, 1999, 2000, 2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
* * * * * * *
The author of this software is David M. Gay.
Copyright (C) 2005 by David M. Gay
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that the copyright notice and this permission notice and warranty
disclaimer appear in supporting documentation, and that the name of
the author or any of his current or former employers not be used in
advertising or publicity pertaining to distribution of the software
without specific, written prior permission.
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
* * * * * * *
The author of this software is David M. Gay.
Copyright (C) 2004 by David M. Gay.
All Rights Reserved
Based on material in the rest of /netlib/fp/gdota.tar.gz,
which is copyright (C) 1998, 2000 by Lucent Technologies.
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
=========================
Parts of the math library
=========================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunSoft, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
* * * * * * *
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
* * * * * * *
FIXME: Cephes math lib
Copyright (C) 1984-1998 Stephen L. Moshier
It sounds vague, but as to be found at
<http://lists.debian.org/debian-legal/2004/12/msg00295.html>, it gives an
impression that the author could be willing to give an explicit
permission to distribute those files e.g. under a BSD style license. So
probably there is no problem here, although it could be good to get a
permission from the author and then add a license into the Cephes files
in MinGW runtime. At least on follow-up it is marked that debian sees the
version a-like BSD one. As MinGW.org (where those cephes parts are coming
from) distributes them now over 6 years, it should be fine.
===================================
Headers and IDLs imported from Wine
===================================
Some header and IDL files were imported from the Wine project. These files
are prominent maked in source. Their copyright belongs to contributors and
they are distributed under LGPL license.
Disclaimer
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

12
ansi.rc
View File

@ -7,13 +7,7 @@
#include <winver.h>
#include "version.h"
#ifdef _WIN64
# define BITS "64"
#else
# define BITS "32"
#endif
1 VERSIONINFO
VS_VERSION_INFO VERSIONINFO
FILEVERSION PVERB
PRODUCTVERSION PVERB
FILEOS VOS_NT
@ -23,13 +17,13 @@ FILETYPE VFT_DLL
{
BLOCK "040904B0"
{
VALUE "Comments", "http://ansicon.adoxa.cjb.net/"
VALUE "Comments", "http://ansicon.adoxa.vze.com/"
VALUE "CompanyName", "Jason Hood"
VALUE "FileDescription", "ANSI Console"
VALUE "FileVersion", PVERSA
VALUE "InternalName", "ANSI" BITS
VALUE "LegalCopyright", "Freeware"
VALUE "OriginalFilename", "ANSI" BITS ".dll"
VALUE "OriginalFilename", ANSIDLL
VALUE "ProductName", "ANSICON"
VALUE "ProductVersion", PVERSA
}

View File

@ -69,9 +69,13 @@
set the code page to convert strings correctly;
expand wildcards for -t;
write the date if appending to the log.
v1.62, 18 July, 2013:
write the bits to the log;
test if creating the registry key fails (HKLM requires admin privileges).
*/
#define PDATE L"14 February, 2013"
#define PDATE L"18 July, 2013"
#include "ansicon.h"
#include "version.h"
@ -85,13 +89,6 @@ int _CRT_glob = 0;
#endif
#ifdef _WIN64
# define BITS L"64"
#else
# define BITS L"32"
#endif
#define CMDKEY L"Software\\Microsoft\\Command Processor"
#define AUTORUN L"AutoRun"
@ -113,6 +110,7 @@ BOOL GetParentProcessInfo( LPPROCESS_INFORMATION ppi, LPTSTR );
// The DLL shares this variable, so injection requires it here.
#ifdef _WIN64
DWORD LLW32;
extern LPVOID base;
#endif
@ -239,7 +237,7 @@ int main( void )
if (installed)
{
fputws( L"\33[m", stdout );
FreeLibrary( GetModuleHandle( L"ANSI" BITS L".dll" ) );
FreeLibrary( GetModuleHandle( ANSIDLL ) );
}
shell = run = TRUE;
@ -277,6 +275,34 @@ int main( void )
pi.hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
pi.hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, pi.dwThreadId );
SuspendThread( pi.hThread );
#ifdef _WIN64
// Find the base address of kernel32.dll if the 64-bit version is
// injecting into a 32-bit parent.
if (IsWow64Process( pi.hProcess, &gui ) && gui)
{
HANDLE hSnap;
MODULEENTRY32 me;
BOOL fOk;
hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE |
TH32CS_SNAPMODULE32,
pi.dwProcessId );
if (hSnap != INVALID_HANDLE_VALUE)
{
me.dwSize = sizeof(MODULEENTRY32);
for (fOk = Module32First( hSnap, &me ); fOk;
fOk = Module32Next( hSnap, &me ))
{
if (_wcsicmp( me.szModule, L"kernel32.dll" ) == 0)
{
base = me.modBaseAddr;
break;
}
}
CloseHandle( hSnap );
}
}
#endif
if (!Inject( &pi, &gui, arg ))
rc = 1;
ResumeThread( pi.hThread );
@ -366,10 +392,10 @@ arg_out:
}
else if (*arg)
{
ansi = LoadLibrary( L"ANSI" BITS L".dll" );
ansi = LoadLibrary( ANSIDLL );
if (ansi == NULL)
{
print_error( L"ANSI" BITS L".dll" );
print_error( ANSIDLL );
rc = 1;
}
@ -511,10 +537,16 @@ void process_autorun( TCHAR cmd )
logstr, prog_path ) + 1);
inst = (towlower( cmd ) == 'i');
RegCreateKeyEx( (iswlower( cmd )) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
CMDKEY, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&cmdkey, &exist );
if (RegCreateKeyEx( (iswlower(cmd)) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
CMDKEY, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&cmdkey, &exist ) != ERROR_SUCCESS)
{
fputws( L"ANSICON: could not update AutoRun", stderr );
if (iswupper( cmd ))
fwprintf( stderr, L" (perhaps use -%c, or run as admin)", towlower(cmd) );
fputws( L".\n", stderr );
}
exist = 0;
RegQueryValueEx( cmdkey, AUTORUN, NULL, NULL, NULL, &exist );
if (exist == 0)
@ -766,7 +798,7 @@ void help( void )
_putws(
L"ANSICON by Jason Hood <jadoxa@yahoo.com.au>.\n"
L"Version " PVERS L" (" PDATE L"). Freeware.\n"
L"http://ansicon.adoxa.cjb.net/\n"
L"http://ansicon.adoxa.vze.com/\n"
L"\n"
#ifdef _WIN64
L"Process ANSI escape sequences in Windows console programs.\n"

View File

@ -7,7 +7,7 @@
#include <winver.h>
#include "version.h"
1 VERSIONINFO
VS_VERSION_INFO VERSIONINFO
FILEVERSION PVERB
PRODUCTVERSION PVERB
FILEOS VOS_NT
@ -17,7 +17,7 @@ FILETYPE VFT_APP
{
BLOCK "040904B0"
{
VALUE "Comments", "http://ansicon.adoxa.cjb.net/"
VALUE "Comments", "http://ansicon.adoxa.vze.com/"
VALUE "CompanyName", "Jason Hood"
VALUE "FileDescription", "ANSI Console"
VALUE "FileVersion", PVERSA
@ -34,3 +34,21 @@ FILETYPE VFT_APP
VALUE "Translation", 0x0409, 0x04B0
}
}
// Add a manifest for the 32-bit version, to prevent registry redirection when
// trying to use HKLM.
#ifndef _WIN64
1 24
{
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>\
<assembly xmlns=""urn:schemas-microsoft-com:asm.v1"" manifestVersion=""1.0"">\
<trustInfo xmlns=""urn:schemas-microsoft-com:asm.v3"">\
<security>\
<requestedPrivileges>\
<requestedExecutionLevel level=""asInvoker"" uiAccess=""false"" />\
</requestedPrivileges>\
</security>\
</trustInfo>\
</assembly>"
}
#endif

View File

@ -32,17 +32,84 @@ TWow64SetThreadContext Wow64SetThreadContext;
#define GetThreadContext Wow64GetThreadContext
#define SetThreadContext Wow64SetThreadContext
extern
#endif
#define MakeVA( cast, offset ) (cast)((DWORD_PTR)base + (DWORD)(offset))
extern DWORD LLW32;
LPVOID base;
int export_cmp( const void* a, const void* b )
{
return strcmp( (LPCSTR)a, MakeVA( LPCSTR, *(const PDWORD)b ) );
}
/*
Get the relative address of the 32-bit LoadLibraryW function from 64-bit code.
This was originally done via executing a helper program (ANSI-LLW.exe), but I
never liked doing that, so now I do it the "hard" way - load the 32-bit
kernel32.dll directly and search the exports.
*/
BOOL get_LLW32( void )
{
HMODULE kernel32;
TCHAR buf[MAX_PATH];
UINT len;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS32 pNTHeader;
PIMAGE_EXPORT_DIRECTORY pExportDir;
PDWORD fun_table, name_table;
PWORD ord_table;
PDWORD pLLW;
len = GetSystemWow64Directory( buf, MAX_PATH );
wcscpy( buf + len, L"\\kernel32.dll" );
// MinGW-w64 has a typo, calling it LINRARY.
kernel32 = LoadLibraryEx( buf, NULL, 0x20/*LOAD_LIBRARY_AS_IMAGE_RESOURCE*/ );
if (kernel32 == NULL)
{
DEBUGSTR( 1, L"Unable to load 32-bit kernel32.dll!" );
return FALSE;
}
// The handle uses low bits as flags, so strip 'em off.
base = (LPVOID)((DWORD_PTR)kernel32 & ~0xFFFF);
pDosHeader = (PIMAGE_DOS_HEADER)base;
pNTHeader = MakeVA( PIMAGE_NT_HEADERS32, pDosHeader->e_lfanew );
pExportDir = MakeVA( PIMAGE_EXPORT_DIRECTORY,
pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].
VirtualAddress );
fun_table = MakeVA( PDWORD, pExportDir->AddressOfFunctions );
name_table = MakeVA( PDWORD, pExportDir->AddressOfNames );
ord_table = MakeVA( PWORD, pExportDir->AddressOfNameOrdinals );
pLLW = bsearch( "LoadLibraryW", name_table, pExportDir->NumberOfNames,
sizeof(DWORD), export_cmp );
if (pLLW == NULL)
{
DEBUGSTR( 1, L"Could not find LoadLibraryW!" );
FreeLibrary( kernel32 );
return FALSE;
}
LLW32 = fun_table[ord_table[pLLW - name_table]];
FreeLibrary( kernel32 );
return TRUE;
}
#else
DWORD LLW32;
#endif
void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
{
CONTEXT context;
DWORD ep;
DWORD len;
LPVOID mem;
DWORD mem32;
DWORD pr;
#define CODESIZE 20
BYTE code[CODESIZE+TSIZE(MAX_PATH)];
union
@ -50,6 +117,9 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
PBYTE pB;
PDWORD pL;
} ip;
#ifdef _WIN64
BOOL entry = FALSE;
#endif
#ifdef IMPORT_WOW64
if (Wow64GetThreadContext == 0)
@ -71,46 +141,105 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
if (len > TSIZE(MAX_PATH))
return;
if (LLW32 == 0)
{
#ifdef _WIN64
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
// ...ANSI32.dll\0
CopyMemory( code, dll, len - TSIZE(7) );
// ...ANSI-LLW.exe\0
CopyMemory( code + len - TSIZE(7), L"-LLW.exe", TSIZE(9) );
if (!CreateProcess( (LPCTSTR)code, NULL, NULL, NULL, FALSE, 0, NULL, NULL,
&si, &pi ))
{
DEBUGSTR( 1, L"Failed to execute \"%s\".", (LPCTSTR)code );
return;
}
WaitForSingleObject( pi.hProcess, INFINITE );
GetExitCodeProcess( pi.hProcess, &LLW32 );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
#else
LLW32 = (DWORD)GetProcAddress( GetModuleHandle( L"kernel32.dll" ),
"LoadLibraryW" );
#endif
}
CopyMemory( code + CODESIZE, dll, len );
len += CODESIZE;
context.ContextFlags = CONTEXT_CONTROL;
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
GetThreadContext( ppi->hThread, &context );
mem = VirtualAllocEx( ppi->hProcess, NULL, len, MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
PAGE_READWRITE );
mem32 = (DWORD)(DWORD_PTR)mem;
ip.pB = code;
*ip.pB++ = 0x68; // push eip
*ip.pL++ = context.Eip;
ep = context.Eip;
if (LLW32 == 0)
{
#ifndef _WIN64
LLW32 = (DWORD)GetProcAddress( GetModuleHandle( L"kernel32.dll" ),
"LoadLibraryW" );
#else
struct unicode_string
{
USHORT Length;
USHORT MaximumLength;
DWORD Buffer;
};
struct ldr_module // incomplete definition
{
DWORD next, prev;
DWORD baseAddress;
DWORD entryPoint;
DWORD sizeOfImage;
struct unicode_string fullDllName;
struct unicode_string baseDllName;
} ldr;
WCHAR basename[MAX_PATH];
if (!get_LLW32())
return;
// Determine the base address of the 32-bit kernel32.dll. If injecting
// into the parent process, base has already been determined. Otherwise,
// use the PEB to walk the loaded modules.
if (base == 0)
{
// When a process is created suspended, EAX has the entry point and EBX
// points to the PEB.
if (!ReadProcessMemory( ppi->hProcess, UIntToPtr( context.Ebx + 0x0C ),
ip.pL, 4, NULL ))
{
DEBUGSTR( 1, L"Failed to read Ldr from PEB." );
return;
}
// In case we're a bit slow (which seems to be unlikely), set up an
// infinite loop as the entry point.
WriteProcessMemory( ppi->hProcess, mem, "\xEB\xFE", 2, NULL );
FlushInstructionCache( ppi->hProcess, mem, 2 );
ep = context.Eax;
context.Eax = mem32;
SetThreadContext( ppi->hThread, &context );
VirtualProtectEx( ppi->hProcess, mem, len, PAGE_EXECUTE, &pr );
// Now resume the thread, as the PEB hasn't even been created yet.
ResumeThread( ppi->hThread );
while (*ip.pL == 0)
{
Sleep( 0 );
ReadProcessMemory( ppi->hProcess, UIntToPtr( context.Ebx + 0x0C ),
ip.pL, 4, NULL );
}
// Read PEB_LDR_DATA.InInitializationOrderModuleList.Flink.
ReadProcessMemory( ppi->hProcess, UIntToPtr( *ip.pL + 0x1c ),
&ip.pL[1], 4, NULL );
// Sometimes we're so quick ntdll.dll is the only one present, so keep
// looping until kernel32.dll shows up.
for (;;)
{
ldr.next = ip.pL[1];
do
{
ReadProcessMemory( ppi->hProcess, UIntToPtr( ldr.next ),
&ldr, sizeof(ldr), NULL );
ReadProcessMemory( ppi->hProcess, UIntToPtr( ldr.baseDllName.Buffer ),
basename, ldr.baseDllName.MaximumLength, NULL );
if (_wcsicmp( basename, L"kernel32.dll" ) == 0)
{
LLW32 += ldr.baseAddress;
goto gotit;
}
} while (ldr.next != *ip.pL + 0x1c);
}
gotit:
SuspendThread( ppi->hThread );
VirtualProtectEx( ppi->hProcess, mem, len, pr, &pr );
entry = TRUE;
}
else
LLW32 += PtrToUint( base );
#endif
}
*ip.pB++ = 0x68; // push ep
*ip.pL++ = ep;
*ip.pB++ = 0x9c; // pushf
*ip.pB++ = 0x60; // pusha
*ip.pB++ = 0x68; // push L"path\to\ANSI32.dll"
@ -123,6 +252,11 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
WriteProcessMemory( ppi->hProcess, mem, code, len, NULL );
FlushInstructionCache( ppi->hProcess, mem, len );
VirtualProtectEx( ppi->hProcess, mem, len, PAGE_EXECUTE, &pr );
#ifdef _WIN64
if (entry)
return;
#endif
context.Eip = mem32;
SetThreadContext( ppi->hThread, &context );
}

View File

@ -1,85 +0,0 @@
# Makefile for ANSICON.
# Jason Hood, 11 March, 2006. Updated 20 June, 2009.
# I've used TDM64 (gcc 4.6.1), building the 32-bit version in the x86 directory
# and the 64-bit version in the x64 directory. MinGW32 (gcc 3.4.5) will also
# build the 32-bit version.
# 19 November, 2010:
# explicitly use 64-bit flags, in case the compiler isn't.
#
# 13 December, 2011:
# use CMD for file operations, not programs from fileutils.
#
# 23 November, 2012:
# set the base address of the DLLs to AC0000[00] (AnsiCon).
CC = gcc
CFLAGS = -O2 -Wall
X86OBJS = x86/proctype.o x86/injdll32.o x86/util.o
X64OBJS = x64/proctype.o x64/injdll64.o x64/injdll32.o x64/util.o
x86/%.o: %.c ansicon.h
$(CC) -m32 -c $(CFLAGS) $< -o $@
x86/%v.o: %.rc version.h
windres -U _WIN64 -F pe-i386 $< $@
x64/%.o: %.c ansicon.h
$(CC) -m64 -c $(CFLAGS) $< -o $@
x64/%v.o: %.rc version.h
windres -F pe-x86-64 $< $@
all: ansicon32 ansicon64
ansicon32: x86 x86/ansicon.exe x86/ANSI32.dll
ansicon64: x64 x64/ansicon.exe x64/ANSI64.dll x64/ANSI32.dll x64/ANSI-LLW.exe
x86:
cmd /c "mkdir x86"
x86/ansicon.exe: x86/ansicon.o $(X86OBJS) x86/ansiconv.o
$(CC) -m32 $+ -s -o $@
x86/ANSI32.dll: x86/ANSI.o $(X86OBJS) x86/ansiv.o
$(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC0000
x64:
cmd /c "mkdir x64"
x64/ansicon.exe: x64/ansicon.o $(X64OBJS) x64/ansiconv.o
$(CC) -m64 $+ -s -o $@
x64/ANSI64.dll: x64/ANSI.o $(X64OBJS) x64/ansiv.o
$(CC) -m64 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC000000
x64/ANSI32.dll: x64/ANSI32.o x64/proctype32.o x86/injdll32.o x86/util.o x86/ansiv.o
$(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC0000
x64/ANSI-LLW.exe: ANSI-LLW.c
$(CC) -m32 $(CFLAGS) $< -s -o $@
x86/ansicon.o: version.h
x86/ANSI.o: version.h
x64/ansicon.o: version.h
x64/ANSI.o: version.h
x86/util.o: version.h
x64/util.o: version.h
x86/ansiconv.o: ansicon.rc
x86/ansiv.o: ansi.rc
x64/ansiconv.o: ansicon.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
# anything at all.
clean:
-cmd /c "del x86\*.o 2>nul"
-cmd /c "del x64\*.o 2>nul"

112
makefile.gcc Normal file
View File

@ -0,0 +1,112 @@
# MinGW/MinGW-w64 makefile for ANSICON.
# Jason Hood, 11 March, 2006. Updated 20 June, 2009.
#
# 19 November, 2010:
# explicitly use 64-bit flags, in case the compiler isn't.
#
# 13 December, 2011:
# use CMD for file operations, not programs from fileutils.
#
# 23 November, 2012:
# set the base address of the DLLs to AC0000[00] (AnsiCon).
#
# 17 & 18 July, 2013:
# work with 32-bit only, 64-bit only or multilib compilers;
# hide the commands (use V=1 to show them).
#
# Tested with:
# * MinGW/gcc 4.7.2;
# * tdm-gcc-4.7.1-2;
# * tdm64-gcc-4.7.1-3;
# * MinGW-builds x64-4.8.1-release-posix-seh-rev1.
CC = gcc
CFLAGS = -O2 -Wall
#ARCH = 32
#ARCH = 64
#ARCH = multi
ifndef ARCH
# Use the machine to distinguish between MinGW and MinGW-w64.
ifeq (,$(findstring 64,$(shell gcc -dumpmachine)))
ARCH = 32
else
# It's 64-bit, if it's multi the lib name will be different.
ifeq ($(shell gcc -m32 -print-libgcc-file-name),$(shell gcc -m64 -print-libgcc-file-name))
ARCH = 64
else
ARCH = multi
endif
endif
endif
X86OBJS = x86/proctype.o x86/injdll32.o x86/util.o
X64OBJS = x64/proctype.o x64/injdll64.o x64/injdll32.o x64/util.o
V ?= 0
ifeq ($(V),0)
CCmsg = @echo $<;
RCmsg = $(CCmsg)
LDmsg = @echo $@;
endif
x86/%.o: %.c ansicon.h
$(CCmsg)$(CC) -m32 -c $(CFLAGS) $< -o $@
x86/%v.o: %.rc version.h
$(RCmsg)windres -U _WIN64 -F pe-i386 $< $@
x64/%.o: %.c ansicon.h
$(CCmsg) $(CC) -m64 -c $(CFLAGS) $< -o $@
x64/%v.o: %.rc version.h
$(RCmsg)windres -F pe-x86-64 $< $@
x64/%32.o: %.c
$(CCmsg)$(CC) -m32 -DW32ON64 $(CFLAGS) $< -c -o $@
ifeq ($(ARCH),multi)
all: ansicon32 ansicon64
else
all: ansicon$(ARCH)
endif
ansicon32: x86 x86/ansicon.exe x86/ANSI32.dll x64 x64/ANSI32.dll
ansicon64: x64 x64/ansicon.exe x64/ANSI64.dll
x86:
cmd /c "mkdir x86"
x86/ansicon.exe: x86/ansicon.o $(X86OBJS) x86/ansiconv.o
$(LDmsg)$(CC) -m32 $+ -s -o $@
x86/ANSI32.dll: x86/ANSI.o $(X86OBJS) x86/ansiv.o
$(LDmsg)$(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC0000
x64:
cmd /c "mkdir x64"
x64/ansicon.exe: x64/ansicon.o $(X64OBJS) x64/ansiconv.o
$(LDmsg)$(CC) -m64 $+ -s -o $@
x64/ANSI64.dll: x64/ANSI.o $(X64OBJS) x64/ansiv.o
$(LDmsg)$(CC) -m64 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC000000
x64/ANSI32.dll: x64/ANSI32.o x64/proctype32.o x86/injdll32.o x86/util.o x86/ansiv.o
$(LDmsg)$(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC0000
x86/ansicon.o: version.h
x86/ANSI.o: version.h
x86/util.o: version.h
x64/ansicon.o: version.h
x64/ANSI.o: version.h
x64/util.o: version.h
# Need two commands, because if the directory doesn't exist, it won't delete
# anything at all.
clean:
-cmd /c "del x86\*.o 2>nul"
-cmd /c "del x64\*.o 2>nul"

View File

@ -1,17 +1,23 @@
# VC makefile for ANSICON.
# Jason Hood, 15 November, 2010.
# I've used Visual C++ 2008 Express for the 32-bit version and the 2003 R2
# Platform SDK for the 64-bit version. Since these are entirely separate
# environments, define BITS to decide which should be built. Note that the
# 64-bit version still requires the 32-bit ANSI32.dll, so both environments
# are required and you should build the 32-bit version before the 64-bit.
#
# Tested with:
# * Visual Studio 6.0 (VC6);
# * Visual C++ 2003 Toolkit (VC7);
# * Platform SDK for Windows Server 2003 R2 (VC8 64-bit);
# * Visual Studio 2008 Express SP1 (VC9);
# * Visual Studio 2010 Professional (VC10).
#
# Note that the 64-bit version still requires a 32-bit compiler.
#
# 22 & 23 November, 2012:
# determine if the PSDK is used automatically;
# use AC0000[00] (AnsiCon) as the base address;
# twiddle stuff around to support VC6 (with 2003 PSDK) for the 32-bit version;
# determine BITS automatically.
#
# 18 July, 2013:
# hide the commands (use V=1 to show them).
#BITS = 32
#BITS = 64
@ -29,6 +35,7 @@ DIR = x86
!ELSE
!IF $(BITS) == 64
DIR = x64
RFLAGS = /D_WIN64
!ELSE
!ERROR BITS should be defined to 32 or 64.
!ENDIF
@ -36,9 +43,10 @@ DIR = x64
# This is required for the 2003 Platform SDK, but not for Visual Studio 2010.
!IF "$(_NMAKE_VER)" == "7.00.8882"
!IF $(BITS) == 64
LIBS64 = bufferoverflowu.lib
# The 2003 Toolkit doesn't have MSVCRT.LIB (but VC98 does).
!IF $(BITS) == 32 && !DEFINED(SHARE) && !DEFINED(MSVCDIR)
# The 2003 Toolkit doesn't have MSVCRT.LIB, but VC98 does.
!ELSEIF !DEFINED(SHARE) && !DEFINED(MSVCDIR)
SHARE =
!ENDIF
!ENDIF
@ -48,22 +56,34 @@ SHARE =
SHARE = /MD
!ENDIF
CC = cl
CFLAGS = /nologo /W3 /Ox /GF $(SHARE) /D_CRT_SECURE_NO_WARNINGS
LIBS = advapi32.lib user32.lib
# Manifest tool to embed the manifest required by 2008.
MT = mt.exe
CFLAGS = /nologo /W3 /O2 $(SHARE) /D_CRT_SECURE_NO_WARNINGS
LIBS = advapi32.lib user32.lib $(LIBS64)
X86OBJS = x86\proctype.obj x86\injdll32.obj x86\util.obj
X64OBJS = x64\proctype.obj x64\injdll64.obj x64\injdll32.obj x64\util.obj
!IF !DEFINED(V)
V = 0
!ENDIF
!IF $(V) == 0
CCmsg = @
RCmsg = @echo $<&
LDmsg = @echo $@&
MTmsg = @echo Embedding manifest&
!ENDIF
{}.c{$(DIR)}.obj:
$(CC) /c $(CFLAGS) /Fo$@ $<
$(CCmsg)$(CC) /c $(CFLAGS) /Fo$@ $<
{}.rc{$(DIR)}.res:
rc /fo$@ $<
$(RCmsg)$(RC) $(RFLAGS) /fo$@ $<
all: ansicon$(BITS)
ansicon32: x86 x86\ansicon.exe x86\ANSI32.dll x64 x64\ANSI32.dll x64\ANSI-LLW.exe
ansicon32: x86 x86\ansicon.exe x86\ANSI32.dll x64 x64\ANSI32.dll
ansicon64: x64 x64\ansicon.exe x64\ANSI64.dll
@ -71,25 +91,34 @@ x86:
mkdir x86
x86\ansicon.exe: x86\ansicon.obj $(X86OBJS) x86\ansicon.res
$(CC) /nologo $(SHARE) /Fe$@ $** $(LIBS) /link /filealign:512
$(LDmsg)$(CC) /nologo $(SHARE) /Fe$@ $** $(LIBS) /link /filealign:512
!IF "$(_NMAKE_VER)" == "9.00.30729.01"
$(MTmsg)$(MT) /nologo -manifest $@.manifest -outputresource:$@;1
@del $@.manifest
!ENDIF
x86\ANSI32.dll: x86\ANSI.obj $(X86OBJS) x86\ansi.res
$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link /base:0xAC0000 /section:.shared,s /filealign:512
$(LDmsg)$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link /base:0xAC0000 /section:.shared,s /filealign:512
!IF "$(_NMAKE_VER)" == "9.00.30729.01"
$(MTmsg)$(MT) /nologo -manifest $@.manifest -outputresource:$@;2
@del $@.manifest
!ENDIF
x64:
mkdir x64
x64\ansicon.exe: x64\ansicon.obj $(X64OBJS) x64\ansicon.res
$(CC) /nologo $(SHARE) /Fe$@ $** $(LIBS) $(LIBS64)
$(LDmsg)$(CC) /nologo $(SHARE) /Fe$@ $** $(LIBS)
x64\ANSI64.dll: x64\ANSI.obj $(X64OBJS) x64\ansi.res
$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) $(LIBS64) /link /base:0xAC000000 /section:.shared,s
$(LDmsg)$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link /base:0xAC000000 /section:.shared,s
x64\ANSI32.dll: x64\ANSI32.obj x64\proctype32.obj x86\injdll32.obj x86\util.obj x86\ansi.res
$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link /base:0xAC0000 /section:.shared,s /filealign:512
x64\ANSI-LLW.exe: ANSI-LLW.c
$(CC) $(CFLAGS) /Fe$@ /Fo$*.obj $? $(LIBS64)
$(LDmsg)$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link /base:0xAC0000 /section:.shared,s /filealign:512
!IF "$(_NMAKE_VER)" == "9.00.30729.01"
$(MTmsg)$(MT) /nologo -manifest $@.manifest -outputresource:$@;2
@del $@.manifest
!ENDIF
ansicon.c: ansicon.h version.h
ansicon.rc: version.h
@ -101,9 +130,9 @@ injdll64.c: ansicon.h
proctype.c: ansicon.h
x64\ANSI32.obj: ANSI.c
$(CC) /DW32ON64 /c $(CFLAGS) /Fo$@ $?
$(CCmsg)$(CC) /DW32ON64 /c $(CFLAGS) /Fo$@ $?
x64\proctype32.obj: proctype.c
$(CC) /DW32ON64 /c $(CFLAGS) /Fo$@ $?
$(CCmsg)$(CC) /DW32ON64 /c $(CFLAGS) /Fo$@ $?
clean:
-del $(DIR)\*.obj $(DIR)\*.res $(DIR)\*.lib $(DIR)\*.exp

View File

@ -1,65 +1,62 @@
ANSICON
Copyright 2005-2012 Jason Hood
Copyright 2005-2013 Jason Hood
Version 1.61. Freeware
Version 1.62. Freeware
===========
Description
===========
Description
===========
ANSICON provides ANSI escape sequences for Windows console programs. It
provides much the same functionality as `ANSI.SYS' does for MS-DOS.
provides much the same functionality as 'ANSI.SYS' does for MS-DOS.
============
Requirements
============
Requirements
============
32-bit: Windows 2000 Professional and later (it won't work with NT or 9X).
64-bit: Vista and later (it won't work with XP64).
============
Installation
============
Installation
============
Add x86 (if your OS is 32-bit) or x64 (if 64-bit) to your PATH, or copy
the relevant files to a directory already on the PATH. Alternatively,
use option `-i' (or `-I') to install it permanently, by adding an entry
to CMD.EXE's AutoRun registry value (current user or local machine,
respectively). Uninstall simply involves closing any programs that are
currently using it, running with `-u' (and/or `-U') to remove the Auto-
Run entry/ies, then removing the directory from PATH or deleting the
files. No other changes are made.
Add "x86" (if your OS is 32-bit) or "x64" (if 64-bit) to your PATH, or copy
the relevant files to a directory already on the PATH. Alternatively, use
option '-i' (or '-I', if permitted) to install it permanently, by adding an
entry to CMD.EXE's AutoRun registry value (current user or local machine,
respectively).
---------
Upgrading
---------
Uninstall simply involves closing any programs that are currently using it;
running with '-u' (and/or '-U') to remove it from AutoRun; removing the
directory from PATH; and deleting the files. No other changes are made
(although you may have also created environment variables).
Upgrading
---------
Delete ANSI.dll, it has been replaced with ANSI32.dll.
Delete ANSI-LLA.exe, it has been replaced with ANSI-LLW.exe.
Delete ANSI-LLA.exe and ANSI-LLW.exe, they are no longer used.
Uninstall a pre-1.50 version and reinstall with this version.
=====
Usage
=====
Usage
=====
Options (case sensitive):
-l Log to %temp%\ansicon.log.
-l Log to "%TEMP%\ansicon.log".
-p Enable the parent process (i.e. the command shell used to
run ANSICON) to recognise escapes.
-p Enable the parent process (i.e. the command shell used to run
ANSICON) to recognise escapes.
-m Set the current (and default) attribute to grey on black
("monochrome"), or the attribute following the `m' (please
use `COLOR /?' for attribute values).
("monochrome"), or the attribute following the 'm' (please
use 'COLOR /?' for attribute values).
-e Echo the command line - a space or tab after the `e' is
-e Echo the command line - a space or tab after the 'e' is
ignored, the remainder is displayed verbatim.
-E As above, but no newline is added.
@ -70,22 +67,22 @@
-T Display "==> FILE NAME <==", a blank line (or an error
message), the file and another blank line.
Running ANSICON with no arguments will start a new instance of the com-
mand processor (the program defined by the `ComSpec' environment var-
iable, typically `CMD.EXE'), or display standard input if it is redir-
ected. Any argument will be treated as a program and its arguments.
Running ANSICON with no arguments will start a new instance of the command
processor (the program defined by the 'ComSpec' environment variable, typ-
ically 'CMD.EXE'), or display standard input if it is redirected. Any arg-
ument will be treated as a program and its arguments.
Eg: `ansicon -m30 -t file.ans' will display `file.ans' using black on
E.g.: 'ansicon -m30 -t file.ans' will display "file.ans" using black on
cyan as the default color.
The attribute may start with "-" to permanently reverse the foreground
and background colors (but not when using `-p'). Eg: `ansicon -m-f0 -t
The attribute may start with '-' to permanently reverse the foreground and
background colors (but not when using '-p'). E.g.: 'ansicon -m-f0 -t
file.log' will use reversed black on white as the default (i.e. white on
black, with foreground sequences changing the background).
If you experience trouble with certain programs, the log may help in
finding the cause; it can be found at "%TEMP%\ansicon.log". A number
should follow the `l':
If you experience trouble with certain programs, the log may help in find-
ing the cause; it can be found at "%TEMP%\ansicon.log". A number should
follow the 'l':
0 No logging
1 Log process start and end
@ -95,53 +92,55 @@
8 Append to the existing file (add to any of the above)
16 Log all imported modules (add to any of the above)
The log option will not work with `-p'; set the environment variable
ANSICON_LOG instead. The variable is only read once when a new process
is started; changing it won't affect running processes. If you identify
a module that causes problems, add it to the ANSICON_EXC environment
variable (see ANSICON_API below, but the extension is required).
The log option will not work with '-p'; set the environment variable
ANSICON_LOG instead. The variable is only read once when a new process is
started; changing it won't affect running processes. If you identify a
module that causes problems, add it to the ANSICON_EXC environment variable
(see ANSICON_API below, but the extension is required).
E.g.: 'ansicon -l5' will start a new command processor, logging every pro-
cess it starts along with their output.
Once installed, the ANSICON environment variable will be created. This
variable is of the form "WxH (wxh)", where W & H are the width and
height of the buffer and w & h are the width and height of the window.
The variable is updated whenever a program reads it directly (i.e. as
an individual request, not as part of the entire environment block).
For example, "set an" will not update it, but "echo %ansicon%" will.
Also created is ANSICON_VER, which contains the version without the
point (1.50 becomes "150"). This variable does not exist as part of the
environment block ("set an" will not show it).
variable is of the form "WxH (wxh)", where 'W' & 'H' are the width and
height of the buffer and 'w' & 'h' are the width and height of the window.
The variable is updated whenever a program reads it directly (i.e. as an
individual request, not as part of the entire environment block). For
example, 'set an' will not update it, but 'echo %ansicon%' will. Also
created is ANSICON_VER, which contains the version without the point (1.50
becomes "150"). This variable does not exist as part of the environment
block ('set an' will not show it).
If installed, GUI programs will not be hooked. Either start the program
directly with `ansicon', or add it to the ANSICON_GUI variable (see
directly with 'ansicon', or add it to the ANSICON_GUI variable (see
ANSICON_API below).
Using `ansicon' after install will always start with the default attrib-
utes, restoring the originals on exit; all other programs will use the
current attributes. The shift state is always reset for a new process.
Using 'ansicon' after install will always start with the default attrib-
utes, restoring the originals on exit; all other programs will use the cur-
rent attributes. The shift state is always reset for a new process.
The Windows API WriteFile and WriteConsoleA functions will set the num-
ber of characters written, not the number of bytes. When using a multi-
byte character set, this results in a smaller number (since multiple
bytes are used to represent a single character). Some programs recog-
nise this as a reduced write and will inadvertently repeat previous
characters. If you discover such a program, use the ANSICON_API envir-
onment variable to record it and override the API, returning the origin-
al byte count. Ruby is an example of such a program (at least, up till
1.9.2p0), so use "set ANSICON_API=ruby" to avoid the repitition. The
full syntax of the variable is:
The Windows API WriteFile and WriteConsoleA functions will set the number
of characters written, not the number of bytes. When using a multibyte
character set, this results in a smaller number (since multiple bytes are
used to represent a single character). Some programs recognise this as a
reduced write and will inadvertently repeat previous characters. If you
discover such a program, use the ANSICON_API environment variable to record
it and override the API, returning the original byte count. Ruby (prior to
1.9.3) is an example of such a program, so use 'set ANSICON_API=ruby' to
avoid the repitition. The full syntax is:
ANSICON_API=[!]program;program;program...
PROGRAM is the name of the program, with no path and extension. The
leading exclamation inverts the usage, meaning the API will always be
overridden, unless the program is in the list. The variable can be made
permanent by going to System Properties, selecting the Advanced tab and
clicking Environment Variables (using XP; Vista/7 may be different).
PROGRAM is the name of the program, with no path and extension. The lead-
ing exclamation inverts the usage, meaning the API will always be over-
ridden, unless the program is in the list. The variable can be made perm-
anent by going to System Properties, selecting the Advanced tab (with Vista
onwards, this can be done by running "SystemPropertiesAdvanced") and click-
ing Environment Variables.
====================
Sequences Recognised
====================
Sequences Recognised
====================
The following escape sequences are recognised.
@ -178,40 +177,36 @@
\e[#k VPB Line Position Backward
\e[#e VPR Line Position Forward
`\e' represents the escape character (ASCII 27); `#' represents a
decimal number (optional, in most cases defaulting to 1); BEL, SO and
SI are ASCII 7, 14 and 15. Regarding SGR: bold will set the foreground
intensity; underline and blink will set the background intensity;
conceal uses background as foreground. See `sequences.txt' for a more
complete description.
'\e' represents the escape character (ASCII 27); '#' represents a decimal
number (optional, in most cases defaulting to 1); BEL, SO and SI are ASCII
7, 14 and 15. Regarding SGR: bold will set the foreground intensity; blink
and underline will set the background intensity; conceal uses background as
foreground. See "sequences.txt" for a more complete description.
I make a distinction between "\e[m" and "\e[0;...m". Both will restore
the original foreground/background colors (and so "0" should be the
first parameter); the former will also restore the original bold and
underline attributes, whilst the latter will explicitly reset them. The
environment variable ANSICON_DEF can be used to change the default col-
ors (same value as `-m'; setting the variable does not change the cur-
rent colors).
I make a distinction between '\e[m' and '\e[0;...m'. Both will restore the
original foreground/background colors (and so '0' should be the first para-
meter); the former will also restore the original bold and underline attri-
butes, whilst the latter will explicitly reset them. The environment var-
iable ANSICON_DEF can be used to change the default colors (same value as
'-m'; setting the variable does not change the current colors).
=================
Sequences Ignored
=================
Sequences Ignored
=================
The following escape sequences are explicitly ignored.
\e(? Designate G0 character set (`?' is anything).
\e)? Designate G1 character set (`?' is anything).
\e(? Designate G0 character set ('?' is anything).
\e)? Designate G1 character set ('?' is anything).
\e[?... Private sequence
\e[>... Private sequence
The G0 character set is always ASCII; the G1 character set is always
the DEC Special Graphics Character Set.
The G0 character set is always ASCII; the G1 character set is always the
DEC Special Graphics Character Set.
==================================
DEC Special Graphics Character Set
==================================
DEC Special Graphics Character Set
==================================
This is my interpretation of the set, as shown by
http://vt100.net/docs/vt220-rm/table2-4.html.
@ -252,34 +247,34 @@
} U+00A3 Pound Sign
~ U+00B7 Middle Dot
G1.txt is a Unicode file to view the glyphs "externally". G1.bat is a
batch file (using `x86\ansicon') to show the glyphs in the console. The
batch file (using 'x86\ansicon') to show the glyphs in the console. The
characters will appear as they should using Lucida (other than the Sym-
bols), but code page will influence them when using a raster font (but
of particular interest, 437 and 850 both show the Box Drawings).
bols), but code page will influence them when using a raster font (but of
particular interest, 437 and 850 both show the Box Drawings).
===========
Limitations
===========
Limitations
===========
The entire console buffer is used, not just the visible window.
Building rubyinstaller on Win7 crashes (XP is fine).
There's a conflict with NVIDIA's drivers, requiring the setting of the
Environment Variable:
There's a conflict with NVIDIA's 64-bit drivers, requiring the setting
of the Environment Variable:
ANSICON_EXC=nvd3d9wrap.dll,nvd3d9wrapx.dll
ANSICON_EXC=nvd3d9wrap.dll;nvd3d9wrapx.dll
===============
Version History
===============
Version History
===============
Legend: + added, - bug-fixed, * changed.
1.62 - 18 July, 2013:
- indicate if opening HKLM failed;
* removed ANSI-LLW.exe again, properly this time;
* add the architecture (32- or 64-bit) to the log.
1.61 - 14 February, 2013:
* revert back to using ANSI-LLW.exe, as the new method was unreliable.
@ -311,7 +306,7 @@
- -p by itself will not restore original color;
- output error messages to stderr;
* logging is always available, with various levels; include the pid;
* don't automatically hook GUI programs, use `ansicon' or ANSICON_GUI;
* don't automatically hook GUI programs, use 'ansicon' or ANSICON_GUI;
* always place first in AutoRun; don't run if already installed;
+ global reverse video capability;
+ added ANSICON_VER to provide version/install test;
@ -401,36 +396,34 @@
+ initial release.
===============
Acknowledgments
===============
Acknowledgments
===============
Jean-Louis Morel, for his Perl package Win32::Console::ANSI. It
provided the basis of `ANSI.dll'.
Jean-Louis Morel, for his Perl package Win32::Console::ANSI. It provided
the basis of 'ANSI.dll'.
Sergey Oblomov (hoopoepg), for Console Manager. It provided the basis
of `ansicon.exe'.
Sergey Oblomov (hoopoepg), for Console Manager. It provided the basis of
'ansicon.exe'.
Anton Bassov's article "Process-wide API spying - an ultimate hack" in
"The Code Project".
Anton Bassov's article "Process-wide API spying - an ultimate hack" in "The
Code Project".
Richard Quadling - his persistence in finding bugs has made ANSICON
what it is today.
Richard Quadling - his persistence in finding bugs has made ANSICON what it
is today.
Dmitry Menshikov, Marko Bozikovic and Philippe Villiers, for their
assistance in making the 64-bit version a reality.
Dmitry Menshikov, Marko Bozikovic and Philippe Villiers, for their assis-
tance in making the 64-bit version a reality.
Luis Lavena and the Ruby people for additional improvements.
Leigh Hebblethwaite for documentation tweaks.
=======
Contact
=======
Contact
=======
mailto:jadoxa@yahoo.com.au
http://ansicon.adoxa.cjb.net/
http://ansicon.adoxa.vze.com/
https://github.com/adoxa/ansicon
Jason Hood
@ -440,19 +433,17 @@
Australia
============
Distribution
============
Distribution
============
The original zipfile can be freely distributed, by any means. However,
I would like to be informed if it is placed on a CD-ROM (other than an
archive compilation; permission is granted, I'd just like to know).
Modified versions may be distributed, provided it is indicated as such
in the version text and a source diff is made available. In particular,
the supplied binaries are freely redistributable, but the x64 binaries
must also include COPYING.MinGW-w64-runtime.txt. A formal license (zlib)
is available in LICENSE.txt.
The original zipfile can be freely distributed, by any means. However, I
would like to be informed if it is placed on a CD-ROM (other than an arch-
ive compilation; permission is granted, I'd just like to know). Modified
versions may be distributed, provided it is indicated as such in the ver-
sion text and a source diff is made available. In particular, the supplied
binaries are freely redistributable. A formal license (zlib) is available
in LICENSE.txt.
==============================
Jason Hood, 14 February, 2013.
==========================
Jason Hood, 18 July, 2013.

2
util.c
View File

@ -60,7 +60,7 @@ void DEBUGSTR( int level, LPTSTR szFormat, ... )
{
SYSTEMTIME now;
GetLocalTime( &now );
fprintf( file, "ANSICON v" PVERSA " log (%d) started "
fprintf( file, "ANSICON (" BITSA "-bit) v" PVERSA " log (%d) started "
"%d-%.2d-%.2d %d:%.2d:%.2d\n",
log_level,
now.wYear, now.wMonth, now.wDay,

View File

@ -2,8 +2,18 @@
version.h - Version defines.
*/
#define PVERS L"1.61" // wide string
#define PVERSA "1.61" // ANSI string (windres 2.16.91 didn't like L)
#define PVERE L"161" // wide environment string
#define PVEREA "161" // ANSI environment string
#define PVERB 1,6,1,0 // binary (resource)
#define PVERS L"1.62" // wide string
#define PVERSA "1.62" // ANSI string (windres 2.16.91 didn't like L)
#define PVERE L"162" // wide environment string
#define PVEREA "162" // ANSI environment string
#define PVERB 1,6,2,0 // binary (resource)
#ifdef _WIN64
# define BITS L"64"
# define BITSA "64"
#else
# define BITS L"32"
# define BITSA "32"
#endif
#define ANSIDLL L"ANSI" BITS L".dll"