TC官方合作论坛

 找回密码
 立即注册
查看: 6510|回复: 16

【剑仙教程】tc内联汇编 (编写原理)。

  [复制链接]
发表于 2018-4-11 12:03:28 来自手机 | 显示全部楼层 |阅读模式

马上加入TC

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

x
本帖最后由 剑仙十号 于 2019-12-2 12:06 编辑

tc内联汇编(编写原理)。
源码 :http://52tc.info/forum.php?mod=viewthread&tid=70508

Visual Basic内嵌汇编语言解决方案
转载 2006年08月20
VB简单易用,但功能有时候受限制。VC、Delphi都可以直接在程序中写汇编代码,可恼的是,VB不行。我在网上也看过许多有关于VB嵌入汇编的方法,不过有些方法,过于复杂,而且也没相应的介绍。我这里提供一种方法,也许大家以后可能有用!
    基本思路:汇编代码,可以存在一个byte类型的数组中,然后通过某种手段,把系统控制权,转交给这段汇编代码,我们的汇编代码段,就得到了执行。但如何让这段汇编代码,获得系统的控制权限呢?查查WIN API手册,就可以知道有CallWindowProc这个函数。这个函数本是用于调用用户自己定义的窗口过程的,其原形如下:

Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As   Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    它有5个参数。lpPrevWnFunc是一个long型,等于用户自己窗口过程的地址,其余3个都是窗口过程所必须的参数,详见MSDN.

    我们只需要关心第一个参数:lpPrevWndFunc,窗口过程地址。如果,我们把自己的汇编代码地址,传进去会怎么样?当然,CallWindowProc就把这个地址,当成窗口过程地址,然后,调用这段汇编代码了。我们的汇编代码便得到执……

    当然,也得装摸做样的吧,将其余4个参数传进去,就传4个0算了,因为这4个参数,我们更本不用,但又是CallWindowProc必须的,不要忘了,我们传进去的lpPrevWndFunc,并非真正的窗口过程地址,而是自己的汇编码地址。

    具体一点,比如,我们要嵌入一段什么也不干的汇编代码:

Dim AsmCode() as byte
redim AsmCode(8)
'生成机器代码
AsmCode(0) = &H58 'POP EAX
AsmCode(1) = &H59 'POP ECX
AsmCode(2) = &H59 'POP ECX
AsmCode(3) = &H59 'POP ECX
AsmCode(4) = &H59 'POP ECX
AsmCode(5) = &H50 'PUSH EAX
'你可以在这里添加你想执行的Asm代码...
'.....如果添加的话,后面的数组偏移需要做相应改动
'你添加的代码在这里结束
'将控制权交还主程序
AsmCode(6) = &HC3 'RET
'.....
    然后:

CallDllFunction = CallWindowProc(VarPtr(AsmCode(0), 0, 0, 0, 0)
    VarPtr函数,用于取变量地址。返回一个long 型值。

    为什么前面要执行几个pop和一个push呢?因为我们是以一段汇编代码首地址,伪装成一个窗口过程的,系统调用CallWindowProc时,实际上除lpPrevWndFunc,我们还传入了4个参数,就是上面的的4个0,而CallWindoProc函数在调用lpPrevWndFunc这段汇编代码程序时,把其余4个参数是压入了堆栈的。相当于执行了以下代码:

xxxx00A4H: push 0
xxxx00A6H: push 0
xxxx00A8H: push 0
xxxx00AAH: push 0
xxxx00ACH: call VarPtr(AsmCode(0))(这段代码我们是看不见的,是CallWindoProc在内部做的处理)
xxxx00AFH: ......
    因为我们根本没有用到这4个参数,所以我们只需要将它弹出。所以,我们执行了4个POP ECX,就是把这4个不用的参数弹出,以保持堆栈指针的正确性。但为什么还要,第一句的:POP EAX,还是因为CallWindowProc把lpPrevWndFunc当成一个窗口过程的原故,因为作为一个正常的窗口过程,在执行Call语句的时候,得把Call语句的下一条指令地址push到堆栈中,用于子程序ret.在上面这段代码就是执行了:push xxxx00afh.事实上,在CallWindowProc中,实际上隐含执行这么几句,我们必须关心的代码:

push 0;参数入栈
push 0
push 0
push 0
push xxxx00afh;(当执行call 时,自动执行)
    为了能让窗口过程执行结束后堆栈指针保持平衡,当然要执行相应的pop指令,第一个pop eax是把子程序返回的地址暂时保存在寄存器eax中,然后弹出4个不用的参数。

    接着把保存在eax中返回地址,压回堆栈。当执行ret时,就能正确返回到CallWindowProc中了。

游客,如果您要查看本帖隐藏内容请回复


回复

使用道具 举报

 楼主| 发表于 2018-4-11 13:39:33 来自手机 | 显示全部楼层
本帖最后由 剑仙十号 于 2020-4-12 22:22 编辑

二楼,更新信息专用。
tc简单开发_兴趣群:
143358382 (497/500)

tc简单开发_爱好群:
433286131 (498/500)

tc简单开发_高级:
891069033 (99/500)

编程四大F:
1、流程控制,2、变量和数组,
3、函数多线程,4、系统api。
本群大神众多,新手众多,群文件内_资源海量。希望新手分享 更多的学习笔记,减少重复造轮子的时间。
回复 支持 反对

使用道具 举报

发表于 2018-9-3 20:01:36 | 显示全部楼层
阿萨德阿萨德
回复 支持 反对

使用道具 举报

发表于 2018-11-6 20:18:22 | 显示全部楼层




tc内联汇编
回复 支持 反对

使用道具 举报

发表于 2019-2-23 10:13:39 来自手机 | 显示全部楼层
学习了
回复

使用道具 举报

发表于 2019-3-5 14:42:20 | 显示全部楼层
回复

使用道具 举报

发表于 2019-4-10 01:49:04 | 显示全部楼层
学习看看
回复

使用道具 举报

发表于 2019-10-20 15:30:34 | 显示全部楼层
55555555555555555556
回复 支持 反对

使用道具 举报

发表于 2019-10-27 17:20:34 | 显示全部楼层

阿萨德阿萨德
回复 支持 反对

使用道具 举报

发表于 2019-11-12 19:05:22 | 显示全部楼层
自定义功能-数组按大小排序
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

推荐上一条 /2 下一条

关闭

小黑屋|TC官方合作论坛 (苏ICP备18045623号)

GMT+8, 2024-5-19 12:01 , Processed in 0.059192 second(s), 22 queries .

Powered by 海安简单软件服务部

© 2008-2019 版权所有 保留所有权利

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