diff --git a/ANSI-LLW.c b/ANSI-LLW.c new file mode 100644 index 0000000..ed048b0 --- /dev/null +++ b/ANSI-LLW.c @@ -0,0 +1,16 @@ +/* + 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. +*/ + +#define WIN32_LEAN_AND_MEAN +#include + +int main( void ) +{ + return (DWORD)LoadLibraryW; +} diff --git a/ANSI.c b/ANSI.c index ee7265f..bb58a55 100644 --- a/ANSI.c +++ b/ANSI.c @@ -53,6 +53,9 @@ v1.30, 3 August to 7 September, 2010: x64 support. + + v1.31, 13 November, 2010: + fix multibyte conversion problems. */ #define UNICODE @@ -934,10 +937,10 @@ void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi, if (con) { - CHAR dll[MAX_PATH]; + WCHAR dll[MAX_PATH]; #ifdef _WIN64 - DWORD len = GetModuleFileNameA( GetModuleHandleA( "ANSI64.dll" ), - dll, sizeof(dll) ); + DWORD len = GetModuleFileName( GetModuleHandleA( "ANSI64.dll" ), + dll, lenof(dll) ); if (x86) { dll[len-6] = '3'; @@ -949,7 +952,7 @@ void Inject( LPPROCESS_INFORMATION pinfo, LPPROCESS_INFORMATION lpi, InjectDLL64( pinfo, dll ); } #else - GetModuleFileNameA( GetModuleHandleA( "ANSI32.dll" ), dll, sizeof(dll) ); + GetModuleFileName( GetModuleHandleA( "ANSI32.dll" ), dll, lenof(dll) ); InjectDLL32( pinfo, dll ); #endif } @@ -1091,28 +1094,26 @@ WINAPI MyWriteConsoleA( HANDLE hCon, LPCVOID lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved ) { - DWORD Mode; - #define BUF_SIZE 4096 - WCHAR buf[BUF_SIZE]; - DWORD len; - BOOL rc = TRUE; + DWORD Mode; + LPWSTR buf; + DWORD len; + BOOL rc = TRUE; // if we write in a console buffer with processed output if (GetConsoleMode( hCon, &Mode ) && (Mode & ENABLE_PROCESSED_OUTPUT)) { UINT cp = GetConsoleOutputCP(); DEBUGSTR( TEXT("\\WriteConsoleA: %lu \"%.*hs\""), nNumberOfCharsToWrite, nNumberOfCharsToWrite, lpBuffer ); - *lpNumberOfCharsWritten = 0; - while (nNumberOfCharsToWrite) + len = MultiByteToWideChar( cp, 0, lpBuffer, nNumberOfCharsToWrite, NULL, 0 ); + buf = malloc( len * sizeof(WCHAR) ); + if (buf == NULL) { - len = (nNumberOfCharsToWrite > BUF_SIZE) ? BUF_SIZE - : nNumberOfCharsToWrite; - MultiByteToWideChar( cp, 0, lpBuffer, len, buf, len ); - rc = ParseAndPrintString( hCon, buf, len, &Mode ); - *lpNumberOfCharsWritten += Mode; - lpBuffer += len; - nNumberOfCharsToWrite -= len; + *lpNumberOfCharsWritten = 0; + return (nNumberOfCharsToWrite == 0); } + MultiByteToWideChar( cp, 0, lpBuffer, nNumberOfCharsToWrite, buf, len ); + rc = ParseAndPrintString( hCon, buf, len, lpNumberOfCharsWritten ); + free( buf ); return rc; } else diff --git a/ansicon.c b/ansicon.c index 28d513b..531c8f2 100644 --- a/ansicon.c +++ b/ansicon.c @@ -37,10 +37,13 @@ v1.30, 3 August to 7 September, 2010: x64 support. + + v1.31, 13 November, 2010: + use LLW to fix potential Unicode path problems. */ -#define PVERS "1.30" -#define PDATE "7 September, 2010" +#define PVERS "1.31" +#define PDATE "13 November, 2010" #define UNICODE #define _UNICODE @@ -57,6 +60,8 @@ #include #include "injdll.h" +#define lenof(str) (sizeof(str)/sizeof(TCHAR)) + #ifdef __MINGW32__ int _CRT_glob = 0; #endif @@ -64,10 +69,10 @@ int _CRT_glob = 0; #ifdef _WIN64 # define InjectDLL InjectDLL64 -# define BITS "64" +# define BITS L"64" #else # define InjectDLL InjectDLL32 -# define BITS "32" +# define BITS L"32" #endif @@ -91,12 +96,12 @@ BOOL GetParentProcessInfo( LPPROCESS_INFORMATION ppi ); void Inject( LPPROCESS_INFORMATION ppi ) { DWORD len; - CHAR dll[MAX_PATH]; + WCHAR dll[MAX_PATH]; - len = GetModuleFileNameA( NULL, dll, sizeof(dll) ); + len = GetModuleFileName( NULL, dll, lenof(dll) ); while (dll[len-1] != '\\') --len; - lstrcpyA( dll + len, "ANSI" BITS ".dll" ); + lstrcpy( dll + len, L"ANSI" BITS L".dll" ); InjectDLL( ppi, dll ); } diff --git a/ansicon.rc b/ansicon.rc index 0b88235..deb2999 100644 --- a/ansicon.rc +++ b/ansicon.rc @@ -7,8 +7,8 @@ #include 1 VERSIONINFO -FILEVERSION 1,3,0,0 -PRODUCTVERSION 1,3,0,0 +FILEVERSION 1,3,1,0 +PRODUCTVERSION 1,3,1,0 FILEOS VOS_NT FILETYPE VFT_APP { @@ -19,12 +19,12 @@ FILETYPE VFT_APP VALUE "Comments", "http://ansicon.adoxa.cjb.net/" VALUE "CompanyName", "Jason Hood" VALUE "FileDescription", "ANSI Console" - VALUE "FileVersion", "1.30" + VALUE "FileVersion", "1.31" VALUE "InternalName", "ansicon" VALUE "LegalCopyright", "Freeware" VALUE "OriginalFilename", "ansicon.exe" VALUE "ProductName", "ANSICON" - VALUE "ProductVersion", "1.30" + VALUE "ProductVersion", "1.31" } } diff --git a/injdll.h b/injdll.h index 8541941..e9e1029 100644 --- a/injdll.h +++ b/injdll.h @@ -10,7 +10,7 @@ #define WIN32_LEAN_AND_MEAN #include -void InjectDLL32( LPPROCESS_INFORMATION, LPCSTR ); -void InjectDLL64( LPPROCESS_INFORMATION, LPCSTR ); +void InjectDLL32( LPPROCESS_INFORMATION, LPCWSTR ); +void InjectDLL64( LPPROCESS_INFORMATION, LPCWSTR ); #endif diff --git a/injdll32.c b/injdll32.c index 6a1f73b..105dbf2 100644 --- a/injdll32.c +++ b/injdll32.c @@ -31,23 +31,24 @@ TWow64SetThreadContext Wow64SetThreadContext; #endif -DWORD LLA; +DWORD LLW; -void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCSTR dll ) +void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) { CONTEXT context; DWORD len; LPVOID mem; DWORD mem32; #define CODESIZE 20 - BYTE code[CODESIZE+MAX_PATH]; + BYTE code[CODESIZE+MAX_PATH*sizeof(WCHAR)]; - len = lstrlenA( dll ) + 1; + len = lstrlenW( dll ) + 1; if (len > MAX_PATH) return; + len *= sizeof(WCHAR); - if (LLA == 0) + if (LLW == 0) { #ifdef _WIN64 extern HMODULE hKernel; @@ -62,18 +63,19 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCSTR dll ) PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); - CopyMemory( code, dll, len - 7 ); // ...ANSI32.dll\0 - CopyMemory( code + len - 7, "-LLA.exe", 9 ); // ...ANSI-LLA.exe\0 + // ...ANSI32.dll\0 + CopyMemory( code, dll, len - 7*sizeof(WCHAR) ); + // ...ANSI-LLA.exe\0 + CopyMemory( code + len - 7*sizeof(WCHAR), L"-LLA.exe", 9*sizeof(WCHAR) ); if (!CreateProcess( (char*)code, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) return; WaitForSingleObject( pi.hProcess, INFINITE ); - GetExitCodeProcess( pi.hProcess, &LLA ); + GetExitCodeProcess( pi.hProcess, &LLW ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); #else - LLA = (DWORD)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), - "LoadLibraryA" ); + LLW = (DWORD)LoadLibraryW; #endif } @@ -97,10 +99,10 @@ void InjectDLL32( LPPROCESS_INFORMATION ppi, LPCSTR dll ) *ip.pL++ = context.Eip; *ip.pB++ = 0x9c; // pushf *ip.pB++ = 0x60; // pusha - *ip.pB++ = 0x68; // push "path\to\ANSI32.dll" + *ip.pB++ = 0x68; // push L"path\to\ANSI32.dll" *ip.pL++ = mem32 + CODESIZE; - *ip.pB++ = 0xe8; // call LoadLibraryA - *ip.pL++ = LLA - (mem32 + (ip.pB+4 - code)); + *ip.pB++ = 0xe8; // call LoadLibraryW + *ip.pL++ = LLW - (mem32 + (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 0a04140..d0ffb44 100644 --- a/injdll64.c +++ b/injdll64.c @@ -18,16 +18,16 @@ #define WIN32_LEAN_AND_MEAN #include -void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCSTR dll ) +void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCWSTR dll ) { CONTEXT context; DWORD len; LPVOID mem; - DWORD64 LLA; + DWORD64 LLW; #define CODESIZE 92 static BYTE code[CODESIZE+MAX_PATH] = { 0,0,0,0,0,0,0,0, // original rip - 0,0,0,0,0,0,0,0, // LoadLibraryA + 0,0,0,0,0,0,0,0, // LoadLibraryW 0x9C, // pushfq 0x50, // push rax 0x51, // push rcx @@ -45,8 +45,8 @@ void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCSTR 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, "path\to\ANSI.dll" - 0xFF,0x15,-49,-1,-1,-1, // call LoadLibraryA + 0x48,0x8D,0x0D,41,0,0,0, // lea ecx, L"path\to\ANSI.dll" + 0xFF,0x15,-49,-1,-1,-1, // call LoadLibraryW 0x48,0x83,0xC4,0x28, // add rsp, 40 0x41,0x5F, // pop r15 0x41,0x5E, // pop r14 @@ -65,12 +65,13 @@ void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCSTR dll ) 0x58, // pop rax 0x9D, // popfq 0xFF,0x25,-91,-1,-1,-1, // jmp original Rip - 0, // dword alignment for LLA, fwiw + 0, // dword alignment for LLW, fwiw }; - len = lstrlenA( dll ) + 1; + len = lstrlenW( dll ) + 1; if (len > MAX_PATH) return; + len *= sizeof(WCHAR); CopyMemory( code + CODESIZE, dll, len ); len += CODESIZE; @@ -78,8 +79,7 @@ void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCSTR dll ) GetThreadContext( ppi->hThread, &context ); mem = VirtualAllocEx( ppi->hProcess, NULL, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); - LLA = (DWORD64)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), - "LoadLibraryA" ); + LLW = (DWORD64)LoadLibraryW; union { @@ -89,7 +89,7 @@ void InjectDLL64( LPPROCESS_INFORMATION ppi, LPCSTR dll ) ip.pB = code; *ip.pL++ = context.Rip; - *ip.pL++ = LLA; + *ip.pL++ = LLW; WriteProcessMemory( ppi->hProcess, mem, code, len, NULL ); FlushInstructionCache( ppi->hProcess, mem, len ); diff --git a/makefile b/makefile index d8c4452..6f0d86a 100644 --- a/makefile +++ b/makefile @@ -22,9 +22,12 @@ x64/%v.o: %.rc all: ansicon32 ansicon64 -ansicon32: x86/ansicon.exe x86/ANSI32.dll +ansicon32: x86 x86/ansicon.exe x86/ANSI32.dll -ansicon64: x64/ansicon.exe x64/ANSI64.dll x64/ANSI32.dll x64/ANSI-LLA.exe +ansicon64: x64 x64/ansicon.exe x64/ANSI64.dll x64/ANSI32.dll x64/ANSI-LLW.exe + +x86: + mkdir x86 x86/ansicon.exe: x86/ansicon.o x86/injdll32.o x86/ansiconv.o $(CC) -m32 $+ -s -o $@ @@ -32,6 +35,9 @@ x86/ansicon.exe: x86/ansicon.o x86/injdll32.o x86/ansiconv.o x86/ANSI32.dll: x86/ANSI.o x86/injdll32.o x86/ansiv.o $(CC) -m32 $+ -s -o $@ -mdll -Wl,-shared +x64: + mkdir x64 + x64/ansicon.exe: x64/ansicon.o x64/injdll64.o x64/ansiconv.o $(CC) $+ -s -o $@ @@ -39,9 +45,9 @@ x64/ANSI64.dll: x64/ANSI.o x64/injdll64.o x64/injdll32.o x64/ansiv.o $(CC) $+ -s -o $@ -mdll -Wl,-shared x64/ANSI32.dll: x86/ANSI32.dll - cmd /c copy x86\ANSI32.dll x64\ANSI32.dll + cp -p x86/ANSI32.dll x64/ANSI32.dll -x64/ANSI-LLA.exe: ANSI-LLA.c +x64/ANSI-LLW.exe: ANSI-LLW.c $(CC) -m32 $(CFLAGS) $< -s -o $@ x86/ansiconv.o: ansicon.rc @@ -50,4 +56,5 @@ x64/ansiconv.o: ansicon.rc x64/ansiv.o: ansi.rc clean: - -cmd /c "del x86\*.o x64\*.o" + -rm x86/*.o + -rm x64/*.o diff --git a/readme.txt b/readme.txt index d9ab8b8..73457da 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Copyright 2005-2010 Jason Hood - Version 1.30. Freeware + Version 1.31. Freeware =========== @@ -39,6 +39,7 @@ --------- Delete ANSI.dll, it has been replaced with ANSI32.dll. + Delete ANSI-LLA.dll, it has been replaced with ANSI-LLW.dll. ===== @@ -121,6 +122,10 @@ Legend: + added, - bug-fixed, * changed. + 1.31 - 13 November, 2010: + - fixed multibyte support (no extra junk with UTF-8 files); + * fixed potential problem if install path uses Unicode. + 1.30 - 7 September, 2010: + x64 version. @@ -233,4 +238,4 @@ ============================== - Jason Hood, 7 September, 2010. + Jason Hood, 13 November, 2010. diff --git a/x64/ANSI-LLA.exe b/x64/ANSI-LLA.exe deleted file mode 100644 index 42afd66..0000000 Binary files a/x64/ANSI-LLA.exe and /dev/null differ diff --git a/x64/ANSI32.dll b/x64/ANSI32.dll deleted file mode 100644 index b1cf2fd..0000000 Binary files a/x64/ANSI32.dll and /dev/null differ diff --git a/x64/ANSI64.dll b/x64/ANSI64.dll deleted file mode 100644 index 955a5c0..0000000 Binary files a/x64/ANSI64.dll and /dev/null differ diff --git a/x64/ansicon.exe b/x64/ansicon.exe deleted file mode 100644 index d01f8b3..0000000 Binary files a/x64/ansicon.exe and /dev/null differ diff --git a/x86/ANSI32.dll b/x86/ANSI32.dll deleted file mode 100644 index b1cf2fd..0000000 Binary files a/x86/ANSI32.dll and /dev/null differ diff --git a/x86/ansicon.exe b/x86/ansicon.exe deleted file mode 100644 index ebc26c3..0000000 Binary files a/x86/ansicon.exe and /dev/null differ