类人猿 发表于 2017-8-23 12:31:39

ASM32本地汇编库

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

   这个是按键精灵2014或者按键9有效。按键X版本无效。(按键2014风琪仙)
Declare Function Asm Lib"ToAsm" Alias"Asm"(ByVal code As String,ByVal 长度 As Long) As Long
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
Declare Function RtlZeroMemory Lib"kernel32.dll" Alias"RtlZeroMemory"(ByVal 目的内存 As String,ByVal 长度 As Long) As Long
Declare Function MultiByteToWideChar Lib"kernel32.dll" Alias"MultiByteToWideChar"(ByVal CodePage As Long,ByVal dwFlags As Long,ByVal lpMultiByteStr As Long,ByVal cchMultiByte As Long,ByVal lpWideCharStr As Long,ByVal lpWideCharStr As Long) As Long



Function 取指针长度(指针)
If 指针 > 0 Then
      取指针长度 = LocalSize(指针)
      Else
      TracePrint "错误的指针!"
End If
      
End Function


Function 指针到文本(指针)
JS_txt_anjian = space(取指针长度(指针)\2)
RtlMoveMemory JS_txt_anjian, 指针, 取指针长度(指针)
指针到文本=JS_txt_anjian
End Function


Function写代码(汇编代码)
    Dim 局部数组, 指令集,临时值
    指令集="EAX|EBX|ECX|EDX|ESP|EBP|ESI|EDI|AX|BX|CX|DX|AL|BL|CL|DL|AH|BH|CH|DH|DI|SI|BP|SP|IP|EIP|CS|DS|ES|SS"
    //G_code_text = G_code_text + 汇编代码 + chr(10)
    G_测试=汇编代码
    If 汇编代码 <> "" Then
      If Asm(G_测试, Len(G_测试)) = 0 Then //如果编译器认为出错

            局部数组 = split(汇编代码, " ")
            Select Case UBound(局部数组)
            Case 0//为单一指令时,报错
                TracePrint "错误的指令>>>" + 汇编代码
                G_code_text = "XXXXXXXX"
                Goto OVER
            Case 1// 为带操作数指令时,判断是否为调用函数
                临时值 = 取址(局部数组(1))
//                TracePrint 临时值
                If 临时值>0 Then
                  G_code_text = G_code_text + 局部数组(0) + " " + Cstr(临时值) + chr(10)
                Else
                  If InStr("LOOP|JMP|JE|JNE|JB|JNB|JA|JNA|JCC|JZ|JE|JNZ|JNE|JS|JNS|JO|JNO|JP|JPE|JNP|JPO|JC|JB|JNAE|JNC|JNB|JAE", UCase(局部数组(0))) >= 0 Then
                            if UBound(split(局部数组(1),","))=0 then
                        G_code_text = G_code_text + 汇编代码 + chr(10)
                            Goto over
                        end if
                  End If


                  局部数组 = split(汇编代码, ",")
                  If UBound(局部数组) = 1 Then
                        临时值 = 取址(局部数组(1))
                        If 临时值>0 Then
                            G_code_text = G_code_text + 局部数组(0) + "," + Cstr(临时值) + chr(10)
                        Else
                            TracePrint "汇编代码:" + 汇编代码 + " 错误!" + "   位置>>>" + 局部数组(1)
                           G_code_text = "XXXXXXXX"
                            Goto OVER
                        End If
                  Else
                        TracePrint "库中无此函数>>>" + 汇编代码
                        G_code_text = "XXXXXXXX"
                        Goto OVER
                  End If
                End If      
            End Select
            //         TracePrint "汇编代码语法有误!错误的代码>>>【 " + G_测试+" 】"
      Else
            G_code_text = G_code_text +汇编代码+chr(10)
      End If
    End If
    Rem OVER
    写代码= 汇编代码
End Function

Function 运行代码Ex(代码指针,可选参数1, 可选参数2, 可选参数3, 可选参数4)
if 代码指针<>0 then
运行代码Ex=CallWindowProcA(代码指针, 可选参数1, 可选参数2, 可选参数3, 可选参数4)
Else
   TracePrint "无效的指针"
   运行代码Ex=0
end if


End Function

Function 取代码指针()
Dim 字节, 指针,数量
数量 = Asm(G_code_text, Len(G_code_text))//编译
If 数量 > 0 Then
CODE_字节 = space(数量)
MultiByteToWideChar 0, 0, G_code_text, - 1 , CODE_字节, 数量//转换
G_code_text=CODE_字节

   字节 = split(G_code_text, "{")
   字节 = split(字节(1), "}")
   字节 = split(字节(0), ",")
   取代码指针 = 写内存代码(字节)//装载


   G_code_text = ""

   Else
   TracePrint "当前代码存在错误!请仔细检查。"
   取代码指针 =0
End If
End Function

sub 释放指针(指针)
call LocalFree (指针)
End sub


Function 运行代码(可选参数1, 可选参数2, 可选参数3, 可选参数4)
Dim 字节, 指针,数量
数量 = Asm(G_code_text, Len(G_code_text))//编译
If 数量 > 0 Then
CODE_字节 = space(数量)
MultiByteToWideChar 0, 0, G_code_text, - 1 , CODE_字节, 数量//转换
G_code_text=CODE_字节

   字节 = split(G_code_text, "{")
   字节 = split(字节(1), "}")
   字节 = split(字节(0), ",")
   指针 = 写内存代码(字节)//装载

运行代码 = CallWindowProcA(指针, 可选参数1, 可选参数2, 可选参数3, 可选参数4)//运行
   G_code_text = ""
   LocalFree 指针
   Else
   TracePrint "当前代码存在错误!请仔细检查。"
End If
End Function

Function 取址(函数名)
    Dim DLL集,lz,i,z
    DLL集 = "kernel32.dll|user32.dll|winmm.dll|gdi32.dll|wininet.dll|"
    DLL集=DLL集+dll_Name

    lz=split(DLL集,"|")
    For i = 0 To UBound(lz)
TracePrint lz(i)
      z = 取函数地址(lz(i), 函数名)
      If z > 0 Then
            Exit For
      End If
    Next
    取址 = z
End Function

Sub 载入DLL(Dll名)
    dll_Name=dll_Name+dll名+"|"
    call LoadLibraryA(dll名)
End Sub
Function 取函数地址(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模块句柄
    取函数地址=GetProcAddress(模块句柄,字符_指针)
    LocalFree 字符_指针      
End Function
Function 取数组指针(整数数组)'返回数组的首地址,构建和C语言一样的线性数组。
    Dim 数组地址,结构指针
    If VarType(整数数组) = 8204 Then
      数组地址 = LocalAlloc(0, (UBound(整数数组) + 1) * 4)//申请内存构建数组,申请临时内存,用于取巧写整数,并内存清零!!
      结构指针 = LocalAlloc(0, 16)
      RtlFillMemory 数组地址, UBound(整数数组) + 1, 0
      RtlFillMemory 结构指针, 16, 0
      Dim 实际传送次数,写入指针,i//计算需要传送的次数,每次传送4个整数。不足4个算做4个。
      实际传送次数 = UBound(整数数组)+ 1
      实际传送次数 = 实际传送次数 \ 4
      If 实际成员数 mod 4 <> 0 Then
            实际传送次数 =实际传送次数+1
      End If
      写入指针=0//定义变量设置传送写入位置,开始循环写入,如果满4个,全部一起传送
      For i = 0 To 实际传送次数
            If i <= 实际传送次数 - 1 Then
                Call SetRec(结构指针, 整数数组(i*4), 整数数组(i*4+1), 整数数组(i*4+2), 整数数组(i*4+3))
                Call RtlMoveMemory (数组地址+写入指针*16, 结构指针, 16)//一次传送4个整数到内存。
                写入指针 = 写入指针 + 1
                //TracePrint i& "|" &整数数组(i * 4) & "|" & 整数数组(i * 4 + 1) & "|" & 整数数组(i * 4 + 2) & "|" & 整数数组(i * 4 + 3)
            ElseIf i > 实际传送次数 - 1 Then//如果到了最后一次,可能不满4个
                If i * 4 = UBound(整数数组) Then //如果还剩一个
                  Call SetRec(结构指针, 整数数组(i * 4), 0, 0, 0)
                  Call RtlMoveMemory(数组地址 + 写入指针 * 16, 结构指针, 4)//传送1个整数到内存。
                  //TracePrint "剩余1"
                  Exit For
                ElseIf i * 4 + 1 = UBound(整数数组) Then//如果还剩二个
                  Call SetRec(结构指针, 整数数组(i * 4), 整数数组(i * 4+1), 0, 0)
                  Call RtlMoveMemory(数组地址 + 写入指针 * 16, 结构指针, 8)//传送2个整数到内存。
                  //TracePrint "剩余2"
                  Exit For
                ElseIf i * 4 + 2 = UBound(整数数组) Then//如果还剩3个
                  Call SetRec(结构指针, 整数数组(i * 4), 整数数组(i * 4+1), 整数数组(i * 4+2), 0)
                  Call RtlMoveMemory(数组地址 + 写入指针 * 16, 结构指针, 12)//传送3个整数到内存。
                  //TracePrint "剩余3"
                  Exit For
                ElseIf i * 4 + 3 = UBound(整数数组) Then//如果还剩4个
                  Call SetRec(结构指针, 整数数组(i * 4), 整数数组(i * 4+1), 整数数组(i * 4+2), 整数数组(i * 4+3))
                  Call RtlMoveMemory(数组地址 + 写入指针 * 16, 结构指针, 16)//传送4个整数到内存。
                  //TracePrint "剩余4"
                  Exit For
                End If
            End If
      Next
      //TracePrint "写数组指针值:"&写入指针
      写入指针=0
      LocalFree 结构指针//释放临时申请的内存。
      取数组指针 = 数组地址 //返回数组所在的地址。
    Else         
      取数组指针=0
      TracePrint "这不一个整数型数组"               
    End If
End Function
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(字节数组)
      callCallWindowProcA(Ccode, CS_code + i, Clng(字节数组(i)), 0, 0)
    Next
    //返回和释放资源
    写内存代码 =CS_code
    LocalFree Ccode
    LocalFree 临时地址
End Function


页: [1]
查看完整版本: ASM32本地汇编库