吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15585|回复: 220
收起左侧

[原创] typora保护机制与注册逆向分析

    [复制链接]
cugou 发表于 2023-11-6 15:40
本帖最后由 cugou 于 2023-11-6 15:47 编辑

一、起因

一直比较喜欢Typora的简洁与美观(尝试过用 vscode 搭配插件编辑 markdown 文件,体验还是要差一些的),突然发现自己windows机器上很久前安装的typora不让用了,提示:
1.png
幸好原始安装文件还在,对比一下版本,原始安装文件是 0.9.93 版本,而不让用的是 0.10.11。
在我的 ubuntu22.04 机器上安装有 1.7.4 版本,win10上安装了 1.7.6版本。貌似最新的版本开始收费了,还分国内/国外两个版本。(typora.io 这个官网貌似被墙了,真不知道为了个啥。)
本着一个cracker无知者无畏的折腾到底的精神,开始瞎整!

二、摸底、知识和工具准备

😀 逆向分析的第一步就是要了解目标软件是用啥开发的,架构是啥。
一看 typora.exe 好家伙,100多个M,这么大的可执行程序还分析个啥?IDA分析一下都不知道要多久。
由于目前主用 ubuntu22.04 系统,想着顺便从 0 开始学习使用 ghidra 进行 Linux 平台的逆向分析工作。于是从一个小目标开始,需要瞎搞的知识点有了第一次扩充。  

  • ubuntu平台,用ghidra分析 1.7.4 版本;  
  • win7平台,用IDA6.8+x64DBG分析0.10.11版本;  
  • win10平台,用IDA6.8+x64DBG分析 1.7.6版本。(1.7.6 在我的win7下会出现不能在kernel32里面定位 discardVirtualMemory的错误)

悲催的是用 ghidra 静态分析 1.7.4 版本的 typora 有160多M,分析了10个小时也没结束。这个弯路绕太远了,毫无意义。直接放弃。  

😀 正确的打开方式:直接网上搜索
有大神直接用 IDA 分析 typora.exe,提示了一些有用的东东。结合两位成功破解的大神的文章,可以确定 typora 是使用 electron + nodejs 框架,用 javascript 开发的跨平台的桌面程序。(和vscode类似)
所以,啥是 electron/nodejs/javascript?0 基础的暴走,奇怪的知识点需要进行第二次扩充。
这几个每一个都是大部头,越底层的难度越大。被V8引擎绕进去花了不少时间(虽然了解一下好处很多,带着VM的思路去了解,能有不少收获),但就typora的破解来说,只需要涉猎以下内容:  

  1. electron app 的目录结构。  
  2. asar 打包/解压工具 (npm i -g asar)  
  3. node.js: 模块/API/运行环境构建/npm工具;node 命令行环境下运行 js 代码(类似python命令行环境)  
  4. V8 引擎:几乎用不到,因为用到了 Addon N-API 接口库。当然了解V8的好处还是很多的。真实的托管类数据结构,都是在V8引擎里面定义的,有详细的参考手册。  
  5. node.js Addon:通过 C++ 编写的扩展模块,用于扩展 Node.js 的功能。这个是重点,需要知道怎么写扩展模块的基本逻辑。(至少了解 V8 和 C++ 相互调用变量/函数的一两个例子)  
  6. N-API(Node-API)是一组稳定的 C 语言 API,用于编写跨平台的 Node.js Addon。N-API 提供了一套抽象层,使得开发者可以更轻松地编写可移植的扩展模块,而无需担心不同版本的 Node.js 或不同平台之间的兼容性问题。
    这个是需要重点把握的,熟练查阅 nods.js 中 N-API 的文档。
    N-API 实际上是 V8 接口的封装,进行了抽象,但对逆向增加了困难。因为其参数都是一系列 void** 之类的指针,具体在 V8 层进行实际的数据类型转换。所以逆向时,对于托管对象的指针,就别想着查看其数据了。重点应该放在 C++ 的本地数据结构上。   

三、聚焦 main.node

node.js Addon 可以在 js 层直接 require 一个 dll/so。electron 入口可能也是 require 引入 package.json 及里面定义的入口 js 文件的。
0.10.11 版本:PEid 查看算法常数,发现 sbox/rsbox,基本可以确定使用了AES算法。只是windows版本去符号,要从 rbox 逆推找到 AES KEY 和取定其 mode 难度还是比较大的。网上也有人分析到这一步放弃的。当然大神可以直接找到 mode CBC iv 和 AES KEY。
1.7.4 linux 版本:神奇的是没有去除符号,但与0.10.11版本不同,KEY 和 mode 的地方进行了混淆处理,不知道把 CBC 的 iv 怎么藏起来了。懒得去反混淆分析了(主要是能力不够)
有大神直接给出了 main.node 保护electron app的概念验证项目:https://github.com/toyobayashi/electron-asar-encrypt-demo
有了第二部分提到的知识准备后,就可以尝试看一下这个项目。当然像我一样 0 基础的,也可以边看边学,借助 N-API 文档和chatGPT的帮助。
简单总结一下这个项目的思路:  

  1. 由于 node.js 在 js 层可以 hook api,任意隐藏加解密的手段都会失效,所以要想办法将加解密放到 C++ 层去做。(这里可以只将 license 模块放到 addon 里面实现,估计是太过于明显直接暴露攻击目标,所以选择隐藏和加密入口)
  2. 通过重载 V8::_compile() 函数,实现针对性的解密。具体实现有 global 和 this module 的发现/遍历/重建require函数/require原始入口等问题,不是专家,也没搞懂,就破解来说,也不需要搞懂,根据关键字定位 main.node 里的关键函数就行。

结合V8执行js的基本逻辑来理解上面的思路:

// 定义一个 JavaScript 代码字符串
  V8::Local<V8::String> source_code =
      V8::String::NewFromUtf8(isolate, "'Hello, ' + 'World!'").ToLocalChecked();

  // 编译和运行 JavaScript 代码
  V8::Local< V8::Script> script = Script::Compile(context, source_code).ToLocalChecked();
   V8::Local< V8::Value> result = script->Run(context).ToLocalChecked();

V8执行js代码有两个过程,Compile 和 Run。Compile 只接受 V8 的托管字符串(js代码),而 C++ 字符串需要在 isolate(V8的一个独立的运行时虚拟机容器)内创建一个托管的 V8::String,用 N-API 库的话,相应函数是 napi_create_string_utf8(...)。
所以,既然把入口 js 的代码放到 C++ 层加解密,那么要执行它,比然经过上面的三步。重载 _compile 函数就是为了在这一步,给传入的 C++ string(js code)进行解密并创建对应的托管String,以便传给原来的 compile 函数。
理解了这个过程,那么最快、最容易的获取解密后的入口 js code,就在这个过程中。有两个思路,后面介绍。

四、分析 main.node

1、找入口:

  • 0.10.11 windows版本,用IDA查看 exports 导出表,然后一路跟踪下来:
    2.png
    3.png
    4.png
    5.png
    6.png
    addon 开发最后一个宏 NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) 实现的导出绑定,实际上就是调用 napi_module_register 注册了一个module,这个module结构包含一些源代码开发环境的一些信息,和一个__napi_main,在__napi_main中传递了 init 函数的地址。
  • 1.7.6 win10版本,导出表里面只有一个 DllEntryPoint。需要手动在 imports 里面找 napi_module_register,剩下的流程和上面一样。可以定位到 sub_18000492B 就是 init 入口。
    7.png
  • 1.7.4 linux版本,用ghidra查看发现 exports 几乎导出了所有的符号名。不过作者还是遵循了 _init 这个函数名。  

实际上找入口这一步是多余的,有了源代码只要结合关键字符串 _compile 和相应的函数调用,就能很快定位到 init 函数。只是作为一个cracker对流程跟踪的执念,瞎整。  

2、找_compile的重载函数:跟着源代码中的关键字符串找,很容易定位

  module_prototype.DefineProperty(
    Napi::PropertyDescriptor::Function(env,
      Napi::Object::New(env),
      "_compile",
      ModulePrototypeCompile,    // 就是这个函数
      napi_enumerable,            // 实际这个传递参数的地方做了一个wrapper。
      addon_data));

3、作者的 trick 一。

疑似的ModulePrototypeCompile这个函数往里面看的时候,和源代码完全不一致:
8.png
当时也懵了,因为自己是在windows系统上用IDA完全对照源码静态分析。使用静态分析工具查看 refrence to 和 refrence from 都连不上。无奈之下启用 x64DBG 调试。(找到真实的ModulePrototypeCompile函数还是很容易的,因为根据源代码,这个函数里面有非常明显的字符串"app.asar",而且是一个对称的if ... else ...结构。只是想弄清楚开发者到底怎么魔改的。)最后发现真实的ModulePrototypeCompile地址被打包在了上面替换函数的参数里面。调用变成了 call    qword ptr [r8],从而避免了静态分析时候被一撸到底。实际的trick是这样的:
9.png
直到分析 1.7.4 linux版本的时候,就看的很清楚了。
10.png
两者结合可以清楚看到多了一层 Wrapper 把真实函数地址隐藏在 Wrapper的参数里面。  

4、AES解密

后面的部分对于 0.10.11 windows版本来说,和源代码几乎一模一样,就是AES解密的过程,没有源代码那么多函数层级,中间的函数调用估计被 inline 了。但基本结构是一样的。CBC 模式的 iv 被藏在了实际chunck的最前面16个字节。
对于 1.7.4 Linux 版本整体架构不变,但 getKey 和 getIV 做了混淆,IV 怎么藏的也没看明白。尝试用函数的返回值,参照老版本的格式进行解密,发现是错误的。对混淆没什么能力,还是绕路吧。毕竟最终目标是去 main.node 运行。  

五、获取源代码/解密app.asar

1.     0.10.11 windows版本:

11.png
可以直接解密 app.asar(因为打包了几乎所有重要 js 文件,所以一个个调试获取源码也麻烦。)
其AES KEY就编码在指令中,无论是静态获取还是调试 getKey 处获取都可以。
IV 是放在chunck前的16个字节。根据这两个条件,可以直接编写代码对 app.asar 进行解密。  

2.     1.7.4 linux 和 1.7.6 win10版本:

因为看不懂 key  和 iv 的混淆,只能骚操作——直接调试获取 atom.js 的源代码。(只加密了这一个文件,估计是要保证启动速度)
在第三部分的最后,卖了一个关子,说到有两种方式可以获取解密后的 atom.js 入口,这里介绍一下:
(1)其实这个main.node加密框架本身就提供了获取方法,既然能重载_compile,在调用原始_compile之前对js code 进行解密,那么这个框架本身,也可以被cracker用来再次重载_compile,等着后续的main.node将解密好的 js code 传过来,然后 console.log 就可以了。
我不是搞开发的,看这个框架要配置编译环境貌似挺复杂的,留给有electron开发经验的朋友吧。这个方法的好处是:一次投入,终身享受。只要还使用这个框架,点下鼠标就能获得源代码。(当然typora作者也是有备而来,后面会讲到)
(2)napi_create_string_utf8,这个函数接受 C++ 字符串,可以直接从 GDB 或者 x64DBG 中把参数的值 dump 出来。不过因为调用这个函数的地方很多,需要手动定位 ModulePrototypeCompile 函数解密分支里面的那个,下断点。Decrypt函数直接返回了托管字符串,所以还需要深入进去找到正确的返回前最后一个调用 napi_create_string_utf8 的地方。  

iVar4 = napi_create_string_utf8(pnVar15,&DAT_00145b42,0,ppvVar14);

当然大神使用 frida 动态挂钩 napi_create_string_utf8 这种骚操作,咱小白也不懂。  

六、去 main.node 运行

优点是可以保持最快的加载速度,相当于完全开源了。  

1、0.10.11版本

根据0.9.93版本的目录架构,将解密后的文件丢到 typora/resources/app/ 目录下,其他保持不变,就可以直接运行了。  

2、1.7.4 linux 和 1.7.6 win10版本

使用解密后的 atom.js 按照 0.10.11 版本那样直接运行 win10 会弹窗提示 scheme 变量没有定义;linux 下有 typora 进程,不提示错误,需要用 GDB 调试运行才能知道,错误是一样的。这又是闹哪一出?  

  • 找不到暗桩怎么办?
    一开始不能确定导致变量没定义的原因,可能在 js 层,也可能在 main.node 层。js 层搜索了一圈没啥发现,感觉暗桩及有可能还是在 main.node 里面。想个办法验证一下:  
    • patch 函数 ModulePrototypeCompile 里面对于加密/非加密 js code 的 if ... else... 逻辑,都转向非加密的逻辑。  
    • 将解密出来的 atom.js 打包成 app.asar。  
    • 可以成功运行
      其实完成这一步,也可以实现破解了,后面注册逻辑就都是 js 层面的事情了。不过对于一个喜欢瞎折腾的 cracker,做到这个程度,不是很满意,于是继续瞎整。。。  
  • 作者的 trick 二
    在 js 层搜索一下 scheme 没有特殊的用法,对照 0.10.11版本,scheme 是定义一个自定义协议解析的字段,其值为 typora,可以使用 typora://xxx 这样的协议进行处理。
    在 main.node 里面全局搜索 scheme 啥也没发现,一时陷入僵局,作者显然是埋了一个深坑。因为是在 win10 下分析的去符号的版本,所以一时没有头绪。后来决定换个思路,atom.js 最后启动窗口肯定是要加载一个 html 的,这就是 typora 程序的入口。按照这个逻辑 发现了 “entry” 字符串/变量,其值应该是 window.html。现在有了两个键值对 scheme --> typora 和 entry --> 包含window.html。用这4个字符串去IDA搜索交叉引用,可以很快找到一个函数 sub_180012290。分析这个函数,实际一共埋了5个暗桩:addonPath,entry,scheme,shost,shostc。  

这5个暗桩,有的是隐藏了键名,有的是隐藏了键值。  

  • 对键名的隐藏:
    12.png
    这是键值对 addonPath :app.asar。键名 addonPath 的ascii码有些字符做了 + 0x0a 处理。对键值 app.asar 没有处理,就是字符串引用。  
  • 对键值的隐藏,1.7.6 win10版本似乎是花了功夫,进行了比较复杂的处理,似乎还加了混淆。(懒得去深入研究,主要是能力不够)还是看 1.7.4 linux版本的比较直观。
    13.png
    这是键值对 entry :typora://app/typemark/window.html。键名没有加密,键值的处理方式很直观。当然 shost 的值藏的更复杂一些,主要是将单字节的 ascii 变成了4直接的 int。不一一列出来了。  
  • 最后的问题,这些键值对加到哪里去了?
    安装函数linux版本名字是 _initGlobal。当然无论哪个版本,这个函数一开始的 napi_get_global 函数说明了一切。都加到 js 层的全局对象 global 里面了。由于我们要去 main.node 运行,5个暗桩实际上只有后面4个有用。  
    napi_get_global(env, global);
    global['addonPath'] = 'app.asar'
    global['entry'] = 'typora://app/typemark/window.html'
    global['scheme']='typora'
    global['shost'] = 'https://store.typora.io'
    global['shostc'] = 'https://dian.typora.com.cn'

    1.7 版本的 js 使用了 webpack 打包,main.node init 最后的入口调用有两步:  

    const a = require('./atom.js');        // require js 貌似一定要带路径,不然找不到模块,js 也不懂,唉
    a();            // 从 webpack 打包的 atom.js 看,这是一个空函数。反正main.node 调用了,那就照葫芦画瓢吧。

    有了上面这些信息,单独写一个 main.js 把4个全局变量加进去,按步骤调用入口就能实现去 main.node 运行了。  

七、注册思路

这些属于 js 层面的东东,还是经过 webpack 打包和混淆过的。对于 javascript 小白来说,看这种代码和天书差不多。找了个debundle工具,能还原未加密的 dist/static/js/ 里面的文件,但还原 atom.js 报错。最后找了个 webcrack 工具,效果是比较好的格式化了 atom.js,比vscode js fommatter 之类的强。果断祭出大杀器——chatGPT。一开始心太黑,直接把整个 atom.js 复制给 chatGPT,想让它给格式化代码,并给出解释。结果 chatGPT 直接给了一个长长的菜谱,真的是用心良苦😂。  

1、0.10.11版本

0.x版本应该都是作者发布的开发测试版本。而0.10版本很可能是作者第一个使用 main.node 进行加密的验证版本,因为 js 里面连个注册页面都没有,只有简单的验证逻辑和时间校验,超时不让用。
让 0.10.11版本重新跑起来也很间,直接将 License.js 里面表述注册与否的变量的初始值从 null 改成 true 就可以了。  

    hasLicense = true,  // null,

2、1.7.4 linux 和 1.7.6 win10版本。

这两个版本在 main.node 里面对 AES KEY 和 IV,以及暗桩的处理上,有一些差异,win10版本的更复杂和强化了一些。js 层上,关于注册的 445 类,对win32系统有着更加强化的校验。1.7.4linux版本,似乎是可以无限试用的,超时验证逻辑存在bug。
js 分析后,确定 445 类是处理所有注册/校验相关的。联网校验优先,涉及数据结构:  

SLicense 的初步结构:base64(RSA.encrypt(json2str({license:xxx, email:xxx, type:xxx...})))#failCounts#lastRetryDate

注册信息会用服务端私钥加密,本地用公钥解密。再进行 email 和 license 的校验。本地注册也是这个解密验证过程。网络验证不成功,会清空 SLicense,回到未注册版本。
由于公钥解密的介入,想要完美本地注册已经没有意义。想持续使用的思路大致两个(没仔细研究,可能还有坑,看个大概齐吧):  

(1)无限试用:

手动修改 IDate(install date) 时间。  

  • win10 版本在注册表 HKCU\Software\Typora\IDate。
  • linux 版本在 ~/.config/typora/{hash_machine_id} 文件里面。文件格式只是将 json 文件的 ascii 每个字节编成 16 进制文本保存。用 Buffer.from(dataStr, 'hex').toString() 就可以解码。单独改这里貌似也会有问题的,因为会用 ~/.config/typora/profile.data 文件的创建时间恢复 IDate。不过由于时间校验对linux版本的bug存在,似乎不用改,也可以一直免费用。(有可能是我对 js 的理解不够全面,不保证对)  
(2)patch js code:
  • 去掉RSA解密,其他保持不变,可以实现手动注册;然后将 shostc 改成和 shost 一样,利用GFW让网络注册失效。  
  • 直接 patch 掉整个注册校验过程。反正要patch,不如彻底一些,一劳永逸。  

八、加固建议

由于采用 main.node 这种框架把入口的解密放到 C++ 层,那么不可避免的,框架本身可以用来直接获取解密后的 js code,或者是绕不开字符串从 C++ 到 V8容器托管的转换过程。这是 electron 项目保护最大的难点。
作者也进行了很多努力:AES 关键的 key 和 iv 进行了隐藏和混淆;埋了一些暗桩并加密。但用前面的各种骚操作都可以绕过。
个人建议既然埋暗桩,与其花经历在几个全局变量的名字和值上进行各种花式操作,还不如把 445 注册校验类整体/部分放到 main.node 中。至少尽可能让不能脱离 main.node 运行。底层还能使用各种成熟的二进制保护技术,甚至可以引入虚拟机保护,增加逆向成本。  

九、后记

typora风格的markdown编辑器,好像github上有开源的了,有道笔记的 markdown笔记似乎也改成typora这种所见即所得风格了(不过上图要付费,或者自己注册一个免费图床)。选择面变多了。不过typora依然是桌面最优雅的。
整个逆向分析过程学到了不少东西,毕竟几乎整个是从 0 开始学起的。
在 ubuntu 平台使用 ghidra 进行静态分析和动态调试;
对面向对象有了更深层次的理解;
托管与非托管的相互调用,从C#、V8 js、python,有点理解python作为胶水语言在这种场景下为什么强大;发现 js 后面的 AST 是一条不归路啊。
对框架的理解,在逆向中的作用越来越重要了。现在的程序似乎都依赖于某个框架。  


参考文章:
《向Typora学习electron安全攻防》
《Typora 授权解密与剖析》
《Typora解密之跳动的二进制》
《Electron程序逆向(asar归档解包)》
《electron开发、打包与逆向分析》

免费评分

参与人数 154吾爱币 +141 热心值 +134 收起 理由
JTZ + 1 我很赞同!
笙若 + 1 + 1 谢谢@Thanks!
happyovo + 1 + 1 大佬强啊
bigbowl + 1 + 1 我很赞同!
YMGJ + 1 鼓励转贴优秀软件安全工具和文档!
kingchl + 1 我很赞同!
nauh + 1 + 1 谢谢@Thanks!
Mapleoow + 1 + 1 我很赞同!
LTbetter + 1 + 1 牛的,学到了
osptech + 1 + 1 我很赞同!
TiakonPwd + 1 + 1 谢谢@Thanks!
回家笔记~ + 1 + 1 用心讨论,共获提升!
Ptty + 1 用心讨论,共获提升!
DRabbit111 + 1 + 1 我很赞同!
Family951 + 1 + 1 谢谢@Thanks!
trxh2023 + 1 用心讨论,共获提升!
leventQAQ + 1 + 1 我很赞同!
心比天傲 + 1 + 1 我很赞同!
Gonzalo + 1 我很赞同!
wush1 + 1 + 1 用心讨论,共获提升!
duanxf168 + 1 + 1 我很赞同!
chenjingyes + 1 + 1 谢谢@Thanks!
Zerolal + 1 + 1 我很赞同!
jufercircle + 1 + 1 我很赞同!
galen20231111 + 1 我很赞同!
unbounded + 1 我很赞同!
sxjsjt + 1 + 1 用心讨论,共获提升!
agajasme + 1 + 1 热心回复!
霍大爷来玩破解 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
wddddd + 1 + 1 热心回复!
wenzijun + 1 + 1 热心回复!
foxfoxfoxfox + 1 我很赞同!
szmero + 1 + 1 我很赞同!
AndroidZeta + 1 + 1 用心讨论,共获提升!
magicd + 1 + 1 用心讨论,共获提升!
DRZH + 1 我很赞同!
红联-巧克力 + 1 + 1 谢谢@Thanks!
孺子韫 + 1 + 1 我很赞同!
ice-water + 1 + 1 我很赞同!
ycfxhsw + 1 + 1 谢谢@Thanks!
whale_fall123 + 1 + 1 谢谢@Thanks!
Tonyha7 + 2 + 1 谢谢@Thanks!
Reindeer + 1 用心讨论,共获提升!
zhaomy0506 + 1 热心回复!
纪某某i + 1 + 1 我很赞同!
ssdlh + 1 + 1 谢谢@Thanks!
zhangsan173 + 1 + 1 我很赞同!
xends + 1 + 1 用心讨论,共获提升!
cdaxcy + 1 + 1 热心回复!
Crazykim + 1 + 1 用心讨论,共获提升!
KissShotC + 1 谢谢@Thanks!
cheesecat + 1 用心讨论,共获提升!
daxiaobansheng + 1 + 1 我很赞同!
aAChengYay + 1 + 1 我很赞同!
zaixia + 1 用心讨论,共获提升!
LYNiko + 1 + 1 用心讨论,共获提升!
suimengzero + 1 + 1 热心回复!
lingyun011 + 1 + 1 热心回复!
liutongwei + 1 + 1 用心讨论,共获提升!
huiyiyou + 1 + 1 我很赞同!
yixi + 1 + 1 谢谢@Thanks!
zhp_king + 1 我很赞同!
CyberAzrael + 1 + 1 我很赞同!
9324 + 1 用心讨论,共获提升!
lawever + 1 + 1 谢谢@Thanks!
terryyann + 1 + 1 我很赞同!
hswljs + 1 + 1 我很赞同!
荷鹤赫 + 1 用心讨论,共获提升!
Cave + 1 + 1 热心回复!
MakiseSatsuki + 1 我很赞同!
kubenetes + 1 + 1 我很赞同!
guotao323 + 1 + 1 用心讨论,共获提升!
wo2ros + 1 我很赞同!
aficis + 1 + 1 热心回复!
zhangyx98 + 1 + 1 用心讨论,共获提升!
dkmg + 1 + 1 热心回复!
npfjcg + 1 我很赞同!
GS9452 + 1 我很赞同!
SayoYuuki + 1 + 1 我也很喜欢这个md编辑器!
sevenz + 1 + 1 热心回复!
5omggx + 1 + 1 用心讨论,共获提升!
BambooStrip + 1 + 1 我很赞同!
q5544425 + 1 我很赞同!
slmgr.vbs + 1 + 1 用心讨论,共获提升!
chuan9 + 1 + 1 谢谢@Thanks!
Enderhz + 1 + 1 用心讨论,共获提升!
WindsLand + 1 我很赞同!
fs000x + 1 + 1 用心讨论,共获提升!
omaraham + 1 + 1 非常有用。
llnewbee + 1 + 1 我很赞同!
HHJ200318 + 1 + 1 用心讨论,共获提升!
hhhprime1 + 1 + 1 用心讨论,共获提升!
ndocidoctdoc + 1 我很赞同!
nihao022000 + 1 + 1 我很赞同!
mayongz2023 + 1 + 1 我很赞同!
Crycat + 1 我很赞同!
fanpojie123 + 1 + 1 谢谢@Thanks!
ziyou089 + 1 + 1 谢谢@Thanks!
Livring + 1 + 1 我很赞同!
LU0123 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| cugou 发表于 2023-11-9 14:35
apie 发表于 2023-11-6 17:36
能够详细讲解下为什么“python作为胶水语言在这种场景下为什么强大;发现 js 后面的 AST 是一条不归路”的 ...

从COM过来你就知道,在二进制层面进行资源共享的困难。特别是底层语言和托管GC类语言之间的资源共享相互访问。为了不重复造轮子,开发了各种各样的接口和方法。但能称得上优雅/实用的有多少,更不要说能包容各种语言开发的资源库了。
纯粹是个人感受,不见得正确。抛砖引玉罢了。
微笑掩盖忧伤 发表于 2023-11-6 18:16
apie 发表于 2023-11-6 17:36
能够详细讲解下为什么“python作为胶水语言在这种场景下为什么强大;发现 js 后面的 AST 是一条不归路”的 ...

Python是一种高级编程语言,被广泛应用于各种领域,包括科学计算、数据分析、人工智能等。然而,有些人将Python称为“胶水语言”,意思是Python主要用于将各种语言和库“黏合”在一起。

什么是“胶水语言”?
在编程语言中,“胶水语言”通常指那些可以将各种语言和库“黏合”在一起的语言。这种语言的主要特点是易于学习和使用,并且具有丰富的库和工具,可以帮助程序员快速完成任务。Python是一种这样的语言,因为它具有广泛的库和工具,可以轻松地与其他语言和库集成。

然而,将Python称为“胶水语言”并不完全准确。虽然Python的确可以用于连接各种语言和库,但它也是一种强大的编程语言,可以进行许多复杂的任务Python的性能

另一个可以反驳Python是“胶水语言”的观点的因素是Python的性能。虽然Python不像C++和Java等语言那样快速,但它的性能也不是很差。Python的速度可以通过使用一些优化技术来提高,例如使用Cython将Python代码转换为C语言代码、使用NumPy等高性能库进行数值计算等。此外,Python也可以使用多线程和异步编程等技术来提高性能。。
MWH 发表于 2023-11-6 17:31
apie 发表于 2023-11-6 17:36
能够详细讲解下为什么“python作为胶水语言在这种场景下为什么强大;发现 js 后面的 AST 是一条不归路”的原因吗?
Kristin_ 发表于 2023-11-7 01:19
大佬牛,我什么时候能像大佬一样啊
Langvin 发表于 2023-11-7 08:22
感谢楼主分享
rollbor 发表于 2023-11-7 09:05
学习了,感谢分享!!!
gotolala 发表于 2023-11-7 09:09
感谢分享!
abil 发表于 2023-11-7 09:16
感谢分享,认真学习
moyuqianming 发表于 2023-11-7 09:23
感谢大佬分享,谢谢
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 11:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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