VB与VC通信,实现判断是否允许Hook进程创建,请教!

laoli6666 2010-05-01 10:59:18
近日在努力学习消化一段源码,可苦于严重才疏学浅,折腾了多日,虽然看了个“略懂略懂”,可核心功能总是无法实现,拜托哪位大侠能忙里偷闲,帮小菜找找原因所在,并注释解释一番,将不胜感激,定当感激涕零……

代码的主要目的是通过VC编写的DLL来实现全局Hook,当Hook到有进程创建企图时,便向VB编写的主程序发出一个Sendmessage消息,主程序收到该消息后询问用户是否允许该进程创建,通过用户的选择决定Sendmessage的返回值,然后DLL通过返回值决定是否让该进程创建。

现在的问题是:当开启Hook后,VB主程序不会询问用户,而所有新进程直接都无法创建。不知道问题到底出在哪里?

苦思多日而不得其解,身边又无人请教,只好到这里求教,恳请热心大侠多多指教……,完整代码可从这里下载
代码如下:
VC DLL代码:

#include "stdafx.h"
#include <windows.h>
#include "stdio.h"
#include "stdlib.h"

HANDLE hProcess=0;
UCHAR OldCode[5]={0}, NewCode[5]={0};
ULONG FunAddr=0;
HWND hExe=0;
HINSTANCE hMod=0;
HHOOK hHook=0;

// Status: FALSE 关闭HOOK,写入原函数地址,也就是CreateProcessW
// Status:TRUE 打开HOOK,写入自己HOOK函数地址,也就是 CreateProcessWCallBack
BOOL HookStatus(BOOL Status)
{
BOOL ret=FALSE;
if (Status) {
ret = WriteProcessMemory(hProcess, (void *)FunAddr, NewCode, 5, 0);
if (ret) return TRUE;}
else {
ret = WriteProcessMemory(hProcess, (void *)FunAddr, OldCode, 5, 0);
if (ret) return TRUE;}
return FALSE;
}

// CreateProcessW的HOOK函数原型,在调用真实的CreateProcessW之前先做自己的事
BOOL WINAPI CreateProcessWCallBack(LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation){
ULONG ret=0;
BOOL b=FALSE;
COPYDATASTRUCT cds={0};

cds.lpData = (void *)lpApplicationName;
cds.cbData = 255;

// 把lpApplicationName(创建新进程的文件路径)的信息用WM_COPY消息发到自己的窗口
ret = SendMessage(hExe, WM_COPYDATA, GetCurrentProcessId(), (LPARAM)&cds);

// 根据你自己处理WM_COPYDATA消息的结果决定是否创建这个进程,返回1234则创建,否则不创建
if (ret==1234) {
HookStatus(FALSE);
b = CreateProcessW(lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
HookStatus(TRUE);
return b;
} else return FALSE;
return FALSE;
}

// HOOK CreateProcessW函数
BOOL HookCreateProcess(){
ULONG JmpAddr=0;
char msg[255]={0};

FunAddr = (ULONG)GetProcAddress(LoadLibrary("Kernel32.dll"), "CreateProcessW");
memcpy(OldCode, (void *)FunAddr, 5);
NewCode[0] = 0xe9; // jmp 的机器码

// 计算你自定义CreateProcessW的函数原型相对于CreateProcessW函数地址的偏移,5是jmp XXXX指令的长度
JmpAddr = (ULONG)CreateProcessWCallBack - FunAddr - 5;
memcpy(&NewCode[1], &JmpAddr, 4);
//sprintf(msg, "NewCode: %x %x %x %x %x\nFunAddr: %x\nJmpAddr: %x\nMyFun: %x", NewCode[0], NewCode[1], NewCode[2], NewCode[3], NewCode[4], FunAddr, JmpAddr, (ULONG)CreateProcessWCallBack);
//MessageBox(0, msg, "", MB_OK);

// 打开HOOK
HookStatus(TRUE);
return TRUE;
}

// DLL入口函数
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
hMod = (HINSTANCE)hModule;
if (ul_reason_for_call==DLL_PROCESS_ATTACH){

// 打开进程,得到进程HANDLE,用于WriteMemory
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId());
// 查找自己程序的主窗体,用于发送WM_COPYDATA消息
hExe = FindWindow(NULL, "Hook CreateProcessW");
// Hook CreateProcessW函数
HookCreateProcess();}
// DLL从进程中卸载,关闭HOOK
if (ul_reason_for_call==DLL_PROCESS_DETACH) HookStatus(FALSE);
return TRUE;
}

// 卸载windows HOOK
extern "C" __declspec(dllexport) BOOL UnLoadHook(){
return(UnhookWindowsHookEx(hHook));
}

// Windows HOOK 函数
LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam){
return(CallNextHookEx(hHook,nCode,wParam,lParam));
}

// 安装钩子
extern "C" __declspec(dllexport) BOOL StartHook(){
hHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProc, hMod, 0);
if (hHook) return TRUE;
return FALSE;
}


================================================================================
VB Frmmain 代码:

Private Declare Function StartHook Lib "Hook.dll" () As Boolean
Private Declare Function UnLoadHook Lib "Hook.dll" () As Boolean
'download by http://www.codefans.net
Private Sub cmdHook_Click()
If StartHook Then cmdHook.Enabled = False
End Sub

Private Sub cmdUnHook_Click()
If UnLoadHook Then cmdUnHook.Enabled = False: MsgBox "已经解除!": Unload Me
End Sub

Private Sub Form_Initialize()
SetButtonFlat cmdHook.hwnd
SetButtonFlat cmdUnHook.hwnd
End Sub

Private Sub Form_Load()
c = GetWindowLong(hwnd, -4)
SetWindowLong hwnd, -4, AddressOf Wndproc
End Sub

Private Sub Form_Unload(Cancel As Integer)
If cmdUnHook.Enabled Then UnLoadHook: Unload Me
End Sub

Private Function SetButtonFlat(ByVal hwnd As Long) As Boolean
Dim style As Long
style = GetWindowLong(hwnd, (-16))
style = style Or &H8000&
SetButtonFlat = SetWindowLong(hwnd, (-16), style)
End Function


mod_Msg.bas模块代码:

Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function MessageBoxA Lib "user32" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Public c As Long

'download by http://www.codefans.net
Public Function Wndproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim s As String
Dim cds As COPYDATASTRUCT
'FrmMain.Text1.Text = Msg
FrmMain.Print Msg
If Msg = &H4A Then
CopyMemory cds, ByVal lParam, Len(cds)
s = Space(cds.cbData)
CopyMemory ByVal s, ByVal cds.lpData, cds.cbData
s = StrConv(s, vbFromUnicode)
s = Left(s, InStr(1, s, Chr(0)) - 1)
s = "进程(Pid:" & wParam & ")要创建新进程: " & s & ",是否允许?"
If MessageBoxA(0, s, "", 4) = 6 Then
Wndproc = 1234
Else
Wndproc = 0
End If
Exit Function
End If
Wndproc = CallWindowProc(c, hwnd, Msg, wParam, lParam)
End Function
...全文
230 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
laoli6666 2010-05-10
  • 打赏
  • 举报
回复
不好意思啊,有时候解决问题还得靠自己啊,终于发现问题所在了,问题非常简单,却困扰了我很多天,哎,惭愧惭愧!!
为了感谢大家的关注,把问题说明在这里,就是没有注意到这句话:hExe = FindWindow(NULL, "Hook CreateProcessW"); ,原来是没找到窗口,也就是说两边不一致……
laoli6666 2010-05-09
  • 打赏
  • 举报
回复
高手们都在忙什么啊,为什么高手出来指点迷津啊?拜托拜托!
visualassist4680 2010-05-06
  • 打赏
  • 举报
回复
不会vb
sendmessage 的时候 vb的窗口 hwnd 是否正确
接受 wm_copydata 的窗口处理过程是否是 sendmessage 发送的那个
程序是否发送了sendmessage
程序是否成功的hook了 createprocess
是否每个新创建的程序后 hook 了createproces
MoXiaoRab 2010-05-03
  • 打赏
  • 举报
回复
代码的主要目的是通过VC编写的DLL来实现全局Hook,当Hook到有进程创建企图时,便向VB编写的主程序发出一个Sendmessage消息,主程序收到该消息后询问用户是否允许该进程创建,通过用户的选择决定Sendmessage的返回值,然后DLL通过返回值决定是否让该进程创建。
======================
看这个需求,需要Hook CreateProcess?
MoXiaoRab 2010-05-03
  • 打赏
  • 举报
回复
你安装了CreateProcess是吧?那么你再创建进程的时候,是不是用原来的CreateProcess的地址来调用的呢?
尹成 2010-05-02
  • 打赏
  • 举报
回复
我也不会VB,不能帮楼主什么,顶到上面去,让更多前辈来分享自己经验!
lijianli9 2010-05-02
  • 打赏
  • 举报
回复
If Msg = &H4A Then 修改为 If Msg = 74 Then
laoli6666 2010-05-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 visualeleven 的回复:]
很想帮忙,但是不会VB,sorry。。。
[/Quote]
[Quote=引用 3 楼 yincheng01 的回复:]
我也不会VB,不能帮楼主什么,顶到上面去,让更多前辈来分享自己经验!
[/Quote]
谢谢二位的热心,其实VB非常简单,跟VC相比,VB就是小人书级别的小儿科,跟自然语言很接近的,保证能读懂的,而且其实这个例子里主要调用的都是API函数,我觉得应该跟VC更接近……
laoli6666 2010-05-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lijianli9 的回复:]
If Msg = &H4A Then 修改为 If Msg = 74 Then
[/Quote]
谢谢,不过改了也没有效果,结果跟原来一样。
Eleven 2010-05-01
  • 打赏
  • 举报
回复
很想帮忙,但是不会VB,sorry。。。

15,471

社区成员

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

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