Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // DllInjectionTest.cpp
- // Tested on: Windows 11
- // platform x64
- // Develpment on C++ VS 2019
- //
- // Tip: on 64bit box Compile on 64bit archiecture!
- //
- ////////////////////////////////////
- #include <iostream>
- #include <cstdio>
- #include <windows.h>
- #include <tlhelp32.h>
- #include <tchar.h>
- #include <TlHelp32.h>
- #define NT_SUCCESS(x) ((x) >= 0)
- typedef struct _CLIENT_ID {
- HANDLE UniqueProcess;
- HANDLE UniqueThread;
- } CLIENT_ID, * PCLIENT_ID;
- typedef NTSTATUS(NTAPI* pfnRtlCreateUserThread)(
- IN HANDLE ProcessHandle,
- IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
- IN BOOLEAN CreateSuspended,
- IN ULONG StackZeroBits OPTIONAL,
- IN SIZE_T StackReserve OPTIONAL,
- IN SIZE_T StackCommit OPTIONAL,
- IN PTHREAD_START_ROUTINE StartAddress,
- IN PVOID Parameter OPTIONAL,
- OUT PHANDLE ThreadHandle OPTIONAL,
- OUT PCLIENT_ID ClientId OPTIONAL);
- typedef NTSTATUS(WINAPI* LPFUN_NtCreateThreadEx)
- (
- OUT PHANDLE hThread,
- IN ACCESS_MASK DesiredAccess,
- IN LPVOID ObjectAttributes,
- IN HANDLE ProcessHandle,
- IN LPTHREAD_START_ROUTINE lpStartAddress,
- IN LPVOID lpParameter,
- IN BOOL CreateSuspended,
- IN ULONG StackZeroBits,
- IN ULONG SizeOfStackCommit,
- IN ULONG SizeOfStackReserve,
- OUT LPVOID lpBytesBuffer
- );
- //Buffer argument passed to NtCreateThreadEx function
- struct NtCreateThreadExBuffer
- {
- ULONG Size;
- ULONG Unknown1;
- ULONG Unknown2;
- PULONG Unknown3;
- ULONG Unknown4;
- ULONG Unknown5;
- ULONG Unknown6;
- PULONG Unknown7;
- ULONG Unknown8;
- };
- #define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
- BOOL DllInject_1(UINT32 ProcessId, char *DLL_NAME)
- {
- LPVOID LoadLibAddr, RemoteString;
- HANDLE hThread;
- DWORD dwWaitResult, dwExitResult = 0;
- HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
- if (hProcess == NULL)
- {
- std::cout << "Cannot get the Process ID " << ProcessId;
- return (0);
- }
- Sleep(2000);
- LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryA");
- if (LoadLibAddr == NULL)
- {
- return (0);
- }
- //Allocates a buffer for and writes the path to the DLL we want to inject inside of the target process's memory
- RemoteString = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(DLL_NAME)+1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
- if (RemoteString == NULL)
- {
- return (0);
- }
- if (!WriteProcessMemory(hProcess, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME)+1, NULL))
- {
- return (0);
- }
- //Calls LoadLibrary on our specified DLL in the target process
- hThread = CreateRemoteThread(
- hProcess,
- NULL,
- NULL,
- (LPTHREAD_START_ROUTINE)LoadLibAddr,
- (LPVOID)RemoteString,
- NULL,
- NULL
- );
- if (hThread != NULL) {
- dwWaitResult = WaitForSingleObject(hThread, 10000); // keep the dll injection action for 10 seconds before free.
- GetExitCodeThread(hThread, &dwExitResult);
- CloseHandle(hThread);
- VirtualFreeEx(hProcess, RemoteString, 0, MEM_RELEASE);
- return (1);
- }
- return (0);
- }
- BOOL DllInject_2(UINT32 ProcessId, char* DLL_NAME)
- {
- HANDLE ProcessHandle = NULL;
- ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
- UINT32 DllFullPathLength = (strlen(DLL_NAME));
- PVOID DllFullPathBufferData = VirtualAllocEx(ProcessHandle, NULL, DllFullPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if (DllFullPathBufferData == NULL)
- {
- CloseHandle(ProcessHandle);
- return FALSE;
- }
- SIZE_T ReturnLength;
- BOOL bOk = WriteProcessMemory(ProcessHandle, DllFullPathBufferData, DLL_NAME, strlen(DLL_NAME), &ReturnLength);
- LPTHREAD_START_ROUTINE LoadLibraryAddress = NULL;
- HMODULE Kernel32Module = GetModuleHandle(L"Kernel32");
- LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "LoadLibraryA");
- pfnRtlCreateUserThread RtlCreateUserThread = (pfnRtlCreateUserThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlCreateUserThread");
- HANDLE ThreadHandle = NULL;
- NTSTATUS Status = RtlCreateUserThread(ProcessHandle, NULL, FALSE, 0, 0, 0, LoadLibraryAddress, DllFullPathBufferData, &ThreadHandle, NULL);
- if (ThreadHandle == NULL)
- {
- CloseHandle(ProcessHandle);
- return FALSE;
- }
- if (!NT_SUCCESS(Status))
- {
- CloseHandle(ProcessHandle);
- return FALSE;
- }
- if (WaitForSingleObject(ThreadHandle, INFINITE) == WAIT_FAILED)
- {
- return FALSE;
- }
- CloseHandle(ProcessHandle);
- CloseHandle(ThreadHandle);
- return TRUE;
- }
- int EnableSeDebugPrivilege(void) {
- HANDLE hToken;
- LUID Val;
- TOKEN_PRIVILEGES tp;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
- return(GetLastError());
- if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Val))
- return(GetLastError());
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = Val;
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL))
- return(GetLastError());
- CloseHandle(hToken);
- return 1;
- }
- int main(int argc, char *argv[])
- {
- DWORD dwTargetProcessID = 0;
- char DLL_NAME[512] = "";
- int iMethod = 0;
- if (argc == 4)
- {
- iMethod = atoi(argv[1]);
- if ((iMethod < 1) || (iMethod > 2))
- {
- std::cout << "** Arg(1) must be 1 or 2.";
- return (-1);
- }
- strcpy_s(DLL_NAME, argv[2]);
- dwTargetProcessID = atoi(argv[3]);
- }
- else
- {
- std::cout << "** Usage: <1 | 2> <Full_DLL_Path_and_Filename> <ProcessID> ";
- std::cout << "** Arg(1) is the method will be used for DLL injection.";
- return -1;
- }
- std::cout << "DLL Injection Test \n";
- if (EnableSeDebugPrivilege() == 1)
- std::cout << "[+] Get All Privilege [ok!].\n";
- else
- std::cout << "[-]Cannot Get All Privilege.\n";
- std::cout << "[+] Try to inject...";
- /// //// ---------------------------------------------------------------------
- DWORD CurrentSessionID, RemoteSessionID, RemoteProcessID;
- if (!ProcessIdToSessionId(GetCurrentProcessId(), &CurrentSessionID))
- {
- std::cout << "\nFailed to get the current session with error" << GetLastError() ;
- return -1;
- }
- if (!ProcessIdToSessionId(dwTargetProcessID, &RemoteSessionID))
- {
- std::cout << "\nFailed to get the remote session with error" << GetLastError() ;
- return -2;
- }
- BOOLEAN bResult = false;
- (iMethod == 1) ? (bResult = DllInject_1(dwTargetProcessID, DLL_NAME)) : (bResult = DllInject_2(dwTargetProcessID, DLL_NAME));
- if (bResult)
- {
- std::cout << "\nSUCCESSFUL!\n";
- }
- else
- {
- std::cout << "\nFailed!\n";
- return -3;
- }
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment