使用范例: 给100自增10次并输出结果 Dim ab as New ASM.Builder With ab .mov_eax_edx For i As Integer = 0 To 9 .Inc_eax Next .ret End With Dim ar As New ASM.Invoker msgbox(ar.Invoke(ab,100))
已知机器码: public 循环右移一位() As Byte={ &H89,&HD0, &HD1,&HC8, &HC3 } Dim ar As New ASM.Invoker msgbox("&H"+ar.Invoke(循环右移一位,1).ToString("x"))'我估计结果是&H80000000
更新!支持Windows8了!替换掉旧的Invoker类即可 *** <summary> *** 执行机器码,现在此操作支持Windows8 *** </summary> *** <remarks></remarks> Public Class Invoker Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As IntPtr, dwSize As Int32, flNewProtect As Int32, ByRef lpflOldProtect As Int32) As Integer Private Const PAGE_EXECUTE_READWRITE = &H40 Private Delegate Function Ret1Arg(arg1 As UInteger) As UInteger *** <summary> *** 执行机器码,能使用一个参数,有一个返回值 *** </summary> *** <param name="asmByteData">机器码数组</param> *** <param name="param1">第一个参数</param> *** <returns></returns> *** <remarks></remarks> Function Invoke(asmByteData As Byte(), param1 As UInteger, Optional IsWindows8 As Boolean = True) As UInteger Dim startAddress As IntPtr = UnsafeAddrOfPinnedArrayElement(asmByteData, 0) If IsWindows8 Then VirtualProtect(startAddress, asmByteData.Length, PAGE_EXECUTE_READWRITE, 0) Dim methodPtr As FieldInfo = GetType(Ret1Arg).GetField("_methodPtr", BindingFlags.NonPublic Or BindingFlags.Instance) Dim del As New Ret1Arg(Function(arg1 As UInteger) Return 0 End Function) methodPtr.SetValue(del, startAddress) *偷梁换柱,强行用反射把函数指针的地址改成我们的asm字节码 Return del(param1) End Function *** <summary> *** 执行机器码,能使用一个参数,有一个返回值 *** </summary> *** <param name="asmByteData">机器码生成器</param> *** <param name="param1">第一个参数</param> *** <returns></returns> *** <remarks></remarks> Function Invoke(asmByteData As Builder, param1 As UInteger) As UInteger Return Invoke(asmByteData.ToByteArray, param1) End Function End Class