【问题标题】:C++ & Windows - DLL Injection by NtCreateThreadEx function is not workedC++ 和 Windows - NtCreateThreadEx 函数的 DLL 注入不起作用
【发布时间】:2016-03-10 18:36:49
【问题描述】:

我已经编写了 DLL 注入器。我使用 CreateRemoteThread 注入我的 DLL 进行处理,一切都很好。 现在我正在尝试通过未记录的函数 NtCreateThreadEx 注入 DLL 来处理。我写了注射器,但他不工作。

当我使用 32 位注入器将 32 位 DLL 注入到 32 位进程时 一切正常。 问题是当我使用 64 位注入器将 64 位 DLL 注入到 64 位进程时。

我的 DLL 代码:

#include <windows.h>

///Compilation with option -m64

extern "C" BOOL __stdcall DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
   MessageBox( NULL, "MESSAGE FROM 64 BIT DLL", "Lorem ipsum", MB_ICONINFORMATION | MB_OKCANCEL );
   return 0;
}

我的 TestApp 代码

#include <iostream>
#include <windows.h>
int main()
{

   std::cout << " Lorem  IPSUM" << std::endl;

   //HMODULE HDLL = LoadLibraryA("dll64.dll");

   //std::cout << "Error: " << GetLastError() << std::endl;
   while(1)
   {
       std::cout << "petla" << std::endl;
       Sleep(5000);
   }
   return 0;
}

我的注射器代码:

#include <iostream>
#include <string>
#include <windows.h>
///  64 bit OS - Windows 7
///=====================
///* In this same user context ("User")
///TYPE OF(32/64 bits)
///INJECTOR===DLL===PROCESS===RESULT
///   32      32     32      -SUCESS
///   64      64     64      -FALIED (error: 1300)
                    //Handle to process,Address of'LoadLibraryA',see DllAdr
///TO DO
///* Inject DLL to process from normal user context ("User") to higher user context (Zarzadca)
///* Inject DLL to process from normal user context ("User") to other normal user context (User1)


HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,    LPVOID lpSpace);
int privileges();

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 << "ptr size = " << sizeof(void *) << std::endl;

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

    ///std::cout << "Get path to DLL" << std::endl;
    ///std::cin >> pathToDLL;

    if( privileges() != 0 )
    {
        std::cout <<  "Cannot get the right privileges" << std::endl;
    }

    HProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    if(HProcess == NULL)
    {
        std::cout << "Could not find process" << std::endl;
        std::cout << GetLastError() << std::endl;
        system("pause");
        return GetLastError();
    }

    DllAdr = (LPVOID)VirtualAllocEx(HProcess, NULL, pathToDLL.size() +1, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if(DllAdr == NULL)
    {
        std::cout <<"Can not allocate memory." << std::endl;
        std::cout << GetLastError() << std::endl;
        system("pause");
        return GetLastError();
    }

    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" << std::endl;
        std::cout << GetLastError() << std::endl;
        system("pause");
        return GetLastError();
    }

    LibAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    if(LibAddr == NULL)
    {
        std::cout << "Unable to locate LoadLibraryA" << std::endl;
        std::cout << GetLastError() << std::endl;
        system("pause");
        return GetLastError();
    }

    hThread = NtCreateThreadEx(HProcess,LibAddr,DllAdr);
    ///DWORD threadId = 0;
    ///hThread = CreateRemoteThread(HProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LibAddr, DllAdr, 0, &threadId);
    if(hThread == NULL)
    {
        std::cout << "Error: ";
        std::cout << GetLastError() << std::endl;
        system("pause");
        return GetLastError();
    }
    system("pause");
}
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpSpace)
{
    ///The prototype of NtCreateThreadEx from undocumented.ntinternals.com
    typedef DWORD (WINAPI * functypeNtCreateThreadEx)(
        PHANDLE                 ThreadHandle,
        ACCESS_MASK             DesiredAccess,
        LPVOID                  ObjectAttributes,
        HANDLE                  ProcessHandle,
        LPTHREAD_START_ROUTINE  lpStartAddress,
        LPVOID                  lpParameter,
        BOOL                    CreateSuspended,
        DWORD                   dwStackSize,
        DWORD                   Unknown1,
        DWORD                   Unknown2,
        LPVOID                  Unknown3
    );

    HANDLE                      hRemoteThread           = NULL;
    HMODULE                     hNtDllModule            = NULL;
    functypeNtCreateThreadEx    funcNtCreateThreadEx    = NULL;

    //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;
    }
    funcNtCreateThreadEx = (functypeNtCreateThreadEx)GetProcAddress( hNtDllModule, "NtCreateThreadEx" );
    if ( !funcNtCreateThreadEx )
    {
        std::cout << "Cannot get procedure address  error: " << GetLastError() << std::endl;
        return NULL;
    }
    funcNtCreateThreadEx( &hRemoteThread,  /*GENERIC_ALL*/0x1FFFFF, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, NULL );
    std::cout << "Status NtCreateThreadEx  " << GetLastError()       << std::endl;
    std::cout << "hRemoteThread:           " << hRemoteThread        << std::endl;
    std::cout << "hNtDllModule:            " << hNtDllModule         << std::endl;
    std::cout << "funcNtCreateThreadEx:    " << funcNtCreateThreadEx << std::endl;
    return hRemoteThread;
}
int privileges()
{
  HANDLE Token;
  TOKEN_PRIVILEGES tp;
  if(OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token)) ///It opens the access token associated with a process.
  {
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);///Function retrieves the locally unique identifier (LUID)

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        if (AdjustTokenPrivileges(Token, false, &tp, sizeof(tp), NULL, NULL) != 0)///Function enables or disables privileges in the specified access token.
        {
            return 0; //OK
        }
   }
   return 1;
}

当我使用 64 位注入器将 64 位 DLL 注入 64 位进程时,函数 NtCreateThreadEx 返回错误 1300 的代码并且我的 DLL 不执行。 我用来在 64 位架构上编译:g++ (tdm64-1) 5.1.0 我正在以普通用户的身份使用 Virus Windows 7 64 位。以管理员身份运行没有帮助。 我不知道为什么它不起作用,我做错了什么。

PS:当我使用 32 位注入器将 32 位 DLL 注入 32 位进程时,函数 NtCreateThreadEx 返回错误 1300 的代码,但我的 DLL 执行。 在 32 位版本中,TestApp GetLastError 返回代码 1114。 我用于在 32 位架构上编译:g++ (tdm-2) 4.8.1

我包含图片

I based on:
http://www.p-programowanie.pl/cpp/dll-injection/ - Dll Injection (polish)
====
http://www.codeproject.com/Questions/369890/Ask-about-NtCreateThreadEx-in-Window-x 
- Ask about NtCreateThreadEx in Window 7 x64!
=====
http://www.rohitab.com/discuss/topic/39535-code-injections-beginner-and-advanced/ Code Injections [beginner and advanced]
=====
http://securityxploded.com/ntcreatethreadex.php Remote Thread Execution in System Process using NtCreateThreadEx for Vista & Windows7
=====
http://cpp0x.pl/dokumentacja/WinAPI/Systemowe-kody-bledow-1300-1699/1470 Systemowe kody błędów (1300-1699) (polish)


Link to my topic on other forum (polish): http://forum.4programmers.net/C_i_C++/267735-dll_injection_w_windows_za_pomoca_nieudokumentowanej_funkcji_w_winapi?p=1234215#id1234215

【问题讨论】:

  • 你没有检查函数是否失败; GetLastError 是没有意义的,除非 a) 函数返回其记录在案的故障代码,并且 b) 函数被记录为使用 GetLastError 来指示其错误代码。
  • DWORD 似乎是堆栈大小的错误类型。在CreateRemoteThread 文档中,它是SIZE_T(指针大小)。这将在移植到 64 位时产生问题。
  • 你说得对。我将 DWORD 替换为 64 位大小的变量 (SIZE_T)。这么简单,我傻了。现在一切正常。非常感谢。

标签: c++ windows winapi dll-injection


【解决方案1】:

当我使用他将 DLL 注入我的用户空间中的其他进程时,我的注入器正在工作(我作为普通用户工作) 但它不工作时 我正在注入 csrss.exe(或其他系统的进程)。 我得到错误 5 的代码 - 访问被拒绝,当我以管理员身份运行注入器时,我得到错误 0 的代码(成功?)但我的 DLL 没有中止进程 ( abort() - 我尝试做 BSoD)。

我阅读了有关会话分离的信息,我认为这是我的问题的原因,所以我有一个问题:我如何破解 Windows :) 如果不可能,我可以将 DLL 作为普通用户注入到管理员上下文(或其他普通用户的进程)中吗?

【讨论】:

  • 如果没有先启用 SeDebugPrivilege(这可以通过 Win32 API -> NtAdjustPrivilegesToken 完成),您将无法访问在会话 0(又名 NT 授权帐户)下执行的进程 - 您必须以管理员身份运行才能但是这样做。此外,从 Windows 8 开始,csrss.exe 是一个受保护的进程(由 Windows 内核强制执行)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多