📄 inject.c
字号:
/***********************************************************
* Restore the subclassed remote process window procedure. *
* Return: 0=failure, 1=success *
***********************************************************/
#pragma optimize("", off)
#pragma check_stack(off)
static DWORD WINAPI EjectFunc (INJDATA *pData)
{
return (pData->fnSetWindowLong(pData->hwnd, GWL_WNDPROC, (long)pData->fnOldSASWndProc) != 0);
}
static int AfterEjectFunc(void) {return 3;}
/**************************************************************
* Return the window handle of the remote process (Winlogon). *
**************************************************************/
#pragma optimize("", off)
#pragma check_stack(off)
static HWND WINAPI GetSASWnd (INJDATA *pData)
{
return (pData->fnFindWindow(pData->szClassName, pData->szWindowName));
}
static int AfterGetSASWnd(void) {return 4;}
/***************************************************************************
* Copies InjectFunc(), GetSASWnd() , SASWindowProc() and INJDATA to the *
* remote process. *
* Starts the execution of the remote InjectFunc(), which subclasses the *
* remote process default window procedure handler. *
* *
* Return value: 0=failure, 1=success *
***************************************************************************/
int InjectCode ()
{
HANDLE hProcess = 0; // Process handle
HMODULE hUser32 = 0; // Handle of user32.dll
BYTE *pCodeRemote; // Address of InjectFunc() in the remote process.
BYTE *pGetSASWndRemote; // Address of GetSASWnd() in the remote process.
HANDLE hThread = 0; // The handle and ID of the thread executing
DWORD dwThreadId = 0; // the remote InjectFunc().
INJDATA DataLocal; // INJDATA structure
BOOL fUnicode; // TRUE if remote process is Unicode
int nSuccess = 0; // Subclassing succeded?
DWORD dwNumBytesCopied = 0; // Number of bytes written to the remote process.
DWORD size; // Calculated function size (= AfterFunc() - Func())
int SearchSize; // SASWindowProc() dummy addr. search size
int nDummyOffset; // Offset in SASWindowProc() of dummy addr.
BOOL FoundDummyAddr; // Dummy INJDATA reference found in SASWindowProc() ?
HWND hSASWnd; // Window handle of Winlogon process
BYTE *p;
// Enable Debug privilege (needed for some processes)
if (!EnablePrivilege(SE_DEBUG_NAME, TRUE))
return 0;
// Get handle of "USER32.DLL"
hUser32 = GetModuleHandle("user32");
if (!hUser32)
return 0;
// Get remote process ID
PID = GetPIDFromName(szProcessName);
if (PID == -1)
return 0;
// Open remote process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if (!hProcess)
return 0;
__try
{
// Initialize INJDATA for GetSASWnd() call
strcpy(DataLocal.szClassName, "SAS Window class");
strcpy(DataLocal.szWindowName, "SAS window");
DataLocal.fnFindWindow = (FINDWINDOW) GetProcAddress(hUser32, "FindWindowA");
if (DataLocal.fnFindWindow == NULL)
__leave;
// Allocate memory in the remote process and write a copy of initialized INJDATA into it
size = sizeof(INJDATA);
pDataRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pDataRemote)
__leave;
if (!WriteProcessMemory(hProcess, pDataRemote, &DataLocal, size, &dwNumBytesCopied) || dwNumBytesCopied != size)
__leave;
// Allocate memory in remote process and write a copy of GetSASWnd() into it
size = (PBYTE)AfterGetSASWnd - (PBYTE)GetSASWnd;
pGetSASWndRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pGetSASWndRemote)
__leave;
if (!WriteProcessMemory(hProcess, pGetSASWndRemote, &GetSASWnd, size, &dwNumBytesCopied) || dwNumBytesCopied != size)
__leave;
// Start execution of remote GetSASWnd()
hThread = CreateRemoteThread(hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE) pGetSASWndRemote,
pDataRemote,
0 ,
&dwThreadId);
// Failed
if (!hThread)
__leave;
// Wait for GetSASWnd() to terminate and get return code (SAS Wnd handle)
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &hSASWnd);
// Didn't found "SAS window"
if (!hSASWnd)
__leave;
// Cleanup
VirtualFreeEx(hProcess, pGetSASWndRemote, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE);
pGetSASWndRemote = NULL;
pDataRemote = NULL;
// Allocate memory in remote process and write a copy of SASWindowProc() into it
size = (PBYTE)AfterSASWindowProc - (PBYTE)SASWindowProc;
pSASWinProcRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pSASWinProcRemote)
__leave;
if (!WriteProcessMemory(hProcess, pSASWinProcRemote, &SASWindowProc, size, &dwNumBytesCopied) || dwNumBytesCopied != size)
__leave;
// Is remote process unicode ?
fUnicode = IsWindowUnicode(hSASWnd);
// Initialize the INJDATA structure
DataLocal.fnSetWindowLong = (SETWINDOWLONG) GetProcAddress(hUser32, fUnicode ? "SetWindowLongW" : "SetWindowLongA");
DataLocal.fnCallWindowProc = (CALLWINDOWPROC) GetProcAddress(hUser32, fUnicode ? "CallWindowProcW": "CallWindowProcA");
DataLocal.fnSASWndProc = (WNDPROC) pSASWinProcRemote;
DataLocal.hwnd = hSASWnd;
if (DataLocal.fnSetWindowLong == NULL ||
DataLocal.fnCallWindowProc == NULL)
{
__leave;
}
// Allocate memory in the remote process and write a copy of initialized INJDATA into it
size = sizeof(INJDATA);
pDataRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pDataRemote)
__leave;
if (!WriteProcessMemory(hProcess, pDataRemote, &DataLocal, size, &dwNumBytesCopied) || dwNumBytesCopied != size)
__leave;
// Change dummy INJDATA address in SASWindowProc() by the real INJDATA pointer
p = (PBYTE)&SASWindowProc;
size = (PBYTE)AfterSASWindowProc - (PBYTE)SASWindowProc;
SearchSize = size - sizeof(DWORD) + 1;
FoundDummyAddr = FALSE;
for (; SearchSize > 0; p++, SearchSize--)
{
if (*(DWORD *)p == DUMMY_ADDR) // Found
{
nDummyOffset = p - (PBYTE)&SASWindowProc;
if (!WriteProcessMemory(hProcess, pSASWinProcRemote + nDummyOffset, &pDataRemote, sizeof(pDataRemote), &dwNumBytesCopied) ||
dwNumBytesCopied != sizeof(pDataRemote))
{
__leave;
}
FoundDummyAddr = TRUE;
break;
}
}
// Couldn't change the dummy INJDATA addr. by the real addr. in SASWindowProc() !?!
// Don't execute the remote copy of SASWindowProc() because the pData pointer is invalid !
if (!FoundDummyAddr)
{
__leave;
}
// Allocate memory in the remote process and write a copy of InjectFunc() to the allocated memory
size = (PBYTE)AfterInjectFunc - (PBYTE)InjectFunc;
pCodeRemote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pCodeRemote)
__leave;
if (!WriteProcessMemory(hProcess, pCodeRemote, &InjectFunc, size, &dwNumBytesCopied) || dwNumBytesCopied != size)
__leave;
// Start execution of remote InjectFunc()
hThread = CreateRemoteThread(hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE) pCodeRemote,
pDataRemote,
0 ,
&dwThreadId);
if (!hThread)
__leave;
// Wait for InjectFunc() to terminate and get return code
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &nSuccess);
// InjectFunc() successfull
// if (nSuccess)
// MessageBeep(0);
}
__finally
{
// Failed ?
if (!nSuccess)
{
// Release memory for INJDATA and SASWindowProc()
if (pDataRemote)
VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE);
if (pSASWinProcRemote)
VirtualFreeEx(hProcess, pSASWinProcRemote, 0, MEM_RELEASE);
pDataRemote = NULL;
pSASWinProcRemote = NULL;
}
// Release remote GetSASWnd()
if (pGetSASWndRemote)
VirtualFreeEx(hProcess, pGetSASWndRemote, 0, MEM_RELEASE);
// Release remote InjectFunc() (no longer needed)
if (pCodeRemote)
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
if (hThread)
CloseHandle(hThread);
}
CloseHandle(hProcess);
// Disable the DEBUG privilege
EnablePrivilege(SE_DEBUG_NAME, FALSE);
return nSuccess; // 0=failure; 1=success
}
/**********************************************************************
* Copies EjectFunc() to the remote process and starts its execution. *
* The remote EjectFunc() restores the old window procedure. *
* *
* Return value: 0=failure, 1=success *
**********************************************************************/
int EjectCode ()
{
HANDLE hProcess; // Remote process handle
DWORD *pCodeRemote; // Address of EjectFunc() in the remote process
HANDLE hThread = NULL; // The handle and ID of the thread executing
DWORD dwThreadId = 0; // the remote EjectFunc().
int nSuccess = 0; // EjectFunc() success ?
DWORD dwNumBytesCopied = 0; // Number of bytes written to the remote process.
DWORD size; // Calculated function size (= AfterFunc() - Func())
// Enable Debug privilege (needed for some processes)
EnablePrivilege(SE_DEBUG_NAME, TRUE);
// Remote INDATA and SASWindowProc() must exist
if (!pDataRemote || !pSASWinProcRemote)
return 0;
// Open the process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if (hProcess == NULL)
return 0;
// Allocate memory in the remote process and write a copy of EjectFunc() to the allocated memory
size = (PBYTE)AfterEjectFunc - (PBYTE)EjectFunc;
pCodeRemote = (PDWORD) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pCodeRemote)
{
CloseHandle(hProcess);
return 0;
}
if (!WriteProcessMemory(hProcess, pCodeRemote, &EjectFunc, size, &dwNumBytesCopied) || dwNumBytesCopied != size)
{
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}
// Start execution of the remote EjectFunc()
hThread = CreateRemoteThread(hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE) pCodeRemote,
pDataRemote,
0 ,
&dwThreadId);
// Failed
if (!hThread)
{
goto END;
}
// Wait for EjectFunc() to terminate and get return code
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &nSuccess);
// Failed to restore old window procedure ?
// Then leave INJDATA and the SASWindowProc()
if (nSuccess == 0)
goto END;
// Release memory for remote INJDATA and SASWindowProc()
if (pDataRemote)
VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE);
if (pSASWinProcRemote)
VirtualFreeEx(hProcess, pSASWinProcRemote, 0, MEM_RELEASE);
pDataRemote = NULL;
pSASWinProcRemote = NULL;
// MessageBeep(0); // success
END:
if (hThread)
CloseHandle(hThread);
// Release EjectFunc() memory
if (pCodeRemote)
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
CloseHandle(hProcess);
// Disable the DEBUG privilege
EnablePrivilege(SE_DEBUG_NAME, FALSE);
return nSuccess; // 0=failure; 1=success
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -