<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Bluore</title><description>在这里写写画画</description><link>https://bluore.top/</link><language>zh_CN</language><item><title>Linux常用命令-小记</title><link>https://bluore.top/posts/archlinuxnote/</link><guid isPermaLink="true">https://bluore.top/posts/archlinuxnote/</guid><pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;网络&lt;/h1&gt;
&lt;h2&gt;ip address 命令&lt;/h2&gt;
&lt;p&gt;查看本机网络接口&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[04:24:18 PM]
╰─&amp;gt;$ ip a
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: enp4s0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500qdisc fq_codel state DOWN group default qlen 1000
    link/ether 1c:83:41:ce:04:ea brd ff:ff:ff:ff:ff:ff
    altname enx1c8341ce04ea
3: wlo1: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 98:bd:80:34:02:a6 brd ff:ff:ff:ff:ff:ff
    altname wlp3s0
    altname wlx98bd803402a6
    inet 10.218.0.141/15 brd 10.219.255.255 scope global dynamic noprefixroute wlo1
       valid_lft 603914sec preferred_lft 603914sec
    inet6 fe80::6ff3:52be:8bcf:c275/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
4: singbox_tun: &amp;lt;POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP&amp;gt; mtu 9000 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 172.18.0.1/30 brd 172.18.0.3 scope global singbox_tun
       valid_lft forever preferred_lft forever
    inet6 fe80::3dd2:db03:6ace:55c5/64 scope link stable-privacy proto kernel_ll
       valid_lft forever preferred_lft forever`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面是开启了&lt;code&gt;TUN（虚拟网卡）&lt;/code&gt;代理的运行情况，如果需要卸载&lt;code&gt;虚拟网卡&lt;/code&gt;执行&lt;code&gt;ip link delete &amp;lt;虚拟网卡名&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;iwd 连接网络&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;iwctl
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;device list
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 填写你扫描到的设备
station wlan0 scan
station wlan0 get-networks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;station wlan0 connect &amp;lt;网络名称&amp;gt;
# 回车后输入密码
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[05:17:44 PM]
╰─&amp;gt;$ iwctl
NetworkConfigurationEnabled: disabled
StateDirectory: /var/lib/iwd
Version: 3.11
[iwd]# device list
                                    Devices                                   *
--------------------------------------------------------------------------------
  Name                  Address               Powered     Adapter     Mode
--------------------------------------------------------------------------------
  wlan0                 98:bd:80:34:02:a6     on          phy0        station

[iwd]# station wlan0 scan
[iwd]# station wlan0 get-networks
                               Available networks                             *
--------------------------------------------------------------------------------
      Network name                      Security            Signal
--------------------------------------------------------------------------------
      NSU-SDN                           open                ****
      此消彼长                          psk                 ****
      Bluore&apos;s phone                    psk                 ****
      来蹭你爹的网                      psk                 ****

[iwd]# station wlan0 connect &quot;Bluore&apos;s phone&quot;
Type the network passphrase for Bluore&apos;s phone psk.
Passphrase: ********
[iwd]# exit
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;分区&lt;/h1&gt;
&lt;h2&gt;lsblk&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;lsblk -f
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[06:15:02 PM]
╰─&amp;gt;$ lsblk -f
NAME FSTYPE FSVER LABEL    UUID      FSAVAIL FSUSE% MOUNTPOINTS
zram0
     swap   1     zram0    9fb3a373-be98-4e93-aba6-88fdb3a6f25c                [SWAP]
nvme0n1
│
├─nvme0n1p1
│    vfat   FAT32          7049-B703       140.4M    30% /efi
├─nvme0n1p2
│
├─nvme0n1p3
│    ntfs         System   249A76BE9A768C54
├─nvme0n1p4
│    ntfs                  E29473BC94739231
├─nvme0n1p5
│    ntfs         Software B65659F95659BB37
├─nvme0n1p6
│    btrfs                 032c17e9-7417-4345-b04f-5ee0561a7ced   30.6G    83% /home
│                     /
└─nvme0n1p7
     btrfs                 9fea03d7-4c78-47cc-83ea-940ff1afc944
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;fdisk &amp;amp; cfdisk&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;fdisk -l
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[06:16:43 PM]
╰─&amp;gt;$ sudo fdisk -l
Disk /dev/nvme0n1: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: KINGSTON SNV2S1000G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: C1F0B2B5-3ACF-4502-A82D-5DB9C5B64466

Device              Start        End   Sectors   Size Type
/dev/nvme0n1p1         40     409639    409600   200M EFI System
/dev/nvme0n1p2     409640     442407     32768    16M Microsoft reserved
/dev/nvme0n1p3     444416  313382911 312938496 149.2G Microsoft basic data
/dev/nvme0n1p4  313382912  315015167   1632256   797M Windows recovery environment
/dev/nvme0n1p5  315015168 1124514447 809499280   386G Microsoft basic data
/dev/nvme0n1p6 1544091648 1953523711 409432064 195.2G Linux filesystem
/dev/nvme0n1p7 1124515840 1544091647 419575808 200.1G Linux filesystem

Partition table entries are not in disk order.


Disk /dev/zram0: 30.52 GiB, 32769048576 bytes, 8000256 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;GRUB 更新&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;grub-install --target=x86_64-efi --efi-directory=&amp;lt;EFI挂载目录&amp;gt; --bootloader-id=&amp;lt;启动项名称&amp;gt;
grub-mkconfig -o /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;可用于在 live 环境中修复EFI启动项&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;杂项&lt;/h1&gt;
&lt;h2&gt;配置镜像源 &lt;strong&gt;pacman&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#
reflector -a 12 -c cn -f 10 --sort score --v --save /etc/pacman.d/mirrorlist
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获取系统相关信息&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;uanme -a
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;fastfetch
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>模仿赛机 - abc题目快捷提交</title><link>https://bluore.top/posts/submit-help/</link><guid isPermaLink="true">https://bluore.top/posts/submit-help/</guid><pubDate>Wed, 28 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;关于&lt;code&gt;submit&lt;/code&gt;的原理和使用&lt;/p&gt;
&lt;h1&gt;实现原理&lt;/h1&gt;
&lt;p&gt;使用时执行这个命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;submit abc123d.cpp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会创建一个本地的服务器，监听&lt;code&gt;9974&lt;/code&gt;端口，浏览器插件通过http轮训&lt;code&gt;localhost:9974&lt;/code&gt;来获取提交的文件（最多监听10s）&lt;/p&gt;
&lt;p&gt;浏览器插件可以通过文件名推断atcoder的对应题目的提交链接（使用cph的短名称自动命名），模拟输入代码和点击提交按钮（默认等待5s用来过cloudflare的人机验证）&lt;/p&gt;
&lt;p&gt;:::warning
由于chorme对于插件有一定的限制，会在后台10s内杀掉插件，所以需要点击插件进入监听页面
:::&lt;/p&gt;
&lt;h1&gt;下载和使用&lt;/h1&gt;
&lt;p&gt;将编译好的exe程序添加到环境变量PATH中&lt;/p&gt;
&lt;p&gt;:::tip
下载方式：&lt;a href=&quot;https://github.com/bluore/submit&quot;&gt;Github&lt;/a&gt;
::github{repo=&quot;Bluore/submit&quot;}
:::&lt;/p&gt;
&lt;p&gt;浏览器安装插件，使用时点击插件图标进入监听页面&lt;/p&gt;
&lt;p&gt;:::tip
下载方式：&lt;a href=&quot;https://github.com/bluore/submit-plugin&quot;&gt;Github&lt;/a&gt;
::github{repo=&quot;Bluore/submit-plugin&quot;}
:::&lt;/p&gt;
&lt;p&gt;使用时在控制台中输入命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;submit &amp;lt;filename&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning
仅支持&lt;code&gt;AtCoder Beginner Contest&lt;/code&gt;上的题目，且文件名使用&lt;code&gt;Competitive Programming Helper (cph)&lt;/code&gt;插件的短文件名格式
:::&lt;/p&gt;
</content:encoded></item><item><title>加密客户端</title><link>https://bluore.top/posts/vpn-share/</link><guid isPermaLink="true">https://bluore.top/posts/vpn-share/</guid><pubDate>Thu, 22 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;仅提供更加安全访问内网设备和加密访问的方式&lt;/p&gt;
&lt;h1&gt;下载&lt;/h1&gt;
&lt;h2&gt;v2ray 客户端&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/2dust/v2rayN/releases&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::warning&lt;/p&gt;
&lt;p&gt;未知来源，谨慎下载&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://haha-1366927206.cos.accelerate.myqcloud.com/tutorial/windows/v2ray/v2rayN-windows-64-desktop.zip&quot;&gt;Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://coke.cn-nb1.rains3.com/v2rayNG_1.10.32_universal.apk&quot;&gt;Android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;Clash 客户端&lt;/h2&gt;
&lt;p&gt;:::warning&lt;/p&gt;
&lt;p&gt;未知来源，谨慎下载&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://haha-1366927206.cos.accelerate.myqcloud.com/tutorial/windows/clash/Clash.for.Windows.Setup.0.20.39.exe&quot;&gt;Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://coke.cn-nb1.rains3.com/cmfa-2.11.21-meta-universal-release.apk&quot;&gt;Android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;FLClash 客户端&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/chen08209/FlClash/releases&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>我做了个视奸我自己的网站 - CheckMe</title><link>https://bluore.top/posts/checkme/</link><guid isPermaLink="true">https://bluore.top/posts/checkme/</guid><description>记录一下制作这个网站所遇到的问题和解决方案</description><pubDate>Sun, 18 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;关于我做了个视奸我自己的网站 me.bluore.top&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本文记录一下纯小白的我在写这个项目中遇到的困难&lt;/p&gt;
&lt;p&gt;能够实时视奸自己的网页是如何完成的呢，首先我想到的困难就是数据获取的问题，以及如何长期后台保活的问题&lt;/p&gt;
&lt;h1&gt;获取数据&lt;/h1&gt;
&lt;p&gt;如果是Windows系统中，这个问题就很简单，可以写一个简单的py脚本即可获取并传递数据，将文件添加快捷方式到&lt;code&gt;C:\Users\&amp;lt;用户名&amp;gt;\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup&lt;/code&gt;的文件夹下系统就会开机自启动该程序&lt;/p&gt;
&lt;p&gt;不过如果是Android系统该如果获取数据呢？&lt;/p&gt;
&lt;p&gt;最开始想的是，是否可以通过写一个App，通过申请无障碍权限来进行获取数据，并尽可能后台保活，可是不会Java和Android开发的我很快放弃了这个想法，不过正巧最近换了新的手机 ~（旧的没有放到转转）~ ，顺手刷了机，于是这个问题就简单了&lt;/p&gt;
&lt;p&gt;下面记录一下我去是如何获取Android系统中的数据，并后台长期保活&lt;/p&gt;
&lt;h2&gt;应用进程数据如何获取 ？&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys activity top | grep ACTIVITY
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;示例输出 ( MT资源管理器模拟终端 )&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys activity top | grep ACTIVITY
  ACTIVITY com.v2ray.ang/.ui.MainActivity b6cc31a pid=(not running) userId=0 uid=10334 displayId=0(type=INTERNAL)
  ACTIVITY me.weishu.kernelsu/.ui.MainActivity 3246fc5 pid=(not running) userId=0 uid=10413 displayId=0(type=INTERNAL)
  ACTIVITY org.lsposed.manager/.ui.activity.MainActivity b5ee8f8 pid=(not running) userId=0 uid=10335 displayId=0(type=INTERNAL)
  ACTIVITY com.taobao.taobao/com.taobao.tao.welcome.Welcome f6a9a8c pid=(not running) userId=0 uid=10349 displayId=0(type=INTERNAL)
  ACTIVITY com.jingdong.app.mall/com.jd.lib.productdetail.ProductDetailActivity b14b607 pid=(not running) userId=0 uid=10396 displayId=0(type=INTERNAL)
  ACTIVITY com.tencent.mobileqq/.activity.SplashActivity cfc32cb pid=20711 userId=0 uid=10358 displayId=0(type=INTERNAL)
  ACTIVITY com.suda.yzune.wakeupschedule/.schedule.ScheduleActivity 5364210 pid=7721 userId=0 uid=10432 displayId=0(type=INTERNAL)
  ACTIVITY tv.danmaku.bili/.MainActivityV2 1e0fc74 pid=16964 userId=0 uid=10336 displayId=0(type=INTERNAL)
  ACTIVITY com.twitter.android/com.twitter.app.main.MainActivity 3b31223 pid=528 userId=0 uid=10402 displayId=0(type=INTERNAL)
  ACTIVITY com.google.android.youtube/.app.honeycomb.Shell$HomeActivity 88a1c87 pid=7596 userId=0 uid=10365 displayId=0(type=INTERNAL)
  ACTIVITY com.tencent.mm/.ui.LauncherUI 905c54c pid=24420 userId=0 uid=10356 displayId=0(type=INTERNAL)
  ACTIVITY mark.via/.Shell d839efd pid=666 userId=0 uid=10385 displayId=0(type=INTERNAL)
  ACTIVITY com.android.launcher/.Launcher 4818b2c pid=5268 userId=0 uid=10222 displayId=0(type=INTERNAL)
  ACTIVITY bin.mt.plus/l.ᩳۛ᩵ 27fd27e pid=11838 userId=0 uid=10398 displayId=0(type=INTERNAL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个命令可以获取所有的活动的应用进程的包名，不过当前活动的进程包名是哪一个?&lt;/p&gt;
&lt;p&gt;经过数据的实践和统计发现，最后一行的包名正是当前正在使用的应用的包名，所以先通过&lt;code&gt;tail -1&lt;/code&gt;筛选最近使用的应用的进程信息，再进行正则表达式进行匹配&lt;code&gt;s/.*ACTIVITY \([^/]*\)\/.*/\1/p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;完整的命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys activity top | grep ACTIVITY | tail -1 | sed -n &apos;s/.*ACTIVITY \([^/]*\)\/.*/\1/p&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys activity top | grep ACTIVITY | tail -1 | sed -n &apos;s/.*ACTIVITY \([^/]*\)\/.*/\1/p&apos;
bin.mt.plus
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获取手机电量&lt;/h2&gt;
&lt;h3&gt;通用方法&lt;/h3&gt;
&lt;p&gt;通过&lt;code&gt;dumpsys battery&lt;/code&gt;通用的方法可以获取到手机的电量&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;测试机型: &lt;em&gt;一加 Ace5 ( 版本号：PKG110_15.0.0.840(CN01) )&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys battery
Current OPLUS Battery Service state:
  Charger voltage : 4757
  Battery current : -1589
  ChargerTechnology: 0
  ChargeFastCharger: false
  PlugType: 2
  UpdatesStopped: false
  UsbHwStatus: 0
  BatteryHwStatus: -2147483648
  HwStatusIsSet: 1
  BatteryIcStatus: -2147483648
  IcStatusIsSet: 1

  mUsbStatus: 0
  PhoneTemp: 330
  ThermalFeatureOn: true
Current Battery Service state:
  AC powered: false
  USB powered: true
  Wireless powered: false
  Dock powered: false
  Max charging current: 2000000
  Max charging voltage: 5000000
  Charge counter: 4864000
  status: 2
  health: 2
  present: true
  level: 87
  scale: 100
  voltage: 4402
  temperature: 325
  technology: Li-ion
  Charging state: 0
  Charging policy: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的&lt;code&gt;level: 87&lt;/code&gt;就是手机显示的电量，完整筛选后的命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys battery | grep level | awk &apos;{print $2}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys battery | grep level | awk &apos;{print $2}&apos;
88
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就直接获取到了当前的面板电量&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;不过这里获取到的手机电量可能并不是真实的手机电量，而是显示的面板电量(即：手机厂商想让你看到的手机电量)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;手机真实电量&lt;/h3&gt;
&lt;p&gt;这里就不展开说了，目前本机型的 $\mathrm{面板电量} \ne  \mathrm{实际电量}$&lt;/p&gt;
&lt;h2&gt;获取当前播放的媒体标题&lt;/h2&gt;
&lt;p&gt;有了前面的经验，这次就顺利多了，使用&lt;code&gt;dumpsys media_session&lt;/code&gt;获取到一大堆信息后用&lt;code&gt;sed -n &apos;/User Records:/,/Controller Records:/p&apos;&lt;/code&gt;筛选到用户进程，然后取第一个媒体的数据&lt;code&gt;grep -m 1 &apos;metadata:&apos;&lt;/code&gt;( 因为最近播放的媒体会把之前后台播放的给顶掉，直接获取第一个即可 )，拿到媒体的标题&lt;code&gt;sed &apos;s/.*description=//&apos;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;执行结果：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
The Bird Song (with Em Beihold), Noah Floersch/Em Beihold, The Bird Song (with Em Beihold)      
➜ sdcard sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
何御, 李姿逸RizRea, 何御
➜ sdcard sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
小画家！, 自动连播, null
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;运行图&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到，歌曲名重复了一遍&lt;/p&gt;
&lt;p&gt;如果是播放B站视频，则歌曲名最后会显示null，这样并不美观而且会让获取的数据冗余，所以我通过&lt;code&gt;cut -d&apos;,&apos; -f1&lt;/code&gt;进行截取第一项（歌曲名）和第二项（作者名）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos; | cut -d&apos;,&apos; -f1
sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos; | cut -d&apos;,&apos; -f2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这两行，分别获取标题（歌曲名、视频标题）和作者（作者名、B站状态）&lt;/p&gt;
&lt;p&gt;这样，在安卓系统中的Root环境我们便可以获取数据了&lt;/p&gt;
&lt;h2&gt;如何发送数据并后台保活&lt;/h2&gt;
&lt;p&gt;正巧我使用的设备是刷上KSU的Root设备，所以我使用的方案是写一个&lt;code&gt;mksh&lt;/code&gt;的Shell脚本，打包成一个模块，刷入到Root管理器中，开机自启动且不会被杀后台（我没遇到过）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;刷入模块&quot; /&gt;&lt;/p&gt;
&lt;p&gt;其实&lt;strong&gt;ADB权限&lt;/strong&gt;也是可以的，不过会有一些限制，我就没试了 （￣︶￣） &amp;lt;-懒&lt;/p&gt;
&lt;h1&gt;代码编写&lt;/h1&gt;
&lt;p&gt;解决了核心问题，其他的就简单了&lt;/p&gt;
&lt;p&gt;后端选择&lt;code&gt;Golang&lt;/code&gt;语言，&lt;code&gt;Gin&lt;/code&gt;框架+&lt;code&gt;MySQL&lt;/code&gt;数据库，前端选择&lt;code&gt;Vue&lt;/code&gt;然后&lt;code&gt;Deepseek&lt;/code&gt;自己写 ~( vscode，你已经是一个成熟的ide了，该自己写代码了 )~ ，对于没有写过项目的我来说（刚速通完golang语法），顺便练习一下写代码的能力，所以后端边学边写，关掉了goland的整行提示 ~折磨自己~ ，自己去慢慢搓代码 ~(导致写一堆自己不想修复的Bug)~&lt;/p&gt;
&lt;p&gt;本仓库使用前后端分开部署，使用不同域名（或使用Nginx来路由），桌面端支持&lt;strong&gt;Windows&lt;/strong&gt;，手机端支持&lt;strong&gt;Root + Android&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;欢迎大家来部署玩玩&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Bluore/CheckMe&quot;&gt;CheckMe - Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1&gt;效果演示&lt;/h1&gt;
&lt;p&gt;桌面端&amp;amp;移动端&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;桌面端&amp;amp;移动端&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Bluore/CheckMe&quot;}&lt;/p&gt;
</content:encoded></item><item><title>NSU作业平台 破解</title><link>https://bluore.top/posts/nsuwork/</link><guid isPermaLink="true">https://bluore.top/posts/nsuwork/</guid><pubDate>Fri, 06 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;东软教学平台作业的客观题答案获取与一键作答&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ==UserScript==
// @name         【答案显示|自动答题】成都东软学院(大连东软应该也可以)||4S平台试卷答案显示||一键答题
// @license      MIT
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  进入题目后，右上角会显示题目的答案，照着选就行了
// @author       You
// @match        *://sep.study.neuedu.com/#/paper/*
// @grant        none
// @downloadURL https://update.greasyfork.org/scripts/519339/%E3%80%90%E7%AD%94%E6%A1%88%E6%98%BE%E7%A4%BA%7C%E8%87%AA%E5%8A%A8%E7%AD%94%E9%A2%98%E3%80%91%E6%88%90%E9%83%BD%E4%B8%9C%E8%BD%AF%E5%AD%A6%E9%99%A2%28%E5%A4%A7%E8%BF%9E%E4%B8%9C%E8%BD%AF%E5%BA%94%E8%AF%A5%E4%B9%9F%E5%8F%AF%E4%BB%A5%29%7C%7C4S%E5%B9%B3%E5%8F%B0%E8%AF%95%E5%8D%B7%E7%AD%94%E6%A1%88%E6%98%BE%E7%A4%BA%7C%7C%E4%B8%80%E9%94%AE%E7%AD%94%E9%A2%98.user.js
// @updateURL https://update.greasyfork.org/scripts/519339/%E3%80%90%E7%AD%94%E6%A1%88%E6%98%BE%E7%A4%BA%7C%E8%87%AA%E5%8A%A8%E7%AD%94%E9%A2%98%E3%80%91%E6%88%90%E9%83%BD%E4%B8%9C%E8%BD%AF%E5%AD%A6%E9%99%A2%28%E5%A4%A7%E8%BF%9E%E4%B8%9C%E8%BD%AF%E5%BA%94%E8%AF%A5%E4%B9%9F%E5%8F%AF%E4%BB%A5%29%7C%7C4S%E5%B9%B3%E5%8F%B0%E8%AF%95%E5%8D%B7%E7%AD%94%E6%A1%88%E6%98%BE%E7%A4%BA%7C%7C%E4%B8%80%E9%94%AE%E7%AD%94%E9%A2%98.meta.js
// ==/UserScript==

(function() {
    &apos;use strict&apos;;
    // 定义全局变量
    var getData = null;

    // 创建悬浮窗的函数
    function createFloatingWindow() {
        var window = document.createElement(&apos;div&apos;);
        window.id = &apos;floatingWindow&apos;;
        window.style.position = &apos;fixed&apos;;
        window.style.top = &apos;10px&apos;;
        window.style.right = &apos;10px&apos;;
        window.style.width = &apos;300px&apos;;
        window.style.height = &apos;400px&apos;;
        window.style.backgroundColor = &apos;white&apos;;
        window.style.border = &apos;1px solid black&apos;;
        window.style.zIndex = &apos;9999&apos;;
        window.style.overflow = &apos;auto&apos;;
        document.body.appendChild(window);
        // 添加列表项
        var title = document.createElement(&apos;h2&apos;);
        title.textContent = &apos;试卷信息&apos;;
        window.appendChild(title);
        // 添加提示信息
        var info = document.createElement(&apos;p&apos;);
        info.textContent = &apos;试卷信息加载中...&apos;;
        window.appendChild(info);
        // 题目信息列表
        var list = document.createElement(&apos;ul&apos;);
        window.appendChild(list);
        // 创建按钮
        var button = document.createElement(&apos;button&apos;);
        button.textContent = &apos;一键答题&apos;;
        button.style.marginTop = &apos;10px&apos;;
        button.addEventListener(&apos;click&apos;, clickAnswerButton);
        window.appendChild(button);
        // 点击关闭按钮的事件
        var closeButton = document.createElement(&apos;button&apos;);
        closeButton.textContent = &apos;关闭悬浮窗&apos;;
        closeButton.style.marginTop = &apos;10px&apos;;
        closeButton.style.float = &apos;right&apos;;
        closeButton.addEventListener(&apos;click&apos;, closeFloatingWindow);
        window.appendChild(closeButton);
        return window;
    }
    
    // 关闭悬浮窗的函数
    function closeFloatingWindow() {
        var floatingWindow = document.getElementById(&apos;floatingWindow&apos;);
        floatingWindow.parentNode.removeChild(floatingWindow);
    }

    function ansButtonClick(ansPath) {
        setTimeout(() =&amp;gt; {
          document.querySelector(ansPath).click();
          callback(&quot;&amp;gt;&amp;gt;&amp;gt;&quot;+ansPath);
        }, Math.ceil(Math.random() * 3000));
    }

    // 点击按钮的函数
    function clickAnswerButton() {
        var data = getData;
        //setTimeout(function(){
        for (var type in data[&apos;data&apos;]){
            for(var question in data[&apos;data&apos;][type][&apos;studentPartQuestionList&apos;]){
                var questionJson = data[&apos;data&apos;][type][&apos;studentPartQuestionList&apos;][question];
                for(var ans in questionJson[&apos;selectReferenceAnswerList&apos;]){
                    for(var choose in questionJson[&apos;questionOptionList&apos;]){
                        if(questionJson[&apos;selectReferenceAnswerList&apos;][ans] == questionJson[&apos;questionOptionList&apos;][choose][&apos;id&apos;]){
                            var ansPath = &quot;#questionId&quot;+ questionJson[&apos;markId&apos;]  +&quot; &amp;gt; div &amp;gt; div:nth-child(2) &amp;gt; div:nth-child(3) &amp;gt; div &amp;gt; label:nth-child(&quot;+ String(choose-(-1)) +&quot;)&quot;;
                            // const startTime = performance.now();
                            // while (performance.now() - startTime &amp;lt; 100) {}                            console.log(ansPath);
                            // document.querySelector(ansPath).click();
                            ansButtonClick(ansPath,(result)=&amp;gt;{
                                console.log(result);
                            })
                        }
                    }
                }
            }
        }
        //},0);
    }

    // 题目列表删除函数
    function removeListInfo() {
        var floatingWindow = document.getElementById(&apos;floatingWindow&apos;);
        // 将提示更改为&apos;试卷信息已经完成加载&apos;
        var info = floatingWindow.getElementsByTagName(&apos;p&apos;)[0];
        info.textContent = &apos;试卷信息已经完成加载&apos;;
        // 删除列表
        var list = floatingWindow.getElementsByTagName(&apos;ul&apos;)[0];
        while (list.firstChild) {
            list.removeChild(list.firstChild);
        }
    }

    // 题目列表添加函数
    function addListInfo(data) {
        var floatingWindow = document.getElementById(&apos;floatingWindow&apos;);
        // 添加一项data到ul末尾 
        var list = floatingWindow.getElementsByTagName(&apos;ul&apos;)[0];
        var li = document.createElement(&apos;li&apos;);
        li.textContent = data;
        list.appendChild(li);
        
    }

    // 发起GET请求并处理响应的函数
    function fetchPaperInfo() {
        // 获取当前URL的哈希部分
        var hash = window.location.hash;
        // 去除哈希前的&apos;#&apos;符号
        var hashContent = hash.replace(/^#/, &apos;&apos;);
        // 以&apos;/&apos;分割字符串
        var parts = hashContent.split(&apos;/&apos;);
        // 获取第一项和第二项，注意检查数组长度以避免越界
        var firstPart = parts[2] || &apos;&apos;; // 第一项
        var secondPart = parts[3] || &apos;&apos;; // 第二项
        //console.log(&apos;第一项:&apos;, firstPart);
        //console.log(&apos;第二项:&apos;, secondPart);
        var params = &apos;candidateId=&apos;+firstPart+&apos;&amp;amp;arrangementId=&apos;+secondPart;
        var token = localStorage.getItem(&apos;token&apos;); // 从本地存储中获取Token
        var xhr = new XMLHttpRequest();
        xhr.open(&apos;GET&apos;, &apos;http://sep.study.neuedu.com/se-tool-gateway/biz/test/student/test/paper/info?&apos; + params, true);
        xhr.setRequestHeader(&apos;Token&apos;, token); // 设置请求头中的Token
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 &amp;amp;&amp;amp; xhr.status == 200) {
                var response = JSON.parse(xhr.responseText);
                getData = response;
                displayPaperInfo(getData);
            } else if (xhr.readyState == 4) {
                document.getElementById(&apos;floatingWindow&apos;).innerHTML = &apos;Failed to fetch data: &apos; + xhr.status;
            }
        };
        xhr.send();
    }

    // 显示试卷信息的函数
    function displayPaperInfo(data) {
        var testNum = 0;
        removeListInfo();
        for (var type in data[&apos;data&apos;]){
            addListInfo(data[&apos;data&apos;][type][&apos;partName&apos;]);
            for(var question in data[&apos;data&apos;][type][&apos;studentPartQuestionList&apos;]){
                testNum++;
                var questionJson = data[&apos;data&apos;][type][&apos;studentPartQuestionList&apos;][question];
                //var result = &quot;题目：&quot;+questionJson[&apos;stem&apos;]+&quot; 答案：&quot;;
                var testTitle = questionJson[&apos;stem&apos;];
                if(testTitle.length&amp;gt;15){
                    testTitle = testTitle.substring(0,14)+&quot;...&quot;;
                }
                addListInfo(testNum+&quot;、题目：&quot;+testTitle);
                for(var ans in questionJson[&apos;selectReferenceAnswerList&apos;]){
                    for(var choose in questionJson[&apos;questionOptionList&apos;]){
                        if(questionJson[&apos;selectReferenceAnswerList&apos;][ans] == questionJson[&apos;questionOptionList&apos;][choose][&apos;id&apos;]){
                            //result += choose[&apos;questionOption&apos;]+&quot;&amp;lt;/br&amp;gt;&quot;;
                            var _listShow = [&apos;A&apos;,&apos;B&apos;,&apos;C&apos;,&apos;D&apos;,&apos;E&apos;,&apos;F&apos;,&apos;G&apos;,&apos;H&apos;,&apos;I&apos;,&apos;J&apos;,&apos;K&apos;,&apos;L&apos;,&apos;M&apos;,&apos;N&apos;,&apos;O&apos;,&apos;P&apos;,&apos;Q&apos;,&apos;R&apos;,&apos;S&apos;,&apos;T&apos;,&apos;U&apos;,&apos;V&apos;,&apos;W&apos;,&apos;X&apos;,&apos;Y&apos;,&apos;Z&apos;];
                            addListInfo(_listShow[choose]+&quot;.&quot;+questionJson[&apos;questionOptionList&apos;][choose][&apos;questionOption&apos;]);
                        }
                    }
                    //console.log(ans);
                }
            }
        }
    }

    // 页面加载完成后执行
    window.addEventListener(&apos;load&apos;, function() {
        var floatingWindow = createFloatingWindow();
        fetchPaperInfo();
    });
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://greasyfork.org/zh-CN/scripts/519339-%E7%AD%94%E6%A1%88%E6%98%BE%E7%A4%BA-%E8%87%AA%E5%8A%A8%E7%AD%94%E9%A2%98-%E6%88%90%E9%83%BD%E4%B8%9C%E8%BD%AF%E5%AD%A6%E9%99%A2-%E5%A4%A7%E8%BF%9E%E4%B8%9C%E8%BD%AF%E5%BA%94%E8%AF%A5%E4%B9%9F%E5%8F%AF%E4%BB%A5-4s%E5%B9%B3%E5%8F%B0%E8%AF%95%E5%8D%B7%E7%AD%94%E6%A1%88%E6%98%BE%E7%A4%BA-%E4%B8%80%E9%94%AE%E7%AD%94%E9%A2%98&quot;&gt;Greasy Fork&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>学校手势签到/扫码签到破解思路分享</title><link>https://bluore.top/posts/nsustudy/</link><guid isPermaLink="true">https://bluore.top/posts/nsustudy/</guid><pubDate>Sat, 09 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;始于一次兴起，想对学校的签到软件进行抓包试试，在一次英语课的签到上尝试了一下，偶然发现:&lt;/p&gt;
&lt;h1&gt;手势签到破解思路&lt;/h1&gt;
&lt;p&gt;使用的签到方式是手势签到，以下是本次签到的手势&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;签到手势&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后使用手机抓包软件&lt;code&gt;HttpCanary&lt;/code&gt;抓了一下响应发现，在没有完成签到的情况下，&lt;strong&gt;响应内容竟然有手势密码??!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;以下是抓包的&lt;strong&gt;响应&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 
Date: Tue, 05 Nov 2024 02:43:42 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: PUT, GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
Access-Control-Max-Age: 1728000

238
{
  &quot;code&quot;: 0,
  &quot;msg&quot;: null,
  &quot;intercepted&quot;: true,
  &quot;data&quot;: [
    {
      &quot;calendarId&quot;: &quot;1840326648611450882&quot;,
      &quot;calendarName&quot;: &quot;Mini project 2 - A child’s clutter awaits an adult’s return&quot;,
      &quot;calendarOrder&quot;: 7,
      &quot;businessList&quot;: [
        {
          &quot;collegeId&quot;: &quot;2263&quot;,
          &quot;termId&quot;: &quot;1832946583942795266&quot;,
          &quot;calendarId&quot;: &quot;1840326648611450882&quot;,
          &quot;teachClassId&quot;: &quot;1839557950615138356&quot;,
          &quot;courseId&quot;: &quot;1711200736744427521&quot;,
          &quot;teachingArrangementId&quot;: &quot;1839557950581583956&quot;,
          &quot;type&quot;: &quot;1&quot;,
          &quot;businessId&quot;: &quot;1853629118787575810&quot;,
          &quot;attendanceType&quot;: 1,
          &quot;insCountDown&quot;: 571,
          &quot;attendanceCode&quot;: &quot;1,2,3&quot;,
          &quot;createTime&quot;: &quot;2024-11-05 10:43:15&quot;,
          &quot;isAnonymous&quot;: null
        }
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到&lt;code&gt;attendanceCode&lt;/code&gt;的值为*&lt;code&gt;1,2,3&lt;/code&gt;*，这样似乎不太明显，如果像下图这样编号一下呢:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;编号图&quot; /&gt;&lt;/p&gt;
&lt;p&gt;是不是一下就清楚了，这个接口竟然在没有签完到的情况下将数据库的完整信息返回了，理论这个数据不应该返回出来&lt;/p&gt;
&lt;p&gt;然后再来看一下签到的&lt;strong&gt;请求&lt;/strong&gt;是怎样的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POST /se-tool-gateway/biz/attendance/studentAttendanceBiz/save HTTP/1.1
token: 66bad09b-edad-4e64-a80c-7c1c1db994c4
Referer: http://sep.study.neuedu.com/
Content-Type: application/json; charset=utf-8
Content-Length: 186
Host: sep.study.neuedu.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.10.0

{
  &quot;access_token&quot;: &quot;66bad09b-edad-4e64-a80c-7c1c1db994c4&quot;,
  &quot;termId&quot;: &quot;1832946583942795266&quot;,
  &quot;attendanceType&quot;: &quot;1&quot;,
  &quot;instanceId&quot;: &quot;1853629118787575810&quot;,
  &quot;collegeId&quot;: &quot;2263&quot;,
  &quot;attendanceCode&quot;: &quot;1,2,3&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不出所料，&lt;code&gt;attendanceCode&lt;/code&gt;的值被原样传递，甚至不需要更改，直接就可以发送签到的请求&lt;/p&gt;
&lt;p&gt;那这样的话签到就简单了，只需要把获取的响应里面的字段拿出来直接放在请求里面理论上就可以实现签到了&lt;/p&gt;
&lt;h1&gt;扫码签到破解&lt;/h1&gt;
&lt;p&gt;经过实操，以上的猜测没有问题，于是我有了一个想法，是不是扫码签到也是同样的原理，也就可以做到无须二维码即可签到&lt;/p&gt;
&lt;p&gt;虽然是扫码签到，但是可以用二维码扫描软件看出，二维码本质只是在传递&lt;code&gt;13&lt;/code&gt;位的随机数字，同样抓包可得&lt;code&gt;attendanceCode&lt;/code&gt;字段，和前面一样，直接传递即可，其中需要把&lt;code&gt;&quot;attendanceType&quot;: &quot;2&quot;&lt;/code&gt;赋值为&lt;code&gt;2&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;access_token&quot;: &quot;d4b82353-17d2-449c-893e-e58f7c088c26&quot;,
  &quot;termId&quot;: &quot;1832946583942795266&quot;,
  &quot;attendanceType&quot;: &quot;2&quot;,
  &quot;instanceId&quot;: &quot;1854401114356383746&quot;,
  &quot;collegeId&quot;: &quot;2263&quot;,
  &quot;attendanceCode&quot;: &quot;1730958814553&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;登录破解&lt;/h1&gt;
&lt;p&gt;于是有了这些想法和猜测，接下来便是从登录到签到的请求全部扒干净即可&lt;/p&gt;
&lt;p&gt;以下是登录的请求&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;POST /se-tool-gateway/data/user/systemUser/userLoginPost HTTP/1.1
token: ed8ff7ca-2aeb-43e3-b446-20e61f09fea7
Referer: http://sep.study.neuedu.com/
Content-Type: application/json; charset=utf-8
Content-Length: 87
Host: sep.study.neuedu.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.10.0

{
  &quot;p&quot;: &quot;YEhIr8eIyWw4mt7Ax61sTA\u003d\u003d&quot;,
  &quot;collegeId&quot;: &quot;2263&quot;,
  &quot;loginCode&quot;: &quot;24*********&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以及响应&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 
Date: Wed, 06 Nov 2024 01:59:12 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: PUT, GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
Access-Control-Max-Age: 1728000

36e
{
  &quot;createTime&quot;: &quot;2024-09-10 10:28:31&quot;,
  &quot;createUser&quot;: &quot;oshwk1ab5f9e1bc7d4d838b55**********&quot;,
  &quot;updateTime&quot;: &quot;2024-11-05 19:41:28&quot;,
  &quot;updateUser&quot;: &quot;system&quot;,
  &quot;userId&quot;: &quot;2518290&quot;,
  &quot;collegeId&quot;: &quot;2263&quot;,
  &quot;collegeDisplayName&quot;: &quot;成都东软学院&quot;,
  &quot;mobile&quot;: &quot;17200********&quot;,
  &quot;realName&quot;: &quot;***&quot;,
  &quot;roles&quot;: &quot;4&quot;,
  &quot;sysCode&quot;: &quot;24*************&quot;,
  &quot;departmentName&quot;: &quot;计算机与软件学院&quot;,
  &quot;majorName&quot;: &quot;计算机类&quot;,
  &quot;adminClassName&quot;: &quot;计算机类***&quot;,
  &quot;enrollmentYear&quot;: 2024,
  &quot;email&quot;: &quot;************&quot;,
  &quot;password&quot;: &quot;*****************&quot;,
  &quot;state&quot;: 1,
  &quot;sex&quot;: &quot;男&quot;,
  &quot;cardType&quot;: &quot;0&quot;,
  &quot;isTeaching&quot;: 1,
  &quot;stuState&quot;: 1,
  &quot;departmentId&quot;: &quot;620&quot;,
  &quot;majorId&quot;: &quot;702&quot;,
  &quot;adminClassId&quot;: &quot;203*****4&quot;,
  &quot;userName&quot;: &quot;***********************&quot;,
  &quot;accessToken&quot;: &quot;d320bdf2-20aa-4f99-a63b-7*************&quot;,
  &quot;coorperativeType&quot;: 1,
  &quot;teachingType&quot;: 1,
  &quot;roleList&quot;: [
    {
      &quot;roleId&quot;: &quot;4&quot;,
      &quot;roleName&quot;: &quot;学生&quot;,
      &quot;roleCode&quot;: &quot;STUDENT&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后拿到&lt;code&gt;accessToken&lt;/code&gt;作为后续身份验证的依据，不过发现了一个问题，请求负载里面的&lt;code&gt;password&lt;/code&gt;并不是我所输入的密码，既然没有响应那么就是在本地做了加密&lt;/p&gt;
&lt;p&gt;如果要做登录页面的话那就要想办法把登录的加密手段给破解出来，否则使用的用户需要自己抓一次自己的密码加密后的密文，这并不优雅也提高了门槛&lt;/p&gt;
&lt;p&gt;于是我尝试试试常用加密算法里面如何将&lt;code&gt;TLgkg96~&lt;/code&gt;加密为&lt;code&gt;Xp5R2yTnBP+nBTEIZhdJ+A\u003d\u003d&lt;/code&gt;，在各种在线网站上试了各种方法都未能复原这个密文，但是我有了一个思路便是这个加密似乎是需要一个&lt;code&gt;key&lt;/code&gt;来进行加密的，这个&lt;code&gt;key&lt;/code&gt;是在本地的一个字符串常量，所以我想法是在&lt;code&gt;MT资源管理器&lt;/code&gt;里面搜字符串常量有没有结果，不过无功而返，难道要放弃这个功能吗？&lt;/p&gt;
&lt;p&gt;几天后...这时我突然想到了一个软件：&lt;code&gt;算法助手&lt;/code&gt;，于是我打开了虚拟机试一试&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;算法助手&quot; /&gt;&lt;/p&gt;
&lt;p&gt;结果也是在如同预期发现了加密的算法，如上图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-3.png&quot; alt=&quot;验证加密&quot; /&gt;&lt;/p&gt;
&lt;p&gt;于是在在线加密网站上验证了这个加密方法&lt;/p&gt;
&lt;p&gt;加密采用&lt;code&gt;AES&lt;/code&gt;加密，&lt;code&gt;key&lt;/code&gt;是固定为&lt;code&gt;757da2be61249c18&lt;/code&gt;并写死在代码里面的，这样就能就能通过密码得到密文&lt;/p&gt;
&lt;h1&gt;软件编写&lt;/h1&gt;
&lt;p&gt;之后的逻辑便是 &lt;code&gt;获取课程&lt;/code&gt; -&amp;gt; &lt;code&gt;课程信息&lt;/code&gt; -&amp;gt; &lt;code&gt;签到任务&lt;/code&gt;，这样拿到签到的响应，进行之前的签到请求即可&lt;/p&gt;
&lt;p&gt;软件采用&lt;code&gt;欲v6&lt;/code&gt;语言编写，使用在移动端设计Android应用的软件&lt;code&gt;iApp&lt;/code&gt;来开发，软件演示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-4.png&quot; alt=&quot;软件演示&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个猜测在一次高数课上得到了验证&lt;/p&gt;
&lt;p&gt;:::tip
视频暂不演示
:::&lt;/p&gt;
&lt;p&gt;软件开源地址：（宇宙声明：仅供学习，请勿用于非法用途）&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Bluore/NSUedu&quot;}&lt;/p&gt;
&lt;p&gt;:::warning&lt;/p&gt;
&lt;p&gt;不过现在你别想一些歪门邪道了，这个平台在25年便弃用了&lt;/p&gt;
&lt;p&gt;作者声明：未滥用此漏洞，没有逃课（〃｀ 3′〃）&lt;/p&gt;
&lt;p&gt;此文章写于&lt;code&gt;2026-1-19&lt;/code&gt;，也是在弃用之后&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
</content:encoded></item><item><title>NSU校园网自动连接的教程</title><link>https://bluore.top/posts/nsunetwork/</link><guid isPermaLink="true">https://bluore.top/posts/nsunetwork/</guid><pubDate>Thu, 24 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note&lt;/p&gt;
&lt;p&gt;本文主要讲程序的使用&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;为了解决校园网连接很麻烦，且一段时间后还会自动断开连接的问题，于是写了一个py程序用来自动连接校园网来简化操作和防止断开&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./image-1.png&quot; alt=&quot;校园网连接&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当时写的石山代码:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import requests
import time
import json
import os

loginKey = { #默认配置
    &quot;username&quot; : &apos;学号&apos;,
    &quot;password&quot; : &apos;一次性密钥&apos;,       #网页登录后cookie中获取
    &quot;testtime&quot; : 5,                 #检测网络连接状况时差（单位s）
    &quot;timeout&quot; : 5,                  #超时连接失败失败（单位s）
    &quot;outInFirstRequest&quot; : False,    #第一次请求就连接成功是否退出程序
    &quot;autoOutOtherIp&quot; : True,        #自动踢出其他正在连接的IP
    &quot;networkName&quot; : &quot;学生-移动-100M&quot; #自动连接的网络名称
}

def information(type):
    if type==&apos;loginKey&apos;:
        return &apos;&apos;&apos;
{ #默认配置
    &quot;username&quot; : &apos;学号&apos;,             #填写自己登录校园网的学号
    &quot;password&quot; : &apos;一次性密钥&apos;,       #网页登录后cookie中获取
    &quot;testtime&quot; : 5,                 #检测网络连接状况时差（单位s）
    &quot;timeout&quot; : 5,                  #超时连接失败失败（单位s）
    &quot;outInFirstRequest&quot; : False,    #第一次请求就连接成功是否退出程序
    &quot;autoOutOtherIp&quot; : True,        #自动踢出其他正在连接的IP
    &quot;networkName&quot; : &quot;学生-移动-100M&quot; #自动连接的网络名称
}
        &apos;&apos;&apos;

if(not os.path.exists(&quot;data.txt&quot;)):
    print(&quot;不存在配置文件，尝试创建文件&quot;)
    with open(&quot;data.txt&quot;, &apos;w&apos;, encoding=&apos;utf-8&apos;) as file:
        json.dump(loginKey, file, ensure_ascii=False, indent=4)
    print(information(&apos;loginKey&apos;))
    print(&quot;已经创建配置文件，请编辑同文件夹下data.txt填写账户和一次性密钥后【重新启动】此程序&quot;)
    time.sleep(120)
    exit()

with open(&apos;data.txt&apos;, &apos;r&apos;, encoding=&apos;utf-8&apos;) as file:
    loginKey = json.load(file)



def testIPState(username,passwordCode):
    urlTest = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersTest = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postTest = {
        &quot;DoWhat&quot;: &quot;Check&quot;
    }
    cookieTest = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlTest, headers=headersTest, json=postTest, cookies=cookieTest, timeout=loginKey[&apos;timeout&apos;])
    return result.json()


def linkNetwork(username,passwordCode):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;OpenNet&quot;,
        &quot;Package&quot;: loginKey[&apos;networkName&apos;]              #&quot;学生-移动-100M&quot;
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)
    return result.json()

def loginNetwork(username,passwordCode):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;Login&quot;,
        &quot;remember&quot;:True,
        &quot;username&quot;:username,
        &quot;password&quot;:passwordCode
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)

def listLinkNetwork(username,passwordCode):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;GetInfo&quot;
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)
    return result.json()

def delLinkNetwork(username,passwordCode,ip):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;CloseNet&quot;,
        &quot;IP&quot;: ip
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)
    return result.json()

exitFlag = False
if loginKey[&apos;outInFirstRequest&apos;]:
    try:
        getStste = testIPState(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
        print(&quot;已连接网络，3秒后自动退出&quot;)
        exitFlag = True
        time.sleep(3)
    except:
        print(&quot;!&amp;gt;&amp;gt;something error&quot;)
        time.sleep(3)

while 1:
    if exitFlag == True:
        break
    try:
        getStste = testIPState(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
        #print(getStste)
        print(&apos;&amp;gt;&amp;gt;&amp;gt;&apos;+getStste[&apos;Message&apos;])
        time.sleep(0.1)
        if getStste[&apos;Result&apos;]:
            if getStste[&apos;Message&apos;] == &apos;已上线IP，免认证！&apos;:
                time.sleep(loginKey[&apos;testtime&apos;])
                continue
            if getStste[&apos;Message&apos;] == &apos;已登录IP，免认证！&apos;:
                print(&quot;!&amp;gt;&amp;gt;尝试上线本机&quot;)
                getStste = linkNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
                if getStste[&apos;Message&apos;] == &apos;同时登录数已达上限！&apos;:
                    if not loginKey[&apos;autoOutOtherIp&apos;]:
                        time.sleep(loginKey[&apos;testtime&apos;])
                        continue
                    #print(&quot;其他设备正在上线中，将在10秒后重试&quot;)
                    print(&quot;&amp;gt;&amp;gt;&amp;gt;其他设备正在上线中，正在尝试查询其他设备&quot;)
                    getStste = listLinkNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
                    time.sleep(0.1)
                    print(&quot;&amp;gt;&amp;gt;&amp;gt;其他设备正在上线中，正在尝试查询其他设备&quot;)
                    getStste = delLinkNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;], getStste[&apos;Data&apos;][&apos;OIA&apos;][0][&apos;IP&apos;])
                    if(getStste[&apos;Result&apos;]):
                        print(f&quot;&amp;gt;&amp;gt;&amp;gt;已成功下线IP({getStste[&apos;IP&apos;]})，正在尝试上线本设备&quot;)
                        time.sleep(0.1)
                        continue
                    print(f&quot;&amp;gt;&amp;gt;&amp;gt;下线IP({getStste[&apos;IP&apos;]})失败，请求返回信息{getStste[&apos;Message&apos;]}&quot;)
                    time.sleep(5)
                continue
        if getStste[&apos;Result&apos;] == &apos;needLogin&apos;:
            print(&quot;!&amp;gt;&amp;gt;尝试自动登录&quot;)
            loginNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
        if not getStste[&apos;Result&apos;]:
            if getStste[&apos;Message&apos;] == &apos;请求太频繁，请稍后再试...&apos;:
                print(&quot;3秒后重试&quot;)
                time.sleep(3)
    except:
        print(&quot;!&amp;gt;&amp;gt;something error&quot;)
        time.sleep(3)

exit()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::github{repo=&quot;Bluore/NSUnetwork&quot;}&lt;/p&gt;
&lt;h1&gt;使用方法&lt;/h1&gt;
&lt;p&gt;下载程序&lt;a href=&quot;https://github.com/Bluore/NSUnetwork/releases/tag/main&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:::tip
&lt;code&gt;nsunetowrk_console.exe&lt;/code&gt;版本运行后会有控制台输出&lt;/p&gt;
&lt;p&gt;&lt;code&gt; nsunetowrk_NO-console.exe&lt;/code&gt;版本运行后没有控制台输出，后台无感运行
:::&lt;/p&gt;
&lt;h2&gt;使用软件&lt;/h2&gt;
&lt;p&gt;首次打开时会出现提示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;不存在配置文件，尝试创建文件

{ #默认配置
    &quot;username&quot; : &apos;学号&apos;,             #填写自己登录校园网的学号
    &quot;password&quot; : &apos;一次性密钥&apos;,       #网页登录后cookie中获取
    &quot;testtime&quot; : 5,                 #检测网络连接状况时差（单位s）
    &quot;timeout&quot; : 5,                  #超时连接失败失败（单位s）
    &quot;outInFirstRequest&quot; : False,    #第一次请求就连接成功是否退出程序
    &quot;autoOutOtherIp&quot; : True,        #自动踢出其他正在连接的IP
    &quot;networkName&quot; : &quot;学生-移动-100M&quot; #自动连接的网络名称
}

已经创建配置文件，请编辑同文件夹下data.txt填写账户和一次性密钥后【重新启动】此程序
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开文件目录下的&lt;code&gt;data.txt&lt;/code&gt;文件按提示编辑，如何填写请看后文&lt;/p&gt;
&lt;p&gt;填写完成后请再次运行程序即可自动连接&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;autoOutOtherIp&lt;/code&gt; 为 &lt;code&gt;True&lt;/code&gt;时会自动踢出其他设备&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;获取&lt;code&gt;username&lt;/code&gt;和&lt;code&gt;password&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;先登录账号&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按下&lt;code&gt;F12&lt;/code&gt;打开控制台，进入&lt;code&gt;存储&lt;/code&gt;栏(也可能叫&lt;code&gt;应用&lt;/code&gt;、&lt;code&gt;Application&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-3.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;复制值到配置文件即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;如何开机自启动&lt;/h2&gt;
&lt;p&gt;按下&lt;code&gt;Win + R&lt;/code&gt;按键打开运行面板，输入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shell:startup
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开文件夹，将程序的快捷方式放入该文件夹即可&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;文章实际发布时间&lt;code&gt;2026-1-19&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item></channel></rss>