Вместо CreateRemoteThread и NtCreateThreadEx (оба сбоя) используйте RtlCreateUserThread.

ожусь в процессе создания программы безопасности для моей сети. Одним из примеров является проверка и мониторинг того, как называются API и библиотеки. DLL, чтобы сделать это, и программа, которая сопровождает это, уже закончены. Но есть проблема, которую я не могу решить.

При попытке внедрить мою dll в системные процессы (такие как explorer.exe, мой основной процесс тестирования системы) сNtCreateThreadEx Я получаю возвращаемое значение: C0000022, это означает что-то вроде: Status_Access_Denied (возвращается в NTSTATUS, но DWORD будет делать)

Я понятия не имею, что делать, я работаю как администратор, я поднял свои привилегии и использовал соответствующие функции, все еще я получаю c0000022

Вот код, который я использую, чтобы ввести

#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)
#define CREATE_THREAD_ACCESS ( PROCESS_ALL_ACCESS )

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);

    printf("\nHandle to process: %x\n", hProc);

    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;

    }


    printf("\nRemote address: %x\n", RemoteString);

    if(WriteProcessMemory(hProc, (LPVOID)RemoteString, dllName, strlen(dllName), NULL) == NULL){

        printf("WriteProcessMemory() 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 function (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
                                         );

    printf("NTCreateThreadEx return: %x\n", status);

    // Resume the thread execution

    WaitForSingleObject(pRemoteThread, INFINITE);


    //Check the return code from remote thread function
    DWORD dwExitCode;
    if( GetExitCodeThread(pRemoteThread, (DWORD*) &dwExitCode) )
    {
        printf("\n Remote thread returned with status = %d\n", dwExitCode);
    }


    CloseHandle(pRemoteThread); 


    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;
        }
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос