吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 466|回复: 14
收起左侧

[求助] VxKex NEXT对Win8.1的兼容问题

  [复制链接]
NEOWISE 发表于 2026-1-9 22:58
VxKex NEXT是一个Win7扩展API兼容层。本人是项目开发者之一,准备将其移植到Win8.1上。目前,项目已部分兼容Win8.1,主要问题是无法将IFEO设置传播到子进程上。
VxKex NEXT对子进程使用NtOpenKey钩子以传播IFEO设置。以下为代码:
[C] 纯文本查看 复制代码

STATIC CONST BYTE KexpNtOpenKeyHook32_Win7[] = {
	0xE8, 0x00, 0x00, 0x00, 0x00, 0x58, 0x83, 0xC0, 0x06, 0xEB, 0x43, 0x00, 0x38, 0x00, 0x3A, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x7B, 0x00, 0x56, 0x00, 0x78, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x78, 0x00,
	0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00,
	0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x56, 0x00, 0x69, 0x00, 0x72, 0x00, 0x74, 0x00, 0x75, 0x00,
	0x61, 0x00, 0x6C, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x80, 0x38,
	0x00, 0x75, 0x2A, 0x64, 0x8B, 0x15, 0x30, 0x00, 0x00, 0x00, 0x8B, 0x52, 0x10, 0x81, 0x62, 0x08,
	0xFF, 0xBF, 0xFF, 0xFF, 0x8B, 0x54, 0x24, 0x0C, 0x8B, 0x4A, 0x04, 0x85, 0xC9, 0x74, 0x0E, 0xFE,
	0x00, 0x8D, 0x48, 0x01, 0x83, 0xC0, 0x09, 0x89, 0x41, 0x04, 0x89, 0x4A, 0x08, 0xB8, 0xB6, 0x00,
	0x00, 0x00, 0xBA, 0x00, 0x03, 0xFE, 0x7F, 0x83, 0x3A, 0x00, 0x74, 0x05, 0xFF, 0x12, 0xC2, 0x0C,
	0x00, 0xB8, 0x0F, 0x00, 0x00, 0x00, 0x31, 0xC9, 0x8D, 0x54, 0x24, 0x04, 0x64, 0xFF, 0x15, 0xC0,
	0x00, 0x00, 0x00, 0x83, 0xC4, 0x04, 0xC2, 0x0C, 0x00
};

// KexpNtOpenKeyHook64:
//		cmp		[.AlreadyRewritten], 0				; Check if already rewrote key name
//		jnz		.DontRewrite						; If so, just syscall
//
//		; Clear RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING flag in ProcessParameters.
//		; The flag is set by the kernel to indicate that there is no IFEO key. and if it
//		; is set, the NTDll loader won't try to open the IFEO key and won't call this hook
//		; in the right way to cause proper VxKex initialization.
//		mov		rax, gs:0x60						; rax = PEB address
//		mov		rax, [rax+0x20]						; rax = Peb->ProcessParmameters
//		and		dword [rax+8], ~0x4000				;  ProcessParameters->Flags &= ~RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING
//
//		mov		rax, [r8+0x08]						; r8 = ObjectAttributes->RootDirectory
//		test	eax, eax							; if RootDirectory == NULL
//		jz		.DontRewrite						; then don't rewrite (because it isn't the call
//													; that we want to rewrite)
//		; Now we are definitely rewriting.
//		inc		[.AlreadyRewritten]					; flag to future calls of this hook
//		lea		rax, [.PropagationVirtualKeyName]	; rax = &PropagationVirtualKeyName
//		mov		[rax+0x08], rax
//		add		qword [rax+0x08], 16				; : PropagationVirtualKeyName->Buffer = &PropagationVirtualKeyString
//		mov		[r8+0x10], rax						; ObjectAttributes->ObjectName = &PropagationVirtualKeyName
//
// .DontRewrite:
//		; This is just the Ntopenkey syscall as usual.
//		mov		r10, rcx
//		mov		eax, 0x0F
//		syscall
//		ret
//
// .AlreadyRewritten: db 0
//
//		; NOPs for alignment of the UNICODE_STRING structure
//		nop
//		nop
//		nop
//		nop
//		nop
//
// ; UNICODE_STRING structure
// .PropagationVirtualKeyName:
//		dw		0x38	; Length
//		dw		0x3A	; MaximumLength
//		dd		0		; (padding)
//		dq		0		; pointer, gets filled out by code
// .PropagationVirtualKeyString
// ; {VxKexPropagationVirtualKey}
//		dw		'{', 'V', 'x', 'K', 'e', 'x', 'P', 'r', 'o', 'p', 'a', 'g', 'a', 't'
//		dw		'i', 'o', 'n', 'V', 'i', 'r', 't', 'u', 'a', 'l', 'K', 'e', 'y', '}', 0
//

STATIC CONST BYTE KexpNtOpenKeyHook64_Win7[] = {
	0x80, 0x3D, 0x43, 0x00, 0x00, 0x00, 0x00, 0x75, 0x36, 0x65, 0x48, 0x8B, 0x04, 0x25, 0x60, 0x00,
	0x00, 0x00, 0x48, 0x8B, 0x40, 0x20, 0x81, 0x60, 0x08, 0xFF, 0xBF, 0xFF, 0xFF, 0x49, 0x8B, 0x40,
	0x08, 0x85, 0xC0, 0x74, 0x1A, 0xFE, 0x05, 0x1F, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x05, 0x1E, 0x00,
	0x00, 0x00, 0x48, 0x89, 0x40, 0x08, 0x48, 0x83, 0x40, 0x08, 0x10, 0x49, 0x89, 0x40, 0x10, 0x49,
	0x89, 0xCA, 0xB8, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x05, 0xC3, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90,
	0x38, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x7B, 0x00, 0x56, 0x00, 0x78, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x78, 0x00, 0x50, 0x00, 0x72, 0x00,
	0x6F, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00,
	0x6E, 0x00, 0x56, 0x00, 0x69, 0x00, 0x72, 0x00, 0x74, 0x00, 0x75, 0x00, 0x61, 0x00, 0x6C, 0x00,
	0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x7D, 0x00, 0x00, 0x00
};


此代码在Win7上正常运作,在Win8.1上修改系统调用数为0x11后无效。根据对Win8.1的ntdll.dll逆向,NtOpenKey第一次调用时会检查IFEO注册表设置并修改一个变量值。关键代码实现可能在WerpGlobalFlagsForProcess函数中。由于本人不懂汇编语言,完全靠AI分析代码,所以不清楚如何修改这段汇编代码,恳请大佬们提供解决方案,谢谢!

免费评分

参与人数 1热心值 +1 收起 理由
gleave + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

gleave 发表于 2026-1-10 08:57
伟大的开发者
炫迈 发表于 2026-1-10 14:20
Win8.1的IFEO机制和Win7确实有本质区别,你这个钩子在Win7能用是因为Win7的loader会多次调用NtOpenKey检查IFEO,但Win8.1改成了单次检查加缓存机制,你那个清标志位的方法在Win8.1的Peb->ProcessParameters里已经不管用了,我之前给一个类似项目做过兼容,关键是要在进程创建早期就注入,而不是等NtOpenKey被调用,建议你改用ProcessNotify回调,在PsSetCreateProcessNotifyRoutine里拦截新进程创建,直接修改新进程的EPROCESS结构里的Flags字段,把IMAGE_FILE_EXECUTION_OPTIONS标志位提前置上,这样loader就不会跳过IFEO检查了,另外Win8.1的ntdll里有个WerRegisterRuntimeExceptionModule函数也会干扰IFEO传播,你得在LdrpInitializeProcess函数里下钩子,时机要比NtOpenKey更早,我调试过Win8.1的ntdll,它的IFEO检查逻辑在LdrpSnapIAT里就完成了,比Win7提前了两个函数调用层级,你那个UNICODE_STRING硬编码的方法在Win8.1上会被内核校验绕过,建议改用RtlCreateUnicodeString动态生成,这样最稳妥
lsg642 发表于 2026-1-10 09:51
iSummer999 发表于 2026-1-10 10:47
win8用的人不多了
drw 发表于 2026-1-10 10:53
哇,作者来了,谢谢啦,经常用!
studyggm 发表于 2026-1-10 11:40
for win8 依然支持楼主,有必要的
 楼主| NEOWISE 发表于 2026-1-10 18:24
炫迈 发表于 2026-1-10 14:20
Win8.1的IFEO机制和Win7确实有本质区别,你这个钩子在Win7能用是因为Win7的loader会多次调用NtOpenKey检查I ...

是否可以不用驱动,只用一个内核模式dll调用这个函数?
msn882 发表于 2026-1-10 18:49
NEOWISE 发表于 2026-1-10 18:24
是否可以不用驱动,只用一个内核模式dll调用这个函数?

IFEO 不就是exe重定向吗? 这功能基本没用吧,吧这个功能在win8中去掉不就好了
 楼主| NEOWISE 发表于 2026-1-10 18:58
msn882 发表于 2026-1-10 18:49
IFEO 不就是exe重定向吗? 这功能基本没用吧,吧这个功能在win8中去掉不就好了

这个功能当然非常有用,不只是exe重定向,可以对进程进行很多底层操作,实现兼容新版WinAPI。没了这个功能,VxKex NEXT就罢工了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-1-13 17:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表