VB调用API函数,c copymemoryy b(0), ByVal "1234", 4的问题

此篇博文为
我是个懒人,我的目标就是干最少的活,完成最多的事情。当我看到网上那么多帖子中讨论的方法都很麻烦时,我觉得应该有更简单的办法。
调用api其实就是call过去,我的第一反应是:建一个空的function。得到api的入口,然后复制代码,覆盖掉我的function。执行我的function就等于执行了api。
但仔细一想不行,很多api会jmp +xxx,这样的话,我不能保证把jmp到的代码都复制下来如果自己检测jmp,会变得很麻烦。
那么如果复制代码不行,那我不复制行不行?接下来很容易就想到了,为什么不改写我的function,让他直接跳转到api呢?
好像可以耶~
call不行,因为会有压栈动作,我这个汇编盲这点还是知道的。那么就jmp吧&&最近看api hook看得太多了,经典的5个字节。 jmp的好处多多,没有任何多余动作,参数完整保留到jmp目的地。
问题又来了,怎么才可以知道我的function在哪里呢?容易,经常用到回调函数的朋友一定知道Addressof操作符吧,它的作用就是返回函数的入口。但是vb里面是不能直接使用a=Addressof b的,必须在函数中调用。
那么我们就走个弯路: a=Clng(&&H& & Hex(Addressof b)) 把Addressof b当作参数传给Hex函数就可以了,得到16进制,然后再用Clng转换成10进制。这样就得到了b函数的地址了。
接下来就容易了,只要在a地址处写入5个字节就行了,具体哪五个字节其实我也不知道,我随便找了个程序,od载入一下,找了个jmp看一下16进制代码,明白了,原来是E9啊。后面4个字节容易,算一下就行了。它=目标地址-E9的地址-5。
好了,问题基本解决。那么参数呢?走一步算一步吧,实验对象经典的MessageBoxA 4个参数。那么我就新建一个模块,输入2行代码:
Public Function myFunc(ByVal a As Long = 0, ByVal b As Long = 0, ByVal c As Long = 0, ByVal d As Long = 0) As Long
End Function
再来个主窗口:
text1=Clng(&&H& & Hex(Addressof myFunc))
再来个按钮:
call myFunc(0,0,0,0)
编译,od载入,ctrl+g到text1里显示的地址,哈哈
xor eax,eax
还真简单,od里at MessageBoxA,然后记下MessageBoxA的地址,返回myFunc地址,把原来的代码修改成jmp MessageBoxA-myFuc -5。
回到程序里点按钮,哈哈,msgbox出现了。 接下来就容易了,先测试下传参数怎么样。
call myFunc(me.hwnd, strptr(&123&),strptr(&456&),0)
因为myFunc的原型4个参数都是byval的long,而MessageBoxA的2、3个参数是字符串指针,所以我就用strptr得到字符串的地址,然后传过去,就不会有问题了。
执行一下,果然没错。 再来看看多个参数怎么办。我想到了Optional,这样就可以不用管参数个数了。
因为如果有2个必选参数,4个Optional参数,那么你传2个参数进去,后面的4个参数因为不存在就不会压栈,如果api有3、4、5、6个参数,我只要按参数个数传就可以了,少于myFunc的参数会自动省略掉。
这是我觉得最巧妙的地方,[color=Red]所以不会有参数数量问题[/color]
试验一下吧:改成
Public Function myFunc(Optional ByVal a As Long = 0, Optional ByVal b As Long = 0, Optional ByVal c As Long = 0, _
Optional ByVal d As Long = 0, Optional ByVal e As Long = 0, Optional ByVal f As Long = 0) As Long
End Function
&其他不变。。。执行一下看看,omg,成功了,哈~ 写上10个参数,应该可以应付任何api了吧?
哈哈,那么到这里原理大家都明白了吧?至于如何写入那5个字节的jmp就随意了,CopyMemory和WriteProcessMemory都可以
我的程序用的是WriteProcessMemory,用起来顺手。剩下的大家就看源代码吧~
实现的核心代码其实就8行
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:546次
排名:千里之外君,已阅读到文档的结尾了呢~~
本人也是初学API,基本概念是驾驭系统资源的便捷的接口。此资料是从网上收集,经本人略加编辑而成。无意涉及版权问题。请勿用于商业目的。
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
API的使用方法,实例和函数大全
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口VB 文件关联问题_百度知道VB动态调用API
VB动态调用API
如题,如何用LoadLibrary动态调用API?例如动态调用ShellExecute打开网页.最好有具体代码!
'--------模块中---------
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPrivate Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As LongPrivate 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 LongPrivate Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As LongPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Private m_opIndex As LongPrivate m_OpCode() As Byte
Public Function CallApiByName(ByVal libName As String, ProcName As String, ParamArray Params()) As Long&&&&&&& Dim hProc As Long&&&&&&& Dim hModule As Long&&&&&&&& &&&&&&& ReDim m_OpCode(400 + 6 * UBound(Params))
&&&&&&& hModule = LoadLibrary(ByVal libName)&&&&&&& If hModule = 0 Then&&&&&&&&&&&&&&& MsgBox "Library读取失败!"&&&&&&&&&&&&&&& Exit Function&&&&&&& End If&&&&&&&& &&&&&&& hProc = GetProcAddress(hModule, ByVal ProcName)&&&&&&& If hProc = 0 Then&&&&&&&&&&&&&&& MsgBox "函数读取失败!", vbCritical&&&&&&&&&&&&&&& FreeLibrary hModule&&&&&&&&&&&&&&& Exit Function&&&&&&& End If&&&&&&&& &&&&&&& CallApiByName = CallWindowProc(GetCodeStart(hProc, Params), 0, 1, 2, 3)&&&&&&&& &&&&&&& FreeLibrary hModuleEnd Function
Private Function GetCodeStart(ByVal lngProc As Long, ByVal arrParams As Variant) As Long&&&&&&& Dim lngIndex As Long, lngCodeStart As Long&&&&&&& lngCodeStart = (VarPtr(m_OpCode(0)) Or &HF) + 1&&&&&&& &&&&&&& m_opIndex = lngCodeStart - VarPtr(m_OpCode(0))&&&&&&& &&&&&&& For lngIndex = 0 To m_opIndex - 1&&&&&&&&&&&&&&& m_OpCode(lngIndex) = &HCC 'int 3&&&&&&& Next lngIndex
&&&&&&& For lngIndex = UBound(arrParams) To 0 Step -1&&&&&&&&&&&&&&& AddByteToCode &H68&&&&&&&&&&&&&&& AddLongToCode CLng(arrParams(lngIndex))&&&&&&& Next lngIndex&&&&&&& &&&&&&& AddByteToCode &HE8&&&&&&& AddLongToCode lngProc - VarPtr(m_OpCode(m_opIndex)) - 4
&&&&&&& AddByteToCode &HC2&&&&&&& AddByteToCode &H10&&&&&&& AddByteToCode &H0&&&&&&& &&&&&&& GetCodeStart = lngCodeStartEnd Function
Private Sub AddLongToCode(lData As Long)&&&&&&& CopyMemory m_OpCode(m_opIndex), lData, 4&&&&&&& m_opIndex = m_opIndex + 4End Sub
Private Sub AddIntToCode(iData As Byte)&&&&&&& CopyMemory m_OpCode(m_opIndex), iData, 2&&&&&&& m_opIndex = m_opIndex + 2End Sub
Private Sub AddByteToCode(bData As Byte)&&&&&&& m_OpCode(m_opIndex) = bData&&&&&&& m_opIndex = m_opIndex + 1End Sub
'-----------调用-------------
&&&&&&& Dim b1() As Byte&&&&&&& Dim b2() As Byte&&&&&&& &&&&&&& b1 = StrConv("Open", vbFromUnicode)b2 = StrConv(& &, vbFromUnicode)&&&&&&& &&&&&&& CallApiByName "Shell32.dll", "ShellExecuteA", 0, VarPtr(b1(0)), VarPtr(b2(0)), 0, 0, 0
调用为什么不能直接CallApiByName &Shell32.dll&, &ShellExecuteA&, 0,&Open&,& &, 0, 0, 0呢?
你应该多了解一下内存的调配,如果你用汇编调用参数传入的都是DWORD,对于整形参数直接传进去就可以了,字符型参数当然得传进他们的指针。
略懂社热议
略懂社热议
等待您来回答
编程领域专家
&SOGOU - 京ICP证050897号谁能教我用VB做这个_百度知道}

我要回帖

更多关于 delphi copymemory 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信