⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inject.c

📁 键盘锁
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (!(hNTDll = LoadLibrary("NTDLL.DLL")))
        return -1;

    // Load ZwQuerySystemInformation() dynamically
    if (!(ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNTDll, "ZwQuerySystemInformation")))
	{
		FreeLibrary(hNTDll);
		SetLastError(ERROR_PROC_NOT_FOUND);
        return -1;
	}

    // Find needed buffer length
    do
    {
		if (!(pBuffer = malloc(BufferLen)))
		{
			FreeLibrary(hNTDll);
			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
	        return -1;
		}

		Status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation,
					                      pBuffer, BufferLen, NULL);

		if (Status == STATUS_INFO_LENGTH_MISMATCH)
		{
			free(pBuffer);
			BufferLen *= 2;
		}
		else if (!NT_SUCCESS(Status))
		{
			free(pBuffer);
			FreeLibrary(hNTDll);
			return -1;
		}
    }
    while (Status == STATUS_INFO_LENGTH_MISMATCH);

	pInfo = (PSYSTEM_PROCESSES)pBuffer;
    for (;;)
    {
		pszProcessName = pInfo->ProcessName.Buffer;
		if (pszProcessName == NULL)
			pszProcessName = L"Idle";

        // Process found ?
        if (wcsicmp(pszProcessName, wcProcessName) == 0)
        {
			dwPID = pInfo->ProcessId;
			free(pBuffer);
			FreeLibrary(hNTDll);
			return dwPID;
        }

		if (pInfo->NextEntryDelta == 0)
			break;

		// Find the address of the next process structure
		pInfo = (PSYSTEM_PROCESSES)(((PUCHAR)pInfo) + pInfo->NextEntryDelta);
    }

    free(pBuffer);
	FreeLibrary(hNTDll);
    return -1;
}


/********************************
 * Return PID for Process Name. *
 ********************************/
DWORD GetPIDFromName(char *szProcessName)
{
    DWORD   dwPID;
    OSVERSIONINFO   info;

    info.dwOSVersionInfoSize = sizeof(info);
    GetVersionEx(&info);

	// Get PID using Toolhelp or  ZwQuerySystemInformation() depending on the OS version
    if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
        dwPID = GetPIDFromNameToolhelp(szProcessName);
    else if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
        dwPID = GetPIDFromNameZwQuerySystemInformation(szProcessName);
    else
        dwPID = -1;

    return dwPID;
}


/////////////////////////////////////////////// Inject DLL ////////////////////////////////////////////

extern		HINSTANCE	hInst;					// Instance handle
DWORD		hLibModule;							// Handle of injected library
char		*szDllName     = "injdll.dll";			// Library to inject
char		*szProcessName = "winlogon.exe";	// Process to inject

/*****************************************
 * Load a library into a remote process. *
 *****************************************/
int InjectDll()
{
	HANDLE	hThread;				// Thread handle
	HANDLE	hProcess;				// Process handle
    DWORD	dwPID;					// Process ID
	char	szLibPath[MAX_PATH];	// Full DLL path
	void	*pLibRemote;			// Address (in the remote process) where szLibPath will be copied to

	// Enable DEBUG privilege
    if (!EnablePrivilege(SE_DEBUG_NAME, TRUE))
		return 0;

	// Get remote process id
    dwPID = GetPIDFromName(szProcessName);
    if (dwPID == -1)
		return 0;

	// Open remote process
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
	if (hProcess == NULL)
		return 0;

	// Get full path of the DLL
	if (!GetModuleFileName(hInst, szLibPath, MAX_PATH))
		return 0;
	strcpy(strrchr(szLibPath, '\\') + 1 , szDllName);

	// Allocate memory in the remote process to store the szLibPath string
	pLibRemote = VirtualAllocEx(hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE);
	if (pLibRemote == NULL)
		return 0;
	// Copy the szLibPath string to the remote process.
	if (!WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath, sizeof(szLibPath), NULL))
		return 0;

	// Load the DLL into the remote process 
	// (via CreateRemoteThread() & LoadLibrary())
	hThread = CreateRemoteThread(hProcess, 
								 NULL, 
								 0,	
								 (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA"), 
								 pLibRemote, 
								 0, 
								 NULL);
	// Failed
	if(hThread == NULL)
	{
		VirtualFreeEx(hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE);
		return 0;
	}

	// Wait for LoadLibrary() to finish and get return code (handle of loaded library)
	WaitForSingleObject(hThread, INFINITE);
	GetExitCodeThread(hThread, &hLibModule);
	CloseHandle(hThread);
	CloseHandle(hProcess);

	// Free remote memory for szLibPath
	VirtualFreeEx(hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE);

	// Remote LoadLibrary() failed
	if (!hLibModule)
		return 0;

	// Disable DEBUG privilege
	EnablePrivilege(SE_DEBUG_NAME, FALSE);

	return 1;
}


/****************************************************
 * Unload injected library from the remote process. *
 ****************************************************/
int EjectDll()
{
	HANDLE	hThread;
	HANDLE	hProcess;
    DWORD	dwPID;
	DWORD	dwRetFreeLibrary;

	// Enable DEBUG privilege
    if (!EnablePrivilege(SE_DEBUG_NAME, TRUE))
		return 0;

	// Get remote process id
    dwPID = GetPIDFromName(szProcessName);
    if (dwPID == -1)
		return 0;

	// Open remote process
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
	if (hProcess == NULL)
		return 0;

	// Unload the DLL from the remote process 
	// (via CreateRemoteThread & FreeLibrary)
	hThread = CreateRemoteThread(hProcess,
								 NULL, 
								 0,
								 (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "FreeLibrary"),
								 (void*)hLibModule,
								 0, 
								 NULL );
	// Failed to unload
	if (hThread == NULL)
		return 0;

	// Wait for FreeLibrary() to finish and get return code
	WaitForSingleObject(hThread, INFINITE);
	GetExitCodeThread(hThread, &dwRetFreeLibrary);
	CloseHandle(hThread);
	CloseHandle(hProcess);

	// Disable DEBUG privilege
	EnablePrivilege(SE_DEBUG_NAME, FALSE);

	return (dwRetFreeLibrary);
}

////////////////////////////////////////////// Inject Code ////////////////////////////////////////

/**************************************************************************************************************
 * Some tips when using CreateRemoteThread()/WriteProcessMemory().                                            *
 *                                                                                                            *
 * 1. Analise generated code.                                                                                 *
 *    Check injected functions for absolute addressing (calls, jumps, data references, ...)                   * 
 *    and other generated code that shouldn't be there.                                                       *
 *    Use:                                                                                                    *
 *    A) Project\Settings\C/C++\Listing Files\Listing file type=Assembly, Machine Code, and Source.           *
 *    B) A disassembler (wdasm32).                                                                            *
 *    C) A debugger (softice).                                                                                *
 *                                                                                                            *
 * 2. Turn off stack probes.                                                                                  *
 *    Check for __chkstk() references in the listing files.                                                   *
 *    A) Use #pragma check_stack(off). [DOESN'T SEEMS TO WORK ?!?]                                            *
 *    B) Use less than 4K of local variables.                                                                 *
 *    C) Augment the stack size: /Gs size (Project\Settings\C/C++\ProjectOptions)                             *
 *                                                                                                            *
 * 3. Remove the /GZ switch in the debug build.                                                               *
 *    Check for __chkesp() references in the listing files.                                                   *
 *    A) Project\Settings\C/C++\Project Options                                                               *
 *                                                                                                            *
 * 4. Disable incremental compilation (/Gi).                                                                  *
 *    A) Use #pragma comment(linker, "/INCREMENTAL:NO")                                                       *
 *    B) Remove the /Gi switch (Project\Settings\C/C++\Customize\Enable incremental compilation=Off           *
 *    C) Declare the functions as static.                                                                     *
 *                                                                                                            *
 * 5. Don't let optimization screw your code.                                                                 *
 *    A) Turn off optimization (Project\Settings\C/C++\General\Optimizations=Disable(Debug)                   *
 *    B) Use #pragma optimize("", off)                                                                        *
 *    C) Don't write functions with the same prototype (e.g. AfterFuncX()). Let them return different values. *
 *                                                                                                            *
 * 6. Split switch() statements in 3 cases maximum, or use if/then/else.                                      *
 *                                                                                                            *
 * 7. Don't call any functions besides those in KERNEL32.LL and USER32.DLL (USER32.DLL isn't garanted to be   *
 *    mapped into every process).                                                                             *
 *    Use LoadLibrary()/GetProcAddress if you need functions from other libraries.                            *
 *                                                                                                            *
 * 8. Don't use any static strings.                                                                           *
 *    Pass them in INJDATA.                                                                                   *
 *                                                                                                            *
 * 9. Don't call any function directly.                                                                       *
 *    Copy each routine to the remote process individually and supply their addresses in INJDATA.             *
 *                                                                                                            *
 * 10. Good luck.                                                                                             *
 *     If you analise the generated code (using a disassembler) you should catch any errors before executing  *
 *     the code (and crashing the process !).                                                                 *
 **************************************************************************************************************/  

#pragma comment(linker, "/INCREMENTAL:NO")	// Turns off incremental linking

// Global variables
DWORD	PID;						// PID of injected process
BYTE	*pDataRemote;				// Address of INJDATA in the remote process
BYTE	*pSASWinProcRemote;			// The address of SASWindowProc() in the remote process

#define	DUMMY_ADDR	0x12345678		// Dummy addr of INJDATA

// INJDATA: Memory block passed to each remote injected function.
// We pass every function address or string data in this block.
typedef LONG		(WINAPI *SETWINDOWLONG)	  (HWND, int, LONG); 
typedef LRESULT		(WINAPI *CALLWINDOWPROC)  (WNDPROC, HWND, UINT, WPARAM, LPARAM);
typedef HWND		(WINAPI *FINDWINDOW)	  (LPCTSTR, LPCTSTR);

typedef struct {
	SETWINDOWLONG	fnSetWindowLong;	// Addr. of SetWindowLong()
	CALLWINDOWPROC	fnCallWindowProc;	// Addr. of CallWindowProc()
	FINDWINDOW		fnFindWindow;		// Addr. of FindWindow()
	char			szClassName[50];	// Class name = "SAS Window class"
	char			szWindowName[50];	// Window name = "SAS window"
	HWND			hwnd;				// Window handle of injected process
	WNDPROC			fnSASWndProc;		// Addr. of remote SASWindowProc
	WNDPROC 		fnOldSASWndProc;	// Addr. of old SASWindowProc
} INJDATA, *PINJDATA;


/*****************************************************************
 * Subclassed window procedure handler for the injected process. *
 *****************************************************************/

#pragma optimize("", off)
#pragma check_stack(off)

static LRESULT CALLBACK SASWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	// INJDATA pointer. 
	// Must be patched at runtime !
	INJDATA* pData = (INJDATA *)DUMMY_ADDR;

	if (uMsg == WM_HOTKEY)
	{
		// Ctrl+Alt+Del
		if (lParam == MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE))
			return 1;

		// Ctrl+Shift+Esc
		if (lParam == MAKELONG(MOD_CONTROL | MOD_SHIFT, VK_ESCAPE))
			return 1;
	}

	// Call the original window procedure
	return pData->fnCallWindowProc(pData->fnOldSASWndProc, hwnd, uMsg, wParam, lParam);		
}


static int AfterSASWindowProc(void) {return 1;}



/*************************************************
 * Subclass the remote process window procedure. *
 * Return: 0=failure, 1=success                  *
 *************************************************/

#pragma optimize("", off)
#pragma check_stack(off)

static DWORD WINAPI InjectFunc (INJDATA *pData) 
{
	// Subclass window procedure
	pData->fnOldSASWndProc = (WNDPROC) pData->fnSetWindowLong (pData->hwnd, GWL_WNDPROC, (long)pData->fnSASWndProc);	

	return (pData->fnOldSASWndProc != NULL);
}


static int AfterInjectFunc(void) {return 2;}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -