@@ -0,0 +1,208 @@
//===============================================================================================//
// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "LoadLibraryR.h"
#include "GetProcAddressR.h"
#pragma comment(lib,"Advapi32.lib")
#define BREAK_WITH_ERROR ( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; }
void ReadFromPipe (HANDLE hSTD_OUT_Read )
{
puts ("[*] Started reading" );
BOOL ok = FALSE;
LPVOID pOutputBuffer = NULL ;
UCHAR buf [1025 ] = { 0 };
DWORD dwBufferSize = 0 ,
dwRead = 0 ;
pOutputBuffer = LocalAlloc (LPTR , 1024 );
do
{
ok = ReadFile (hSTD_OUT_Read , buf , 1024 , & dwRead , NULL );
if (dwRead == 0 )
break ;
pOutputBuffer = LocalReAlloc (
pOutputBuffer ,
dwBufferSize + dwRead ,
LMEM_MOVEABLE | LMEM_ZEROINIT
);
dwBufferSize += dwRead ;
memcpy ( (char * )pOutputBuffer + (dwBufferSize - dwRead ), buf , dwRead );
memset (buf , 0 , dwRead );
} while (ok == TRUE);
printf ("[+] Output:\n%s\n" , pOutputBuffer );
memset (pOutputBuffer , 0 , dwBufferSize );
LocalFree (pOutputBuffer );
pOutputBuffer = NULL ;
}
// Simple app to inject a reflective DLL into a process vis its process ID.
int main ( int argc , char * argv [] )
{
HANDLE hFile = NULL ;
LPVOID lpBuffer = NULL ;
DWORD dwLength = 0 ;
DWORD dwBytesRead = 0 ;
HANDLE hToken ;
TOKEN_PRIVILEGES priv = {0 };
#ifdef WIN_X64
char * cpDllFile = "reflective_dll.x64.dll" ;
#else
#ifdef WIN_X86
char * cpDllFile = "reflective_dll.dll" ;
#else WIN_ARM
char * cpDllFile = "reflective_dll.arm.dll" ;
#endif
#endif
HANDLE hProcess = NULL ;
if (argc < 2 )
{
printf ("[x] Please specify child process path: inject.x64.exe c:\\windows\\system32\\rundll32.exe\n" );
return 0 ;
}
do
{
LPCSTR cpCommandLine = "hello from injector" ;
hFile = CreateFileA ( cpDllFile , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
if ( hFile == INVALID_HANDLE_VALUE )
BREAK_WITH_ERROR ( "Failed to open the DLL file" );
dwLength = GetFileSize ( hFile , NULL );
if ( dwLength == INVALID_FILE_SIZE || dwLength == 0 )
BREAK_WITH_ERROR ( "Failed to get the DLL file size" );
lpBuffer = HeapAlloc ( GetProcessHeap (), 0 , dwLength );
if ( !lpBuffer )
BREAK_WITH_ERROR ( "Failed to get the DLL file size" );
if ( ReadFile ( hFile , lpBuffer , dwLength , & dwBytesRead , NULL ) == FALSE )
BREAK_WITH_ERROR ( "Failed to alloc a buffer!" );
if ( OpenProcessToken ( GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , & hToken ) )
{
priv .PrivilegeCount = 1 ;
priv .Privileges [0 ].Attributes = SE_PRIVILEGE_ENABLED ;
if ( LookupPrivilegeValue ( NULL , SE_DEBUG_NAME , & priv .Privileges [0 ].Luid ) )
AdjustTokenPrivileges ( hToken , FALSE, & priv , 0 , NULL , NULL );
CloseHandle ( hToken );
}
// Child Process
puts ("[*] Setup for child process" );
HANDLE hStdInPipeRead = NULL ;
HANDLE hStdInPipeWrite = NULL ;
HANDLE hStdOutPipeRead = NULL ;
HANDLE hStdOutPipeWrite = NULL ;
SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES ), NULL , TRUE };
if ( !CreatePipe (& hStdInPipeRead , & hStdInPipeWrite , & sa , 0 ) )
{
printf ("[-] Failed Input pipe: %d\n" , GetLastError ());
return -1 ;
}
if ( !CreatePipe (& hStdOutPipeRead , & hStdOutPipeWrite , & sa , 0 ) )
{
printf ("[-] Failed Output pipe: %d\n" , GetLastError ());
return -1 ;
}
STARTUPINFOA si = { 0 };
si .cb = sizeof (STARTUPINFOA );
si .dwFlags = STARTF_USESTDHANDLES ;
si .hStdError = hStdOutPipeWrite ;
si .hStdOutput = hStdOutPipeWrite ;
si .hStdInput = hStdInPipeRead ;
PROCESS_INFORMATION pi = { 0 };
if ( !CreateProcessA (NULL , argv [1 ], NULL , NULL , TRUE, CREATE_NO_WINDOW | CREATE_SUSPENDED , NULL , NULL , & si , & pi ) )
{
return -1 ;
}
printf ("[*] Created child process in suspended state: %d\n" , pi .dwProcessId );
/*LPVOID lpRemoteCommandLine = VirtualAllocEx(hProcess, NULL, strlen(cpCommandLine) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!lpRemoteCommandLine)
BREAK_WITH_ERROR("[INJECT] inject_dll. VirtualAllocEx 1 failed");
if (!WriteProcessMemory(hProcess, lpRemoteCommandLine, cpCommandLine, strlen(cpCommandLine) + 1, NULL))
BREAK_WITH_ERROR("[INJECT] inject_dll. WriteProcessMemory 1 failed");*/
puts ("[*] Press enter to inject..." );
getchar ();
HANDLE hModule = LoadRemoteLibraryR ( pi .hProcess , lpBuffer , dwLength , NULL );
printf ("[*] Resumed process thread: %d\n" , ResumeThread (pi .hThread ));
WaitForSingleObject (hModule , -1 );
// Handling output from process
CloseHandle (hStdOutPipeWrite );
CloseHandle (hStdInPipeRead );
ReadFromPipe (hStdOutPipeRead );
CloseHandle (hStdOutPipeRead );
CloseHandle (hStdInPipeWrite );
DWORD ExitCode = 0 ;
GetExitCodeProcess (pi .hProcess , & ExitCode );
printf ("[*] Process Exit code: %d\n" , ExitCode );
} while ( 0 );
if ( lpBuffer )
HeapFree ( GetProcessHeap (), 0 , lpBuffer );
return 0 ;
}