Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将x86 DLL从WOW64进程注入x64进程_C++_Windows_Dll_Reverse Engineering_Dll Injection - Fatal编程技术网

C++ 如何将x86 DLL从WOW64进程注入x64进程

C++ 如何将x86 DLL从WOW64进程注入x64进程,c++,windows,dll,reverse-engineering,dll-injection,C++,Windows,Dll,Reverse Engineering,Dll Injection,有没有办法将x86 DLL从WOW64进程注入x64进程?我知道根据MSDN,通常不可能: 在64位Windows上,64位进程无法加载32位动态链接 库(DLL)。此外,32位进程无法加载64位DLL 但我在Metasploit的存储库中发现了以下内容,并想知道如何在我的项目中使用它: /* * Attempt to gain code execution in a native x64 process from a wow64 process by transitioning out of

有没有办法将x86 DLL从WOW64进程注入x64进程?我知道根据MSDN,通常不可能:

在64位Windows上,64位进程无法加载32位动态链接 库(DLL)。此外,32位进程无法加载64位DLL

但我在Metasploit的存储库中发现了以下内容,并想知道如何在我的项目中使用它:

/*
 * Attempt to gain code execution in a native x64 process from a wow64 process by transitioning out of the wow64 (x86)
 * enviroment into a native x64 enviroment and accessing the native win64 API's.
 * Note: On Windows 2003 the injection will work but in the target x64 process issues occur with new 
 *       threads (kernel32!CreateThread will return ERROR_NOT_ENOUGH_MEMORY). Because of this we filter out
 *       Windows 2003 from this method of injection, however the APC injection method will work on 2003.
 */
DWORD inject_via_remotethread_wow64( HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter, HANDLE * pThread )
{
    DWORD dwResult           = ERROR_SUCCESS;
    EXECUTEX64 pExecuteX64   = NULL;
    X64FUNCTION pX64function = NULL;
    WOW64CONTEXT * ctx       = NULL;
    OSVERSIONINFO os         = {0};

    do
    {
        os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );

        if( !GetVersionEx( &os ) )
            BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: GetVersionEx failed" )

        // filter out Windows 2003
        if ( os.dwMajorVersion == 5 && os.dwMinorVersion == 2 )
        {
            SetLastError( ERROR_ACCESS_DENIED );
            BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: Windows 2003 not supported." )
        }

        // alloc a RWX buffer in this process for the EXECUTEX64 function
        pExecuteX64 = (EXECUTEX64)VirtualAlloc( NULL, sizeof(migrate_executex64), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
        if( !pExecuteX64 )
            BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: VirtualAlloc pExecuteX64 failed" )

        // alloc a RWX buffer in this process for the X64FUNCTION function (and its context)
        pX64function = (X64FUNCTION)VirtualAlloc( NULL, sizeof(migrate_wownativex)+sizeof(WOW64CONTEXT), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
        if( !pX64function )
            BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: VirtualAlloc pX64function failed" )

        // copy over the wow64->x64 stub
        memcpy( pExecuteX64, &migrate_executex64, sizeof(migrate_executex64) );

        // copy over the native x64 function
        memcpy( pX64function, &migrate_wownativex, sizeof(migrate_wownativex) );

        // set the context
        ctx = (WOW64CONTEXT *)( (BYTE *)pX64function + sizeof(migrate_wownativex) );

        ctx->h.hProcess       = hProcess;
        ctx->s.lpStartAddress = lpStartAddress;
        ctx->p.lpParameter    = lpParameter;
        ctx->t.hThread        = NULL;

        dprintf( "[INJECT] inject_via_remotethread_wow64: pExecuteX64=0x%08X, pX64function=0x%08X, ctx=0x%08X", pExecuteX64, pX64function, ctx );

        // Transition this wow64 process into native x64 and call pX64function( ctx )
        // The native function will use the native Win64 API's to create a remote thread in the target process.
        if( !pExecuteX64( pX64function, (DWORD)ctx ) )
        {
            SetLastError( ERROR_ACCESS_DENIED );
            BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: pExecuteX64( pX64function, ctx ) failed" )
        }

        if( !ctx->t.hThread )
        {
            SetLastError( ERROR_INVALID_HANDLE );
            BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: ctx->t.hThread is NULL" )
        }

        // Success! grab the new thread handle from of the context
        *pThread = ctx->t.hThread;

        dprintf( "[INJECT] inject_via_remotethread_wow64: Success, hThread=0x%08X", ctx->t.hThread );

    } while( 0 );

    if( pExecuteX64 )
        VirtualFree( pExecuteX64, 0, MEM_DECOMMIT );

    if( pX64function )
        VirtualFree( pX64function, 0, MEM_DECOMMIT );

    return dwResult;
}
我尝试使用以下代码:

#include <boost/scope_exit.hpp>

#include <Windows.h>

#include <cstdlib>
#include <iostream>

typedef struct _WOW64CONTEXT
{
  union
  {
    HANDLE hProcess;
    BYTE bPadding2[8];
  } h;
  union
  {
    LPVOID lpStartAddress;
    BYTE bPadding1[8];
  } s;
  union
  {
    LPVOID lpParameter;
    BYTE bPadding2[8];
  } p;
  union
  {
    HANDLE hThread;
    BYTE bPadding2[8];
  } t;
} WOW64CONTEXT, *LPWOW64CONTEXT;

typedef BOOL(WINAPI * X64FUNCTION)(DWORD dwParameter);
typedef DWORD(WINAPI * EXECUTEX64)(X64FUNCTION pFunction, DWORD dwParameter);

BYTE migrate_executex64[] = "\x55\x89\xE5\x56\x57\x8B\x75\x08\x8B\x4D\x0C\xE8\x00\x00\x00\x00"
                            "\x58\x83\xC0\x25\x83\xEC\x08\x89\xE2\xC7\x42\x04\x33\x00\x00\x00"
                            "\x89\x02\xE8\x09\x00\x00\x00\x83\xC4\x14\x5F\x5E\x5D\xC2\x08\x00"
                            "\x8B\x3C\x24\xFF\x2A\x48\x31\xC0\x57\xFF\xD6\x5F\x50\xC7\x44\x24"
                            "\x04\x23\x00\x00\x00\x89\x3C\x24\xFF\x2C\x24";

BYTE migrate_wownativex[] = "\xFC\x48\x89\xCE\x48\x89\xE7\x48\x83\xE4\xF0\xE8\xC8\x00\x00\x00"
                            "\x41\x51\x41\x50\x52\x51\x56\x48\x31\xD2\x65\x48\x8B\x52\x60\x48"
                            "\x8B\x52\x18\x48\x8B\x52\x20\x48\x8B\x72\x50\x48\x0F\xB7\x4A\x4A"
                            "\x4D\x31\xC9\x48\x31\xC0\xAC\x3C\x61\x7C\x02\x2C\x20\x41\xC1\xC9"
                            "\x0D\x41\x01\xC1\xE2\xED\x52\x41\x51\x48\x8B\x52\x20\x8B\x42\x3C"
                            "\x48\x01\xD0\x66\x81\x78\x18\x0B\x02\x75\x72\x8B\x80\x88\x00\x00"
                            "\x00\x48\x85\xC0\x74\x67\x48\x01\xD0\x50\x8B\x48\x18\x44\x8B\x40"
                            "\x20\x49\x01\xD0\xE3\x56\x48\xFF\xC9\x41\x8B\x34\x88\x48\x01\xD6"
                            "\x4D\x31\xC9\x48\x31\xC0\xAC\x41\xC1\xC9\x0D\x41\x01\xC1\x38\xE0"
                            "\x75\xF1\x4C\x03\x4C\x24\x08\x45\x39\xD1\x75\xD8\x58\x44\x8B\x40"
                            "\x24\x49\x01\xD0\x66\x41\x8B\x0C\x48\x44\x8B\x40\x1C\x49\x01\xD0"
                            "\x41\x8B\x04\x88\x48\x01\xD0\x41\x58\x41\x58\x5E\x59\x5A\x41\x58"
                            "\x41\x59\x41\x5A\x48\x83\xEC\x20\x41\x52\xFF\xE0\x58\x41\x59\x5A"
                            "\x48\x8B\x12\xE9\x4F\xFF\xFF\xFF\x5D\x4D\x31\xC9\x41\x51\x48\x8D"
                            "\x46\x18\x50\xFF\x76\x10\xFF\x76\x08\x41\x51\x41\x51\x49\xB8\x01"
                            "\x00\x00\x00\x00\x00\x00\x00\x48\x31\xD2\x48\x8B\x0E\x41\xBA\xC8"
                            "\x38\xA4\x40\xFF\xD5\x48\x85\xC0\x74\x0C\x48\xB8\x00\x00\x00\x00"
                            "\x00\x00\x00\x00\xEB\x0A\x48\xB8\x01\x00\x00\x00\x00\x00\x00\x00"
                            "\x48\x83\xC4\x50\x48\x89\xFC\xC3";

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    std::cout << "Usage: " << argv[0] << " [pid]" << std::endl;
    return EXIT_SUCCESS;
  }

  int pid = std::atoi(argv[1]);
  if (pid == 0)
  {
    std::cerr << "Invalid pid" << std::endl;
    return EXIT_FAILURE;
  }

  HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  if (process_handle == NULL)
  {
    std::cerr << "An error occurred while using function OpenProcess. Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }
  BOOST_SCOPE_EXIT_ALL(process_handle)
  {
    CloseHandle(process_handle);
  };

  LPVOID load_library_addr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
  if (load_library_addr == NULL)
  {
    std::cerr << "An error occurred while using function GetProcAddress. Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }

  const char* dll_path = "D:\\helper.dll";

  LPVOID dll_path_memory = VirtualAllocEx(process_handle, NULL, strlen(dll_path) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  if (dll_path_memory == NULL)
  {
    std::cerr << "An error occurred while using function VirtualAllocEx. Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }

  BOOL res = WriteProcessMemory(process_handle, dll_path_memory, dll_path, strlen(dll_path) + 1, NULL);
  if (res == 0)
  {
    std::cerr << "An error occurred while using function WriteProcessMemory. Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }

  HANDLE thread_handle = CreateRemoteThread(process_handle, NULL, 0, (LPTHREAD_START_ROUTINE)load_library_addr, dll_path_memory, 0, NULL);
  if (thread_handle == NULL)
  {
    std::cerr << "An error occurred while using function CreateRemoteThread. Error code: " << GetLastError() << std::endl;

    EXECUTEX64 pExecuteX64 = (EXECUTEX64)VirtualAlloc(NULL, sizeof(migrate_executex64), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (pExecuteX64 == NULL)
    {
      std::cerr << "An error occurred while using function VirtualAlloc. Error code: " << GetLastError() << std::endl;
      return EXIT_FAILURE;
    }

    X64FUNCTION pX64function = (X64FUNCTION)VirtualAlloc(NULL, sizeof(migrate_wownativex) + sizeof(WOW64CONTEXT), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (pX64function == NULL)
    {
      std::cerr << "An error occurred while using function VirtualAlloc. Error code: " << GetLastError() << std::endl;
      return EXIT_FAILURE;
    }

    std::memcpy(pExecuteX64, &migrate_executex64, sizeof(migrate_executex64));
    std::memcpy(pX64function, &migrate_wownativex, sizeof(migrate_wownativex));

    WOW64CONTEXT* ctx = (WOW64CONTEXT *)((BYTE *)pX64function + sizeof(migrate_wownativex));
    ctx->h.hProcess = process_handle;
    ctx->s.lpStartAddress = load_library_addr;
    ctx->p.lpParameter = dll_path_memory;
    ctx->t.hThread = NULL;

    if (!pExecuteX64(pX64function, (DWORD)ctx))
    {
      std::cerr << "Error" << std::endl;
      return EXIT_FAILURE;
    }

    if (!ctx->t.hThread)
    {
      std::cerr << "ctx->t.hThread is NULL" << std::endl;
      return EXIT_FAILURE;
    }

    HANDLE hThread = ctx->t.hThread;

    if (ResumeThread(hThread) == (DWORD)-1)
    {
      std::cerr << "An error occurred while using function ResumeThread. Error code: " << GetLastError() << std::endl;
      return EXIT_FAILURE;
    }
  }

  WaitForSingleObject(thread_handle, INFINITE);

  std::cout << "Done" << std::endl;
}
#包括
#包括
#包括
#包括
类型定义结构\u WOW64CONTEXT
{
联盟
{
处理hProcess;
字节bPadding2[8];
}h;
联盟
{
LPVOID lpStartAddress;
字节bPadding1[8];
}s;
联盟
{
LPVOID参数;
字节bPadding2[8];
}p;
联盟
{
处理hThread;
字节bPadding2[8];
}t;
}WOW64CONTEXT,*LPWOW64CONTEXT;
typedef BOOL(WINAPI*X64FUNCTION)(DWORD DWORD参数);
typedef DWORD(WINAPI*EXECUTEX64)(x64函数pFunction,DWORD DWORD参数);
字节迁移\u executex64[]=“\x55\x89\xE5\x56\x57\x8B\x75\x08\x8B\x4D\x0C\xE8\x00\x00\x00”
“\x58\x83\xC0\x25\x83\xEC\x08\x89\xE2\xC7\x42\x04\x33\x00\x00”
“\x89\x02\xE8\x09\x00\x00\x00\x83\xC4\x14\x5F\x5E\x5D\xC2\x08\x00”
“\x8B\x3C\x24\xFF\x2A\x48\x31\xC0\x57\xFF\xD6\x5F\x50\xC7\x44\x24”
“\x04\x23\x00\x00\x00\x00\x89\x3C\x24\xFF\x2C\x24”;
BYTE migrate\u wownativex[]=“\xFC\x48\x89\xCE\x48\x89\xE7\x48\x83\xE4\xF0\xE8\x88\x00\x00”
“\x41\x51\x41\x50\x52\x51\x56\x48\x31\xD2\x65\x48\x8B\x52\x60\x48”
“\x8B\x52\x18\x48\x8B\x52\x20\x48\x8B\x72\x50\x48\x0F\xB7\x4A\x4A”
“\x4D\x31\xC9\x48\x31\xC0\xAC\x3C\x61\x7C\x02\x2C\x20\x41\xC1\xC9”
“\x0D\x41\x01\xC1\xE2\xED\x52\x41\x51\x48\x8B\x52\x20\x8B\x42\x3C”
“\x48\x01\xD0\x66\x81\x78\x18\x0B\x02\x75\x72\x8B\x80\x88\x00”
“\x00\x48\x85\xC0\x74\x67\x48\x01\xD0\x50\x8B\x48\x18\x44\x8B\x40”
“\x20\x49\x01\xD0\xE3\x56\x48\xFF\xC9\x41\x8B\x34\x88\x48\x01\xD6”
“\x4D\x31\xC9\x48\x31\xC0\xAC\x41\xC1\xC9\x0D\x41\x01\xC1\x38\xE0”
“\x75\xF1\x4C\x03\x4C\x24\x08\x45\x39\xD1\x75\xD8\x58\x44\x8B\x40”
“\x24\x49\x01\xD0\x66\x41\x8B\x0C\x48\x44\x8B\x40\x1C\x49\x01\xD0”
“\x41\x8B\x04\x88\x48\x01\xD0\x41\x58\x41\x58\x5E\x59\x5A\x41\x58”
“\x41\x59\x41\x5A\x48\x83\xEC\x20\x41\x52\xFF\xE0\x58\x41\x59\x5A”
“\x48\x8B\x12\xE9\x4F\xFF\xFF\x5D\x4D\x31\xC9\x41\x51\x48\x8D”
“\x46\x18\x50\xFF\x76\x10\xFF\x76\x08\x41\x51\x41\x51\x49\xB8\x01”
“\x00\x00\x00\x00\x00\x00\x00\x00\x48\x31\xD2\x48\x8B\x0E\x41\xBA\xC8”
“\x38\xA4\x40\xFF\xD5\x48\x85\xC0\x74\x0C\x48\xB8\x00\x00\x00”
“\x00\x00\x00\x00\xEB\x0A\x48\xB8\x01\x00\x00\x00\x00\x00\x00\x00\x00”
“\x48\x83\xC4\x50\x48\x89\xFC\xC3”;
int main(int argc,char*argv[])
{
如果(argc!=2)
{

std::cout不是真的

64位Windows操作系统可以本机运行64位代码,也可以使用WOW64运行32位代码。但是,每个进程只能是一个或另一个进程

当进入内部时,您可以看到每个进程被标记为32位或64位。当操作系统指示CPU运行与该进程相关联的线程时,它将跳转为32位或64位代码

因此,如果您以某种方式将32位字节码(不管它从哪里编码,DLL或其他东西)加载到64位进程中,当操作系统运行它时,进程将崩溃,因为进程将处于64位模式,并将操作码解释为64位操作码

在32位代码上运行64位代码也是如此

编辑


事实上,x32 WOW64进程有可能执行x64代码。根据这一点,我找不到有关运行x86代码的x64进程的资源。

尽管它没有完全相同的功能(将x86代码注入x64进程),您是否考虑过使用COM包装器?我使用COM解决了这一问题,可以从两个方向(x86到x64,或x64到x86)解决。但不要尝试加载进程中的dll,请使用windows代理服务器。@Steven Hansen您能给我提供更多信息吗?另外,我并没有这两个应用程序的源代码--我正在尝试修复COM包装器中一个软件中的错误,您可以创建自己的自定义接口,并像正常情况一样加载/调用dll。dll的源代码I这不是必需的。只是研究COM服务器。有时这些服务器是用ATL编写的(可能是搜索的有用术语),Visual Studio支持许多帮助程序来编写它们。根据您发布的Metasploit代码中的注释,它不会将32位代码注入目标64位进程。它将64位代码从32位进程注入目标64位进程。它们使用的WinAPI函数比我发布的要多——请看e Metasploit的存储库。事实上,他们也这么做——从WOW64进程向x64进程注入DLL,所以我想知道在我的案例中有什么问题。你检查过Metasploit的代码是否成功地将x86 DLL注入x64进程吗?事实上,有人声称你可以在进程内的32位和64位之间切换。我正在检查检查此项-检查此项:-流程可以使用适当的程序集切换模式(为什么操作系统不支持它?)。但是,没有用于此项的操作系统API,通常不受支持。