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
	 Jason Hood
						Jason Hood