VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 86652|回复: 174

[原创] 全球首创? 再次突破VB极限!VB真正稳定多线程(不用tlb,tls,ax,pcode)

  [复制链接]
 楼主| 发表于 2010-4-26 09:25:03 | 显示全部楼层 |阅读模式
本帖最后由 VBProFan 于 2010-4-29 16:21 编辑

全球首创? 全球再次突破VB极限!

只需在线程中加一行代码实现 VB 真正稳定多线程

不需要...
1.不需要写tlb库(感觉麻烦了,使用tlb主要是防止vb设置err.lastDllerr),
2.不需要处理tls(很多都是暴力copy,不知道有没有后遗症?)
3.不需要编译成activx exe(这东东会在注册表留下垃圾项,从VB的引用中会看到),
4.不需要编译成p-code(P代码的坏处众所周知了)
5.不需要干掉 setSysXXXerr(干掉后 err.lastDllErr肯定无效啦,不爽)
6.不需要远程创建线程...(汗,谁发明的,好厉害,转了好大一个圈)
...(还有没有?)

俗话说得好,有钱能使鬼推磨,果然不假...
此次的灵感来源于这1000块大洋...

http://www.vbgood.com/viewthread.php?tid=92649

(上面的代码是使用P CODE实现的VB线程安全)
等你学会了全球首创大法后,就能把他改为本机代码的线程安全.原代码不需要用TLB再次封装修改.

  1. '无文档的VB API
  2. Public Declare Function CreateIExprSrvObj Lib "msvbvm60.dll" (ByVal p1_0 As Long, ByVal p2_4 As Long, ByVal p3_0 As Long) As Long
  3. '调用方法:在线程函数的第一行加上
  4. CreateIExprSrvObj 0, 4, 0
复制代码
下面的多线程来源于网上因为懒得再写,他是用P-CODE实现的VB线程安全)
http://www.freevbcode.com/ShowCode.Asp?ID=4029

接下来.用上面"全球首创"的方法改进一下...


  1. Public Sub test_function()
  2. CreateIExprSrvObj 0, 4, 0'加到线程函数的第一句

  3. Dim i As Long
  4. Dim ret As Long
  5. ...

  6. Public Sub test_function2()
  7. CreateIExprSrvObj 0, 4, 0'此例中共有2个线程,所以加2句,这是第2句
  8. msgbox "ok?" '测试 VB的提示框...(效果自己下载代码看)
  9. ''''
复制代码
此法使用后VB的字符串操作都可以在线程中进行...
当然了,仍有不足之处,暂时不说(其实在别的贴子说过了),留给大家去发现...

未完待续...(根据反应的良好后再加以重点说明.反应不好的就不说明了 )

PS:有钱的记得加钱,没钱的记得加分啊~~~ 这样才会继续公开VB内幕...
PPS:如果是mei nv也可以向老汉使mei ren计,偶可是会中计滴...

-----------------------下面是揭密----------------------------
只需在线程中加一行代码实现 VB 真正稳定多线程揭密

1.为什么要声明成tlb库的原因.
众所周知,VB的函数包装了API,举例:
当调用GetProcAddr时,VB是用的DllCallFunction(好像是这个名吧?记不太清了)先检查有没有加载,有的话直接JMP过去,没有的话又要执行几个API进行加载. 同样的,当调用GetLastWin32Err(估计这是个名吧?记不太清)同样的,又是经过了几个API.这时的错误号己经不是最初的那个API的错误了.(可能己被覆盖) 那么API出错怎么知道呢,调用源码中声明的API的时候,VB就自作聪明的在后面加上一句SetXXXErr(全名记不太清).这样一来.当在多线程或回调中调用API时.变成了下面这样
DllCall MessageBox
SetXXXErr err.LastDllError (这个err是个对象,保存winapi.GetLastError的值,免得被VB函数中调用的API覆盖了错误信息)
在一般情况下是正常的,在线程中由于这个err没有初始化,所以就会保存错误号到未初始化的内存中.就出现线程错误了.
用TLB时VB编译后这个函数放到了PE头部的导入表中,调用时就不需要LoadLib,GetProcAddr,直接jmp 到导入表的地址即可(由PE的加载器填入)
这样就不会有VB中多余的API操作影响winapi.GetLastError的值了.所以VB又自作主张的去掉了SetXXXerr...这样线程中就正常了,当然(还是不能调用其它的VB函数(特别是和对象有关的)
这样一来,每个需要用的函数要用TLB声明一下,相当的麻烦.结果本来只需要写一行声明在源码中,变成了写到TLB的源文件I/ODL中,再用midl编译,还要再引用,最后才能使用...(这里己经讲到关键了,就不再废话了,不然pjz说我充字数骗稿费就不好了-_-!)
总之用TLB写VB函数不是给VB的程序员用的,是给VC+SDK这类程序员用...
例子:顶楼的声明去掉,改为TLB即成.

2.不需要处理tls(很多都是暴力copy,不知道有没有后遗症?)

不知道是谁发明的...好像是CSDN的超级绿豆?这种我看着晕,所以没测试...
例子:http://www.vbgood.com/viewthread.php?tid=88445
(VBProFan 注:iceboy 的 copy tls

3.不需要编译成activx exe(这东东会在注册表留下垃圾项,从VB的引用中会看到),

这个我最早在国外发现...
由于和揭密无关,就不说了,简单说下,如果想取消注册表的项,可以 shell "filename.exe /unregserver"
例子: http://www.vbgood.com/viewthread.php?tid=65375

4.不需要编译成p-code(P代码的坏处众所周知了)

和揭密无关,为节省版面略之...(猜想由于PCODE在虚拟机中运行,所以VB的对象都是OK的,不会有什么大问题)
例子: 顶楼的那个国外的链接

5.不需要干掉 setSysXXXerr

头痛医头,脚头医脚的办法.
nop掉后也只能用VB内声明的API,还是无法用VB字符串之类的函数

6.不需要远程创建线程...

和揭密无关,略过
例子自己找吧: 好像是chenhui530的RtlCreateUserThread
最最关键来源于这里:
http://www.vbgood.com/viewthread.php?tid=88445
这段文字...
需要说明的是在线程函数里面,只有一次调用API的机会~
因为VB编译器会在每个API后面添加__vbaSetSystemError,
如果未经处理__vbaSetSystemError是肯定会出错的...(后面还有一些,和主题无关略之)

也就是说我们只有一次机会... -_-!
于是开始老汉猜想(不是哥德巴赫猜想)
1.那么最好的办法是什么?
2.为什么在VB的IDE中可以运行?
原因只有一点:就是VB中己经初始化了他需要的对象.
那么有没有初始化对象的这个未公开的函数呢?
于是开始追踪:
(过程可到看雪参观: http://bbs.pediy.com/showthread.php?threadid=36400)
仅贴关键思路点:

  1. OD自动反汇编了这个有问题的KEYGEN。我们逐步跟踪,到下面的代码时,出现异常,问题就出在__vbaStrCat中。
  2. 004012BC   .  E8 2B020000   CALL <JMP.&msvbvm60.__vbaStrCat>
  3.     我们跟入__vbaStrCat:
  4. ...
  5. 660E5F47    FF15 18EE1066   CALL DWORD PTR DS:[6610EE18]             ; DS:[6610EE18]=00000000,问题出在这里
  6. ...
  7. 跟到660E5F47时出现异常,我们看到PTR DS:[6610EE18]为0,我们拿原来的CRACKME或者直接拿msvbvm60.dll反汇编,跟入__vbaStrCat:
  8. 660E5F47    FF15 18EE1066   CALL DWORD PTR DS:[6610EE18]             ; OLEAUT32.VarBstrCat
  9.    可以看出问题所在:PTR DS:[6610EE18]在CRACKEME中有被初始化成VarBstrCat而在KEYGEN中没有。
复制代码
也就是说,我们需要找一个初始化的函数...继续追踪...

  1. text:66004D81                                         ; CreateIExprSrvObj+3E p
  2.     CreateIExprSrvObj觉得可疑,跟进看看:
  3. .text:660EA734                 public CreateIExprSrvObj
  4. .text:660EA734 CreateIExprSrvObj proc near
  5. ...
  6. .text:660EA772                 call    sub_66004D81  <---- 就是这个CALL
  7.     我们需要这个CALL,deroko对CALL进行了修改并使之运行正常:
  8.     push    0
  9.     push    4
  10.     push    0
  11.     call    CreateIExprSrvObj(记得改call为cinvoke)
  12. ...
复制代码
到此,我们己经找到了未公开的初始化函数.那就是CreateIExprSrvObj,根据上面的PUSH共有三个参数声明成VB的API.

  1. '无文档的VB API
  2. Public Declare Function CreateIExprSrvObj Lib "msvbvm60.dll" (ByVal p1_0 As Long, ByVal p2_4 As Long, ByVal p3_0 As Long) As Long
  3. '调用方法:在线程函数的第一行加上
  4. CreateIExprSrvObj 0, 4, 0
复制代码
刚才说了,我们只有一次机会可以调用API,那就是调用CreateIExprSrvObj 0,4,0 完成初始化过程.
此时线程中的第二条API应该就是__vbaSetSystemError,也就是非TLB多线程的瓶颈,
这个时候己经没关系了,因为上面己经完成了初始化.至此揭密己经告一段落.为什么参数是0,4,0?
这个就不太清楚了,因为是无文档的东东...留给大家继续发现...

------------------------揭密完成-----------------------

本帖子中包含更多资源

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

x

评分

参与人数 44威望 +266 金钱 +72 人气 +60 收起 理由
sunfrank + 13 + 3 很给力
orz12 + 1 很给力!
xdxdxd + 1 赞一个!
tianlanp + 1 很给力!
a6688979 + 1 很给力!
sq03 + 1 很给力!
baimnmss + 1 + 1 神马都是浮云
176803941 + 1 我很赞同
rogerge + 1 赞一个 类似思路10年前想过,后来因为用AC
suysung + 1 我很赞同
brightdog + 1 很好的教程,学习了,谢谢!
neilbr + 1 精品啊,顶之。
ppa0001 + 5 + 1 真是不错,向你学习。
aq1212 + 5 + 1 我分不多...
ruihongli + 1 + 1
reker + 20 + 20 + 3 本年度最NB研究成果
dahual + 5 + 1 wonderful
ntaryl + 5 + 1 nice
junyuqin + 8 + 1 发布源码,感谢分享!
zhaidoudou123 + 8 + 1 精品文章
wolf3t + 1 + 1 我很赞同
cwa9958 + 16 + 2 看你说的这么热闹
ghostlanse + 1 好东西 谢谢了
513069906 + 5 + 1 恶意灌水
beixue + 13 + 2 精品文章
inat + 1 + 1 精品文章
cjsaohan + 3 + 1 确实是一个很好的尝试
菜鸟学飞 + 10 + 2 呵呵 都忘了加分了~~
coyove + 10 + 2 来晚了
VBProFan + 20 + 20 + 3 CreateIExprSrvObj 0, 4, 0
forditor + 5 + 1 膜拜!
jackierobin + 5 + 1 发布源码
blk661 + 10 + 2 精品文章
cfc771 + 8 + 1 精品文章
cnlamb + 10 + 2 精品
无聊耍耍酷 + 5 + 1 好样的,加油,VB未来看你的了!
acme_pjz + 5 + 2 不错(未测试),不过我的程序估计不仅仅是线
gxght1122 + 2 + 1 老汉就是老汉
仙剑魔 + 12 + 12 加油搞定msgbox
youhm + 16 + 2 精品文章
eqing1111 + 8 + 2 还得是老汉啊。
catchwind + 2 + 1 我只能给这么点分了...
yimins + 20 + 20 + 3 不错,CreateIExprSrvObj果然是一个神奇的
lekj + 8 + 1 模拜一下

查看全部评分

本帖被以下淘专辑推荐:

 楼主| 发表于 2010-4-26 09:29:25 | 显示全部楼层
PSSS:第一次发表提示"含有XX关键字" 是不是美"女"也是关键字? -_-!
PSSSS:第二次发表提示标题长过80字符...幸好内容还在,估计没力再打第二遍了...
PSSSSS:第三次发表终于成功.编辑加入附件.

评分

参与人数 1威望 +5 人气 +1 收起 理由
garyng + 5 + 1 狂顶!!!!!!太好了!!

查看全部评分

回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2010-4-26 09:37:35 | 显示全部楼层
wowow ...利害利害..试了一下...呵呵...

评分

参与人数 1人气 +1 收起 理由
download + 1 试成功了没?成功了还不加分?

查看全部评分

回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2010-4-26 09:48:36 | 显示全部楼层
超赞一个!
我这1000大元花得值,这个方法确实可以非常完美的实现多线程。
编译后的文件PE结构好像和原来都不一样了?厉害!
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2010-4-26 09:53:47 | 显示全部楼层
本帖最后由 lekj 于 2010-4-26 09:57 编辑

成功了哇......而且马上加分了哇...还加了 8 个威望...


我试的时候....

弹出 IE..

然后 两个时间在跑....

没有了 MsgBox "ok?" 出来哦......
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-4-26 10:07:07 | 显示全部楼层
成功了哇......而且马上加分了哇...还加了 8 个威望...


我试的时候....

弹出 IE..

然后 两个时间在跑....

没有了&nbsp;MsgBox "ok?" 出来哦......
lekj 发表于 2010-4-26 09:53


是啊,哈哈

不知道为何 msgbox 不出来...(估计另有弦机)不过他不出错了
回复 支持 反对

使用道具 举报

发表于 2010-4-26 10:07:40 | 显示全部楼层
先留个记号,回头测试通过了一定来加分!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-4-26 10:16:04 | 显示全部楼层
超赞一个!
我这1000大元花得值,这个方法确实可以非常完美的实现多线程。
编译后的文件PE结构好像和原来都不一样了?厉害!
jangogo 发表于 2010-4-26 09:48


听你这么一说,我试了几个壳(ZP,VM,ASP)都可以.没什么问题.

PE结构没变化的,因为不使用TLB,
使用TLB后会在PE的导入表多一些项目.只是线程会有些变化.
回复 支持 反对

使用道具 举报

发表于 2010-4-26 11:10:02 | 显示全部楼层
牛B。。。。
回复 支持 反对

使用道具 举报

发表于 2010-4-26 11:14:26 | 显示全部楼层
没玩过多线程。能否做过实际例子?例如:文件搜索,Load/Insert multi images from/to Database?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2022-10-7 06:41

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表