vb动态加载dll的一个类-实现vb动态加载dll并动态调用dll导出的函数的一个方便办法.docx
Vb动态加载d1.1.的一个类,实现vb动态加载d1.1.并动态调用d1.1.导出的函数的一个方便办法自从会vb用调用动态库函数以来,我一直在想:如何动态的调用d1.1.里的函数?网上有一个用Ca1.1.WindowProc函数的方法,不过我还是喜欢自己有个办法.今天工夫不负有心人,我终于把我心中一直想的办法给实现了,干脆就往自己的空间上贴吧专昔误的地方,希望可以得到有这方面的师傅给以指正,以求进步!对于系统api我没有尝试,如果调用约定相符,应该适用于对系统api的调用.我自己用c写个d1.1.,然后在vb里写了这个类.以下代码只是我简单的实现,主要的是看实现的道理.VC代码:I1.1.我把d1.1.文件名命名为:d1.1.#inc1.ude<Windows.h>#inc1.ude<std1.ib.h>#inc1.ude<string.h>#inc1.ude,stdafx.h,BOO1.APIENTRYDI1.Mairi(HAND1.EhModu1.e,DWORDu1._reason_for_ca1.1.,1.PVOIDIpReserved)(returnTRUE;)extern'C'BOO1._dec1.spec(d1.1.export)add(inta)MeSSageBoXA(NU1.1.,'运行在d1.1.里成功',MBJDK);a=999;return1;)/vb代码:'类代码:Private状态标志AsBoo1.eanPrivate模块句柄As1.ongPrivate本地函数地址备份(0To4)AsBytePrivate被替换函数的地址As1.ongPub1.icFunction替换函数地址(模块名AsString,函数名AsStringz本地函数地址As1.ong)AsBoo1.eanIfO=本地函数地址Then替换函数地址=OExitFunctionEndIf被替换函数的地址=替换函数地址Dim函数地址As1.ongDimaAs1.ongDim跳转指令(OTo4)AsByte'加载模块模块句柄=1.Oad1.ibrary(模块名)IfO<>模块句柄Then'状态标志=1E1.se:替换函数地址二OExitFunctionEndIf检索函数地址函数地址=GetPrOCAddreSS(ByVa1.模块句柄,ByVaI函数名)If0<>函数地址Then'状态标志=1E1.se替换函数地址=0ExitFunctionEndIf计算跳转地址a二函数地址-(本地函数地址+5)构造跳转地址跳转指令(0)=233a=WriteProcessMemory(-1.zByVa1.VarPtr(跳转指令Q),ByVaIVarPtr(八)z4,0)If0=aThen替换函数地址二0ExitFunctionEndIf'先备份本地函数入口指令a=WriteProcessMemory(-1.zByVaIVarPtr(本地函数地址备份(0),ByVaI本地函数地址,5,0)If0=aThen替换函数地址二0ExitFunctionEndIf'写入跳转指令a=WriteProcessMemory(-1.zByVaI本地函数地址,ByVaIVarPtr(跳转指令(0),5,0)If0=aThen替换函数地址=0ExitFunction日se:状态标志二1替换函数地址=1EndIfEndFunctionPub1.icFunction还原函数地址()AsBoo1.eanIf0=状态标志Then还原函数地址=0ExitFunctionEndIfDimaAs1.onga=WriteProcessMemory(-1.zByVaI被替换函数的地址,ByVaIVarPtr(本地函数地址备份(0),5,0)If0=aThen还原函数地址=0ExitFunctionE1.se:状态标志=0还原函数地址=1EndIfFree1.ibrary模块句柄EndFunctionPub1.icFunction当前状态()AsBoo1.ean当前状态=状态标志EndFunctionIiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiivvviiiivviivvvvivvvviiiiivviiiivvvivvvi,vb普通模块代码:'读写内存的api函数Pub1.icDec1.areFunctionWriteProcessMemory1.ib,kerne1.32,(ByVaIhProcessAs1.ong,ByVaI_IpBaseAcIcIressAsAnyzIpBufferAsAnyzByVaInSizeAs1.ong,IpNumberfBytesWrittenAs1.ong)As1.ong'加载模块的api函数Pub1.icDec1.areFunction1.oad1.ibrary1.ib,kerne1.32,A1.ias'1.oad1.ibraryA'(ByVaIIp1.ibFiIeNameAsString)As1.ong检索模块里函数地址的api函数Pub1.icDec1.areFunctionGetProcAddress1.ib,kerne1.32,(ByVaIhModu1.eAs1.ong,ByVaIIpProcNameAsString)As1.ongIPub1.icDec1.areFunctionFree1.ibrary1.ib,kerne1.32,(ByVaIH1.ibModuIeAs1.ong)As1.ong节莫拟一个函数与d1.1.里,我们想调用函数类型和参数一致,用类将函数的地址替换Pub1.icFunction测试函数(参数As1.ong)AsBoo1.ean我们随便给返回0,因为这个指令将不会被程序执行到测试函数=0EndFunction,vb窗口模块代码:PrivateSubForm_1.oad()Dim模块名AsString,函数名AsString模块名二App.Path+'d1.1.d1.1.,模块名现在可以自己定了,自由了!函数名=,add'DimpAsBoo1.eanDimaaAsNewC1.ass1.P=aa.替换函数地址(模块名,函数名,AddreSSOf测试函数)IfpThen测试函数O'将会弹出对话筐:运行在d1.1.里!aa.还原函数地址EndIfEndSub