//Filename:inject.cpp
#include "main.h"
typedef DWORD NTSTATUS;
struct NtCreateThreadExBuffer{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
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
);
using namespace std;
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
BOOL LoadDll(char *procName, char *dllName);
BOOL InjectDLL(DWORD dwProcessID, char *dllName);
BOOL LoadDll(char *dllName, DWORD dwProcID){
 printf("Process Id to Inject: %d",dwProcID);
 if(!dwProcID){
  printf("No vailid PID\n");
  return false;
 }
 FILE* FileCheck = fopen(dllName, "r");
 if(FileCheck==NULL){
printf("\nUnable to inject %s", dllName);
return false;
 }
 fclose(FileCheck);
 if(!InjectDLL(dwProcID, dllName)){
  printf("injection failed\n");
return false;
 } else {
return true;
 }
}
BOOL InjectDLL(DWORD dwProcessID, char *dllName){
HANDLE hProc;
HANDLE hToken;
char buf[50]={0};
LPVOID RemoteString, LoadLibAddy;
if(!dwProcessID)return false;
HANDLE hCurrentProc = GetCurrentProcess();
if (!OpenProcessToken(hCurrentProc,TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken)){
 printf("OpenProcessToken Error:%d\n", GetLastError());
 
} else {
 if (!RaisePrivleges(hToken, (char*)SE_DEBUG_NAME)){
  printf("SetPrivleges SE_DEBUG_NAME Error:%d\n", GetLastError());
  
 }
}
if (hToken)CloseHandle(hToken);
hProc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, dwProcessID);
if(!hProc){
 printf("OpenProcess() failed: %d", GetLastError());
 return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(!LoadLibAddy){
 printf("GetProcAddress() failed: %d", GetLastError());
 return false;
}
RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(dllName), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if(RemoteString == NULL){
 printf("VirtualAllocEx() failed: %d", GetLastError());
 return false;
}
if(WriteProcessMemory(hProc, (LPVOID)RemoteString, dllName, strlen(dllName), NULL) == NULL){
printf("WriteProcessMemoery() failed: %d", GetLastError());
return false;
}
/*
if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){
  printf("CreateRemoteThread() failed: %d", GetLastError());
     return false;
}
*/
HMODULE modNtDll = GetModuleHandle("ntdll.dll");
if( !modNtDll )
{
printf("n failed to get module handle for ntdll.dll, Error=0x%.8x", GetLastError());
return 0;
}
LPFUN_NtCreateThreadEx funNtCreateThreadEx =
(LPFUN_NtCreateThreadEx) GetProcAddress(modNtDll, "NtCreateThreadEx");
if( !funNtCreateThreadEx )
{
printf("n failed to get funtion (NTCreateThreadEx) address from ntdll.dll, Error=0x%.8x\nTrying CreateRemoteThread api\n", GetLastError());
if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){
  printf("CreateRemoteThread() failed: %d", GetLastError());
     return false;
} else {
 printf("CreateRemoteThread success!\n");
 return true;
}
return 0;
} 
NtCreateThreadExBuffer ntbuffer;
memset (&ntbuffer,0,sizeof(NtCreateThreadExBuffer));
DWORD temp1 = 0;
DWORD temp2 = 0;
HANDLE pRemoteThread = NULL;
ntbuffer.Size = sizeof(NtCreateThreadExBuffer);
ntbuffer.Unknown1 = 0x10003;
ntbuffer.Unknown2 = 0x8;
ntbuffer.Unknown3 = &temp2;
ntbuffer.Unknown4 = 0;
ntbuffer.Unknown5 = 0x10004;
ntbuffer.Unknown6 = 4;
ntbuffer.Unknown7 = &temp1;
ntbuffer.Unknown8 = 0;
NTSTATUS status = funNtCreateThreadEx(
&pRemoteThread,
0x1FFFFF,
NULL,
hProc,
(LPTHREAD_START_ROUTINE) LoadLibAddy,
(LPVOID)RemoteString,
FALSE, //start instantly
NULL,
NULL,
NULL,
&ntbuffer
);
// Resume the thread execution
CloseHandle(hProc);
return true;
}
BOOL RaisePrivleges( HANDLE hToken, char *pPriv ){
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.Privileges[0].Luid.HighPart = 0;
tkp.Privileges[0].Luid.LowPart = 0;
if (!LookupPrivilegeValue(NULL, pPriv, &tkp.Privileges[0].Luid)){
 printf("LookupPrivilegeValue Error:%d\n", GetLastError());
 return FALSE;
}
int iRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0x10, (PTOKEN_PRIVILEGES)NULL, 0);
if (iRet == NULL){
 printf( "AdjustTokenPrivileges Error:%d\n", GetLastError());
 return TRUE;
} else {
 iRet = GetLastError();
switch (iRet){
 case ERROR_NOT_ALL_ASSIGNED:{
 printf("AdjustTokenPrivileges ERROR_NOT_ALL_ASSIGNED\n" );
 return FALSE;
        }
 case ERROR_SUCCESS:{
 return TRUE;
        }
 default:{
 printf("AdjustTokenPrivileges Unknow Error:%d\n", iRet);
 return FALSE;
   }
}
}
}