关于挂接CreateProcessW的疑问

AtomicDream 2008-10-28 06:22:34
大家好:

我在使用detours v2.1挂接api,运行正常,但关于宽字符有一个问题:
程序a.exe调用了CreateProcess.
我挂接了CreateProcessA,验证可以拦截到a.exe的CreateProcess调用并拦截;
然后,挂接了CreateProcessW,这时却无法拦截到a.exe的CreateProcess调用
疑问点:
Kernel32.dll中的CreateProcessA的实现应该是这样的:
CreateProcessA(para)
{
将para转换为宽字符paraw
CreateProcessW(paraw)
}
因此,凡是用 CreateProcessA能挂接的,用CreateProcessW应该也能挂接到,而且更底层,但实际并非如此。

...全文
311 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
peakxp 2008-12-01
  • 打赏
  • 举报
回复
Windows via C/C++虽然说CreateProcessA将单字节转换为双字节后调用CreateProcessW,但只是底层实现,并不是显示地在用户层调用,而Detours挂接的是用户层的CreateProcessW,所以不行。
KeSummer 2008-11-05
  • 打赏
  • 举报
回复
用调试器下个断点在CreateProcessW和CreateProcessA,然后看看有没调用到。
xlt123 2008-10-29
  • 打赏
  • 举报
回复
CreateProcessW显然是可以挂接的。

HMODULE h = LoadLiberay("kernel32.dll");
fa = GetProcAddress(h,"CreateProcessW");

查找函数导入表,找字符串 "Kernel32.dll"
再找每一个节,找到与fa相等的值,就是CreateProcessW的地址。
替换成挂接函数的地址就可以了。

如果无法找到与fa相等的值,说明在你之前,已经有进程挂接了a.exe的CreateProcessW.
这时候,也可以用硬编码的方式挂接。
定义7个字符的数组
unsigned char new_code[] = {0B8H,0,0,0,0,0FFH,0E0H};

将0,0,0,0替换成挂接函数的地址。

这7个字节的意思是 MOV EAX,address_of_proc ; JMP EAX

unsigned char old_code[] = {0,0,0,0,0,0,0}; 将CreateProcessW的头7个字节读出来,保存进数组。

再将 new_code 7个字节写入 CreateProcessW 开始处就实现了挂接。

需要注意的是挂接函数的写法。如果在挂接函数里不需要再调用 CreateProcessW
则简单了。只需要直接返回就可以了。

如果需要再调用 CreateProcessW,则需要将 old_code 写回 CreateProcessW,
调用完后,再将 new_code 写入 CreateProcessW。重新挂接。

需要注意下栈的状态。
vcPlayer 2008-10-29
  • 打赏
  • 举报
回复
这个要看内核的情况了。你跟踪一下CreateProcessA在你的EXE程序中是否就是调用的CreateProcessW来实现的?说不定直接进入内核模式调用了呢NtCreateProcess?
AtomicDream 2008-10-29
  • 打赏
  • 举报
回复
我是在XP下,detours 2.1
static BOOL (WINAPI * TrueCreateProcessW)(LPCWSTR lpApplicationName...) = CreateProcessW;
__declspec(dllexport) BOOL WINAPI NewCreateProcess(...)
{
MessageBoxW(...)
return TrueCreateProcess(...
}
CreateProcessA雷同。

挂接的应该没问题,挂接过好多函数了。
WinEggDrop 2008-10-29
  • 打赏
  • 举报
回复
xp/2003你要挂的是CreateProcessEx(),你挂CreateProcessW()会失效的.
dirdirdir3 2008-10-29
  • 打赏
  • 举报
回复
错了,只是vista是这样做,xp也是不同的...............
sys0004 2008-10-29
  • 打赏
  • 举报
回复
哦,应该不至于这么弱吧

你咋做的?
dirdirdir3 2008-10-29
  • 打赏
  • 举报
回复
看在什么系统了,xp和vista下面是这样。
而98则是分开做的..........
sanshao27 2008-10-29
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 cnzdgs 的回复:]
我现在是想先确定一下你得到的“无法拦截”的结论是否正确,所以问你是如何得出这个结论的。既然是自己的程序就更好办了,用F5运行程序,在你的Hook函数上设置一个断点,看能否执行到。
[/Quote]

同意
cnzdgs 2008-10-29
  • 打赏
  • 举报
回复
我现在是想先确定一下你得到的“无法拦截”的结论是否正确,所以问你是如何得出这个结论的。既然是自己的程序就更好办了,用F5运行程序,在你的Hook函数上设置一个断点,看能否执行到。
AtomicDream 2008-10-29
  • 打赏
  • 举报
回复
大家所答非所问,有人说用IAT方式挂接,那个是没有问题的,正确。但我问的是detours挂接的错误。
挂接CreateProcessW也没有错误,错误描述请见第一个帖子所述。
有人说可能是GetProcAddress获得的,也不对,我试验的a.exe就是我自己写的程序,只有一个CreateProcessA一段代码而已。
如果不能排除各种复杂的可能,我就不会问这个问题了。
AtomicDream 2008-10-29
  • 打赏
  • 举报
回复
这是Windows 核心编程第四和第五版中说的。
[Quote=引用 10 楼 hbdycnm 的回复:]
Kernel32.dll中的CreateProcessA的实现应该是这样的:
CreateProcessA(para)
{
将para转换为宽字符paraw
CreateProcessW(paraw)
}

//我没查到这个东西呢? Kernel32.dll的代码公开了吗?
为什么做这样的判断呢?
[/Quote]
wym_2007 2008-10-29
  • 打赏
  • 举报
回复
dll下怎么跟踪CreateProcess呢?
hbdycnm 2008-10-29
  • 打赏
  • 举报
回复
Kernel32.dll中的CreateProcessA的实现应该是这样的:
CreateProcessA(para)
{
将para转换为宽字符paraw
CreateProcessW(paraw)
}

//我没查到这个东西呢? Kernel32.dll的代码公开了吗?
为什么做这样的判断呢?
cnzdgs 2008-10-29
  • 打赏
  • 举报
回复
你是怎么确定没有拦截到的?贴一下相关代码。
另外,也不排除有CreateProcessA不调用CreateProcessW的可能。
xlt123 2008-10-29
  • 打赏
  • 举报
回复
当然,也许a.exe中的CreateProcessW不是被别的进程挂接了,而是
a.exe 用 LoadLibrary+GetProcAddress 调用。

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧