【MASM,VB6】论坛老大VB6指针的拓展
本帖最后由 smitest 于 2020-2-18 21:29 编辑最近做一个进程内存共享的项目,出于VB访问数据方便,想到了VB变量与内存绑定的问题,花了大约一周的时间学习了VB的数据类型结构,通过多方比较,最后采用了variant类型作为指针,实际使用起来更加方便。
直接上代码和说明:
特点:1一个指针,随时可以改变指向数据的类型2 具备指针增量可任意指定特性,对于内存不对齐的数据搜索很有用,比如一个4字节内存(1234),可以映射成3个Integer(12 23 34)
需要进一步探讨,可联系QQ 347895961.
主文件,没啥好解释的。
.686p
.model flat, stdcall
option casemap :none
.mmx
.XMM
include windows.inc
include MyFun.asm
.const
.data
.data?
hInstance dd ?
.CODE
LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD
.if reason == DLL_PROCESS_ATTACH
mov eax,hInstDLL
mov hInstance,eax
mov eax,TRUE
ret
.endif
ret
LibMain Endp
End LibMain
DEF文件,Aogo的IDE用的很舒服,可惜不更新了
LIBRARY VB6Ex
DESCRIPTION This DLL by MASMPlus
EXPORTS
int3
stBindVar
stUnBindAll
stUnBind
处理代码
int3 proto ;调试VB程序用的,对这个主题没啥意义
stBindVar protopVar:DWORD,pMem:DWORD,nSize:DWORD,nType:DWORD,nStep:DWORD
stUnBindAll proto
stUnBindproto pVar:DWORD
;以下的暂时写的支持的VB数据类型,该常数对应于VB的VBVARTYPE枚举结构
vbInteger equ 2
vbLong equ 3
vbSingle equ 4
vbDouble equ 5
vbCurrency equ 6
vbBoolean equ 11
vbByte equ17
;以上变量对应的内存字节数据
vbIntegerSize equ 2
vbLongSize equ 4
vbSingleSize equ 4
vbDoubleSize equ 8
vbCurrencySize equ 8
vbBooleanSize equ 2
vbByteSize equ1
;安全数组结构
SafeArray1D struct
cDims dw 0
fFeatures dw 0
cbStep dd 0
cLocks dd 0
pvData dd 0
Elements dd 0
Lbound dd 0
reserved0 dd 0
reserved1 dd 0
SafeArray1D ends
;Variant数据类型
Variant struct
vType db 0
vArray db 0
reserved1 dw 0
BindID dd 0
pSafeArray dd 0
reserved2 dd 0
Variant ends
;最大指针数目
MaxSize equ 16
.DATA
align 16
Varptr dd MaxSize dup(0)
align 16
VarStructVariant MaxSize dup (<>)
align 16
VarSA SafeArray1D MaxSize dup(<>)
.code
;指针绑定内存数据 参数分别为:要绑定的指针,内存地址,内存大小,指针类型,指针增量
stBindVar proc uses edx ecx esi edi pVar:DWORD,pMem:DWORD,nSize:DWORD,nType:DWORD,nStep:DWORD
local mType,mStep,mElements
mov eax,nType
.if eax==vbByte
mov mStep,vbByteSize
.elseif eax==vbInteger
mov mStep,vbIntegerSize
.elseif eax==vbLong
mov mStep,vbLongSize
.elseif eax==vbSingle
mov mStep,vbSingleSize
.elseif eax==vbDouble
mov mStep,vbDoubleSize
.elseif eax==vbBoolean
mov mStep,vbBooleanSize
.elseif eax==vbCurrency
mov mStep,vbCurrencySize
.else
mov mStep,vbByteSize
mov nType,vbByte
.endif
.if nStep!=0
mov eax,nStep
mov mStep,eax
.endif
xor edx,edx
mov eax,nSize
div mStep
.if edx!=0
inc eax
.endif
mov mElements,eax
mov eax,pVar
mov edi,offset Varptr
mov ecx,MaxSize
cld
repnz scasd
.if !Zero?
xor eax,eax
mov edi,offset Varptr
mov ecx,MaxSize
repnz scasd
.if !Zero?
mov eax,-1
ret
.endif
mov eax,pVar
.endif
sub ecx,MaxSize
not ecx
mov ,eax
pxor xmm0,xmm0
mov edi,pVar
movupd ,xmm0
shl ecx,4
lea esi,
assume esi:ptr SafeArray1D
mov WORD ptr .cDims,1
mov WORD ptr .fFeatures,92h
mov eax,mStep
mov .cbStep,eax
mov .cLocks,0
mov eax,pMem
mov .pvData,eax
mov eax,mElements
mov .Elements,eax
mov .Lbound,0
lea esi,
assume esi:ptr Variant
mov eax,nType
mov BYTE ptr .vType,al
mov BYTE ptr .vArray,32
mov .reserved1,0
mov .BindID,'xEBV'
mov .reserved2,'TSyb'
lea eax,
mov .pSafeArray,eax
assume esi:nothing
movupd xmm0,
movupd ,xmm0
fclex
ret
stBindVar endp
;解除绑定
stUnBindAllproc uses edi ecx
mov edi,offset Varptr
xor ecx,ecx
pxor xmm0,xmm0
@@:
mov eax,
.if eax!=0
movupd ,xmm0
mov DWORD ptr ,0
.endif
inc ecx
cmp ecx,MaxSize
jb @B
ret
stUnBindAll endp
;解除单个变量的绑定
stUnBind proc uses edi ecx pVar:DWORD
mov eax,pVar
mov edi,offset Varptr
mov ecx,MaxSize
cld
repnz scasd
.if Zero?
pxor xmm0,xmm0
mov eax,
movupd ,xmm0
mov DWORD ptr ,0
xor eax,eax
.endif
ret
stUnBind endp
;调试VB程序用,研究VB数据存储访问结构就这个发挥了巨大作用
int3 proc
int 3
ret
int3 endp
smitest 发表于 2020-2-23 21:55
跟踪了一下,PtrLng还是被VB翻译成GetMem4,不知道咋回事。
是这样的,PtrXXX属性的Property Get就是GetMemN,Property Let就是PutMemN、Property Set就是SetMemN。
这几组函数本质上是VB6给类成员Public变量生成属性用的。
好像理解了,猜想是GetMem4定义成属性的效果。 系统消息 发表于 2020-2-20 19:26
msvbvm60.dll其实给我们提供了内存操作函数,只不过没有公开而已,我们直接写tlb声明这个未公开函数就行了 ...
还有请问大佬,entry(0x60000000)里0x60000000是啥意思呢 跟踪了一下,PtrLng还是被VB翻译成GetMem4,不知道咋回事。 VB6使用例子
Public Declare Function stUnBindAll Lib "vb6ex" () As Long
Public Declare Function stUnBind Lib "vb6ex" (ByRef Var As Variant) As Long
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
Public aa(1 To 16) As Byte, b As Long
Public ptr, ptr2, ptr3
Sub Main()
For I = 1 To 16 Step 2
aa(I) = I
Next
b = 45
stBindVar ptr, VarPtr(aa(1)), 16, vbInteger, 2
stBindVar ptr2, VarPtr(aa(1)), 16, vbByte, 3
stBindVar ptr3, VarPtr(b), 4, vbLong, 0
ptr(3) = 88: ptr3(0) = 99
stUnBind ptr
stUnBindAll
End Sub 本帖最后由 smitest 于 2020-2-18 21:33 编辑
最终库文件,引用TLB就不需要声明了。 来给大佬暖帖 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-20 19:26
msvbvm60.dll其实给我们提供了内存操作函数,只不过没有公开而已,我们直接写tlb声明这个未公开函数就行了 ...
哟!好东西啊,那啥时候把这个TLB的源码弄成一个github repo,让我们自己编译呢? 本帖最后由 系统消息 于 2020-2-22 19:10 编辑
0xAA55 发表于 2020-2-22 16:44
哟!好东西啊,那啥时候把这个TLB的源码弄成一个github repo,让我们自己编译呢? ...
源码不在现在这台电脑上,过段时间吧。还有就是最近有群友发现我tlb有一些地方有BUG,需要改进。
smitest 发表于 2020-2-23 22:03
还有请问大佬,entry(0x60000000)里0x60000000是啥意思呢
反编译工具的BUG
页:
[1]