【发布时间】:2014-03-05 11:40:54
【问题描述】:
我在想如何在不使用 EasyHook 或类似库之类的 C++ 库的情况下将 API 与 C# 或 VB.Net 挂钩。
我喜欢学习这个的目的不是为了任何恶意,它只是为了获得更多的经验并找到.net 的极限。
假设我喜欢挂钩 MessageBoxA API。
我首先通过 Importing System.Runtime.InterropServices 导入它,然后在 user32.dll 中为 MessageBoxA API 调用添加 PInvoke 签名
<DllImport("user32.dll", EntryPoint:="MessageBoxW",
SetLastError:=True, Charset:=Charset.Unicode)>
Public Function MessageBox(
hwnd As IntPtr,
<MarshalAs(UnmanagedType.LPTSTR)>ByVal lpText As String,
<MarshalAs(UnmanagedType.LPTSTR)>ByVal lpCaption As String,
<MarshalAs(UnmanagedType.U4)>ByVal uType As MessageBoxOptions
) As <MarshalAs(UnmanagedType.U4)>MessageBoxResult
End Function
我现在基本上喜欢钩住每个调用 MessageBoxA API 的进程来获取普通文本,但我喜欢使用钩子在 messageBox 文本的末尾附加“钩子”。 一位对 .net 非常有经验的朋友,但不幸的是忙于帮我解决这个问题,他告诉我它绝对可以做到这一点。 步骤是,首先我需要 dll(库)中的实际挂钩函数,稍后我将在进程中注入该函数,然后我需要确定它是本机进程还是托管进程。如果它是托管的,那么没有问题,但如果它是本机进程,我需要一个加载器。 本机进程没有加载 .net,所以我需要先手动加载它,然后再注入 dll。
然后我需要获取指向 .net 方法的指针作为指针,这样我就知道我的钩子应该指向的地址,然后我可以使用 GetProcessAdress 和 LoadLibraryA 来获取指向 API 的指针。 我喜欢在API开头写的JMP可以使用WriteProcessMemory来实现。 有人可以通过挂钩 hte messagebox api 并在调用它之前向它附加一些文本来向我展示如何在上面提到的一个简单示例中实现这一点。
=)
【问题讨论】:
-
我知道API调用不是恶意的,但是api hooks可以被恶意使用。我的意思是挂钩消息框 api,而不仅仅是简单地调用它;)请重新阅读我的 startpost。而复杂的事情我不知道如何实现是.net中的实际挂钩部分
-
好吧,我来解释一下,帮助你理解。假设我在上面调用函数,带有 pinvoke 签名的 messageboxa。我传递了所有参数,然后会弹出一个消息框,对吗?如果我的意思是挂钩,我会将调用重定向到 api。也就是说,我需要在api的开头写一个JMP(指针),它指向我自己的函数。现在,如果我执行 messageboxa 的 apicall 并且系统喜欢执行它,它会因为 JMP 而被重定向到我的函数。在我的函数中,我喜欢在 msgbox 文本中附加一个“挂钩”,然后将修改后的结果发回。
-
结果现在将是:实际 MessageBox 文本 +“钩子”(或我在函数中附加的任何内容。因此,步骤是将 api 调用重定向到我自己的函数,修改结果并将修改后的结果发回到api。(基本上像弯路)。
-
API Hooking 并不总是恶意的,例如 AV 也通过 hook api 来提高其安全性等。
-
messageboxhook 应该只是一个示例,以了解 api 挂钩的概念通常适用于 .net。
标签: c# vb.net api hook api-hook