类人猿 发表于 2017-8-23 12:45:44

按键精灵HOOK钩子(风琪仙)

本帖最后由 类人猿 于 2017-8-23 12:53 编辑

Declare Function SetRec Lib"user32" Alias"SetRect"(ByVal 矩形 As Any,ByVal 左边 As Long,ByVal 顶边 As Long,ByVal 右边 As Long,ByVal 底边 As Long) As Long
Declare Function LocalAllocLib "kernel32" Alias "LocalAlloc" (ByVal wOemChar As Long,ByVal wOmChar As Long) As Long
Declare Function LocalFree Lib "kernel32" Alias "LocalFree" (ByVal hMem As Long) As Long
Declare Function LocalSize Lib "kernel32" (ByVal hMem As Long) As Long
Declare Sub RtlMoveMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal h As Any, ByRef f As Any, ByVal Length As Long)
Declare Function CallWindowProcA Lib"user32.dll" Alias"CallWindowProcA"(ByVal 前1窗口函数地址 As Long,byref 窗口句柄 As Long,ByVal 消息值 As Long,ByVal 附加参数1 As Long,ByVal 附加参数2 As Long) As Long
Declare Function RtlFillMemory Lib"kernel32.dll" Alias"RtlFillMemory"(ByVal 目的内存 As String,ByVal 长度 As Long,ByVal 填充内容 As Any) As Long
Declare Function LoadLibraryA Lib"kernel32.dll" Alias"LoadLibraryA"(ByVal 动态链接库名称 As String) As Long
Declare Function GetProcAddress Lib"kernel32.dll" Alias"GetProcAddress"(ByVal 模块句柄 As Long,ByVal 进程名称 As String) As Long
Declare Function GetModuleHandleA Lib"kernel32.dll" Alias"GetModuleHandleA"(ByVal 模块名 As String) As Long
Declare Function SetWindowsHook Lib"user32.dll" Alias"SetWindowsHookExA"(ByVal 钩子类型 As Long,ByVal 回调函数地址 As Long,ByVal 实例句柄 As Long,ByVal 线程ID As Long) As Long
Declare Function UnhookWindowsHookEx Lib"user32.dll" Alias"UnhookWindowsHookEx"(ByVal 钩子句柄 As Long) As Long



Sub Hook_安装系统钩子(钩子类型, QUI窗口句柄)
Dim u
Pint_call=构造回调函数(QUI窗口句柄)//构造回调函数,取回函数指针
H_Hook = SetWindowsHook(钩子类型, Pint_call, GetModuleHandleA(0), 0)//安装系统钩子

//传入钩子句柄到回调函数,用于呼叫下一钩子。
      u = LocalAlloc(0, 16)
      SetRec u, H_Hook, 0, 0, 0
      RtlMoveMemory P_call_parameter + 12, u, 4
      LocalFree u
End Sub


Function Hook_取回调指针数据()
If P_call_Point > 0 Then
      Hook_取回调指针数据 = 读内存数值(P_call_Point, 4) & "|"
      Hook_取回调指针数据 =Hook_取回调指针数据&读内存数值(P_call_Point+4, 4) & "|"
      Hook_取回调指针数据 =Hook_取回调指针数据& 读内存数值(P_call_Point+8, 4) & "|"
      Hook_取回调指针数据 = Hook_取回调指针数据 & 读内存数值(P_call_Point + 12, 4) & "|"
      Hook_取回调指针数据 = Hook_取回调指针数据 & 读内存数值(P_call_Point+ 16, 4)
End If
TracePrint P_call_Point
End Function

Function 构造回调函数(窗口句柄)
Dim code,Send_API,Hook_Next,Copy_Memory
P_call_parameter = LocalAlloc(0, 16)//分配内存装载回调函数返回的结果
P_call_Point = LocalAlloc(0, 20)


Send_API=取Dll函数地址("user32", "SendMessageA")
Hook_Next=取Dll函数地址("user32", "CallNextHookEx")
Copy_Memory=取Dll函数地址("kernel32.dll", "RtlMoveMemory")

code = "187," + 整数到字节码(P_call_parameter)// mov ebx,P_call_parameter将数据指针赋予EBX
code = code + ",139,69,8"//                     mov eax,      读取第1个参数,并赋给数据指针
code = code + ",137,3"//                        mov ,eax
code = code + ",139,69,12"//                  mov eax,    读取第2个参数,并赋给数据指针
code = code + ",137,67,4"//                     mov ,eax
code = code + ",139,69,16"//                  mov eax,    读取第3个参数,并赋给数据指针
code = code + ",137,67,8"//                     mov ,eax

code = code + ",184," + 整数到字节码(Copy_Memory)// mov eax,Copy_Memory
code = code + ",106,20,255,117,16,104," + 整数到字节码(P_call_Point)+",255,208"
                                             // push 20
                                              //push dword ptr
                                              //push P_call_Point
                                              //call eax
code = code + ",184," + 整数到字节码(Send_API)// mov eax,Send_API   
code = code + ",106,0,106,0,104,103,4,0,0,104," + 整数到字节码(窗口句柄)
                                             // push 0
                                             // push 0
                                             // push 1127
                                             // push 窗口句柄   
code = code + ",255,208"//                      call eax
code = code + ",184," + 整数到字节码(Hook_Next)//mov eax,Hook_Next
code = code + ",255,117,16,255,117,12,255,117,8,255,115,12,255,208,195"
                                             // push dword ptr
                                             // push dword ptr
                                             // push dword ptr
                                             // push dword ptr
                                             // call eax
                                             // ret
                                          
构造回调函数 = 写内存代码(split(code, ","))
TracePrint code
TracePrint 构造回调函数
End Function

Sub Hook_释放钩子
    UnhookWindowsHookEx H_Hook//释放钩子
      LocalFree P_call_parameter//释放回调参数数据指针
      LocalFree P_call_Point//释放回调指针数据指针
      P_call_parameter = 0
      P_call_Point = 0
      LocalFree Pint_call//释放函数指针
End sub

Function 写内存代码(字节数组)
    Dimi,临时数组
    //写一个函数本身需要的汇编代码到内存,这个写的方试比汇编慢,用于支持第二步的进行。
    临时数组 = Array(83, 51, 192, 51, 219, 139, 93, 12, 138, 69, 16, 136, 3, 91, 195)//汇编代码,写内存字节
    Ccode = LocalAlloc(0, UBound(临时数组) + 1)
    临时地址 = LocalAlloc(0, 16)
    For i = 0 To UBound(临时数组)
      Call SetRec (临时地址, 临时数组(i), 0, 0, 0)
      Call RtlMoveMemory (Ccode+i, 临时地址, 1      )//拷贝到代码地址
    Next
    //申请内存装载汇编代码,及内存清零处理。
    CS_code = LocalAlloc(0, UBound(字节数组) + 1)
    RtlFillMemory CS_code, UBound(字节数组) + 1, 0
    //把主代码写到内存
//    MessageBoxUBound(字节数组)
    For i = 0 To UBound(字节数组)
      Call CallWindowProcA(Ccode, CS_code + i, Cint(字节数组(i)), 0, 0)//卡在这里
      TracePrint"Ccode="&Ccode   & " CS_code + i="&CS_code + i & "Cint(字节数组(i))="& Cint(字节数组(i))
    Next
    //返回和释放资源
    写内存代码 = CS_code
    TracePrintCS_code
    LocalFree Ccode
    LocalFree 临时地址
End Function

Function Hook_取回调数据(序列)
If P_call_parameter <> 0 Then
      Select Case 序列
      Case 1
         Hook_取回调数据 = 读内存数值(P_call_parameter, 4)
      Case 2
         Hook_取回调数据 = 读内存数值(P_call_parameter + 4, 4)
      Case 3
         Hook_取回调数据=读内存数值(P_call_parameter+8, 4)
End Select
End If
End Function

Function 取Dll函数地址(dll名, 函数名)
    Dim i,字节组,文本数组,字节数组,模块句柄,文_本_指_针
    文_本_指_针 = LocalAlloc(0, len(函数名) + 1)
    For i = 1 To len(函数名)
      字节组=字节组&Asc(mid(函数名,i,1))&","               
    Next
    字节组 = 字节组 & "0"//Null结束符
    文本数组 = split(字节组, ",")
    字节数组 = 文本数组
    For i = 0 To UBound(文本数组)
      字节数组(i)=Cint(文本数组(i))
    Next
    字符_指针 = 写内存代码(字节数组)
    模块句柄 = GetModuleHandleA(dll名)//先尝试获取模块句柄
    If 模块句柄 <= 0 Then
      模块句柄=LoadLibraryA(dll名)//如果模块没有加载,则加载
    End If
//    MessageBox模块句柄
    取Dll函数地址=GetProcAddress(模块句柄,字符_指针)
    LocalFree 字符_指针      
End Function

Function 整数到字节码(整数)
Dim 商, 余, 临时数

商 = 整数
临时数 = 整数

While (商 \ 256<>0) //转换
商 = 临时数 \ 256
余 = 临时数 mod 256
整数到字节码=整数到字节码+cstr(余)+","
临时数=商
Wend
余 = 整数 mod 256
整数到字节码=整数到字节码+cstr(商)+","

//TracePrint 整数到字节码

//格式处理
If 整数 <= 65535 Then
整数到字节码 = 整数到字节码 + "0,0"
ElseIf 整数 <= 16711680 + 65535 Then
整数到字节码 = 整数到字节码 + "0"
Else
整数到字节码=Left(整数到字节码,Len(整数到字节码)-1)
End If
End Function

Function 读内存数值(内存地址, 字节数)
Dim i
char = space(2)
For i = 0 To 字节数-1
      RtlMoveMemory char , 内存地址+i, 1
      读内存数值=读内存数值+AscB(char)*256^i
Next
End Function

a1441578177 发表于 2017-8-24 19:01:39

有没有鼠标键盘钩子
页: [1]
查看完整版本: 按键精灵HOOK钩子(风琪仙)