简体   繁体   English

dll注入失败

[英]Failing dll injection

I'm in the process of making a security program for my network.我正在为我的网络制作一个安全程序。 One of it's instances is to check and monitor what api's and libraries are called.它的实例之一是检查和监控调用了哪些 api 和库。 The dll to do that and the program that go along with it are already finished.执行此操作的 dll 以及与之相关的程序已经完成。 But there is a problem that I cant seem to fix.但是有一个我似乎无法解决的问题。

When trying to inject my dll into system processes (such as explorer.exe, my main test system process) with NtCreateThreadEx I get the return value: C0000022, it means something along the lines of: Status_Access_Denied (it returns in NTSTATUS, but DWORD will do)当尝试使用NtCreateThreadEx将我的 dll 注入系统进程(例如 explorer.exe,我的主要测试系统进程)时,我得到返回值:C0000022,这意味着类似以下内容:Status_Access_Denied(它返回 NTSTATUS,但 DWORD 将做)

I have no idea what to do, I'm running as Administrator, I raised my privileges, and used the proper functions, still I get c0000022我不知道该怎么办,我以管理员身份运行,我提高了权限并使用了正确的功能,但我仍然得到 c0000022

Here's the code I'm using to inject这是我用来注入的代码

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

Since it's hard to find the right answer to this problem, I am posting even though the thread is old.由于很难找到此问题的正确答案,因此即使该线程很旧,我还是要发帖。 I was trying to inject into x64 service on Win7 x64 and kept running into same problems.我试图在 Win7 x64 上注入 x64 服务并不断遇到同样的问题。 My solution was:我的解决方案是:

  1. Compile both the injector and injection dll as x64.将注入器和注入 dll 编译为 x64。
  2. Instead of CreateRemoteThread & NtCreateThreadEx (both failing) use RtlCreateUserThread.使用 RtlCreateUserThread 代替 CreateRemoteThread 和 NtCreateThreadEx(都失败)。

1) If you're running on VISTA or later then you're possibly trying to inject into a 'protected process' from a 'non protected process'. 1) 如果您在 VISTA 或更高版本上运行,那么您可能试图从“非受保护进程”注入“受保护进程”。 See Process Security and Access Rights in MSDN.请参阅 MSDN 中的进程安全和访问权限 Non protected processes can't create threads in protected processes;非受保护进程不能在受保护进程中创建线程; though I must admit I'd expect the call to open process to fail when you request the inappropriate access rights rather than the subsequent create thread call to fail.尽管我必须承认,当您请求不适当的访问权限而不是随后的创建线程调用失败时,我希望对 open 进程的调用会失败。

2) Why are you using NtCreateThreadEx() rather than simply calling CreateRemoteThread() ? 2) 为什么你使用NtCreateThreadEx()而不是简单地调用CreateRemoteThread()

3) This probably isn't the cause of your problem, but... You're failing to allocate memory for the null terminator in the string, you should be allocating strlen(dllName) + 1 . 3)这可能不是您的问题的原因,但是...您未能为字符串中的空终止符分配内存,您应该分配strlen(dllName) + 1

4) I assume that the process that is doing the injecting and the process that you're injecting into are both the same architecture, you're not running an x86 exe on x64 and expecting to inject into an x64 exe? 4)我假设正在进行注入的进程和您正在注入的进程都是相同的架构,您没有在 x64 上运行 x86 exe 并期望注入 x64 exe?

您必须指定注入的 DLL 的完整路径,否则将找不到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM