技术宅的结界

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

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 214|回复: 11
收起左侧

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

[复制链接]

1

主题

17

帖子

117

积分

用户组: 小·技术宅

UID
5585
精华
0
威望
6 点
宅币
88 个
贡献
0 次
宅之契约
0 份
在线时间
11 小时
注册时间
2020-2-5
发表于 2020-2-18 21:03:57 | 显示全部楼层 |阅读模式

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

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

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

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

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

主文件,没啥好解释的。
[Asm] 纯文本查看 复制代码
.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用的很舒服,可惜不更新了
[Asm] 纯文本查看 复制代码
LIBRARY VB6Ex
DESCRIPTION This DLL by MASMPlus
EXPORTS  
int3
stBindVar
stUnBindAll
stUnBind


处理代码
[Asm] 纯文本查看 复制代码
int3 proto   ;调试VB程序用的,对这个主题没啥意义
stBindVar proto  pVar:DWORD,pMem:DWORD,nSize:DWORD,nType:DWORD,nStep:DWORD 
stUnBindAll proto
stUnBind  proto pVar:DWORD
;以下的暂时写的支持的VB数据类型,该常数对应于VB的VBVARTYPE枚举结构
vbInteger equ 2
vbLong   equ 3
vbSingle equ 4
vbDouble equ 5
vbCurrency equ 6
vbBoolean equ 11 
vbByte equ  17
;以上变量对应的内存字节数据
vbIntegerSize equ 2
vbLongSize   equ 4
vbSingleSize equ 4
vbDoubleSize equ 8
vbCurrencySize equ 8
vbBooleanSize equ 2 
vbByteSize equ  1

;安全数组结构
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
 VarStruct  Variant 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 [Varptr+ecx*4],eax
	
	pxor xmm0,xmm0
	mov edi,pVar
	movupd [edi],xmm0
	shl ecx,4

	lea esi,[VarSA+ecx*2]
	assume esi:ptr SafeArray1D
	mov WORD ptr [esi].cDims,1
	mov WORD ptr [esi].fFeatures,92h
	mov eax,mStep
	mov [esi].cbStep,eax
	mov [esi].cLocks,0
	mov eax,pMem
	mov [esi].pvData,eax
	mov eax,mElements
   mov [esi].Elements,eax
	mov [esi].Lbound,0


	lea esi,[VarStruct+ecx]
	assume esi:ptr Variant
	mov eax,nType
	mov BYTE ptr [esi].vType,al
	mov BYTE ptr [esi].vArray,32
	mov [esi].reserved1,0
	mov [esi].BindID,'xEBV'
	mov [esi].reserved2,'TSyb'
	lea eax,[VarSA+ecx*2]
	mov [esi].pSafeArray,eax	

   assume esi:nothing  

	movupd xmm0,[esi]
 	movupd [edi],xmm0
 	
fclex
 ret
stBindVar endp



 
;解除绑定
stUnBindAll  proc   uses edi ecx
	mov edi,offset Varptr
	xor ecx,ecx
	pxor xmm0,xmm0
	@@:
	mov eax,[edi+ecx*4]
	.if eax!=0
	    movupd [eax],xmm0
	    mov DWORD ptr [edi+ecx*4],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,[edi-4]
		movupd [eax],xmm0
		mov DWORD ptr [edi-4],0
		xor eax,eax
	.endif
 	ret
stUnBind endp


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

 
回复

使用道具 举报

1

主题

17

帖子

117

积分

用户组: 小·技术宅

UID
5585
精华
0
威望
6 点
宅币
88 个
贡献
0 次
宅之契约
0 份
在线时间
11 小时
注册时间
2020-2-5
 楼主| 发表于 2020-2-23 21:55:49 | 显示全部楼层
跟踪了一下,PtrLng还是被VB翻译成GetMem4,不知道咋回事。

1

主题

17

帖子

117

积分

用户组: 小·技术宅

UID
5585
精华
0
威望
6 点
宅币
88 个
贡献
0 次
宅之契约
0 份
在线时间
11 小时
注册时间
2020-2-5
 楼主| 发表于 2020-2-23 22:03:30 | 显示全部楼层
系统消息 发表于 2020-2-20 19:26
msvbvm60.dll其实给我们提供了内存操作函数,只不过没有公开而已,我们直接写tlb声明这个未公开函数就行了 ...

还有请问大佬,entry(0x60000000)里0x60000000是啥意思呢

1

主题

17

帖子

117

积分

用户组: 小·技术宅

UID
5585
精华
0
威望
6 点
宅币
88 个
贡献
0 次
宅之契约
0 份
在线时间
11 小时
注册时间
2020-2-5
 楼主| 发表于 2020-2-23 23:02:39 | 显示全部楼层
好像理解了,猜想是GetMem4定义成属性的效果。

3

主题

53

帖子

839

积分

用户组: 大·技术宅

UID
4293
精华
3
威望
11 点
宅币
585 个
贡献
164 次
宅之契约
0 份
在线时间
61 小时
注册时间
2018-9-19
发表于 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

主题

17

帖子

117

积分

用户组: 小·技术宅

UID
5585
精华
0
威望
6 点
宅币
88 个
贡献
0 次
宅之契约
0 份
在线时间
11 小时
注册时间
2020-2-5
 楼主| 发表于 2020-2-18 21:20:22 | 显示全部楼层
VB6使用例子
[Visual Basic] 纯文本查看 复制代码
 
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

1

主题

17

帖子

117

积分

用户组: 小·技术宅

UID
5585
精华
0
威望
6 点
宅币
88 个
贡献
0 次
宅之契约
0 份
在线时间
11 小时
注册时间
2020-2-5
 楼主| 发表于 2020-2-18 21:31:15 | 显示全部楼层
本帖最后由 smitest 于 2020-2-18 21:33 编辑

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

VB6Ex.dll

3.5 KB, 下载次数: 0

vb6ex.tlb

2.67 KB, 下载次数: 0

1

主题

18

帖子

46

积分

用户组: 初·技术宅

UID
5613
精华
0
威望
2 点
宅币
24 个
贡献
0 次
宅之契约
0 份
在线时间
1 小时
注册时间
2020-2-12
发表于 2020-2-20 15:57:22 | 显示全部楼层
来给大佬暖帖

3

主题

53

帖子

839

积分

用户组: 大·技术宅

UID
4293
精华
3
威望
11 点
宅币
585 个
贡献
164 次
宅之契约
0 份
在线时间
61 小时
注册时间
2018-9-19
发表于 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赋值是对其默认属性赋值)

1055

主题

2415

帖子

6万

积分

用户组: 管理员

一只技术宅

UID
1
精华
221
威望
328 点
宅币
19262 个
贡献
39854 次
宅之契约
0 份
在线时间
1821 小时
注册时间
2014-1-26
发表于 2020-2-22 16:44:28 | 显示全部楼层
系统消息 发表于 2020-2-20 19:26
msvbvm60.dll其实给我们提供了内存操作函数,只不过没有公开而已,我们直接写tlb声明这个未公开函数就行了 ...

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

3

主题

53

帖子

839

积分

用户组: 大·技术宅

UID
4293
精华
3
威望
11 点
宅币
585 个
贡献
164 次
宅之契约
0 份
在线时间
61 小时
注册时间
2018-9-19
发表于 2020-2-22 19:08:26 | 显示全部楼层
本帖最后由 系统消息 于 2020-2-22 19:10 编辑
0xAA55 发表于 2020-2-22 16:44
哟!好东西啊,那啥时候把这个TLB的源码弄成一个github repo,让我们自己编译呢? ...


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

3

主题

53

帖子

839

积分

用户组: 大·技术宅

UID
4293
精华
3
威望
11 点
宅币
585 个
贡献
164 次
宅之契约
0 份
在线时间
61 小时
注册时间
2018-9-19
发表于 2020-2-24 21:35:03 | 显示全部楼层
smitest 发表于 2020-2-23 22:03
还有请问大佬,entry(0x60000000)里0x60000000是啥意思呢

反编译工具的BUG

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图  

GMT+8, 2020-6-4 20:22 , Processed in 0.122075 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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