Add option -pu to unload from the parent

This commit is contained in:
Jason Hood 2017-11-30 21:05:41 +10:00
parent 523c478d67
commit 1a4d6b488f
3 changed files with 78 additions and 41 deletions

9
ANSI.c
View File

@ -1928,8 +1928,13 @@ BOOL HookAPIAllMod( PHookFn Hooks, BOOL restore, BOOL indent )
} }
else else
{ {
if (*(PDWORD)((PBYTE)me.hModule + 36) != 'ISNA' && if (*(PDWORD)((PBYTE)me.hModule + 36) == 'ISNA')
*(PDWORD)((PBYTE)me.hModule + 0x3C) >= 0x40) {
VirtualProtect( (PBYTE)me.hModule + 36, 4, PAGE_READWRITE, &pr );
*((PBYTE)me.hModule + 36+3) = 'U';
VirtualProtect( (PBYTE)me.hModule + 36, 4, pr, &pr );
}
else if (*(PDWORD)((PBYTE)me.hModule + 0x3C) >= 0x40)
{ {
if (log_level & 16) if (log_level & 16)
DEBUGSTR( 2, "%s%s %S", sp, zSkipping, me.szModule ); DEBUGSTR( 2, "%s%s %S", sp, zSkipping, me.szModule );

View File

@ -86,8 +86,9 @@
log: 64-bit addresses get an underscore between the 8-digit groups; log: 64-bit addresses get an underscore between the 8-digit groups;
add error codes to some message. add error codes to some message.
v1.80, 28 October, 2017: v1.80, 28 October & 30 November, 2017:
write newline with _putws, not putwchar (fixes redirecting to CON). write newline with _putws, not putwchar (fixes redirecting to CON);
use -pu to unload from the parent.
*/ */
#define PDATE L"30 November, 2017" #define PDATE L"30 November, 2017"
@ -217,15 +218,16 @@ BOOL Inject( LPPROCESS_INFORMATION ppi, BOOL* gui, LPCTSTR app )
} }
// Use CreateRemoteThread to load our DLL in the target process. // Use CreateRemoteThread to (un)load our DLL in the target process.
void RemoteLoad( LPPROCESS_INFORMATION ppi, LPCTSTR app ) void RemoteLoad( LPPROCESS_INFORMATION ppi, LPCTSTR app, BOOL unload )
{ {
HANDLE hSnap; HANDLE hSnap;
MODULEENTRY32 me; MODULEENTRY32 me;
PBYTE LLW; PBYTE proc;
DWORD rva;
BOOL fOk; BOOL fOk;
DWORD len; DWORD len;
LPVOID mem; LPVOID param;
HANDLE thread; HANDLE thread;
DWORD ticks; DWORD ticks;
#ifdef _WIN64 #ifdef _WIN64
@ -262,48 +264,71 @@ void RemoteLoad( LPPROCESS_INFORMATION ppi, LPCTSTR app )
fputws( L"ANSICON: unable to inject into parent.\n", stderr ); fputws( L"ANSICON: unable to inject into parent.\n", stderr );
return; return;
} }
LLW = NULL; proc = param = NULL;
me.dwSize = sizeof(MODULEENTRY32);
for (fOk = Module32First( hSnap, &me ); fOk; fOk = Module32Next( hSnap, &me ))
{
if (_wcsicmp( me.szModule, L"kernel32.dll" ) == 0)
{
LLW = me.modBaseAddr;
break;
}
}
CloseHandle( hSnap );
if (LLW == NULL)
{
DEBUGSTR( 1, " Unable to locate kernel32.dll" );
goto no_go;
}
len = (DWORD)(prog - prog_path); len = (DWORD)(prog - prog_path);
memcpy( DllName, prog_path, TSIZE(len) ); memcpy( DllName, prog_path, TSIZE(len) );
#ifdef _WIN64 #ifdef _WIN64
type = (IsWow64Process( ppi->hProcess, &WOW64 ) && WOW64) ? 32 : 64; type = (IsWow64Process( ppi->hProcess, &WOW64 ) && WOW64) ? 32 : 64;
wsprintf( DllName + len, L"ANSI%d.dll", type ); wsprintf( DllName + len, L"ANSI%d.dll", type );
LLW += GetProcRVA( L"kernel32.dll", "LoadLibraryW", type ); #endif
me.dwSize = sizeof(MODULEENTRY32);
for (fOk = Module32First( hSnap, &me ); fOk; fOk = Module32Next( hSnap, &me ))
{
if (_wcsicmp( me.szModule, L"kernel32.dll" ) == 0)
{
proc = me.modBaseAddr;
if (!unload)
break;
}
else if (unload)
{
#ifdef _WIN64
if (_wcsicmp( me.szModule, DllName + len ) == 0)
#else
if (_wcsicmp( me.szModule, L"ANSI32.dll" ) == 0)
#endif
param = me.modBaseAddr;
}
}
CloseHandle( hSnap );
if (proc == NULL)
{
DEBUGSTR( 1, " Unable to locate kernel32.dll" );
goto no_go;
}
if (unload && param == NULL)
{
DEBUGSTR( 1, " Unable to locate ANSICON's DLL" );
return;
}
#ifdef _WIN64
rva = GetProcRVA( L"kernel32.dll", (unload) ? "FreeLibrary"
: "LoadLibraryW", type );
#else #else
wcscpy( DllName + len, L"ANSI32.dll" ); wcscpy( DllName + len, L"ANSI32.dll" );
LLW += GetProcRVA( L"kernel32.dll", "LoadLibraryW" ); rva = GetProcRVA( L"kernel32.dll", unload ? "FreeLibrary" : "LoadLibraryW" );
#endif #endif
if (LLW == me.modBaseAddr) if (rva == 0)
goto no_go; goto no_go;
proc += rva;
mem = VirtualAllocEx( ppi->hProcess, NULL, len, MEM_COMMIT, PAGE_READWRITE ); if (!unload)
if (mem == NULL) {
param = VirtualAllocEx(ppi->hProcess, NULL, len, MEM_COMMIT,PAGE_READWRITE);
if (param == NULL)
{ {
DEBUGSTR(1, " Failed to allocate virtual memory (%u)", GetLastError()); DEBUGSTR(1, " Failed to allocate virtual memory (%u)", GetLastError());
goto no_go; goto no_go;
} }
WriteProcMem( mem, DllName, TSIZE(len + 11) ); WriteProcMem( param, DllName, TSIZE(len + 11) );
}
thread = CreateRemoteThread( ppi->hProcess, NULL, 4096, thread = CreateRemoteThread( ppi->hProcess, NULL, 4096,
(LPTHREAD_START_ROUTINE)LLW, mem, 0, NULL ); (LPTHREAD_START_ROUTINE)proc, param, 0, NULL );
WaitForSingleObject( thread, INFINITE ); WaitForSingleObject( thread, INFINITE );
CloseHandle( thread ); CloseHandle( thread );
VirtualFreeEx( ppi->hProcess, mem, 0, MEM_RELEASE ); if (!unload)
VirtualFreeEx( ppi->hProcess, param, 0, MEM_RELEASE );
} }
@ -412,11 +437,13 @@ int main( void )
// else fall through // else fall through
case 'p': case 'p':
{
BOOL unload = (arg[1] == 'p' && arg[2] == 'u');
shell = FALSE; shell = FALSE;
if (GetParentProcessInfo( &pi, arg )) if (GetParentProcessInfo( &pi, arg ))
{ {
pi.hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); pi.hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
RemoteLoad( &pi, arg ); RemoteLoad( &pi, arg, unload );
CloseHandle( pi.hProcess ); CloseHandle( pi.hProcess );
} }
else else
@ -425,6 +452,7 @@ int main( void )
rc = 1; rc = 1;
} }
break; break;
}
case 'm': case 'm':
{ {
@ -918,7 +946,7 @@ L"http://ansicon.adoxa.vze.com/\n"
L"\n" L"\n"
L"Process ANSI escape sequences in " WINTYPE L" console programs.\n" L"Process ANSI escape sequences in " WINTYPE L" console programs.\n"
L"\n" L"\n"
L"ansicon [-l<level>] [-i] [-I] [-u] [-U] [-m[<attr>]] [-p]\n" L"ansicon [-l<level>] [-i] [-I] [-u] [-U] [-m[<attr>]] [-p[u]]\n"
L" [-e|E string | -t|T [file(s)] | program [args]]\n" L" [-e|E string | -t|T [file(s)] | program [args]]\n"
L"\n" L"\n"
L" -l\t\tset the logging level (1=process, 2=module, 3=function,\n" L" -l\t\tset the logging level (1=process, 2=module, 3=function,\n"
@ -928,6 +956,7 @@ L" -u\t\tuninstall - remove ANSICON from the AutoRun entry\n"
L" -I -U\t\tuse local machine instead of current user\n" L" -I -U\t\tuse local machine instead of current user\n"
L" -m\t\tuse grey on black (\"monochrome\") or <attr> as default color\n" L" -m\t\tuse grey on black (\"monochrome\") or <attr> as default color\n"
L" -p\t\thook into the parent process\n" L" -p\t\thook into the parent process\n"
L" -pu\t\tunhook from the parent process\n"
L" -e\t\techo string\n" L" -e\t\techo string\n"
L" -E\t\techo string, don't append newline\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 (\"-\" for stdin), combined as a single stream\n"

View File

@ -52,6 +52,8 @@ Usage
-p Enable the parent process (i.e. the command shell used to run -p Enable the parent process (i.e. the command shell used to run
ANSICON) to recognise escapes. ANSICON) to recognise escapes.
-pu Unload from the parent process, restoring it.
-m Set the current (and default) attribute to grey on black -m Set the current (and default) attribute to grey on black
("monochrome"), or the attribute following the 'm' (please ("monochrome"), or the attribute following the 'm' (please
use 'COLOR /?' for attribute values). use 'COLOR /?' for attribute values).
@ -316,7 +318,8 @@ Version History
+ use the system default sound for the bell; + use the system default sound for the bell;
+ added Play Sound DECPS; + added Play Sound DECPS;
+ added '+' intermediate byte to use the buffer, rather than the window; + added '+' intermediate byte to use the buffer, rather than the window;
+ added palette sequences. + added palette sequences;
+ added -pu to unload from the parent.
1.72 - 24 December, 2015: 1.72 - 24 December, 2015:
- handle STD_OUTPUT_HANDLE & STD_ERROR_HANDLE in WriteFile; - handle STD_OUTPUT_HANDLE & STD_ERROR_HANDLE in WriteFile;