首页
社区
课程
招聘
[原创]TC5.0 (一个脚本开发工具)其底层实现原理分析与推测(半成品)
发表于: 2019-8-4 11:26 8160

[原创]TC5.0 (一个脚本开发工具)其底层实现原理分析与推测(半成品)

2019-8-4 11:26
8160

由于某些原因,在周五第一次接触到了这样一个脚本,而这个脚本的逆向,有些棘手。其运行行为特征也非常奇怪,和之前的纯c&c++加上壳子完全不一样,首先肯定是vc++的一个程序其中混杂了相关的加密内容。
PE工具分析出来如下图(类似,这个test_en是我写的生成的):
(有混淆就混淆吧,挡不住f7大法)

然后long long time 的查找资料,终于在网络上发现了这个脚本的一些有意义的特征。
这个脚本是用TC工具生成的,我第一次听说TC这个工具,和他类似的按键精灵和易语言我都听过。
是我孤陋寡闻了,也印证了学习的必要性。接下来就是查找安装这个TC工具(为啥要下5.0,因为5.0是我在官网找到的最老的版本了,越老越容易暴露特征),安装后自己创建一个工程如下图(对我来说使用他贼简单,已有其他语言编程基础):(本文文末提供所有本文工具下载)

这里我发现了一个有意思的地方,tc作者实现的这套语言集成化极高,但是扩展性等于0,这样有个好处就是实现的原理会简单一些吧,我猜的。
可能有人会问:为啥我要去找这个开发工具写一个test程序,因为我想吐槽一下这个tc的官方论坛贼差劲,tc的逆向资料等于空白,我不知道是不是有人有但是不分享吧。我作为一个小白,我想要 逆向掉这样一个脚本,我必须要了解其生成的程序的原理,包含运行原理和他这门语言的实现原理。(说实话,可能是我太自信了,但是没办法啊,逆向资料太少了)。
还有这里我在想吐槽一句:tc这个我感觉网上很多人的资料都是用来做脚本,从来没有人介绍一下这个工具的底层运行原理。并且官方都没有任何资料解释其原理的,都是卖脚本的,感觉有种闭门造车的感觉,一个语言要发展,社区一定要活跃,否则就呵呵。
到这里,其实我周五想逆向的脚本已经被我抛开了,我只想知道tc这套框架的实现底层原理,我觉得挺有意思的,关键网上资料还少,挺有挑战性。
说不定我掌握这样的原理,我也能实现一个自己的语言出来,不一定要全,一定要专,这样我写的程序给别人逆向的话,可以挡住80%的逆向人员(靠工具自动化的),就像我这样的小白,还有20%的人能手动分析的,只要有功夫,什么都能分析的,拦不住的。(我感觉我已经十分的膨胀了,想自己创造一种语言出来。{:301_997:} {:301_997:} {:301_997:} )(关于上文怎么分析出来脚本是tc写的,请听我慢慢道来)

在我之前学习win的逆向的时候,就是字节写一个简单的win32弹框程序进行分析,直接拉入od,分析起来,很舒服,因为跟明文差不多(:lol 因为没有加壳)
同样,这里我把我写的test_en.exe拉入od,运行,分析。

拉入od,点击确定按钮,弹了一个框出来,暂停,看调用堆栈,不用怀疑,出现了两个明显的特征dll,TLib.dll和TApi.dll。为什么我说它是特征dll,我们可以在tc5的安装目录发现这两个dll,我也在周五的脚本发现了这两个dll,由此可以猜测,这个程序是tc写的。(其实理由有点牵强,但是我可以继续往下分析验证我的观点)

查看程序运行的依赖:

这里我还有一条证据:
在tc开发工具的安装目录的tlib和test_en释放的tlib做md5验证,一样的文件。

通过观察周五的脚本和我写的test_en.exe的开始运行过程中,在OD里面我发现了其会释放TApi和TLib这两个库到用户程序临时目录(因为我发布的test_en.exe不包含任何exe,说明这两个dll是打包到可执行文件中了的)。
根据我写的tc脚本程序。
[mw_shlcode=cpp,true]//开始按钮点击操作
function start_click()
var btn_start_content = "点击开始TEST"
var btn_start_title_msg = "提示"
messagebox(btn_start_content, btn_start_title_msg)

end

//退出按钮_点击操作
function exit_click()

end

function test_en_init()
//这里添加你要执行的代码

end

function test_en_destroy()
//这里添加你要执行的代码
var content = "call detroy"
var title_msg = "提示"
messagebox(content, title_msg)
end

//点击关闭_执行操作
function test_en_close()

end

//消息路由功能
function test_en_pretranslatemessage(hwnd,message,wParam,lParam,time,x,y)

end

//消息过程功能
function test_en_windowproc(message,wParam,lParam)
var test = "windowproc"
end

[/mw_shl_code]

其会在窗口初始化销毁以及鼠标点击事件情况下,执行我用“tc写的程序”,上文弹框的图和下面程序运行初始化的图暴露了一个事情。

到此我可以猜测,tlib和tapi是为了"解释执行"我写的函数,而我写的函数是什么时候调用的呢?是对应的控件事件的时候。其实tc开发工具就暗示我了,只是我没有get到点。


是不是我猜想的那样呢?我们还得深入汇编分析。
首先是关于tc生成的程序执行的原理,在上图按钮点击后,暂停,然后一直运行到主程序空间,你会发现你定义的很多tc调用都会进入以下的fun3。
首先我唯一可以确定的是,从主程序传给tlib只有一个参数,是对应事件的我们在tc中定义的函数名。

我们首先去ida里面看看fun3的定义,

可以看到就是把func_name和GlobalRunTime::g_RunManager这两个参数传给了tlib,然后执行我们在tc中定义的func_name。
剩下就只有两个问题要解决,解决后tc生成的程序底层执行原理就在我们的眼皮子底下了:
1 程序是怎么调用的fun3这个方法,什么原理(新手难度)?
2 fun3是怎么解释执行我们在tc中定义的函数(最难的)?

关于第一个问题,我想我可以解答,我在调试的过程中,在button下消息断点后,单步执行到主程序空间,你会发现,这个线程会在一个特定地方执行。


根据已知的常识知识,我们在win32自定义界面程序开发的时候,会这样做:
RegisterClassW注册一个窗体进入系统,否则你不能够CreateWindow,在RegisterClassW的参数是一个WINDCLASS指针,而这个WINDCLASS其中一个成员变量lpfnWndProc 指向了一个回调函数,这个回调函数专门用于处理os发送到这个窗口的消息,你可以在这里面处理自己感兴趣的消息,不处理的丢给DefWindowProc处理。

回到正题,那么我可以猜测tc调用fun3的原理是,在窗口消息回到函数中,根据特定的消息,调用tlib,只需要传入一个特定消息对应的tc中定义的函数名即可,还有这个GlobalRunTime::g_RunManager全局变量也是重点,圈起来,要考。也就是说,tc这门语言实现起来的原理就是:我在tc中定义的和事件相关的函数,根据os事件驱动来调用,然后传入对应时间对应的tc定义的函数名即可实现过程调用。

关于第二点,tlib是怎么解释执行我们定义的函数的,我没有分析完,昨天陷入误区了,也非常难,可能我还需要其他帮助或者更多的信息来分析,所以本文算是一个半成品,因为最最最核心的内容我都没有分析出来。
以下是我分析了的部分资料:
1 一个事件对应的tc中的方法,会在一次TRunManager::execute调用中执行完,也就是说,调用一次类似fun3的,就会完整的执行完一个tc中定义的事件对应函数。
2 在TRunManager::execute中,会根据TRunManager::findFuncBlockByName(GlobalRunTime::g_RunManager, func_name)来处理一个叫做struct BaseBlock的结构体,我有理由怀疑,这个结构体解码成功,tc的框架的运行原理解释就完成了。


3 根据上图,处理好struct BaseBlock结构体后,又会调用我上图已经改了名字的函数:parse_code_and_run,这里还有一个重要的知识点,划重点,要考,这个parse_code_and_run进去后,会执行完事件对应的我们在tc中定义的函数。
下面是ida中parse_code_and_run的相关已知的注释


4 初始化好后,调用tapi执行对应的action。

1 很遗憾,由于自己技术有限,昨天只能够分析出那么多了,但是我现在已经卡在了分析解释执行的部分上,昨晚觉都没有睡好。
2 从tc这门语言技术实现的角度来说,我还是可以学习到如下的知识点,自己可以建立一个模板程序,然后在程序的对应位置通过一定手段插入我自己定义的方法。一定手段可以是我定义的一个插入工具,我自己定义的方法可以抽象为我自己的一门语言。站着别人的肩膀上,可以用最小的代价,做出一个有趣的事情。
3 从上面来看,其实我想逆向那个周五的脚本已近跑偏了,我跟多的是想探寻类似tc,易语言,按键精灵这种框架实现的底层原理,很有趣。
4 这是我第一次接触tc、按键精灵、易语言之类的,原来国人已经做了很多工作了,抽象了很多内容,至少对于没有学过c||c++的人来说,开发一个小工具是个简单的事情,让许多许多的人都有机会实现一个自己的软件。这里还是对这些作者表示敬意,要实现这些内容,必须对计算机底层,或者说win的运行原理有深入的分析才行。

这篇文章,都是我自己的感悟,如果不对谁的胃口,请勿喷谢谢。
如果本文侵犯了谁的权利,请联系我删除,谢谢。
本文提供的附件请自行放到虚拟机里面测试,这样更加安全。


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

最后于 2019-8-4 11:29 被Iflyinsky编辑 ,原因: 更新
收藏
免费 1
支持
分享
最新回复 (7)
雪    币: 1047
活跃值: (655)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
低版本可以直接提取脚本源码,高版本有一些call if 啥的函数加密,有自己的一套解析引擎。
2019-8-4 22:43
0
雪    币: 551
活跃值: (480)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
Rookietp 低版本可以直接提取脚本源码,高版本有一些call if 啥的函数加密,有自己的一套解析引擎。
多低的版本呢?我想找一个最老的,用了解析引擎的那个版本学习一下,他这个设计非常的有意思
2019-8-5 09:07
0
雪    币: 1047
活跃值: (655)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
Iflyinsky 多低的版本呢?我想找一个最老的,用了解析引擎的那个版本学习一下,他这个设计非常的有意思
4.X的版本是可以提取的,然后修复下可以直接重新编译。
2019-8-5 12:14
0
雪    币: 551
活跃值: (480)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
Rookietp 4.X的版本是可以提取的,然后修复下可以直接重新编译。
有4.x的提取方法有相关资料吗,我网上找了一圈,都没有,太小众了?按照你的说法,5.x以上有些call和if加密了,但是有些肯定是继承了4.x的内容,我去找个4.x的分析分析,看有没有可以新的启发。
2019-8-5 14:10
0
雪    币: 1047
活跃值: (655)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Iflyinsky 有4.x的提取方法有相关资料吗,我网上找了一圈,都没有,太小众了?按照你的说法,5.x以上有些call和if加密了,但是有些肯定是继承了4.x的内容,我去找个4.x的分析分析,看有没有可以新的启发。
TC没多少人用的,大多数都是按键。高版本解密算法好像一样,都是DES AES之类的东西,就是封装和解析的方法那块大改了一下吧。解密啥的都是在mLib.dll里。可以找到Decrypt之类的导出函数。
2019-8-5 19:36
0
雪    币: 551
活跃值: (480)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
Rookietp TC没多少人用的,大多数都是按键。高版本解密算法好像一样,都是DES AES之类的东西,就是封装和解析的方法那块大改了一下吧。解密啥的都是在mLib.dll里。可以找到Decrypt之类的导出函数。
我感兴趣的就是他的封装和解析那一部分,请问你有4.x的提取资料吗?我找个例子试试,看他是怎么解析的,感觉很有意思
2019-8-6 09:24
0
游客
登录 | 注册 方可回帖
返回