C 从x64进程向x86进程注入x86代码

C 从x64进程向x86进程注入x86代码,c,winapi,assembly,x86,x86-64,C,Winapi,Assembly,X86,X86 64,我意识到标题有点复杂,所以让我解释一下我想做什么: 我刚刚完成了一个简单的DLL注入器的编写,这是我正在尝试编写的概念验证。该程序获取当前进程的快照,枚举进程树,并将DLL注入其直接父进程。现在,在理想的条件下,它可以正常工作:32位版本的注入器可以注入32位父进程,64位版本的注入器可以注入64位父进程 不过,我现在要做的是从x64注入器向32位父进程注入一个32位DLL。一旦这个DLL被注入,我希望接着注入一个调用到被注入的DLL导出的函数之一。不过,我不确定这是否真的可行。(我已经编写了一

我意识到标题有点复杂,所以让我解释一下我想做什么:

我刚刚完成了一个简单的DLL注入器的编写,这是我正在尝试编写的概念验证。该程序获取当前进程的快照,枚举进程树,并将DLL注入其直接父进程。现在,在理想的条件下,它可以正常工作:32位版本的注入器可以注入32位父进程,64位版本的注入器可以注入64位父进程

不过,我现在要做的是从x64注入器向32位父进程注入一个32位DLL。一旦这个DLL被注入,我希望接着注入一个调用到被注入的DLL导出的函数之一。不过,我不确定这是否真的可行。(我已经编写了一些代码来确定父进程是32位进程还是64位进程,所以这不会成为问题)

现在,我已经找到了一些代码,它们似乎可以完成第一部分。(至少,我认为它是这样做的)通常,在注入对LoadLibraryW的调用之后,我会得到该调用返回的地址,将相对偏移量添加到我想要调用的导出函数中,然后注入对该函数的调用。不过在这种情况下,我无法将32位库加载到我的64位注入器中,因此我无法像通常那样使用来找到函数的相对偏移量。我通过以下步骤解决了这个问题:

由于我无法使用常规方法找到32位DLL的函数偏移量,因此我当前正在将文件读入缓冲区,使用该缓冲区填充结构,并枚举IMAGE_EXPORT_目录以查找所有导出函数的名称和相对偏移量

因此,在这一点上,我有以下几点:

  • 加载到32位进程中的32位DLL
  • 在32位进程中运行以下代码时等效于funcAddr的值:
代码:

理论上,我现在只需要Hinjecteddl的值,我应该能够调用该函数。不幸的是,尽管如此,我对汇编或机器代码的了解还不够,不知道如何获得那个值

有什么想法吗

(另外,我知道,只要编译两个版本的注入器,并在父进程的处理器架构不匹配时让一个运行另一个,我就可以省去很多麻烦。不过,我正试图避免走这条路。)

编辑:我想这可能有助于解释我在这一概念验证中真正想要实现的目标

我正在试验一个想法,我必须允许在当前控制台中执行子进程,而不需要原始进程等待子进程完成。由于在控制台应用程序中没有内置的API来执行此操作,因此您通常会遇到一个进程树,所有进程都在等待各自的子进程完成。为了简化此功能,我想执行以下操作:

注射 DLL注入器将扮演“执行进程”的角色。(通常必须等待子进程完成的进程)运行时,它确定其父进程的平台,以及父进程是否是基于控制台的应用程序。如果不是,则流程只使用运行所需的子流程,并立即退出。如果父进程是控制台应用程序,注入器将确定使用哪个DLL,挂起最初创建注入器进程的线程,然后将DLL注入父进程

解决我们的功能 一旦DLL就位,注入器将确定DLL导出的函数的地址。(通常,我会通过调用来进行初始注入,然后在该线程上使用来获取父进程中DLL的基址。一旦获得了基址,就可以通过简单的算法找到导出函数的地址,然后我可以使用该地址向该函数注入第二个调用

调用我们的函数 导出的函数将是以下内容:

BOOL RewriteHProcess(句柄hProcess)

注入器将再次使用CreateRemoteThread从父进程的上下文调用此函数,HPProcess是注入器进程的句柄(考虑到线程间内存访问的安全性限制,我不太确定我的第一个想法是否可行,所以如果第一个想法不可行,我就把第二个想法放在一起以供参考。)

  • RewriteHProcess将打开先前挂起的线程进行读写,并使用它在进程的内存中搜索注入进程的句柄。(我们假设父进程当前正在阻止函数的进一步执行。我知道命令提示符至少会阻止,这是我目前的重点)然后,DLL调用一个内部函数来创建所需的子进程,关闭旧句柄,并用新子进程的句柄覆盖内存。此时,它会清理它所能清理的内容并返回。然后注入器将执行它所需的任何剩余清理,恢复挂起的线程,关闭进程的句柄和线程,然后退出,让父进程在等待新的子进程结束时继续阻塞

  • 如果该路径不可行,我的退路是暂停来自注入器的阻塞线程,在注入的DLL中创建新的子进程,清理并退出注入器,然后在DLL中等待子进程完成。此时,DLL将清理,恢复暂停的线程,并卸载自身。(不过,这种路由的缺点是,父级
    HMODULE hInjectedDLL = LoadLibrary("mydll.dll");
    DWORD funcAddr = (DWORD)GetProcAddress(hInjectedDLL, "ExportedFunc") - (DWORD)hInjectedDLL;