diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a45c74f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.zip +/x86 +/x64 diff --git a/ANSI.c b/ANSI.c index bb58a55..099e7aa 100644 --- a/ANSI.c +++ b/ANSI.c @@ -58,18 +58,20 @@ fix multibyte conversion problems. */ -#define UNICODE -#define _UNICODE -#include +#ifndef UNICODE +# define UNICODE +#endif -#define lenof(str) (sizeof(str)/sizeof(TCHAR)) - -#include +#define WIN32_LEAN_AND_MEAN #include +#include +#include #include #include #include "injdll.h" +#define lenof(array) (sizeof(array)/sizeof(*(array))) + #define isdigit(c) ('0' <= (c) && (c) <= '9') // ========== Auxiliary debug function @@ -87,7 +89,7 @@ void DEBUGSTR( LPTSTR szFormat, ... ) // sort of OutputDebugStringf TCHAR szBuffer[1024], szEscape[1024]; va_list pArgList; va_start( pArgList, szFormat ); - _vsntprintf( szBuffer, lenof(szBuffer), szFormat, pArgList ); + _vsnwprintf( szBuffer, lenof(szBuffer), szFormat, pArgList ); va_end( pArgList ); szFormat = szBuffer; @@ -106,10 +108,11 @@ void DEBUGSTR( LPTSTR szFormat, ... ) // sort of OutputDebugStringf case '\t': *pos++ = 't'; break; case '\r': *pos++ = 'r'; break; case '\n': *pos++ = 'n'; break; - case '\e': *pos++ = 'e'; break; - default: pos += _tprintf( pos, TEXT("%.*o"), + case 27 : *pos++ = 'e'; break; + default: + pos += wprintf( pos, L"%.*o", (szFormat[1] >= '0' && szFormat[1] <= '7') ? 3 : 1, - *szFormat ); + *szFormat ); } } else if (*szFormat == '"') @@ -131,19 +134,25 @@ void DEBUGSTR( LPTSTR szFormat, ... ) // sort of OutputDebugStringf szFormat = szEscape; } #if (MYDEBUG > 1) + { FILE* file = fopen( tempfile, "a" ); if (file != NULL) { - _ftprintf( file, TEXT("%s\n"), szFormat ); + fwprintf( file, L"%s\n", szFormat ); fclose( file ); } + } #else OutputDebugString( szFormat ); #endif } #else +#if defined(_MSC_VER) && _MSC_VER <= 1400 +void DEBUGSTR() { } +#else #define DEBUGSTR(...) #endif +#endif // ========== Global variables and constants @@ -223,11 +232,11 @@ WORD foreground; WORD background; WORD bold; WORD underline; -WORD rvideo = 0; -WORD concealed = 0; +WORD rvideo; +WORD concealed; // saved cursor position -COORD SavePos = { 0, 0 }; +COORD SavePos; // ========== Hooking API functions @@ -270,7 +279,7 @@ BOOL HookAPIOneMod( pDosHeader = (PIMAGE_DOS_HEADER)hFromModule; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { - DEBUGSTR( TEXT("error: %s(%d)"), TEXT(__FILE__), __LINE__ ); + DEBUGSTR( L"error: %S(%d)", __FILE__, __LINE__ ); return FALSE; } @@ -280,7 +289,7 @@ BOOL HookAPIOneMod( // One more test to make sure we're looking at a "PE" image if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) { - DEBUGSTR( TEXT("error: %s(%d)"), TEXT(__FILE__), __LINE__ ); + DEBUGSTR( L"error: %S(%d)", __FILE__, __LINE__ ); return FALSE; } @@ -305,7 +314,7 @@ BOOL HookAPIOneMod( PCSTR* lib; PSTR pszModName = MakePtr( PSTR, pDosHeader, pImportDesc->Name ); for (lib = APIs; *lib; ++lib) - if (stricmp( pszModName, *lib ) == 0) + if (_stricmp( pszModName, *lib ) == 0) break; if (*lib == NULL) continue; @@ -335,7 +344,7 @@ BOOL HookAPIOneMod( DWORD flOldProtect, flNewProtect, flDummy; MEMORY_BASIC_INFORMATION mbi; - DEBUGSTR( TEXT(" %hs"), hook->name ); + DEBUGSTR( L" %S", hook->name ); // Get the current protection attributes. VirtualQuery( &pThunk->u1.Function, &mbi, sizeof(mbi) ); // Take the access protection flags. @@ -354,7 +363,7 @@ BOOL HookAPIOneMod( &pThunk->u1.Function, &patch, sizeof(patch), NULL )) { - DEBUGSTR( TEXT("error: %s(%d)"), TEXT(__FILE__), __LINE__ ); + DEBUGSTR( L"error: %S(%d)", __FILE__, __LINE__ ); return FALSE; } @@ -389,7 +398,7 @@ BOOL HookAPIAllMod( PHookFn Hooks, BOOL restore ) if (hModuleSnap == INVALID_HANDLE_VALUE) { - DEBUGSTR( TEXT("error: %s(%d)"), TEXT(__FILE__), __LINE__ ); + DEBUGSTR( L"error: %S(%d)", __FILE__, __LINE__ ); return FALSE; } @@ -403,7 +412,7 @@ BOOL HookAPIAllMod( PHookFn Hooks, BOOL restore ) // We don't hook functions in our own module. if (me.hModule != hDllInstance && me.hModule != hKernel) { - DEBUGSTR( (restore) ? TEXT("Unhooking from %s") : TEXT("Hooking in %s"), + DEBUGSTR( (restore) ? L"Unhooking from %s" : L"Hooking in %s", me.szModule ); // Hook this function in this module. if (!HookAPIOneMod( me.hModule, Hooks, restore )) @@ -448,7 +457,7 @@ void PushBuffer( TCHAR c ) if (nCharInBuffer >= BUFFER_SIZE) { FlushBuffer(); - DEBUGSTR( TEXT("flush") ); + DEBUGSTR( L"flush" ); } } @@ -918,13 +927,13 @@ void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi, } else { - DEBUGSTR( TEXT(" Ignoring unsupported machine (%x)"), + DEBUGSTR( L" Ignoring unsupported machine (%x)", nt_header.FileHeader.Machine ); } } else { - DEBUGSTR( TEXT(" Ignoring non-console subsystem (%u)"), + DEBUGSTR( L" Ignoring non-console subsystem (%u)", nt_header.OptionalHeader.Subsystem ); } break; @@ -990,7 +999,7 @@ BOOL WINAPI MyCreateProcessA( LPCSTR lpApplicationName, &pi )) return FALSE; - DEBUGSTR( TEXT("CreateProcessA: \"%hs\", \"%hs\""), + DEBUGSTR( L"CreateProcessA: \"%S\", \"%S\"", (lpApplicationName == NULL) ? "" : lpApplicationName, (lpCommandLine == NULL) ? "" : lpCommandLine ); Inject( &pi, lpProcessInformation, dwCreationFlags ); @@ -1024,7 +1033,7 @@ BOOL WINAPI MyCreateProcessW( LPCWSTR lpApplicationName, &pi )) return FALSE; - DEBUGSTR( TEXT("CreateProcessW: \"%ls\", \"%ls\""), + DEBUGSTR( L"CreateProcessW: \"%s\", \"%s\"", (lpApplicationName == NULL) ? L"" : lpApplicationName, (lpCommandLine == NULL) ? L"" : lpCommandLine ); Inject( &pi, lpProcessInformation, dwCreationFlags ); @@ -1038,7 +1047,7 @@ HMODULE WINAPI MyLoadLibraryA( LPCSTR lpFileName ) HMODULE hMod = LoadLibraryA( lpFileName ); if (hMod && hMod != hKernel) { - DEBUGSTR( TEXT("Hooking in %hs (LoadLibraryA)"), lpFileName ); + DEBUGSTR( L"Hooking in %S (LoadLibraryA)", lpFileName ); HookAPIOneMod( hMod, Hooks, FALSE ); } return hMod; @@ -1050,7 +1059,7 @@ HMODULE WINAPI MyLoadLibraryW( LPCWSTR lpFileName ) HMODULE hMod = LoadLibraryW( lpFileName ); if (hMod && hMod != hKernel) { - DEBUGSTR( TEXT("Hooking in %ls (LoadLibraryW)"), lpFileName ); + DEBUGSTR( L"Hooking in %s (LoadLibraryW)", lpFileName ); HookAPIOneMod( hMod, Hooks, FALSE ); } return hMod; @@ -1063,7 +1072,7 @@ HMODULE WINAPI MyLoadLibraryExA( LPCSTR lpFileName, HANDLE hFile, HMODULE hMod = LoadLibraryExA( lpFileName, hFile, dwFlags ); if (hMod && hMod != hKernel && !(dwFlags & LOAD_LIBRARY_AS_DATAFILE)) { - DEBUGSTR( TEXT("Hooking in %hs (LoadLibraryExA)"), lpFileName ); + DEBUGSTR( L"Hooking in %S (LoadLibraryExA)", lpFileName ); HookAPIOneMod( hMod, Hooks, FALSE ); } return hMod; @@ -1076,7 +1085,7 @@ HMODULE WINAPI MyLoadLibraryExW( LPCWSTR lpFileName, HANDLE hFile, HMODULE hMod = LoadLibraryExW( lpFileName, hFile, dwFlags ); if (hMod && hMod != hKernel && !(dwFlags & LOAD_LIBRARY_AS_DATAFILE)) { - DEBUGSTR( TEXT("Hooking in %ls (LoadLibraryExW)"), lpFileName ); + DEBUGSTR( L"Hooking in %s (LoadLibraryExW)", lpFileName ); HookAPIOneMod( hMod, Hooks, FALSE ); } return hMod; @@ -1103,7 +1112,7 @@ WINAPI MyWriteConsoleA( HANDLE hCon, LPCVOID lpBuffer, if (GetConsoleMode( hCon, &Mode ) && (Mode & ENABLE_PROCESSED_OUTPUT)) { UINT cp = GetConsoleOutputCP(); - DEBUGSTR( TEXT("\\WriteConsoleA: %lu \"%.*hs\""), nNumberOfCharsToWrite, nNumberOfCharsToWrite, lpBuffer ); + DEBUGSTR( L"\\WriteConsoleA: %lu \"%.*S\"", nNumberOfCharsToWrite, nNumberOfCharsToWrite, lpBuffer ); len = MultiByteToWideChar( cp, 0, lpBuffer, nNumberOfCharsToWrite, NULL, 0 ); buf = malloc( len * sizeof(WCHAR) ); if (buf == NULL) @@ -1133,7 +1142,7 @@ WINAPI MyWriteConsoleW( HANDLE hCon, LPCVOID lpBuffer, DWORD Mode; if (GetConsoleMode( hCon, &Mode ) && (Mode & ENABLE_PROCESSED_OUTPUT)) { - DEBUGSTR( TEXT("\\WriteConsoleW: %lu \"%.*ls\""), nNumberOfCharsToWrite, nNumberOfCharsToWrite, lpBuffer ); + DEBUGSTR( L"\\WriteConsoleW: %lu \"%.*s\"", nNumberOfCharsToWrite, nNumberOfCharsToWrite, lpBuffer ); return ParseAndPrintString( hCon, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten ); @@ -1154,7 +1163,7 @@ WINAPI MyWriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, DWORD Mode; if (GetConsoleMode( hFile, &Mode ) && (Mode & ENABLE_PROCESSED_OUTPUT)) { - DEBUGSTR( TEXT("\\WriteFile: %lu \"%.*hs\""), nNumberOfBytesToWrite, nNumberOfBytesToWrite, lpBuffer ); + DEBUGSTR( L"\\WriteFile: %lu \"%.*S\"", nNumberOfBytesToWrite, nNumberOfBytesToWrite, lpBuffer ); return MyWriteConsoleA( hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, @@ -1175,24 +1184,24 @@ WINAPI MyWriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, void set_ansicon( PCONSOLE_SCREEN_BUFFER_INFO pcsbi ) { CONSOLE_SCREEN_BUFFER_INFO csbi; + TCHAR buf[64]; if (pcsbi == NULL) { HANDLE hConOut; - hConOut = CreateFile( TEXT("CONOUT$"), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, 0 ); + hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, 0 ); GetConsoleScreenBufferInfo( hConOut, &csbi ); CloseHandle( hConOut ); pcsbi = &csbi; } - TCHAR buf[64]; - wsprintf( buf, TEXT("%dx%d (%dx%d)"), + wsprintf( buf, L"%dx%d (%dx%d)", pcsbi->dwSize.X, pcsbi->dwSize.Y, pcsbi->srWindow.Right - pcsbi->srWindow.Left + 1, pcsbi->srWindow.Bottom - pcsbi->srWindow.Top + 1 ); - SetEnvironmentVariable( TEXT("ANSICON"), buf ); + SetEnvironmentVariable( L"ANSICON", buf ); } DWORD @@ -1206,7 +1215,7 @@ WINAPI MyGetEnvironmentVariableA( LPCSTR lpName, LPSTR lpBuffer, DWORD nSize ) DWORD WINAPI MyGetEnvironmentVariableW( LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize ) { - if (lstrcmpiW( lpName, L"ANSICON" ) == 0) + if (lstrcmpi( lpName, L"ANSICON" ) == 0) set_ansicon( NULL ); return GetEnvironmentVariableW( lpName, lpBuffer, nSize ); } @@ -1242,9 +1251,9 @@ void OriginalAttr( void ) HANDLE hConOut; CONSOLE_SCREEN_BUFFER_INFO csbi; - hConOut = CreateFile( TEXT("CONOUT$"), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, 0 ); + hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, 0 ); if (!GetConsoleScreenBufferInfo( hConOut, &csbi )) csbi.wAttributes = 7; CloseHandle( hConOut ); @@ -1281,7 +1290,7 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) #endif hDllInstance = hInstance; // save Dll instance handle - DEBUGSTR( TEXT("hDllInstance = %p"), hDllInstance ); + DEBUGSTR( L"hDllInstance = %p", hDllInstance ); // Get the entry points to the original functions. hKernel = GetModuleHandleA( APIKernel ); @@ -1299,7 +1308,7 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) } else if (dwReason == DLL_PROCESS_DETACH && lpReserved == NULL) { - DEBUGSTR( TEXT("Unloading") ); + DEBUGSTR( L"Unloading" ); HookAPIAllMod( Hooks, TRUE ); } diff --git a/ansicon.c b/ansicon.c index 531c8f2..8b103be 100644 --- a/ansicon.c +++ b/ansicon.c @@ -38,20 +38,22 @@ v1.30, 3 August to 7 September, 2010: x64 support. - v1.31, 13 November, 2010: - use LLW to fix potential Unicode path problems. + v1.31, 13 to 15 November, 2010: + use LLW to fix potential Unicode path problems; + VC compatibility (2008 Express for 32-bit, PSDK 2003 R2 for 64-bit); + explicitly use wide characters (stick with TCHAR, but not ). */ -#define PVERS "1.31" -#define PDATE "13 November, 2010" +#define PVERS L"1.31" +#define PDATE L"15 November, 2010" -#define UNICODE -#define _UNICODE +#ifndef UNICODE +# define UNICODE +#endif #define WIN32_LEAN_AND_MEAN #define _WIN32_WINNT 0x0500 // MinGW wants this defined for OpenThread #include -#include #include #include #include @@ -60,7 +62,7 @@ #include #include "injdll.h" -#define lenof(str) (sizeof(str)/sizeof(TCHAR)) +#define lenof(array) (sizeof(array)/sizeof(*(array))) #ifdef __MINGW32__ int _CRT_glob = 0; @@ -76,8 +78,8 @@ int _CRT_glob = 0; #endif -#define CMDKEY TEXT("Software\\Microsoft\\Command Processor") -#define AUTORUN TEXT("AutoRun") +#define CMDKEY L"Software\\Microsoft\\Command Processor" +#define AUTORUN L"AutoRun" void help( void ); @@ -96,7 +98,7 @@ BOOL GetParentProcessInfo( LPPROCESS_INFORMATION ppi ); void Inject( LPPROCESS_INFORMATION ppi ) { DWORD len; - WCHAR dll[MAX_PATH]; + TCHAR dll[MAX_PATH]; len = GetModuleFileName( NULL, dll, lenof(dll) ); while (dll[len-1] != '\\') @@ -112,9 +114,9 @@ static CONSOLE_SCREEN_BUFFER_INFO csbi; void get_original_attr( void ) { - hConOut = CreateFile( TEXT("CONOUT$"), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, 0 ); + hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, 0 ); GetConsoleScreenBufferInfo( hConOut, &csbi ); } @@ -145,27 +147,27 @@ int main( void ) int rc = 0; int argc; - LPWSTR* argv = CommandLineToArgvW( GetCommandLineW(), &argc ); + LPWSTR* argv = CommandLineToArgvW( GetCommandLine(), &argc ); if (argc > 1) { - if (lstrcmp( argv[1], TEXT("--help") ) == 0 || + if (lstrcmp( argv[1], L"--help" ) == 0 || (argv[1][0] == '-' && (argv[1][1] == '?' || argv[1][1] == 'h')) || (argv[1][0] == '/' && argv[1][1] == '?')) { help(); return rc; } - if (lstrcmp( argv[1], TEXT("--version") ) == 0) + if (lstrcmp( argv[1], L"--version" ) == 0) { - _putts( TEXT("ANSICON (" BITS "-bit) version " PVERS " (" PDATE ").") ); + _putws( L"ANSICON (" BITS L"-bit) version " PVERS L" (" PDATE L")." ); return rc; } } option = (argc > 1 && argv[1][0] == '-'); - if (option && (_totlower( argv[1][1] ) == 'i' || - _totlower( argv[1][1] ) == 'u')) + if (option && (towlower( argv[1][1] ) == 'i' || + towlower( argv[1][1] ) == 'u')) { process_autorun( argv[1][1] ); return rc; @@ -177,15 +179,15 @@ int main( void ) if (option && argv[1][1] == 'm') { WORD attr = 7; - if (_istxdigit( argv[1][2] )) + if (iswxdigit( argv[1][2] )) { - attr = _istdigit( argv[1][2] ) ? argv[1][2] - '0' - : (argv[1][2] | 0x20) - 'a' + 10; - if (_istxdigit( argv[1][3])) + attr = iswdigit( argv[1][2] ) ? argv[1][2] - '0' + : (argv[1][2] | 0x20) - 'a' + 10; + if (iswxdigit( argv[1][3])) { attr <<= 4; - attr |= _istdigit( argv[1][3] ) ? argv[1][3] - '0' - : (argv[1][3] | 0x20) - 'a' + 10; + attr |= iswdigit( argv[1][3] ) ? argv[1][3] - '0' + : (argv[1][3] | 0x20) - 'a' + 10; } } SetConsoleTextAttribute( hConOut, attr ); @@ -196,7 +198,7 @@ int main( void ) option = (argc > 1 && argv[1][0] == '-'); } - installed = (GetEnvironmentVariable( TEXT("ANSICON"), NULL, 0 ) != 0); + installed = (GetEnvironmentVariable( L"ANSICON", NULL, 0 ) != 0); if (option && argv[1][1] == 'p') { @@ -215,7 +217,7 @@ int main( void ) } else { - _putts( TEXT("ANSICON: could not obtain the parent process.") ); + _putws( L"ANSICON: could not obtain the parent process." ); rc = 1; } } @@ -223,7 +225,7 @@ int main( void ) { ansi = 0; if (!installed) - ansi = LoadLibrary( TEXT("ANSI" BITS ".dll") ); + ansi = LoadLibrary( L"ANSI" BITS L".dll" ); if (option && (argv[1][1] == 't' || argv[1][1] == 'T')) { @@ -236,10 +238,10 @@ int main( void ) for (; argc > 2; ++argv, --argc) { if (title) - _tprintf( TEXT("==> %s <==\n"), argv[2] ); + wprintf( L"==> %s <==\n", argv[2] ); display( argv[2], title ); if (title) - _puttchar( '\n' ); + putwchar( '\n' ); } } else @@ -251,21 +253,21 @@ int main( void ) if (cmd[0] == '-' && (cmd[1] == 'e' || cmd[1] == 'E')) { - _fputts( cmd + 3, stdout ); + fputws( cmd + 3, stdout ); if (cmd[1] == 'e') - _puttchar( '\n' ); + putwchar( '\n' ); } - else if (!isatty( 0 ) && *cmd == '\0') + else if (!_isatty( 0 ) && *cmd == '\0') { - display( TEXT("-"), FALSE ); + display( L"-", FALSE ); } else { if (*cmd == '\0') { - cmd = _tgetenv( TEXT("ComSpec") ); + cmd = _wgetenv( L"ComSpec" ); if (cmd == NULL) - cmd = TEXT("cmd"); + cmd = L"cmd"; } ZeroMemory( &si, sizeof(si) ); @@ -278,7 +280,7 @@ int main( void ) else { *skip_arg( cmd ) = '\0'; - _tprintf( TEXT("ANSICON: '%s' could not be executed.\n"), cmd ); + wprintf( L"ANSICON: '%s' could not be executed.\n", cmd ); rc = 1; } } @@ -300,8 +302,8 @@ void print_error( LPCTSTR name, BOOL title ) FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPTSTR)(LPVOID)&errmsg, 0, NULL ); if (!title) - _tprintf( TEXT("ANSICON: %s: "), name ); - _fputts( errmsg, stdout ); + wprintf( L"ANSICON: %s: ", name ); + fputws( errmsg, stdout ); LocalFree( errmsg ); } @@ -309,26 +311,28 @@ void print_error( LPCTSTR name, BOOL title ) // Display a file. void display( LPCTSTR name, BOOL title ) { + HANDLE file; + int c; + LARGE_INTEGER size, offset; + // Handle the pipe differently. if (*name == '-' && name[1] == '\0') { if (title) - _puttchar( '\n' ); - int c; + putwchar( '\n' ); while ((c = getchar()) != EOF) putchar( c ); return; } - HANDLE file = CreateFile( name, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, 0, NULL ); + file = CreateFile( name, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, 0, NULL ); if (file == INVALID_HANDLE_VALUE) { print_error( name, title ); return; } - LARGE_INTEGER size; GetFileSizeEx( file, &size ); if (size.QuadPart != 0) { @@ -336,8 +340,7 @@ void display( LPCTSTR name, BOOL title ) if (map) { if (title) - _puttchar( '\n' ); - LARGE_INTEGER offset; + putwchar( '\n' ); offset.QuadPart = 0; do { @@ -378,11 +381,11 @@ void process_autorun( TCHAR cmd ) len = GetModuleFileName( NULL, ansicon+2, MAX_PATH ); ansicon[0] = '&'; ansicon[1] = ansicon[2+len] = '"'; - _tcscpy( ansicon + 3+len, L" -p" ); + wcscpy( ansicon + 3+len, L" -p" ); len += 6; - inst = (_totlower( cmd ) == 'i'); - RegCreateKeyEx( (_istlower( cmd )) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, + 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 ); @@ -394,12 +397,12 @@ void process_autorun( TCHAR cmd ) { exist += sizeof(TCHAR); RegQueryValueEx( cmdkey, AUTORUN, NULL, &type, (PBYTE)autorun, &exist ); - ansirun = _tcsstr( autorun, ansicon+1 ); + ansirun = wcsstr( autorun, ansicon+1 ); if (inst) { if (!ansirun) { - _tcscpy( (LPTSTR)((PBYTE)autorun + exist - sizeof(TCHAR)), ansicon ); + wcscpy( (LPTSTR)((PBYTE)autorun + exist - sizeof(TCHAR)), ansicon ); RegSetValueEx( cmdkey, AUTORUN, 0, type, (PBYTE)autorun, exist + len*sizeof(TCHAR) ); } @@ -515,32 +518,32 @@ LPTSTR skip_arg( LPTSTR cmd ) void help( void ) { - _putts( TEXT( -"ANSICON by Jason Hood .\n" -"Version " PVERS " (" PDATE "). Freeware.\n" -"http://ansicon.adoxa.cjb.net/\n" -"\n" + _putws( +L"ANSICON by Jason Hood .\n" +L"Version " PVERS L" (" PDATE L"). Freeware.\n" +L"http://ansicon.adoxa.cjb.net/\n" +L"\n" #ifdef _WIN64 -"Process ANSI escape sequences in Windows console programs.\n" +L"Process ANSI escape sequences in Windows console programs.\n" #else -"Process ANSI escape sequences in Win32 console programs.\n" +L"Process ANSI escape sequences in Win32 console programs.\n" #endif -"\n" -"ansicon -i|I | -u|U\n" -"ansicon [-m[]] [-p | -e|E string | -t|T [file(s)] | program [args]]\n" -"\n" -" -i\t\tinstall - add ANSICON to the AutoRun entry\n" -" -u\t\tuninstall - remove ANSICON from the AutoRun entry\n" -" -I -U\t\tuse local machine instead of current user\n" -" -m\t\tuse grey on black (\"monochrome\") or as default color\n" -" -p\t\thook into the parent process\n" -" -e\t\techo string\n" -" -E\t\techo string, don't append newline\n" -" -t\t\tdisplay files (\"-\" for stdin), combined as a single stream\n" -" -T\t\tdisplay files, name first, blank line before and after\n" -" program\trun the specified program\n" -" nothing\trun a new command processor, or display stdin if redirected\n" -"\n" -" is one or two hexadecimal digits; please use \"COLOR /?\" for details." - ) ); +L"\n" +L"ansicon -i|I | -u|U\n" +L"ansicon [-m[]] [-p | -e|E string | -t|T [file(s)] | program [args]]\n" +L"\n" +L" -i\t\tinstall - add ANSICON to 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" -m\t\tuse grey on black (\"monochrome\") or as default color\n" +L" -p\t\thook into the parent process\n" +L" -e\t\techo string\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, name first, blank line before and after\n" +L" program\trun the specified program\n" +L" nothing\trun a new command processor, or display stdin if redirected\n" +L"\n" +L" is one or two hexadecimal digits; please use \"COLOR /?\" for details." + ); } diff --git a/injdll.h b/injdll.h index e9e1029..171f3a6 100644 --- a/injdll.h +++ b/injdll.h @@ -7,10 +7,14 @@ #ifndef INJDLL_H #define INJDLL_H +#ifndef UNICODE +# define UNICODE +#endif + #define WIN32_LEAN_AND_MEAN #include -void InjectDLL32( LPPROCESS_INFORMATION, LPCWSTR ); -void InjectDLL64( LPPROCESS_INFORMATION, LPCWSTR ); +void InjectDLL32( LPPROCESS_INFORMATION, LPCTSTR ); +void InjectDLL64( LPPROCESS_INFORMATION, LPCTSTR ); #endif diff --git a/injdll32.c b/injdll32.c index 90c8ed9..34790b4 100644 --- a/injdll32.c +++ b/injdll32.c @@ -18,10 +18,12 @@ #include "injdll.h" #ifdef _WIN64 +#if defined(__MINGW64__) || (defined(_MSC_VER) && _MSC_VER <= 1400) #include "wow64.h" TWow64GetThreadContext Wow64GetThreadContext; TWow64SetThreadContext Wow64SetThreadContext; +#endif #define CONTEXT WOW64_CONTEXT #undef CONTEXT_CONTROL @@ -34,23 +36,29 @@ TWow64SetThreadContext Wow64SetThreadContext; DWORD LLW; -void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) +void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCTSTR dll ) { CONTEXT context; DWORD len; LPVOID mem; DWORD mem32; #define CODESIZE 20 - BYTE code[CODESIZE+MAX_PATH*sizeof(WCHAR)]; + BYTE code[CODESIZE+MAX_PATH*sizeof(TCHAR)]; + union + { + PBYTE pB; + PDWORD pL; + } ip; - len = lstrlenW( dll ) + 1; + len = lstrlen( dll ) + 1; if (len > MAX_PATH) return; - len *= sizeof(WCHAR); + len *= sizeof(TCHAR); if (LLW == 0) { #ifdef _WIN64 +#ifdef __MINGW64__ extern HMODULE hKernel; #define GETPROC( proc ) proc = (T##proc)GetProcAddress( hKernel, #proc ) GETPROC( Wow64GetThreadContext ); @@ -58,24 +66,25 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) // Assume if one is defined, so is the other. if (Wow64GetThreadContext == 0) return; +#endif - STARTUPINFOW si; + STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); // ...ANSI32.dll\0 - CopyMemory( code, dll, len - 7*sizeof(WCHAR) ); + CopyMemory( code, dll, len - 7*sizeof(TCHAR) ); // ...ANSI-LLW.exe\0 - CopyMemory( code + len - 7*sizeof(WCHAR), L"-LLW.exe", 9*sizeof(WCHAR) ); - if (!CreateProcessW( (LPCWSTR)code, NULL, NULL, NULL, FALSE, 0, NULL, NULL, - &si, &pi )) + CopyMemory( code + len - 7*sizeof(TCHAR), L"-LLW.exe", 9*sizeof(TCHAR) ); + if (!CreateProcess( (LPCTSTR)code, NULL, NULL, NULL, FALSE, 0, NULL, NULL, + &si, &pi )) return; WaitForSingleObject( pi.hProcess, INFINITE ); GetExitCodeProcess( pi.hProcess, &LLW ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); #else - LLW = (DWORD)LoadLibraryW; + LLW = (DWORD)LoadLibrary; #endif } @@ -88,11 +97,6 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) PAGE_EXECUTE_READWRITE ); mem32 = (DWORD)(DWORD_PTR)mem; - union - { - PBYTE pB; - PDWORD pL; - } ip; ip.pB = code; *ip.pB++ = 0x68; // push eip @@ -102,7 +106,7 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) *ip.pB++ = 0x68; // push L"path\to\ANSI32.dll" *ip.pL++ = mem32 + CODESIZE; *ip.pB++ = 0xe8; // call LoadLibraryW - *ip.pL++ = LLW - (mem32 + (ip.pB+4 - code)); + *ip.pL++ = LLW - (mem32 + (DWORD)(ip.pB+4 - code)); *ip.pB++ = 0x61; // popa *ip.pB++ = 0x9d; // popf *ip.pB++ = 0xc3; // ret diff --git a/injdll64.c b/injdll64.c index d0ffb44..b6f8729 100644 --- a/injdll64.c +++ b/injdll64.c @@ -15,17 +15,21 @@ I've decided to simply keep the memory. */ -#define WIN32_LEAN_AND_MEAN -#include +#include "injdll.h" -void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) +void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCTSTR dll ) { CONTEXT context; DWORD len; LPVOID mem; DWORD64 LLW; + union + { + PBYTE pB; + PDWORD64 pL; + } ip; #define CODESIZE 92 - static BYTE code[CODESIZE+MAX_PATH] = { + static BYTE code[CODESIZE+MAX_PATH*sizeof(TCHAR)] = { 0,0,0,0,0,0,0,0, // original rip 0,0,0,0,0,0,0,0, // LoadLibraryW 0x9C, // pushfq @@ -45,7 +49,7 @@ void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) 0x41,0x56, // push r14 0x41,0x57, // push r15 0x48,0x83,0xEC,0x28, // sub rsp, 40 - 0x48,0x8D,0x0D,41,0,0,0, // lea ecx, L"path\to\ANSI.dll" + 0x48,0x8D,0x0D,41,0,0,0, // lea ecx, L"path\to\ANSI64.dll" 0xFF,0x15,-49,-1,-1,-1, // call LoadLibraryW 0x48,0x83,0xC4,0x28, // add rsp, 40 0x41,0x5F, // pop r15 @@ -68,10 +72,10 @@ void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) 0, // dword alignment for LLW, fwiw }; - len = lstrlenW( dll ) + 1; + len = lstrlen( dll ) + 1; if (len > MAX_PATH) return; - len *= sizeof(WCHAR); + len *= sizeof(TCHAR); CopyMemory( code + CODESIZE, dll, len ); len += CODESIZE; @@ -81,11 +85,6 @@ void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) PAGE_EXECUTE_READWRITE ); LLW = (DWORD64)LoadLibraryW; - union - { - PBYTE pB; - PDWORD64 pL; - } ip; ip.pB = code; *ip.pL++ = context.Rip; diff --git a/makefile.vc b/makefile.vc new file mode 100644 index 0000000..1face60 --- /dev/null +++ b/makefile.vc @@ -0,0 +1,70 @@ +# 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. + +#BITS = 32 +#BITS = 64 + +!IFNDEF BITS +BITS = 32 +!ENDIF + +!IF $(BITS) == 32 +DIR = x86 +!ELSE +!IF $(BITS) == 64 +DIR = x64 +!ELSE +!ERROR BITS should be defined to 32 or 64. +!ENDIF +!ENDIF + +CC = cl +CFLAGS = /nologo /W3 /Ox /GF /D_CRT_SECURE_NO_WARNINGS +LIBS = advapi32.lib shell32.lib user32.lib + +{}.c{$(DIR)}.obj: + $(CC) /c $(CFLAGS) /Fo$@ $< + +{}.rc{$(DIR)}.res: + rc /fo$@ $< + +all: ansicon$(BITS) + +ansicon32: x86 x86\ansicon.exe x86\ANSI32.dll + +ansicon64: x64 x64\ansicon.exe x64\ANSI64.dll x64\ANSI32.dll x64\ANSI-LLW.exe + +x86: + mkdir x86 + +x86\ansicon.exe: x86\ansicon.obj x86\injdll32.obj x86\ansicon.res + $(CC) /nologo /Fe$@ $** $(LIBS) + +x86\ANSI32.dll: x86\ANSI.obj x86\injdll32.obj x86\ansi.res +!IF $(BITS) == 32 + $(CC) /nologo /LD /Fe$@ $** $(LIBS) +!ENDIF + +x64: + mkdir x64 + +x64\ansicon.exe: x64\ansicon.obj x64\injdll64.obj x64\ansicon.res + $(CC) /nologo /Fe$@ $** $(LIBS) bufferoverflowu.lib + +x64\ANSI64.dll: x64\ANSI.obj x64\injdll64.obj x64\injdll32.obj x64\ansi.res + $(CC) /nologo /LD /Fe$@ $** $(LIBS) bufferoverflowu.lib + +x64\ANSI32.dll: x86\ANSI32.dll + copy x86\ANSI32.dll x64\ANSI32.dll + +x64\ANSI-LLW.exe: ANSI-LLW.c + $(CC) $(CFLAGS) /Fe$@ /Fo$*.obj $? bufferoverflowu.lib + +clean: + -del $(DIR)\*.obj $(DIR)\*.res diff --git a/wow64.h b/wow64.h index 6b8a1d2..33e0444 100644 --- a/wow64.h +++ b/wow64.h @@ -82,7 +82,7 @@ typedef struct _WOW64_CONTEXT { typedef WOW64_CONTEXT *PWOW64_CONTEXT; -typedef BOOL WINAPI (*TWow64GetThreadContext)( HANDLE hThread, PWOW64_CONTEXT lpContext ); -typedef BOOL WINAPI (*TWow64SetThreadContext)( HANDLE hThread, CONST WOW64_CONTEXT *lpContext ); +typedef BOOL (WINAPI *TWow64GetThreadContext)( HANDLE hThread, PWOW64_CONTEXT lpContext ); +typedef BOOL (WINAPI *TWow64SetThreadContext)( HANDLE hThread, CONST WOW64_CONTEXT *lpContext ); #endif