slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
阅读:1678回复:18

请大家帮忙,看看这段VXD代码(71行)哪里有问题。

楼主#
更多 发布于:2003-12-20 11:46
我不想使用VToolsD进行开发(其实不是不想,而是使用VToolsD只能Build,而不能单独Compile其中某一个文件,故弃之不用)。

下面代码自己封装Hook_Device_Service,然后调用这个例程去Hook _RegOpenKey()服务,但是一运行就蓝屏,不知道哪里有问题。

分可随时加,只要你开口:D:D:D

#include \"StdVxd.h\"
#include \"TdiFlt.h\"      
#include <VMMReg.h>

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
typedef LONG (__stdcall* REGOPENKEY)(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult);

REGOPENKEY OriginalRegOpenKey;

LONG __stdcall MyRegOpenKey(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult)
{
  DbgPrint(\"Call RegOpenKey(), Key = %s\\n\",lpszSubKey);

  return OriginalRegOpenKey(hkey,lpszSubKey,phkResult);
}
          
//---------------------------------------------------------------------------
PVOID VXDINLINE __stdcall Hook_Device_Service(DWORD dwServiceID,PVOID HookProc)
{
  PVOID OldProc = NULL;

  _asm mov EAX,[dwServiceID]
  _asm mov ESI,[HookProc];
  VxDCall(Hook_Device_Service)
  _asm jc  ERROR
  _asm mov [OldProc],ESI
  _asm ERROR:

  return (OldProc);
}

VOID VXDINLINE __stdcall Unhook_Device_Service(DWORD dwServiceID,PVOID OldHookProc)
{
  _asm mov EAX,[dwServiceID]
  _asm mov ESI,[OldHookProc];
  VxDCall(Unhook_Device_Service)
}

//---------------------------------------------------------------------------
//
// Win32程序和VXD通讯时系统调用这个例程
//
SYSCTL BOOL __cdecl OnDeviceIoControl(PIOCTLPARAMS p)
{
  return 0;
}                

//---------------------------------------------------------------------------
//
// VXD被动态装载到内存时系统调用这个例程
//
SYSCTL BOOL __cdecl OnSysDynamicDeviceInit()
{
  DbgPrint(\"OnSysDynamicDeviceInit\");

  OriginalRegOpenKey = (REGOPENKEY)Hook_Device_Service(___RegOpenKey,MyRegOpenKey);

  return TRUE;
}

//---------------------------------------------------------------------------
//
// VXD被动态卸载出内存时系统调用这个例程
//
SYSCTL BOOL __cdecl OnSysDynamicDeviceExit()
{
  DbgPrint(\"OnSysDynamicDeviceExit\");

  Unhook_Device_Service(___RegOpenKey,OriginalRegOpenKey);

  return TRUE;                              
}

cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-12-20 12:06
PVOID VXDINLINE __stdcall Hook_Device_Service(DWORD dwServiceID,PVOID HookProc)
{
  PVOID OldProc = NULL;

  _asm mov EAX,[dwServiceID] <<---不明白,dwServiceID是地址?是不是应该为 _asm mov EAX,dwServiceID?
  _asm mov ESI,[HookProc]; <<---同上
  VxDCall(Hook_Device_Service)
  _asm jc ERROR
  _asm mov [OldProc],ESI <<---同上,你正在做的事情是 _asm mov [00000000h], ESI,这不是空指针吗?
  _asm ERROR:

  return (OldProc);
}

VOID VXDINLINE __stdcall Unhook_Device_Service(DWORD dwServiceID,PVOID OldHookProc)
{
  _asm mov EAX,[dwServiceID] <<---同前
  _asm mov ESI,[OldHookProc]; <<---同前
  VxDCall(Unhook_Device_Service)
}

汇编有阵子没有了,说不定我看错了,呵呵。:-)

[编辑 -  12/20/03 by  cool-net]
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-12-20 12:17
PVOID VXDINLINE __stdcall Hook_Device_Service(DWORD dwServiceID,PVOID HookProc)
{
  PVOID OldProc = NULL;

  _asm mov EAX,[dwServiceID] <<---不明白,dwServiceID是地址?是不是应该为 _asm mov EAX,dwServiceID?
  _asm mov ESI,[HookProc]; <<---同上
  VxDCall(Hook_Device_Service)
  _asm jc ERROR
  _asm mov [OldProc],ESI <<---同上,你正在做的事情是 _asm mov [00000000h], ESI,这不是空指针吗?
  _asm ERROR:

  return (OldProc);
}

VOID VXDINLINE __stdcall Unhook_Device_Service(DWORD dwServiceID,PVOID OldHookProc)
{
  _asm mov EAX,[dwServiceID] <<---同前
  _asm mov ESI,[OldHookProc]; <<---同前
  VxDCall(Unhook_Device_Service)
}

汇编有阵子没有了,说不定我看错了,呵呵。:-)

[编辑 -  12/20/03 by  cool-net]


我也觉得纳闷,但是VMM.H都是那样做的,比如:

HTIMEOUT VXDINLINE
Set_Async_Time_Out(void (*pfnTimeout)(), CMS cms, ULONG ulRefData)
{
    HTIMEOUT htimeout;
    _asm mov eax, [cms]
    _asm mov edx, [ulRefData]
    _asm mov esi, [pfnTimeout]
    VMMCall(Set_Async_Time_Out)
    _asm mov [htimeout], esi
    return(htimeout);
}

PVOID VXDINLINE
_HeapAllocate(ULONG Bytes, ULONG Flags)
{
    PVOID p;
    Touch_Register(eax)
    Touch_Register(ecx)
    Touch_Register(edx)
    _asm push [Flags]
    _asm push [Bytes]
    VMMCall(_HeapAllocate)
    _asm add esp, 8
    _asm mov [p], eax
    return(p);
}


或者谁能告诉我使用VToolsD,但是可以Compiler,而不只是可以Build,这个问题也算解决了。
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-12-20 13:00
___RegOpenKey应该是_RegOpenKey(就一个下划线吧?)

_asm mov EAX,[dwServiceID]
改成
GetVxdServiceOrdinal eax, dwServiceID
合适些

Unhook_Device_Service(___RegOpenKey,OriginalRegOpenKey)
是否应该是
Unhook_Device_Service(_RegOpenKey,MyRegOpenKey)

另外,_RegOpenKey应该是_cdecl而不是__stdcall吧?所以:
typedef LONG (__stdcall* REGOPENKEY)(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult);
可能要改成
typedef LONG (_cdecl* REGOPENKEY)(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult);

可以还有错误没找到,你先试试再说吧。
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-12-20 13:13
___RegOpenKey应该是_RegOpenKey(就一个下划线吧?)

_asm mov EAX,[dwServiceID]
改成
GetVxdServiceOrdinal eax, dwServiceID ---->>> 改成这样后,编译不通过
合适些

Unhook_Device_Service(___RegOpenKey,OriginalRegOpenKey)
是否应该是
Unhook_Device_Service(_RegOpenKey,MyRegOpenKey) ---->>> 改成这样后,编译不通过

另外,_RegOpenKey应该是_cdecl而不是__stdcall吧?所以:
typedef LONG (__stdcall* REGOPENKEY)(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult);
可能要改成
typedef LONG (_cdecl* REGOPENKEY)(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult);

可以还有错误没找到,你先试试再说吧。
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2003-12-20 13:39
我也觉得纳闷,但是VMM.H都是那样做的,比如:

HTIMEOUT VXDINLINE
Set_Async_Time_Out(void (*pfnTimeout)(), CMS cms, ULONG ulRefData)
{
    HTIMEOUT htimeout;
    _asm mov eax, [cms]
    _asm mov edx, [ulRefData]
    _asm mov esi, [pfnTimeout]
    VMMCall(Set_Async_Time_Out)
    _asm mov [htimeout], esi
    return(htimeout);
}

PVOID VXDINLINE
_HeapAllocate(ULONG Bytes, ULONG Flags)
{
    PVOID p;
    Touch_Register(eax)
    Touch_Register(ecx)
    Touch_Register(edx)
    _asm push [Flags]
    _asm push [Bytes]
    VMMCall(_HeapAllocate)
    _asm add esp, 8
    _asm mov [p], eax
    return(p);
}


或者谁能告诉我使用VToolsD,但是可以Compiler,而不只是可以Build,这个问题也算解决了。


set INCLUDE=...
set CL=-c -nologo ...
cl your.cpp

直接用cl呗
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2003-12-20 13:47
不知道你为何要单独compile一个文件呢?
既然用vtoolsd,修改mak文件,把你的文件加入,在build的时候自然会先compile你的文件才link的呀。
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-12-20 14:36
不知道你为何要单独compile一个文件呢?
既然用vtoolsd,修改mak文件,把你的文件加入,在build的时候自然会先compile你的文件才link的呀。


我的项目有很多文件,总不能每更改一个地方都要重新Build一下吧,那样太浪费时间 :(:(:(

而且一次就想更改所有出错的地方也是不可能的,所以只能分而治之,也就是单独编译其中某一个文件了,没想到VToolsD却不能Compile :mad: :mad: :mad:
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-12-20 14:42
[quote] 我也觉得纳闷,但是VMM.H都是那样做的,比如:

HTIMEOUT VXDINLINE
Set_Async_Time_Out(void (*pfnTimeout)(), CMS cms, ULONG ulRefData)
{
    HTIMEOUT htimeout;
    _asm mov eax, [cms]
    _asm mov edx, [ulRefData]
    _asm mov esi, [pfnTimeout]
    VMMCall(Set_Async_Time_Out)
    _asm mov [htimeout], esi
    return(htimeout);
}

PVOID VXDINLINE
_HeapAllocate(ULONG Bytes, ULONG Flags)
{
    PVOID p;
    Touch_Register(eax)
    Touch_Register(ecx)
    Touch_Register(edx)
    _asm push [Flags]
    _asm push [Bytes]
    VMMCall(_HeapAllocate)
    _asm add esp, 8
    _asm mov [p], eax
    return(p);
}


或者谁能告诉我使用VToolsD,但是可以Compiler,而不只是可以Build,这个问题也算解决了。


set INCLUDE=...
set CL=-c -nologo ...
cl your.cpp

直接用cl呗 [/quote]

通过什么方法调用这个命令???总不能让我到DOS自己执行这个命令吧?那样比Build更浪费时间!

如果打开地是.Mak文件,在Settings中根本没有出现Custom Build选项,否则这样做当然不难。

请老大继续指点。
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
9楼#
发布于:2003-12-20 15:24
也只是compile你修改的文件呀,又不全部compile一次的 ;)不过会link,可能还是费时间 :D

你可以把cl什么的那些命令写个bat文件呀
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-12-20 15:38
也只是compile你修改的文件呀,又不全部compile一次的 ;)不过会link,可能还是费时间 :D

你可以把cl什么的那些命令写个bat文件呀


这样做同样浪费时间,我的目的是在VC中按CTRL+F7进行编译。
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-12-20 15:42
搞定了!!!!!

把__stdcall改成__cdecl,其它没变,就OK了。

我以前看《Win95系统编程奥秘》时就已经知道了VXD服务使用__cdecl调用方式,可是真正到自己使用的时候就忘了,我靠!



另外,_RegOpenKey应该是_cdecl而不是__stdcall吧?所以:
typedef LONG (__stdcall* REGOPENKEY)(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult);
可能要改成
typedef LONG (_cdecl* REGOPENKEY)(VMMHKEY hkey, LPTSTR lpszSubKey, PVMMHKEY phkResult);

可以还有错误没找到,你先试试再说吧。


arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
12楼#
发布于:2003-12-20 15:45
把set 和cl放到bat文件,你只要运行bat就可以只compile指定文件,这样也浪费时间啊。

还有一个办法,就是建立一个普通的win32 app,改设置和参数来build你工程,应该可以单独compile一个文件的,没有试过,扯远了 :D :D
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-12-20 15:57
把set 和cl放到bat文件,你只要运行bat就可以只compile指定文件,这样也浪费时间啊。

还有一个办法,就是建立一个普通的win32 app,改设置和参数来build你工程,应该可以单独compile一个文件的,没有试过,扯远了 :D :D


这种方法我早就试过了,结果是VXD可以生成,但是无法LOAD,原因不详。

不管了那么多了,反正我现在的方法也不错,就是有时需要自己封装VXD服务以方便在C中调用。
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-12-20 15:58
给分了。
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
15楼#
发布于:2003-12-20 16:21
[quote]把set 和cl放到bat文件,你只要运行bat就可以只compile指定文件,这样也浪费时间啊。

还有一个办法,就是建立一个普通的win32 app,改设置和参数来build你工程,应该可以单独compile一个文件的,没有试过,扯远了 :D :D


这种方法我早就试过了,结果是VXD可以生成,但是无法LOAD,原因不详。

不管了那么多了,反正我现在的方法也不错,就是有时需要自己封装VXD服务以方便在C中调用。
 [/quote]
我刚试了,应该是有些section没有设置。有些属性我再看看,就能猜出来了 :D :D

Section \".bss\" (00002003) has an unknown VxD section type; image may not load
不要section就会这样滴
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
16楼#
发布于:2003-12-20 16:47
唉,不仔细看了,意义不太大。用editbin改变了几个section的属性。
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-12-20 18:19
先别忙给分啊,真的OK了?

//
// VXD被动态卸载出内存时系统调用这个例程
//
SYSCTL BOOL __cdecl OnSysDynamicDeviceExit()
{
  DbgPrint(\"OnSysDynamicDeviceExit\");

  Unhook_Device_Service(___RegOpenKey,OriginalRegOpenKey); <<---这里应该有大问题吧?第二个参数怎么看我都觉得应该是MyRegOpenKey才对呀?因为你要Unhook的是你自己的过程,而OriginalRegOpenKey里看样子存的是RealProc,这也能Unhook掉吗?

  return TRUE;
}
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-12-20 20:23
先别忙给分啊,真的OK了?

//
// VXD被动态卸载出内存时系统调用这个例程
//
SYSCTL BOOL __cdecl OnSysDynamicDeviceExit()
{
  DbgPrint(\"OnSysDynamicDeviceExit\");

  Unhook_Device_Service(___RegOpenKey,OriginalRegOpenKey); <<---这里应该有大问题吧?第二个参数怎么看我都觉得应该是MyRegOpenKey才对呀?因为你要Unhook的是你自己的过程,而OriginalRegOpenKey里看样子存的是RealProc,这也能Unhook掉吗?

  return TRUE;
}
 


我下午也发现了,现在已经改过来了,你看真仔细啊 :P
游客

返回顶部