通过NtCreateThreadEx

时间:2016-03-14 18:27:28

标签: c++ winapi

我已经编写了DLL注入器,注入我使用NtCreateThread创建远程进程到远程进程 我在64位操作系统上运行 - Windows 7 为了comiple我使用 32位 - g ++(tdm-2)4.8.1 64位 - g ++(tdm64-1)5.1.0

问题涉及我的注射器64位 我有2个问题 1) 好。我的注射器有时工作,有时不起作用。 我不知道是什么原因。

这是有问题的一行 funcNtCreateThreadEx(& hRemoteThread,GENERIC_EXECUTE,NULL,hProcess,(LPTHREAD_START_ROUTINE)lpBaseAddress,lpSpace,FALSE,NULL,NULL,NULL,(LPVOID)ntbuffer);

当我调用函数NtCreateThreadEx并且在最后一个参数中指向NtCreateThreadExBuffer时,它不起作用。

funcNtCreateThreadEx( &hRemoteThread,GENERIC_EXECUTE /*GENERIC_ALL 0x1FFFFF/*Może tu jest błąd*/, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, **ntbuffer** );

当我给出最后一个参数NULL时,它可以工作,我不知道为什么。

funcNtCreateThreadEx( &hRemoteThread,GENERIC_EXECUTE /*GENERIC_ALL 0x1FFFFF/*Może tu jest błąd*/, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, **NULL** );

有什么想法吗?

2) 我使用NtCreateThreadEx,因为我想将代码注入SYSTEM PROCESS(如csrss.exe),因为我喜欢BSoD :)。 不幸的是,我的注入器只能注入代码来处理同一个会话。 原因是?会话分离? (在Vista和以后的所有操作系统上实现) 这是为什么我不能使用CreateRemoteThread 我曾经想过,当我使用NtCreateThreadEx分离会话时不是问题。 我尝试注入DLL以在sesion 0中处理。

我尝试减少权限 我换了:

HProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);

HProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, PID);

等。但它不起作用。 你能告诉我为什么NtCreateThreadEx()在管理模式下工作,但不能在标准模式下工作吗? Maby我应该使用其他未记录的函数(如NtCreateThreadEx),例如NtOpenProcess来处理所有访问的句柄吗?

我知道我应该做什么。请帮帮我。

#include <iostream>
#include <string>
#include <windows.h>

struct NtCreateThreadExBuffer;
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,    LPVOID lpSpace);
BOOL EnableDebugPrivilege();

int main()
{
    int PIDOfProcess = 0;
    std::string pathToDLL = "dll64.dll\0";  ///find DLL in local directory
    DWORD PID        = (DWORD)PIDOfProcess; ///PID
    HANDLE HProcess  = NULL;                ///Handle to process
    LPVOID LibAddr   = NULL;                ///Address of procedure 'LoadLibraryA'
    LPVOID DllAdr    = NULL;                ///Address of memory in other process
    HANDLE hThread   = NULL;                ///Handle to remote thread
    int WirteStatus  = 0;                   ///Status of writing to memory of other process

    std::cout << "Get PID of process" << std::endl;
    std::cin >> PIDOfProcess;
    PID = (DWORD)PIDOfProcess;

    if(EnableDebugPrivilege() == true)
    {
        std::cout << "Debug privilege was enabled with status: "<< GetLastError() << "      [OK]" << std::endl;
    }else std::cout << "Debug privilege was not enabled: "<< GetLastError() << "                 [FAILED]" << std::endl;

/*
NtOpenProcess(
  OUT PHANDLE             ProcessHandle,
  IN ACCESS_MASK          AccessMask,
  IN POBJECT_ATTRIBUTES   ObjectAttributes,
  IN PCLIENT_ID           ClientId );*/
   /// NtOpenProcess();
    HProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, PID);
    if(HProcess == NULL)
    {
        std::cout << "Could not find process: "<< GetLastError() << "                           [FAILED]" << std::endl;
        system("pause");
        return GetLastError();
    }   std::cout << "Process opened:                                    [OK]" << std::endl;

    DllAdr = (LPVOID)VirtualAllocEx(HProcess, NULL, pathToDLL.size() +1, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if(DllAdr == NULL)
    {
        std::cout << "Cannot allocate memory in remote process: "<< GetLastError() << "     [FAILED]" << std::endl;
        system("pause");
        return GetLastError();
    }   std::cout << "Region of memory in remote process allocated:      [OK]" << std::endl;

    WirteStatus = WriteProcessMemory(HProcess, (LPVOID)DllAdr, pathToDLL.c_str() ,pathToDLL.size()+1, NULL);
    if(WirteStatus == 0)
    {
        std::cout << "Could not write to process's address space: "<< GetLastError() << "   [FAILED]" << std::endl;
        system("pause");
        return GetLastError();
    }   std::cout << "A memory has written name of DLL:                  [OK]" << std::endl;

    LibAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    if(LibAddr == NULL)
    {
        std::cout << "Unable to locate LoadLibraryA: "<< GetLastError() << "                [FAILED]" << std::endl;
        system("pause");
        return GetLastError();
    }   std::cout << "A address of procedure LoadLibraryA has found      [OK]" << std::endl;


    hThread = NtCreateThreadEx(HProcess,LibAddr,DllAdr);

    if(hThread == NULL)
    {
        std::cout << "Could not create remote thread on process: "<< GetLastError() << "    [FAILED]" << std::endl;
        system("pause");
        return GetLastError();
    }
    system("pause");
}
struct NtCreateThreadExBuffer///This information is derived based on reverse engineering work.
{
     ULONG Size;
     ULONG Unknown1;
     ULONG Unknown2;
     PULONG Unknown3;
     ULONG Unknown4;
     ULONG Unknown5;
     ULONG Unknown6;
     PULONG Unknown7;
     ULONG Unknown8;
};
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpSpace)
{
    ///The prototype of NtCreateThreadEx from undocumented.ntinternals.com
    ///typ_zwracanej_wartości (__konwencja_wywolania*nazwa_wskaźnika)(typ1 argument1, typ2 argument2);
    /* 2OOO, 11 November http://undocumented.ntinternals.net/
    NTSYSAPI NTSTATUS NTAPI NtCreateThread(
    OUT PHANDLE             ThreadHandle,
    IN ACCESS_MASK          DesiredAccess,
    IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
    IN HANDLE               ProcessHandle,
    OUT PCLIENT_ID          ClientId,
    IN PCONTEXT             ThreadContext,
    IN PINITIAL_TEB         InitialTeb,
    IN BOOLEAN              CreateSuspended );*/
    typedef LONG64 (WINAPI * functypeNtCreateThreadEx)(
         PHANDLE                 ThreadHandle,      ///Handle to thread which will be created                           /// OUT
         ACCESS_MASK             DesiredAccess,     ///possible: GENERIC_WRITE GENERIC_READ GENERIC_EXECUTE GENERIC_ALL//// IN
         LPVOID                  ObjectAttributes,                                                                      /// IN,OPTIONAL
         HANDLE                  ProcessHandle,     ///Handle to our process                                            /// IN
         LPTHREAD_START_ROUTINE  lpStartAddress,
         LPVOID                  lpParameter,
         BOOL                    CreateSuspended,
/*DWORD*/LONG64                  dwStackSize,
         LONG64                  SizeOfStackCommit,
         LONG64                  SizeOfStackReserve,
         LPVOID                  lpBytesBuffer      ///pointer to initialized object of NtCreateThreadExBuffer
    );
    NtCreateThreadExBuffer    * ntbuffer                = NULL;
    HANDLE                      hRemoteThread           = NULL;
    HMODULE                     hNtDllModule            = NULL;
    functypeNtCreateThreadEx    funcNtCreateThreadEx    = NULL;

    ntbuffer = new NtCreateThreadExBuffer;
    memset (ntbuffer,0,sizeof(NtCreateThreadExBuffer));///fill buffer zeros
    DWORD temp1 = 0;
    DWORD temp2 = 0;

    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;

    //Get handle for ntdll which contains NtCreateThreadEx
    hNtDllModule = GetModuleHandle( "ntdll.dll" );
    if ( hNtDllModule == NULL )
    {
        std::cout << "Cannot get module  ntdll.dll  error: " << GetLastError() << std::endl;
        return NULL;
    }   std::cout << "A 'ntdll.dll' module has got: "<< GetLastError() << "                 [OK]" << std::endl;

    funcNtCreateThreadEx = (functypeNtCreateThreadEx)GetProcAddress( hNtDllModule, "NtCreateThreadEx" );
    if ( !funcNtCreateThreadEx )
    {
        std::cout << "Cannot get procedure address  error: " << GetLastError() << std::endl;
        return NULL;
    }   std::cout << "'NtCreateThreadEx' has executed: "<< GetLastError() << "              [OK]" << std::endl;



     ///Here is problem - when in last argument i replace NULL
    funcNtCreateThreadEx( &hRemoteThread,GENERIC_EXECUTE /*GENERIC_ALL 0x1FFFFF/*Może tu jest błąd*/, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, ntbuffer );
    std::cout << "_______________________________________ "                         << std::endl;
    std::cout << "NtCreateThreadEx' has status:         " << GetLastError()       << std::endl;
    std::cout << "hRemoteThread:                        " << hRemoteThread        << std::endl;
    std::cout << "State of handle to DLL:               " << hNtDllModule         << std::endl;
    std::cout << "Addres of prcoedure NtCreateThreadEx: " << funcNtCreateThreadEx << std::endl;
    return hRemoteThread;
}

BOOL EnableDebugPrivilege()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    if(!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
    {
        return FALSE;
    }

    if(!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ))
    {
        return FALSE;
    }

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if(!AdjustTokenPrivileges( hToken, false, &tkp, sizeof( tkp ), NULL, NULL ))
    {
        return FALSE;
    }

    if(!CloseHandle( hToken ))
    {
        return FALSE;
    }
    return TRUE;
}

1 个答案:

答案 0 :(得分:-1)

try:zwcreatethreatex函数。

typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdllDll, "ZwCreateThreadEx");
if (NULL == ZwCreateThreadEx)
{
    ShowError("GetProcAddress_ZwCreateThread");
    return FALSE;
}