New method to obtain 32-bit LoadLibraryW from 64-bit code, eliminating the need
for ANSI-LLW.exe. Set the code page so ansicon.exe can display some strings properly. Expand wildcards for -t. VC6 can now compile the 32-bit version; use it for the release binaries. Improvements to the VC makefile. Describe the sequences in a bit more detail.
This commit is contained in:
parent
ef587f0dee
commit
a52a46c9c1
22
ANSI-LLW.c
22
ANSI-LLW.c
@ -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" );
|
||||
}
|
20
ANSI.c
20
ANSI.c
@ -91,18 +91,23 @@
|
||||
|
||||
v1.53, 12 June, 2012:
|
||||
fixed Update_GRM when running multiple processes (e.g. "cl /MP").
|
||||
|
||||
v1.60, 22 to 24 November, 2012:
|
||||
alternative method to obtain LLW for 64->32 injection;
|
||||
support for VC6 (remove section pragma, rename isdigit to is_digit).
|
||||
*/
|
||||
|
||||
#include "ansicon.h"
|
||||
#include "version.h"
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#define isdigit(c) ('0' <= (c) && (c) <= '9')
|
||||
#define is_digit(c) ('0' <= (c) && (c) <= '9')
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define SHARED __attribute__((shared, section(".share")))
|
||||
#define SHARED __attribute__((shared, section(".shared")))
|
||||
#else
|
||||
#pragma section(".shared", read,write,shared)
|
||||
#pragma data_seg(".shared", "read,write,shared")
|
||||
#pragma data_seg()
|
||||
#define SHARED __declspec(allocate(".shared"))
|
||||
#endif
|
||||
|
||||
@ -228,6 +233,9 @@ SHARED DWORD s_flag;
|
||||
#define GRM_INIT 1
|
||||
#define GRM_EXIT 2
|
||||
|
||||
#ifdef _WIN64
|
||||
SHARED DWORD LLW32;
|
||||
#endif
|
||||
|
||||
|
||||
// Wait for the child process to finish, then update our GRM to the child's.
|
||||
@ -846,7 +854,7 @@ ParseAndPrintString( HANDLE hDev,
|
||||
}
|
||||
else if (state == 3)
|
||||
{
|
||||
if (isdigit( *s ))
|
||||
if (is_digit( *s ))
|
||||
{
|
||||
es_argc = 0;
|
||||
es_argv[0] = *s - '0';
|
||||
@ -873,7 +881,7 @@ ParseAndPrintString( HANDLE hDev,
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
if (isdigit( *s ))
|
||||
if (is_digit( *s ))
|
||||
{
|
||||
es_argv[es_argc] = 10 * es_argv[es_argc] + (*s - '0');
|
||||
}
|
||||
@ -1775,7 +1783,7 @@ void OriginalAttr( void )
|
||||
// and terminated.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
__declspec(dllexport) // to stop MinGW exporting everything
|
||||
__declspec(dllexport) // just to stop MinGW exporting everything
|
||||
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
|
||||
{
|
||||
BOOL bResult = TRUE;
|
||||
|
133
ansicon.c
133
ansicon.c
@ -64,15 +64,21 @@
|
||||
v1.52, 10 April, 2012:
|
||||
fixed running "cmd" if "ComSpec" is not defined;
|
||||
pass process & thread identifiers on the command line (for x86->x64).
|
||||
|
||||
v1.60, 22 & 24 November, 2012:
|
||||
set the code page to convert strings correctly;
|
||||
expand wildcards for -t;
|
||||
write the date if appending to the log.
|
||||
*/
|
||||
|
||||
#define PDATE L"12 June, 2012"
|
||||
#define PDATE L"24 November, 2012"
|
||||
|
||||
#include "ansicon.h"
|
||||
#include "version.h"
|
||||
#include <tlhelp32.h>
|
||||
#include <ctype.h>
|
||||
#include <io.h>
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
int _CRT_glob = 0;
|
||||
@ -96,6 +102,7 @@ void display( LPCTSTR, BOOL );
|
||||
void print_error( LPCTSTR, ... );
|
||||
LPTSTR skip_spaces( LPTSTR );
|
||||
void get_arg( LPTSTR, LPTSTR*, LPTSTR* );
|
||||
void get_file( LPTSTR, LPTSTR*, LPTSTR* );
|
||||
|
||||
void process_autorun( TCHAR );
|
||||
|
||||
@ -103,6 +110,12 @@ BOOL find_proc_id( HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe );
|
||||
BOOL GetParentProcessInfo( LPPROCESS_INFORMATION ppi, LPTSTR );
|
||||
|
||||
|
||||
// The DLL shares this variable, so injection requires it here.
|
||||
#ifdef _WIN64
|
||||
DWORD LLW32;
|
||||
#endif
|
||||
|
||||
|
||||
// Find the name of the DLL and inject it.
|
||||
BOOL Inject( LPPROCESS_INFORMATION ppi, BOOL* gui, LPCTSTR app )
|
||||
{
|
||||
@ -199,6 +212,10 @@ int main( void )
|
||||
GetEnvironmentVariable( L"ANSICON_LOG", logstr, lenof(logstr) );
|
||||
log_level = _wtoi( logstr );
|
||||
|
||||
// Using "" for setlocale uses the system ANSI code page.
|
||||
sprintf( (LPSTR)logstr, ".%u", GetConsoleOutputCP() );
|
||||
setlocale( LC_CTYPE, (LPSTR)logstr );
|
||||
|
||||
#ifdef _WIN64
|
||||
if (*arg == '-' && arg[1] == 'P')
|
||||
{
|
||||
@ -212,8 +229,8 @@ int main( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
if (log_level && !(log_level & 8))
|
||||
DEBUGSTR( 1, NULL ); // create a new file
|
||||
if (log_level)
|
||||
DEBUGSTR( 1, NULL ); // start a new session
|
||||
|
||||
installed = (GetEnvironmentVariable( L"ANSICON_VER", NULL, 0 ) != 0);
|
||||
// If it's already installed, remove it. This serves two purposes: preserves
|
||||
@ -235,8 +252,7 @@ int main( void )
|
||||
case 'l':
|
||||
SetEnvironmentVariable( L"ANSICON_LOG", arg + 2 );
|
||||
log_level = _wtoi( arg + 2 );
|
||||
if (!(log_level & 8)) // unless told otherwise
|
||||
DEBUGSTR( 1, NULL ); // create a new file
|
||||
DEBUGSTR( 1, NULL ); // create a session
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
@ -285,7 +301,7 @@ int main( void )
|
||||
a = -a;
|
||||
a = ((a >> 4) & 15) | ((a & 15) << 4);
|
||||
}
|
||||
SetConsoleTextAttribute( hConOut, a );
|
||||
SetConsoleTextAttribute( hConOut, (WORD)a );
|
||||
SetEnvironmentVariable( L"ANSICON_DEF", NULL );
|
||||
break;
|
||||
}
|
||||
@ -316,14 +332,14 @@ arg_out:
|
||||
{
|
||||
if (*cmd == '\0')
|
||||
{
|
||||
cmd = _wgetenv( L"ComSpec" );
|
||||
if (cmd == NULL)
|
||||
if (GetEnvironmentVariable( L"ComSpec", arg, MAX_PATH ))
|
||||
cmd = arg;
|
||||
else
|
||||
{
|
||||
// CreateProcessW writes to the string, so can't simply point to "cmd".
|
||||
static TCHAR cmdstr[] = L"cmd";
|
||||
cmd = cmdstr;
|
||||
}
|
||||
arg = cmd;
|
||||
}
|
||||
|
||||
ZeroMemory( &si, sizeof(si) );
|
||||
@ -369,7 +385,7 @@ arg_out:
|
||||
else // (*arg == 't' || *arg == 'T')
|
||||
{
|
||||
BOOL title = (*arg == 'T');
|
||||
get_arg( arg, &argv, &cmd );
|
||||
get_file( arg, &argv, &cmd );
|
||||
if (*arg == '\0')
|
||||
wcscpy( arg, L"-" );
|
||||
do
|
||||
@ -382,7 +398,7 @@ arg_out:
|
||||
}
|
||||
else
|
||||
display( arg, title );
|
||||
get_arg( arg, &argv, &cmd );
|
||||
get_file( arg, &argv, &cmd );
|
||||
} while (*arg);
|
||||
}
|
||||
|
||||
@ -650,6 +666,101 @@ void get_arg( LPTSTR arg, LPTSTR* argv, LPTSTR* cmd )
|
||||
}
|
||||
|
||||
|
||||
int glob_sort( const void* a, const void* b )
|
||||
{
|
||||
return lstrcmpi( *(LPCTSTR*)a, *(LPCTSTR*)b );
|
||||
}
|
||||
|
||||
|
||||
// As get_arg, but expand wildcards.
|
||||
void get_file( LPTSTR arg, LPTSTR* argv, LPTSTR* cmd )
|
||||
{
|
||||
HANDLE fh, in;
|
||||
WIN32_FIND_DATA fd;
|
||||
LPTSTR path;
|
||||
int size;
|
||||
char buf[1024];
|
||||
static LPTSTR name;
|
||||
static LPTSTR* glob;
|
||||
static int globbed;
|
||||
|
||||
if (globbed != 0)
|
||||
{
|
||||
if (glob[globbed] == NULL)
|
||||
{
|
||||
free( glob );
|
||||
globbed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy( name, glob[globbed++] );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
get_arg( arg, argv, cmd );
|
||||
if (wcspbrk( arg, L"*?" ) != NULL)
|
||||
{
|
||||
fh = FindFirstFile( arg, &fd );
|
||||
if (fh != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
size = 0;
|
||||
do
|
||||
{
|
||||
if (! (fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
|
||||
FILE_ATTRIBUTE_HIDDEN)))
|
||||
{
|
||||
++globbed;
|
||||
size += (int)wcslen( fd.cFileName ) + 1;
|
||||
}
|
||||
} while (FindNextFile( fh, &fd ));
|
||||
FindClose( fh );
|
||||
|
||||
if (globbed != 0)
|
||||
{
|
||||
for (path = name = arg; *path != '\0'; ++path)
|
||||
if (*path == '\\' || *path == '/')
|
||||
name = path + 1;
|
||||
glob = malloc( (globbed + 1) * sizeof(LPTSTR) + TSIZE(size) );
|
||||
path = (LPTSTR)(glob + globbed + 1);
|
||||
globbed = 0;
|
||||
fh = FindFirstFile( arg, &fd );
|
||||
do
|
||||
{
|
||||
if (! (fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
|
||||
FILE_ATTRIBUTE_HIDDEN)))
|
||||
{
|
||||
// Ignore apparent binary files.
|
||||
wcscpy( name, fd.cFileName );
|
||||
in = CreateFile( arg, GENERIC_READ,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL );
|
||||
if (in != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ReadFile( in, buf, sizeof(buf), (LPVOID)&size, NULL );
|
||||
CloseHandle( in );
|
||||
if (memchr( buf, 0, size ) != NULL)
|
||||
continue;
|
||||
}
|
||||
size = (int)wcslen( fd.cFileName ) + 1;
|
||||
memcpy( path, fd.cFileName, TSIZE(size) );
|
||||
glob[globbed++] = path;
|
||||
path += size;
|
||||
}
|
||||
} while (FindNextFile( fh, &fd ));
|
||||
FindClose( fh );
|
||||
glob[globbed] = NULL;
|
||||
|
||||
qsort( glob, globbed, sizeof(LPTSTR), glob_sort );
|
||||
|
||||
wcscpy( name, glob[0] );
|
||||
globbed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void help( void )
|
||||
{
|
||||
_putws(
|
||||
|
@ -12,7 +12,11 @@
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifdef _WIN64
|
||||
#define _WIN32_WINNT 0x0600 // MinGW-w64 wants this defined for Wow64 stuff
|
||||
#else
|
||||
#define _WIN32_WINNT 0x0500 // MinGW wants this defined for OpenThread
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
135
injdll32.c
135
injdll32.c
@ -18,11 +18,12 @@
|
||||
#include "ansicon.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
#if defined(__MINGW64__) || (defined(_MSC_VER) && _MSC_VER <= 1400)
|
||||
#ifndef WOW64_CONTEXT_ALL
|
||||
#include "wow64.h"
|
||||
|
||||
TWow64GetThreadContext Wow64GetThreadContext;
|
||||
TWow64SetThreadContext Wow64SetThreadContext;
|
||||
#define IMPORT_WOW64
|
||||
#endif
|
||||
|
||||
#define CONTEXT WOW64_CONTEXT
|
||||
@ -30,12 +31,99 @@ TWow64SetThreadContext Wow64SetThreadContext;
|
||||
#define CONTEXT_CONTROL WOW64_CONTEXT_CONTROL
|
||||
#define GetThreadContext Wow64GetThreadContext
|
||||
#define SetThreadContext Wow64SetThreadContext
|
||||
|
||||
#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 address of the 32-bit LoadLibraryW function from 64-bit code. This
|
||||
was originally done via executing a helper program (ANSI-LLW.exe), but for
|
||||
some reason, virus scanners really didn't like it (even when I rewrote it in
|
||||
assembly so it was 1024 bytes and literally two instructions, virustotal
|
||||
still had three scanners complaining). Now I do it the "hard" way - load the
|
||||
32-bit kernel32.dll directly and search the exports. Even worse, it seems
|
||||
Wow64 loads kernel32.dll at a different base address each boot (at least, I
|
||||
hope it only changes each boot). Fortunately, loading the DLL as an image in
|
||||
64-bit code seems to use the 32-bit address.
|
||||
*/
|
||||
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 & 0xFFFF0000);
|
||||
|
||||
// Tests to make sure we're looking at a module image (the 'MZ' header)
|
||||
pDosHeader = (PIMAGE_DOS_HEADER)base;
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
DEBUGSTR( 1, L"Image has no DOS header!" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// The MZ header has a pointer to the PE header
|
||||
pNTHeader = MakeVA( PIMAGE_NT_HEADERS32, pDosHeader->e_lfanew );
|
||||
|
||||
// One more test to make sure we're looking at a "PE" image
|
||||
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
DEBUGSTR( 1, L"Image has no NT header!" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// We now have a valid pointer to the module's PE header.
|
||||
// Get a pointer to its exports section.
|
||||
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!" );
|
||||
return FALSE;
|
||||
}
|
||||
LLW32 = MakeVA( DWORD, fun_table[ord_table[pLLW - name_table]] );
|
||||
|
||||
FreeLibrary( kernel32 );
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
DWORD LLW32;
|
||||
#endif
|
||||
|
||||
|
||||
DWORD LLW;
|
||||
|
||||
|
||||
void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
|
||||
{
|
||||
CONTEXT context;
|
||||
@ -54,12 +142,21 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
|
||||
if (len > TSIZE(MAX_PATH))
|
||||
return;
|
||||
|
||||
if (LLW == 0)
|
||||
if (LLW32 == 0)
|
||||
{
|
||||
HMODULE hKernel = GetModuleHandleA( "kernel32.dll" );
|
||||
#ifdef _WIN64
|
||||
#ifdef __MINGW64__
|
||||
if (!get_LLW32())
|
||||
return;
|
||||
#else
|
||||
LLW32 = (DWORD)GetProcAddress( GetModuleHandleA( "kernel32.dll" ),
|
||||
"LoadLibraryW" );
|
||||
#endif
|
||||
}
|
||||
#ifdef IMPORT_WOW64
|
||||
if (Wow64GetThreadContext == 0)
|
||||
{
|
||||
#define GETPROC( proc ) proc = (T##proc)GetProcAddress( hKernel, #proc )
|
||||
HMODULE hKernel = GetModuleHandleA( "kernel32.dll" );
|
||||
GETPROC( Wow64GetThreadContext );
|
||||
GETPROC( Wow64SetThreadContext );
|
||||
// Assume if one is defined, so is the other.
|
||||
@ -68,30 +165,8 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
|
||||
DEBUGSTR( 1, L"Failed to get pointer to Wow64GetThreadContext.\n" );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
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\".\n", (LPCTSTR)code );
|
||||
return;
|
||||
}
|
||||
WaitForSingleObject( pi.hProcess, INFINITE );
|
||||
GetExitCodeProcess( pi.hProcess, &LLW );
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
#else
|
||||
LLW = (DWORD)GetProcAddress( hKernel, "LoadLibraryW" );
|
||||
#endif
|
||||
}
|
||||
|
||||
CopyMemory( code + CODESIZE, dll, len );
|
||||
len += CODESIZE;
|
||||
@ -111,7 +186,7 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll )
|
||||
*ip.pB++ = 0x68; // push L"path\to\ANSI32.dll"
|
||||
*ip.pL++ = mem32 + CODESIZE;
|
||||
*ip.pB++ = 0xe8; // call LoadLibraryW
|
||||
*ip.pL++ = LLW - (mem32 + (DWORD)(ip.pB+4 - code));
|
||||
*ip.pL++ = LLW32 - (mem32 + (DWORD)(ip.pB+4 - code));
|
||||
*ip.pB++ = 0x61; // popa
|
||||
*ip.pB++ = 0x9d; // popf
|
||||
*ip.pB++ = 0xc3; // ret
|
||||
|
14
makefile
14
makefile
@ -10,6 +10,9 @@
|
||||
#
|
||||
# 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
|
||||
@ -33,7 +36,7 @@ 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
|
||||
ansicon64: x64 x64/ansicon.exe x64/ANSI64.dll x64/ANSI32.dll
|
||||
|
||||
x86:
|
||||
cmd /c "mkdir x86"
|
||||
@ -42,7 +45,7 @@ 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
|
||||
$(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC0000
|
||||
|
||||
x64:
|
||||
cmd /c "mkdir x64"
|
||||
@ -51,13 +54,10 @@ 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
|
||||
$(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
|
||||
|
||||
x64/ANSI-LLW.exe: ANSI-LLW.c
|
||||
$(CC) -m32 $(CFLAGS) $< -s -o $@
|
||||
$(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared,--image-base,0xAC0000
|
||||
|
||||
x86/ansicon.o: version.h
|
||||
x86/ANSI.o: version.h
|
||||
|
49
makefile.vc
49
makefile.vc
@ -7,12 +7,22 @@
|
||||
# 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.
|
||||
|
||||
# 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.
|
||||
|
||||
#BITS = 32
|
||||
#BITS = 64
|
||||
|
||||
!IFNDEF BITS
|
||||
!IF "$(CPU)" == "AMD64" || "$(PLATFORM)" == "x64"
|
||||
BITS = 64
|
||||
!ELSE
|
||||
BITS = 32
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IF $(BITS) == 32
|
||||
DIR = x86
|
||||
@ -24,12 +34,23 @@ DIR = x64
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
CC = cl
|
||||
CFLAGS = /nologo /W3 /Ox /GF /D_CRT_SECURE_NO_WARNINGS
|
||||
LIBS = advapi32.lib user32.lib
|
||||
|
||||
# This is required for the 2003 Platform SDK, but not for Visual Studio 2010.
|
||||
#LIBS64 = bufferoverflowu.lib
|
||||
!IF "$(_NMAKE_VER)" == "7.00.8882"
|
||||
LIBS64 = bufferoverflowu.lib
|
||||
# The 2003 Toolkit doesn't have MSVCRT.LIB (but VC98 does).
|
||||
!IF $(BITS) == 32 && !DEFINED(SHARE) && !DEFINED(MSVCDIR)
|
||||
SHARE =
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# Link with MSVCRT.LIB by default.
|
||||
!IFNDEF SHARE
|
||||
SHARE = /MD
|
||||
!ENDIF
|
||||
|
||||
CC = cl
|
||||
CFLAGS = /nologo /W3 /Ox /GF $(SHARE) /D_CRT_SECURE_NO_WARNINGS
|
||||
LIBS = advapi32.lib user32.lib
|
||||
|
||||
X86OBJS = x86\proctype.obj x86\injdll32.obj x86\util.obj
|
||||
X64OBJS = x64\proctype.obj x64\injdll64.obj x64\injdll32.obj x64\util.obj
|
||||
@ -44,31 +65,28 @@ all: ansicon$(BITS)
|
||||
|
||||
ansicon32: x86 x86\ansicon.exe x86\ANSI32.dll x64\ANSI32.dll
|
||||
|
||||
ansicon64: x64 x64\ansicon.exe x64\ANSI64.dll x64\ANSI-LLW.exe
|
||||
ansicon64: x64 x64\ansicon.exe x64\ANSI64.dll
|
||||
|
||||
x86:
|
||||
mkdir x86
|
||||
|
||||
x86\ansicon.exe: x86\ansicon.obj $(X86OBJS) x86\ansicon.res
|
||||
$(CC) /nologo /Fe$@ $** $(LIBS)
|
||||
$(CC) /nologo $(SHARE) /Fe$@ $** $(LIBS) /link /filealign:512
|
||||
|
||||
x86\ANSI32.dll: x86\ANSI.obj $(X86OBJS) x86\ansi.res
|
||||
$(CC) /nologo /LD /Fe$@ $** $(LIBS)
|
||||
$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link /base:0xAC0000 /section:.shared,s /filealign:512
|
||||
|
||||
x64:
|
||||
mkdir x64
|
||||
|
||||
x64\ansicon.exe: x64\ansicon.obj $(X64OBJS) x64\ansicon.res
|
||||
$(CC) /nologo /Fe$@ $** $(LIBS) $(LIBS64)
|
||||
$(CC) /nologo $(SHARE) /Fe$@ $** $(LIBS) $(LIBS64)
|
||||
|
||||
x64\ANSI64.dll: x64\ANSI.obj $(X64OBJS) x64\ansi.res
|
||||
$(CC) /nologo /LD /Fe$@ $** $(LIBS) $(LIBS64)
|
||||
$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) $(LIBS64) /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 /LD /Fe$@ $** $(LIBS)
|
||||
|
||||
x64\ANSI-LLW.exe: ANSI-LLW.c
|
||||
$(CC) $(CFLAGS) /Fe$@ /Fo$*.obj $? $(LIBS64)
|
||||
$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link /base:0xAC0000 /section:.shared,s /filealign:512
|
||||
|
||||
ansicon.c: ansicon.h version.h
|
||||
ansicon.rc: version.h
|
||||
@ -86,3 +104,6 @@ x64\proctype32.obj: proctype.c
|
||||
|
||||
clean:
|
||||
-del $(DIR)\*.obj $(DIR)\*.res $(DIR)\*.lib $(DIR)\*.exp
|
||||
!IF $(BITS) == 32
|
||||
-del x64\ansi32.obj x64\proctype32.obj
|
||||
!ENDIF
|
||||
|
25
readme.txt
25
readme.txt
@ -3,7 +3,7 @@
|
||||
|
||||
Copyright 2005-2012 Jason Hood
|
||||
|
||||
Version 1.53. Freeware
|
||||
Version 1.60. Freeware
|
||||
|
||||
|
||||
===========
|
||||
@ -18,7 +18,8 @@
|
||||
Requirements
|
||||
============
|
||||
|
||||
Windows 2000 Professional and later (it won't work with NT or 9X).
|
||||
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).
|
||||
|
||||
|
||||
============
|
||||
@ -39,7 +40,7 @@
|
||||
---------
|
||||
|
||||
Delete ANSI.dll, it has been replaced with ANSI32.dll.
|
||||
Delete ANSI-LLA.dll, it has been replaced with ANSI-LLW.dll.
|
||||
Delete ANSI-LLA.exe/ANSI-LLW.exe, they are no longer needed.
|
||||
Uninstall a pre-1.50 version and reinstall with this version.
|
||||
|
||||
|
||||
@ -182,7 +183,8 @@
|
||||
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.
|
||||
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
|
||||
@ -274,6 +276,13 @@
|
||||
|
||||
Legend: + added, - bug-fixed, * changed.
|
||||
|
||||
1.60 - 24 November, 2012:
|
||||
* new method to get the 32-bit LoadLibraryW address from 64-bit code.
|
||||
This removes the need for ANSI-LLW.exe, which caused lots of virus
|
||||
warnings, for some reason.
|
||||
- set the code page to display some file names properly;
|
||||
+ expand wildcards for -t (ignoring directories and hidden/binary files).
|
||||
|
||||
1.53 - 12 June, 2012:
|
||||
- fix for multiple simultaneous process creation (e.g. "cl /MP ...").
|
||||
|
||||
@ -432,8 +441,10 @@
|
||||
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 included.
|
||||
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.
|
||||
|
||||
|
||||
==========================
|
||||
Jason Hood, 12 June, 2012.
|
||||
==============================
|
||||
Jason Hood, 24 November, 2012.
|
||||
|
118
sequences.txt
Normal file
118
sequences.txt
Normal file
@ -0,0 +1,118 @@
|
||||
|
||||
ANSICON
|
||||
Version 1.60
|
||||
|
||||
This is a complete list of the ANSI escape sequences recognised by ANSICON,
|
||||
roughly ordered by function. The initial escape character is assumed.
|
||||
|
||||
|
||||
[m restore default color (and intensity)
|
||||
[0m as above
|
||||
[...m set attributes (any of these numbers, separated by semicolons):
|
||||
0 all attributes off
|
||||
1 bold (foreground is intense)
|
||||
4 underline (background is intense)
|
||||
5 blink (background is intense)
|
||||
7 reverse video
|
||||
8 concealed (foreground becomes background)
|
||||
22 bold off (foreground is not intense)
|
||||
24 underline off (background is not intense)
|
||||
25 blink off (background is not intense)
|
||||
27 normal video
|
||||
28 concealed off
|
||||
30 foreground black
|
||||
31 foreground red
|
||||
32 foreground green
|
||||
33 foreground yellow
|
||||
34 foreground blue
|
||||
35 foreground magenta
|
||||
36 foreground cyan
|
||||
37 foreground white
|
||||
39 default foreground (using current intensity)
|
||||
40 background black
|
||||
41 background red
|
||||
42 background green
|
||||
43 background yellow
|
||||
44 background blue
|
||||
45 background magenta
|
||||
46 background cyan
|
||||
47 background white
|
||||
49 default background (using current intensity)
|
||||
|
||||
[J erase from cursor to the end of display
|
||||
[0J as above
|
||||
[1J erase from the start of diplay to cursor (inclusive)
|
||||
[2J erase display and move cursor to the top-left
|
||||
|
||||
[K erase from cursor to the end of line
|
||||
[0K as above
|
||||
[1K erase from the start of line to cursor (inclusive)
|
||||
[2K erase line
|
||||
|
||||
[X erase one character
|
||||
[#X erase # characters
|
||||
|
||||
[L insert one blank line
|
||||
[#L insert # blank lines
|
||||
|
||||
[M delete one line
|
||||
[#M delete # lines
|
||||
|
||||
[P delete one character
|
||||
[#P delete # characters
|
||||
|
||||
[@ insert one blank character
|
||||
[#@ insert # blank characters
|
||||
|
||||
[A move cursor up one line
|
||||
[#A move cursor up # lines
|
||||
[B move cursor down one line
|
||||
[#B move cursor down # lines
|
||||
[C move cursor right one character
|
||||
[#C move cursor right # characters
|
||||
[D move cursor left one character
|
||||
[#D move cursor left # characters
|
||||
|
||||
[k move cursor up one line
|
||||
[#k move cursor up # lines
|
||||
[e move cursor down one line
|
||||
[#e move cursor down # lines
|
||||
[a move cursor right one character
|
||||
[#a move cursor right # characters
|
||||
[j move cursor left one character
|
||||
[#j move cursor left # characters
|
||||
|
||||
[E move cursor down one line and to first column
|
||||
[#E move cursor down # lines and to first column
|
||||
[F move cursor up one line and to first column
|
||||
[#F move cursor up # lines and to first column
|
||||
|
||||
[G move cursor to first column
|
||||
[#G move cursor to column #
|
||||
|
||||
[` move cursor to first column
|
||||
[#` move cursor to column #
|
||||
|
||||
[d move cursor to first line
|
||||
[#d move cursor to line #
|
||||
|
||||
[H move cursor to top-left
|
||||
[#H move cursor to line # and first column
|
||||
[#;#H move cursor to line #, column #
|
||||
|
||||
[f move cursor to top-left
|
||||
[#f move cursor to line # and first column
|
||||
[#;#f move cursor to line #, column #
|
||||
|
||||
[s save cursor position
|
||||
[u move cursor to saved position
|
||||
|
||||
[?25h show cursor
|
||||
[?25l hide cursor
|
||||
|
||||
[5n sends "\e[0n" to console input (where \e is escape)
|
||||
[6n sends "\e[#;#R" (line & column) to console input
|
||||
[21t sends "\e]lTitle\e\" (the console's window title) to console input
|
||||
]0;TitleST
|
||||
sets the console title to "Title"; ST (string terminator) is either
|
||||
character 7 (BEL) or escape and backslash
|
2
util.c
2
util.c
@ -55,7 +55,7 @@ void DEBUGSTR( int level, LPTSTR szFormat, ... )
|
||||
}
|
||||
if (szFormat == NULL)
|
||||
{
|
||||
file = fopen( tempfile, "wt" );
|
||||
file = fopen( tempfile, (log_level & 8) ? "at" : "wt" );
|
||||
if (file != NULL)
|
||||
{
|
||||
SYSTEMTIME now;
|
||||
|
10
version.h
10
version.h
@ -2,8 +2,8 @@
|
||||
version.h - Version defines.
|
||||
*/
|
||||
|
||||
#define PVERS L"1.53" // wide string
|
||||
#define PVERSA "1.53" // ANSI string (windres 2.16.91 didn't like L)
|
||||
#define PVERE L"153" // wide environment string
|
||||
#define PVEREA "153" // ANSI environment string
|
||||
#define PVERB 1,5,3,0 // binary (resource)
|
||||
#define PVERS L"1.60" // wide string
|
||||
#define PVERSA "1.60" // ANSI string (windres 2.16.91 didn't like L)
|
||||
#define PVERE L"160" // wide environment string
|
||||
#define PVEREA "160" // ANSI environment string
|
||||
#define PVERB 1,6,0,0 // binary (resource)
|
||||
|
Loading…
x
Reference in New Issue
Block a user