168 lines
5.0 KiB
C
168 lines
5.0 KiB
C
/********************************************************************************
|
|
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
|
********************************************************************************/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <shellapi.h>
|
|
|
|
#ifdef _WIN64
|
|
typedef unsigned __int64 UPARAM;
|
|
#else
|
|
typedef unsigned long UPARAM;
|
|
#endif
|
|
|
|
typedef HANDLE (WINAPI *CRTPROC)(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);
|
|
typedef BOOL (WINAPI *WPMPROC)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);
|
|
|
|
BOOL WINAPI InjectLibrary(HANDLE hProcess, const wchar_t *pDLL, DWORD dwLen)
|
|
{
|
|
DWORD dwTemp, dwSize, lastError;
|
|
BOOL bSuccess, bRet = 0;
|
|
HANDLE hThread = NULL;
|
|
LPVOID pStr = NULL;
|
|
UPARAM procAddress;
|
|
SIZE_T writtenSize;
|
|
char pWPMStr[19], pCRTStr[19];
|
|
int i;
|
|
|
|
WPMPROC pWriteProcessMemory;
|
|
CRTPROC pCreateRemoteThread;
|
|
HMODULE hK32;
|
|
|
|
if (!hProcess) return 0;
|
|
|
|
dwSize = (dwLen+1) * sizeof(wchar_t);
|
|
|
|
memcpy(pWPMStr, "X}f{j_}`lj||Bjb`}v", 19); //WriteProcessMemory with each character xor'ed by 15
|
|
memcpy(pCRTStr, "L}jn{j]jb`{j[g}jnk", 19); //CreateRemoteThread with each character xor'ed by 15
|
|
|
|
for(i=0; i<18; i++) pWPMStr[i] ^= 15;
|
|
for(i=0; i<18; i++) pCRTStr[i] ^= 15;
|
|
|
|
hK32 = GetModuleHandle(TEXT("KERNEL32"));
|
|
|
|
pWriteProcessMemory = (WPMPROC)GetProcAddress(hK32, pWPMStr);
|
|
pCreateRemoteThread = (CRTPROC)GetProcAddress(hK32, pCRTStr);
|
|
|
|
pStr = (LPVOID)VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
if (!pStr) goto end;
|
|
|
|
bSuccess = (*pWriteProcessMemory)(hProcess, pStr, (LPVOID)pDLL, dwSize, &writtenSize);
|
|
if (!bSuccess) goto end;
|
|
|
|
procAddress = (UPARAM)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), "LoadLibraryW");
|
|
if (!procAddress) goto end;
|
|
|
|
hThread = (*pCreateRemoteThread)(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)procAddress,
|
|
pStr, 0, &dwTemp);
|
|
if (!hThread) goto end;
|
|
|
|
if (WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0)
|
|
{
|
|
DWORD dw;
|
|
GetExitCodeThread(hThread, &dw);
|
|
bRet = dw != 0;
|
|
|
|
SetLastError(0);
|
|
}
|
|
|
|
end:
|
|
if (!bRet)
|
|
lastError = GetLastError();
|
|
|
|
if (hThread)
|
|
CloseHandle(hThread);
|
|
|
|
if (pStr)
|
|
VirtualFreeEx(hProcess, pStr, 0, MEM_RELEASE);
|
|
|
|
if (!bRet)
|
|
SetLastError(lastError);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nShowCmd)
|
|
{
|
|
LPWSTR pCommandLineW = GetCommandLineW();
|
|
int retVal = 0;
|
|
DWORD procID = 0;
|
|
int numArgs = 0;
|
|
|
|
#ifdef _WIN64
|
|
const wchar_t pDLLName[] = L"GraphicsCaptureHook64.dll";
|
|
#else
|
|
const wchar_t pDLLName[] = L"GraphicsCaptureHook.dll";
|
|
#endif
|
|
|
|
/* -------------------------- */
|
|
|
|
LPWSTR *pCommandLineArgs = CommandLineToArgvW(pCommandLineW, &numArgs);
|
|
if (numArgs > 1)
|
|
{
|
|
procID = wcstoul(pCommandLineArgs[1], NULL, 10);
|
|
if (procID != 0)
|
|
{
|
|
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
|
|
if (hProcess)
|
|
{
|
|
UINT dirLen = GetCurrentDirectory(0, 0); /* includes null terminator */
|
|
const UINT fileNameLen = (sizeof(pDLLName) / sizeof(wchar_t))-1;
|
|
UINT len = dirLen + fileNameLen + 1; /* 1 for '/' */
|
|
wchar_t *pPath;
|
|
|
|
/* -------------------------- */
|
|
|
|
if (dirLen)
|
|
{
|
|
pPath = (wchar_t*)malloc(len * sizeof(wchar_t));
|
|
memset(pPath, 0, len * sizeof(wchar_t));
|
|
|
|
GetCurrentDirectoryW(dirLen, pPath);
|
|
pPath[dirLen-1] = '\\';
|
|
wcsncpy(pPath+dirLen, pDLLName, fileNameLen);
|
|
|
|
if(!InjectLibrary(hProcess, pPath, len-1))
|
|
{
|
|
retVal = GetLastError();
|
|
if(!retVal)
|
|
retVal = -5;
|
|
}
|
|
|
|
free(pPath);
|
|
}
|
|
else
|
|
retVal = -4;
|
|
|
|
CloseHandle(hProcess);
|
|
}
|
|
else
|
|
retVal = -3;
|
|
}
|
|
else
|
|
retVal = -2;
|
|
}
|
|
else
|
|
retVal = -1;
|
|
|
|
LocalFree(pCommandLineArgs);
|
|
|
|
return retVal;
|
|
}
|