C# 类库 Hook Assembly

TypeSharp 2018-01-25 03:28:39
我先描述一下我所处的问题环境:
最近在研究Hook的相关知识。
要求是所有的东西都由C#来完成,包括DLL,EXE。
我进行了下面尝试:
1、使用LoadLibrary加载C#写的DLL,然后SetWindowsHookEx,发现,只能在该进程里模块里找到加载的。
我怀疑是我代码错了。因为回调函数不是DLL里面的,是程序里面的。
2、我开始把回调函数放到DLL里面,但是如何操纵DLL里面的函数呢?我找到的方案是:GetProcAddress。但是我想了想不行。因为DLL是C#写的,里面有类什么的。逻辑上不成立。
3、我于是接着去找资料。发现C#写的DLL,可以用Assembly反射来调用函数。于是我写好了代码,并且调试。发现了问题。
第一,Assembly.LoadFrom("Mydll.dll");执行完,用工具查看,发现进程里没有Mydll这个模块。
第二,我在DLL中启动Hook的函数里写了,如果SetWindowsHookEx失败,就报错。结果报错了。说明SetWindowsHookEx调用失败了。这个失败应该是因为进程里没有Mydll这个模块。

DLL代码:

namespace Mydll
{
public class Main
{
public static int HookInt=0;
public static int CallBack(int nCode, Int32 wParam, IntPtr lParam)
{
return Api.CallNextHookEx(HookInt, nCode, wParam, lParam);

}
public static void HookStart()

{

if (HookInt == 0)

{
// 创建HookProc实例
Api.HookProc HookProcedure = new Api.HookProc(CallBack);
// 设置线程钩子
HookInt = Api.SetWindowsHookEx(Api.WH_CBT, HookProcedure,Process.GetCurrentProcess().Handle, 0);
// 如果设置钩子失败
if (HookInt == 0)
{
Log.Add("Set Hook Failed.");
Process.Start("http://www."+Process.GetCurrentProcess().Handle .ToString()+".com");
}
else
{
Log.Add("Set Hook Successfully.");
Process.Start("http://www.baidu.com");
}

}

}
public static void HookStop()
{
bool t = false;
if (HookInt != 0)

{
t = Api.UnhookWindowsHookEx(HookInt);
HookInt = 0;
}
if (!t)
{
Log.Add("Unhook Failed");
}
else
{
Log.Add("Unhook successfully.");
}
}
}
}



程序代码:

HookStart = null;
HookStop = null;
Assembly assembly = Assembly.LoadFrom("Mydll.dll");
if(assembly != null)
{
Type[] Ts = assembly.GetTypes();
Type AimType=null;
for(int i = 0; i < Ts.Length; i++)
{
if (Ts[i].Name == "Main")
{
AimType = Ts[i];
break;
}
}
if(AimType != null)
{
HookStart = AimType.GetMethod("HookStart");
HookStop = AimType.GetMethod("HookStop");
if(HookStart != null)
{
lBox.Items.Add(HookStart.ToString());
object obj = new object();
Object[] Params = new Object[0] { };
Object rbj = HookStart.Invoke(obj, Params);
if (rbj != null)
{
lBox.Items.Add(rbj.ToString());
}
if (HookStop != null)
{
lBox.Items.Add("Hook Start");
}

}
else
{

}

}


}


希望各位大佬帮忙看下。感谢。
...全文
624 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 5 楼 xinbada1985 的回复:
[quote=引用 4 楼 moodlee 的回复:] [quote=引用 3 楼 xinbada1985 的回复:] Assembly assembly = Assembly.LoadFrom("Mydll.dll"); 我想这个地方找的应该是文件的绝对路径,所以应该需要你把路径补全把!
这个我考虑到了,所以我把这个DLL放到了程序所在的文件夹。[/quote] 放到程序所在文件夹,那只能叫相对路径!绝对路径是D:\Work\514需要加这些东西的[/quote] 我知道什么是绝对路径和相对路径。 我查了资料,LoadFrom里面是可以相对路径和绝对路径。 如果是相对路径,那么就是当前文件夹下的。 我现在已经不通过Assembly反射来调用Mydll.Main.HookStart了。 而是参考你的Mydll.dll.HookStart() 来调用这个函数。(引用Mydll进来)。
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 6 楼 xinbada1985 的回复:
你先写一个绝对路径实验一下看看能不能找到
核心不是这个问题。 或许我之前描述有错误。 我之前说“报错”,那个“报错”的意思是人为报错。 Assembly 反射成功的。也就是说,这个dll是找到的。
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 2 楼 xinbada1985 的回复:
Mydll.Main mydll = new Mydll.Main();
mydll .HookStart();
mydll .HookStop()

这样用试试


其实这样使用和通过Assembly反射效果是一样的。(我说的效果是这个程序最终的执行效果)
SetWindowsHookEx失败。
我觉得主要问题是:
第一:
dll没有一般地加载到进程里面。
我解决这个问题的方法是:
先LoadLibrary。在程序里面写的Loadlibrary.

我用工具看了下。

发现这个dll的确加载进去了。
然后我在dll里面这样写:

为什么我要用过GetModuleHandle获取自身dll的模块句柄呢?是因为C#没有dllmain,所以我暂时没有办法找到获取自身句柄的方法。
然后进行SetWindowsHookEx,log提示:

虽然提示成功了,但是在其他进程里面没有发现Mydll.dll的影子。
所以我怀疑是因为没有DllMain的原因。但是又觉得不是这个原因。


第二:是不是C#写的DLL天生就没有这个能力?
因为托管代码?我觉得不对。DLL加载到进程里,只要这个系统运行环境有.NET框架,这个DLL就可以执行。
会不会是我一开始思路就错了?几率很小,连续奋斗两天,各种思路大都想过了。
xinbada1985 2018-01-25
  • 打赏
  • 举报
回复
引用 4 楼 moodlee 的回复:
[quote=引用 3 楼 xinbada1985 的回复:] Assembly assembly = Assembly.LoadFrom("Mydll.dll"); 我想这个地方找的应该是文件的绝对路径,所以应该需要你把路径补全把!
这个我考虑到了,所以我把这个DLL放到了程序所在的文件夹。[/quote] 放到程序所在文件夹,那只能叫相对路径!绝对路径是D:\Work\514需要加这些东西的
xinbada1985 2018-01-25
  • 打赏
  • 举报
回复
你先写一个绝对路径实验一下看看能不能找到
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 3 楼 xinbada1985 的回复:
Assembly assembly = Assembly.LoadFrom("Mydll.dll"); 我想这个地方找的应该是文件的绝对路径,所以应该需要你把路径补全把!
这个我考虑到了,所以我把这个DLL放到了程序所在的文件夹。
xinbada1985 2018-01-25
  • 打赏
  • 举报
回复
Assembly assembly = Assembly.LoadFrom("Mydll.dll"); 我想这个地方找的应该是文件的绝对路径,所以应该需要你把路径补全把!
xinbada1985 2018-01-25
  • 打赏
  • 举报
回复
Mydll.Main mydll = new Mydll.Main(); mydll .HookStart(); mydll .HookStop() 这样用试试
xinbada1985 2018-01-25
  • 打赏
  • 举报
回复
如果DLL已经引用到工程里面来了!那么就直接Mydll点你要调用的class就可以了,比如下面的。 Wpf.VistaFolderBrowserDialog fbd = new Wpf.VistaFolderBrowserDialog(); // wpf是我自己写的一个DLL,VistaFolderBrowserDialog是这个dll里面的一个class
nicklisir 2018-01-25
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/220040405 这个可以参考下
nicklisir 2018-01-25
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/220040405 这个可以参考下
nicklisir 2018-01-25
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/220040405 这个可以参考下
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 13 楼 liucqa 的回复:
如果要hook的话,可以看看easyhook,没必要自己造轮子吧
你找不重复“造轮子”是什么境界吗? 那是什么都懂了,提高生产效率的时候,才做的事。
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 13 楼 liucqa 的回复:
如果要hook的话,可以看看easyhook,没必要自己造轮子吧
造车必须要造轮子。 一味地用别人的东西,水平提高不到哪里去。
泡泡龙 2018-01-25
  • 打赏
  • 举报
回复
如果要hook的话,可以看看easyhook,没必要自己造轮子吧
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 10 楼 Saleayas 的回复:
需要触发一个 Hook 的消息,然后才会加载进消息所在的进程中。
重新看了下回复的,感觉之前我理解错你的意思了。 能用代码描述一下您的意思吗?(并不需要实例,只要能描述出意思就可以)
TypeSharp 2018-01-25
  • 打赏
  • 举报
回复
引用 10 楼 Saleayas 的回复:
需要触发一个 Hook 的消息,然后才会加载进消息所在的进程中。
也就是说,需要DLLMain了? 我google,看到好像可以通过静态构造函数初始化来触发一个信息。 你有更好的办法吗?
Saleayas 2018-01-25
  • 打赏
  • 举报
回复
需要触发一个 Hook 的消息,然后才会加载进消息所在的进程中。

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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