找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2461|回复: 11

【MASM,VB6】论坛老大VB6指针的拓展

[复制链接]
发表于 2020-2-18 21:03:57 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 smitest 于 2020-2-18 21:29 编辑

最近做一个进程内存共享的项目,出于VB访问数据方便,想到了VB变量与内存绑定的问题,花了大约一周的时间学习了VB的数据类型结构,通过多方比较,最后采用了variant类型作为指针,实际使用起来更加方便。
直接上代码和说明:

特点:1  一个指针,随时可以改变指向数据的类型  2 具备指针增量可任意指定特性,对于内存不对齐的数据搜索很有用,比如一个4字节内存(1234),可以映射成3个Integer(12 23 34)
需要进一步探讨,可联系QQ 347895961.

主文件,没啥好解释的。
  1. .686p
  2. .model flat, stdcall
  3. option casemap :none
  4. .mmx
  5. .XMM
  6. include windows.inc
  7. include MyFun.asm

  8. .const
  9. .data
  10. .data?
  11.         hInstance dd ?
  12. .CODE
  13. LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD
  14.         .if reason == DLL_PROCESS_ATTACH                                         
  15.                 mov eax,hInstDLL
  16.                 mov hInstance,eax
  17.                
  18.                 mov eax,TRUE
  19.                 ret
  20.         .endif
  21. ret
  22. LibMain Endp
  23. End LibMain
复制代码


DEF文件,Aogo的IDE用的很舒服,可惜不更新了
  1. LIBRARY VB6Ex
  2. DESCRIPTION This DLL by MASMPlus
  3. EXPORTS  
  4. int3
  5. stBindVar
  6. stUnBindAll
  7. stUnBind
复制代码


处理代码

  1. int3 proto   ;调试VB程序用的,对这个主题没啥意义
  2. stBindVar proto  pVar:DWORD,pMem:DWORD,nSize:DWORD,nType:DWORD,nStep:DWORD
  3. stUnBindAll proto
  4. stUnBind  proto pVar:DWORD
  5. ;以下的暂时写的支持的VB数据类型,该常数对应于VB的VBVARTYPE枚举结构
  6. vbInteger equ 2
  7. vbLong   equ 3
  8. vbSingle equ 4
  9. vbDouble equ 5
  10. vbCurrency equ 6
  11. vbBoolean equ 11
  12. vbByte equ  17
  13. ;以上变量对应的内存字节数据
  14. vbIntegerSize equ 2
  15. vbLongSize   equ 4
  16. vbSingleSize equ 4
  17. vbDoubleSize equ 8
  18. vbCurrencySize equ 8
  19. vbBooleanSize equ 2
  20. vbByteSize equ  1

  21. ;安全数组结构
  22. SafeArray1D struct
  23.         cDims dw 0
  24.         fFeatures dw 0
  25.         cbStep dd 0
  26.         cLocks dd 0
  27.         pvData dd 0
  28.         Elements dd 0
  29.         Lbound dd 0
  30.         reserved0 dd 0
  31.         reserved1 dd 0
  32. SafeArray1D ends
  33. ;Variant数据类型
  34. Variant struct
  35.         vType db 0
  36.         vArray db 0
  37.         reserved1 dw 0
  38.         BindID dd 0
  39.         pSafeArray dd 0
  40.         reserved2 dd 0
  41. Variant ends

  42. ;最大指针数目
  43. MaxSize equ 16

  44. .DATA
  45. align 16
  46. Varptr dd MaxSize dup(0)
  47. align 16
  48. VarStruct  Variant MaxSize dup (<>)
  49. align 16
  50. VarSA SafeArray1D MaxSize dup(<>)

  51. .code

  52. ;指针绑定内存数据    参数分别为:要绑定的指针,内存地址,内存大小,指针类型,指针增量
  53. stBindVar proc uses edx ecx esi edi pVar:DWORD,pMem:DWORD,nSize:DWORD,nType:DWORD,nStep:DWORD
  54. local mType,mStep,mElements  

  55.    mov eax,nType
  56.    .if eax==vbByte
  57.        mov mStep,vbByteSize
  58.    .elseif eax==vbInteger
  59.        mov mStep,vbIntegerSize
  60.    .elseif eax==vbLong
  61.        mov mStep,vbLongSize
  62.    .elseif eax==vbSingle
  63.        mov mStep,vbSingleSize
  64.    .elseif eax==vbDouble
  65.        mov mStep,vbDoubleSize
  66.    .elseif eax==vbBoolean
  67.        mov mStep,vbBooleanSize
  68.    .elseif eax==vbCurrency
  69.        mov mStep,vbCurrencySize
  70.    .else
  71.        mov mStep,vbByteSize
  72.        mov nType,vbByte
  73.    .endif

  74.    .if nStep!=0
  75.        mov eax,nStep
  76.        mov mStep,eax
  77.    .endif
  78.    xor edx,edx
  79.    mov eax,nSize
  80.    div mStep
  81.    .if edx!=0
  82.        inc eax
  83.    .endif
  84.    mov mElements,eax


  85.         mov eax,pVar
  86.         mov edi,offset Varptr
  87.         mov ecx,MaxSize
  88.         cld
  89.         repnz scasd
  90.         .if !Zero?
  91.                 xor eax,eax
  92.                 mov edi,offset Varptr
  93.                 mov ecx,MaxSize
  94.                 repnz scasd
  95.                 .if !Zero?
  96.                         mov eax,-1
  97.                         ret
  98.                 .endif
  99.                 mov eax,pVar
  100.         .endif
  101.         sub ecx,MaxSize
  102.         not ecx
  103.         mov [Varptr+ecx*4],eax
  104.        
  105.         pxor xmm0,xmm0
  106.         mov edi,pVar
  107.         movupd [edi],xmm0
  108.         shl ecx,4

  109.         lea esi,[VarSA+ecx*2]
  110.         assume esi:ptr SafeArray1D
  111.         mov WORD ptr [esi].cDims,1
  112.         mov WORD ptr [esi].fFeatures,92h
  113.         mov eax,mStep
  114.         mov [esi].cbStep,eax
  115.         mov [esi].cLocks,0
  116.         mov eax,pMem
  117.         mov [esi].pvData,eax
  118.         mov eax,mElements
  119.    mov [esi].Elements,eax
  120.         mov [esi].Lbound,0


  121.         lea esi,[VarStruct+ecx]
  122.         assume esi:ptr Variant
  123.         mov eax,nType
  124.         mov BYTE ptr [esi].vType,al
  125.         mov BYTE ptr [esi].vArray,32
  126.         mov [esi].reserved1,0
  127.         mov [esi].BindID,'xEBV'
  128.         mov [esi].reserved2,'TSyb'
  129.         lea eax,[VarSA+ecx*2]
  130.         mov [esi].pSafeArray,eax       

  131.    assume esi:nothing  

  132.         movupd xmm0,[esi]
  133.         movupd [edi],xmm0
  134.        
  135. fclex
  136. ret
  137. stBindVar endp




  138. ;解除绑定
  139. stUnBindAll  proc   uses edi ecx
  140.         mov edi,offset Varptr
  141.         xor ecx,ecx
  142.         pxor xmm0,xmm0
  143.         @@:
  144.         mov eax,[edi+ecx*4]
  145.         .if eax!=0
  146.             movupd [eax],xmm0
  147.             mov DWORD ptr [edi+ecx*4],0
  148.         .endif
  149.         inc ecx
  150.         cmp ecx,MaxSize
  151.         jb @B
  152.         ret
  153. stUnBindAll endp

  154. ;解除单个变量的绑定
  155. stUnBind proc uses edi ecx pVar:DWORD

  156.         mov eax,pVar
  157.         mov edi,offset Varptr
  158.         mov ecx,MaxSize
  159.         cld
  160.         repnz scasd
  161.         .if Zero?               
  162.                 pxor xmm0,xmm0
  163.                 mov eax,[edi-4]
  164.                 movupd [eax],xmm0
  165.                 mov DWORD ptr [edi-4],0
  166.                 xor eax,eax
  167.         .endif
  168.         ret
  169. stUnBind endp


  170. ;调试VB程序用,研究VB数据存储访问结构就这个发挥了巨大作用
  171. int3 proc
  172. int 3
  173. ret
  174. int3 endp


复制代码
回复

使用道具 举报

发表于 2020-2-25 10:16:41 | 显示全部楼层
smitest 发表于 2020-2-23 21:55
跟踪了一下,PtrLng还是被VB翻译成GetMem4,不知道咋回事。

是这样的,PtrXXX属性的Property Get就是GetMemN,Property Let就是PutMemN、Property Set就是SetMemN。
这几组函数本质上是VB6给类成员Public变量生成属性用的。
回复 赞! 1 靠! 0

使用道具 举报

 楼主| 发表于 2020-2-23 23:02:39 | 显示全部楼层
好像理解了,猜想是GetMem4定义成属性的效果。
回复 赞! 1 靠! 0

使用道具 举报

 楼主| 发表于 2020-2-23 22:03:30 | 显示全部楼层
系统消息 发表于 2020-2-20 19:26
msvbvm60.dll其实给我们提供了内存操作函数,只不过没有公开而已,我们直接写tlb声明这个未公开函数就行了 ...

还有请问大佬,entry(0x60000000)里0x60000000是啥意思呢
回复 赞! 1 靠! 0

使用道具 举报

 楼主| 发表于 2020-2-23 21:55:49 | 显示全部楼层
跟踪了一下,PtrLng还是被VB翻译成GetMem4,不知道咋回事。
回复 赞! 1 靠! 0

使用道具 举报

 楼主| 发表于 2020-2-18 21:20:22 | 显示全部楼层
VB6使用例子

  1. Public Declare Function stUnBindAll Lib "vb6ex" () As Long
  2. Public Declare Function stUnBind Lib "vb6ex" (ByRef Var As Variant) As Long
  3. Public Declare Function stBindVar Lib "vb6ex" (ByRef Var As Variant, ByVal lpMem As Long, ByVal nMemSize As Long, ByVal nType As Long, ByVal nStep As Long) As Long

  4. Public aa(1 To 16) As Byte, b As Long
  5. Public ptr, ptr2, ptr3

  6. Sub Main()
  7.   
  8.   For I = 1 To 16 Step 2
  9.   aa(I) = I
  10.   Next
  11.   b = 45
  12.   
  13.    stBindVar ptr, VarPtr(aa(1)), 16, vbInteger, 2
  14.    stBindVar ptr2, VarPtr(aa(1)), 16, vbByte, 3
  15.    stBindVar ptr3, VarPtr(b), 4, vbLong, 0
  16.    
  17.    ptr(3) = 88: ptr3(0) = 99
  18.    
  19.    stUnBind ptr
  20.   stUnBindAll
  21.   
  22. End Sub
复制代码
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2020-2-18 21:31:15 | 显示全部楼层
本帖最后由 smitest 于 2020-2-18 21:33 编辑

最终库文件,引用TLB就不需要声明了。

VB6Ex.dll

3.5 KB, 下载次数: 1

vb6ex.tlb

2.67 KB, 下载次数: 1

回复 赞! 靠!

使用道具 举报

发表于 2020-2-20 15:57:22 | 显示全部楼层
来给大佬暖帖
回复 赞! 靠!

使用道具 举报

发表于 2020-2-20 19:26:49 | 显示全部楼层
msvbvm60.dll其实给我们提供了内存操作函数,只不过没有公开而已,我们直接写tlb声明这个未公开函数就行了,这样根本不需要依赖任何dll。
https://pan.baidu.com/s/1hqtLQUK 这个是我写的msvbvm60.tlb,里面就是声明的VB6运行库未公开函数,其中内存操作函数我为了让操作更像指针特意声明成了属性,比如:
abc = PtrLng(内存地址1) '读取内存地址1中的Long数据(属性读取)
PtrLng(内存地址2) = 233 '往内存地址2中写入Long数据(属性赋值)
Set PtrObj(内存地址3) = obj '对象要用Set赋值(对象Let赋值是对其默认属性赋值)
回复 赞! 靠!

使用道具 举报

发表于 2020-2-22 16:44:28 | 显示全部楼层
系统消息 发表于 2020-2-20 19:26
msvbvm60.dll其实给我们提供了内存操作函数,只不过没有公开而已,我们直接写tlb声明这个未公开函数就行了 ...

哟!好东西啊,那啥时候把这个TLB的源码弄成一个github repo,让我们自己编译呢?
回复 赞! 靠!

使用道具 举报

发表于 2020-2-22 19:08:26 | 显示全部楼层
本帖最后由 系统消息 于 2020-2-22 19:10 编辑
0xAA55 发表于 2020-2-22 16:44
哟!好东西啊,那啥时候把这个TLB的源码弄成一个github repo,让我们自己编译呢? ...


源码不在现在这台电脑上,过段时间吧。还有就是最近有群友发现我tlb有一些地方有BUG,需要改进。
回复 赞! 靠!

使用道具 举报

发表于 2020-2-24 21:35:03 | 显示全部楼层
smitest 发表于 2020-2-23 22:03
还有请问大佬,entry(0x60000000)里0x60000000是啥意思呢

反编译工具的BUG
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-27 00:28 , Processed in 0.035013 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表