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
{

}

}


}


希望各位大佬帮忙看下。感谢。
...全文
632 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 的消息,然后才会加载进消息所在的进程中。
abstract class 抽象类 accelerator 快捷键 accelerator mapping 快捷键映射 accelerator table 快捷键对应表 access modifier 访问修饰符 Access Pack 访问包 access specifier 访问说明符 access violation 访问冲突 accessibility 辅助功能 accessibility domain 可访问域 Accessibility Options 辅助功能选项 accessor 访问器 action 操作 Active Directory hierarchy Active Directory 层次结构 active document 活动文档 Active Document Containment 活动文档包容 active end 活动结尾 active object 活动对象 active point 活动点 Active Template Library 活动模板库 ActiveX Component ActiveX 组件 ActiveX Control ActiveX 控件 ActiveX control container ActiveX 控件容器 ActiveX Control Interface Wizard ActiveX 控件接口向导 ActiveX Control Test Container ActiveX 控件测试容器 ActiveX Designer ActiveX 设计器 ActiveX Document Migration Wizard ActiveX 文档移植向导 ActiveX-enabled 支持 ActiveX 的 Add key/ Multiply key/ Substract key/ Devide key 加号键/ 乘号键/ 减号键/ 除号键 Add-In 外接程序 Address Book 通讯簿 address space 地址空间 Administrator Mode 管理员模式 advise sink 通知接收 aggregate 聚合 Airbrush 喷枪 All Tables 所有表 allocation hook 分配挂钩 Alternate text "替换文字,备用文本" Always On Top 总在最前面 ambient 环境 ambiguous 不明确 ampersand “&”符 ampersand (&) “and”符 (&) anchor 锚定 (v.);定位点 (n.) animation control 动画控件 apartment-model threading 单元模型线程 application framework 应用程序框架 Application Wizard 应用程序向导 Apply Now 立即应用 apply to similar 应用到相似项 argument 参数 Arrange Tables 排列表 array initializer 数组初始值设定项 array rank 数组秩 arrow cap 箭头帽 ARROW key 箭头键 ArrowHourGlass 箭头沙漏 ArrowQuestion 箭头问号 article family 文章族 assembly 程序集;汇编 assembly manifest 程序集清单 assert 断言 assign 分配 associate 关联 asterisk (""*"") 星号(“*”) asynchronous moniker 异步名字对象 asynchronous peek operation 异步查看操作 ATL Object Wizard ATL 对象向导 atomic operation 原子操作 attached table 附加表 attribute 属性 Attributed Component Wizard 属性化组件向导 Attributed Programming 属性化编程 Attributes Property Attributes 属性 Authentication 身份验证 authorable 可创作(的) Auto completion for commands 自动完成命令 Auto Increment 自动增加 Auto Syntax Check 自动语法校验 Automatic 自动 automation 自动化 automation-enabled 启用自动化

111,111

社区成员

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

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

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