Darren Ou

欢迎来到我的个人博客。

  • 我是一名 iOS / macOS 开发者,base 广州,喜欢捣鼓电子产品,擅长打羽毛球。
  • 我将在这里记录技术,记录生活。
  • Just for fun ~

3D 打印入坑记

一、前言 一直梦想着能有一间充满极客范的书房,里面有简洁的电脑桌,墙上挂满各类工具,旁边的工作台上面放着 3D 打印机。 小孩差不多两岁了,经常给他买各种各样的玩具,想着如果有 3D 打印机,想要什么玩具都能打印出来。 其实就是给自己一个任性的理由买一台“不实用”的 3D 打印机哈哈。 二、选购 买之前大概做了下功课,消费级的 3D 打印机大致有两种,一种是 FDM 3D 打印机,另一种是光固化 3D 打印机。 光固化打印机打印出来的模型会比较精致,不会有明显的层纹,比较适合打印手办。入门门槛比较高,操作较为繁琐,关键是打印时会散发有毒气体,家有小孩就排除光固化打印机了。 所以只在 FDM 打印机里面挑选,其实 FDM 的原理就是把材料熔化后一层层地堆积成型,我主要在关注创想三维跟拓竹这两个国内的品牌。 可选的型号也不多,创想三维的 K1 跟拓竹的 P1S,两者相差接近一千块,所以我最后选择的是性价比较高的 K1。 三、打印 大家可以先看看 3D 打印的效果 随着对 3D 打印理解的深入,发现 3D 打印里面的学问非常多,我还只是懂点皮毛。 1. 温度 不同的材料对温度的要求不一样,比如: PLA 材料,喷嘴温度 190 – 230°C,热床温度 35 – 45°C; ABS 材料,喷嘴温度 220 – 250°C,热床温度 80 – 100°C。温度不对,容易出现翘边的情况。 2. 速度 速度会影响打印模型的最终效果,总体来说速度越慢精度越高,打印的效果越好。 特别是起始层的打印,起始层相当于整个模型的基础,我习惯使用一半的速度来打印起始层,比如速度我设置 150 mm/s,起始层的打印速度我会设置为 75 mm/s。 3. 平台附着 平台附着其实就是先在平台上打印一层,解决模型无法粘到平台上的问题,特别是一些跟平台接触面很小的模型,使用平台附着就非常必要。 4. 支撑 因为模型是一层层地打印的,如果遇到一些悬空的结构,如果没有支撑会导致打印失败,所以需要根据实际情况添加支撑。...

September 15, 2023 · Darren Ou

群晖 NAS - ChatGPT 部署

一、前言 我在平时工作生活中 ChatGPT 用得很频繁,但会有时候不方便设置代理使用。有时朋友需要用时教育成本也比较高。 如果可以直接访问使用就很好解决我的痛点了。 在上一篇文章「群晖 NAS - 代理设置」中,已经设置好了群晖的代理。 另外,本文不涉及 ChatGPT 账号注册、APIKey 申请等内存,下面只介绍 ChatGPT 的部署。 二、部署 网上有非常多优秀的 ChatGPT 开源项目,我这里使用的是 chatgpt-web。 1、镜像下载 # ssh登录到群晖 ssh user_name@ip_address # 获取超级权限 sudo -i # 拉取镜像 docker pull chenzhaoyu94/chatgpt-web 2、配置 设置访问 web 使用的端口即可 只需要关注两个环境变量: HTTPS_PROXY:这里填写上篇文章设置好的端口,要注意的是这个 IP 地址需要填写群晖的 IP 地址,不能使用 127.0.0.1; OPENAI_API_KEY:这个填写 API Key,教程网上一大堆。 3、测试

June 3, 2023 · Darren Ou

群晖 NAS - 代理设置

一、前言 因网络环境导致,在群晖中的 Docker 拉取镜像或者部分套件中的服务会经常失败,对我们来说有一个顺畅的网络环境能大大提高幸福感。 其实方案有非常多,例如前置软路由,或者使用 Tailscale 设置出口节点等。这里介绍一个相对简单的方法。 二、部署 1、镜像下载 我们使用 Docker 进行部署,方便后续管理。 此时直接使用群晖里的 Docker 图形界面拉取镜像会失败,我们通过 ssh 登录到群晖,使用 docker pull xxx 的方式会比较方便。 # ssh登录到群晖 ssh user_name@ip_address # 获取超级权限 sudo -i # 拉取镜像 docker pull dreamacro/clash docker pull haishanh/yacd 这里比较简单,只用到了 docker pull 命令,如果对 Docker 命令不是很熟悉,配置可以使用群晖内部的 Docker 图形界面。 2、Docker 配置 a. Clash 配置 首先需要从服务商那里获取配置文件,这里命名为config.yaml,然后存储到群晖 docker/clash/config.yaml; 配置文件映射到 /root/.config/clash/config.yaml; 设置端口,下面群晖配置时需要用到, 运行。 b. yacd 配置 yacd 是 clash 的仪表盘,yacd 配置非常简单,指定访问端口即可。 3、群晖配置 控制面板 - 网络 - 常规 - 代理服务器 - 填写刚设置的IP端口 - 应用...

May 26, 2023 · Darren Ou

群晖 NAS - frp 使用及实现 Mac 远程访问

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 一、服务端配置 1、安装及配置 这里以群晖 NAS 为例: 在 Docker 注册表里搜索 frps,安装 latest 版本(也可以安装指定版本); 在映像里创建容器,并进入高级设置; 在高级设置里启用自动重新启动; 在存储空间添加文件,装载路径为 /etc/frp/frps.ini; 网络里勾选使用与 Docker Host 相同的网络; 启动容器。 2、frps.ini 配置文件 [common] bind_port = 7000 token = your_token dashboard_port = 7500 dashboard_user = your_dashboard_user dashboard_pwd = your_dashboard_pwd vhost_http_port = 8000 vhost_https_port = 8001 二、客户端配置 1、安装及配置 同样以群晖 NAS 为例,安装及配置基本跟服务端相同,配置文件改为 frpc.ini 即可。 2、frpc.ini 配置文件 [common] server_addr = your_server_addr server_port = 7000 tls_enable = true token = your_token [ssh] type = tcp local_ip = 192....

July 8, 2022 · Darren Ou

群晖 NAS - 阿里云盘挂载及数据同步

一、前言 阿里云盘即使不是会员也不会限速,获得广大好评。如果能把阿里云盘挂载到 NAS 上,相当于扩充了 NAS 的磁盘容量,也可以利用这一点实现在线播放视频、数据同步等功能。 aliyundrive-webdav 这个工具可以让阿里云盘成为支持 WebDAV 协议的文件服务器,下面简单介绍其安装及使用。 二、安装配置 1、aliyundrive-webdav 安装 在 Docker 注册表里搜索 aliyundrive-webdav,安装 latest 版本(也可以安装指定版本); 在映像里创建容器,并进入高级设置; 在高级设置里启用自动重新启动; 在存储空间添加文件夹,装载路径为 /etc/aliyundrive-webdav/; 添加 8080 端口; 添加 REFRESH_TOKEN、WEBDAV_AUTH_USER、WEBDAV_AUTH_PASSWORD 三个环境变量(REFRESH_TOKEN 在后面介绍如何获取); 启动容器。 2、refresh_token 获取 登录阿里云盘网页版,F12 进入开发者模式,然后在对应位置获取 refresh_token。 三、挂载 四、数据同步

June 8, 2022 · Darren Ou

群晖 NAS - 使用篇

一、前言 距离去年入坑 NAS 已经一年多了(群晖 NAS - 购置篇),这一年多里学习了很多 NAS 的玩法,感觉能够发挥了 NAS 应有的作用。 这里简单介绍一下我利用 NAS 做了什么事情,但不会介绍详细的实现方法,因为网上已经有大量的参考文章。 二、外网访问 能在外网访问家里的 NAS,会多很多玩法,所以怎么实现外网访问是我入坑 NAS 的第一课。 1、QuickConnect QuickConnect 是群晖官方提供的远程访问服务,使用起来最简单门槛最低,但存在几个缺点: 限速比较严重,只有 500k/s 左右下载速度; 数据会经过群晖服务器进行中转,且账号必须绑定手机号,让我觉得会有隐私问题; 只有白群晖能用,黑群晖无法激活。 基于这几个缺点,我需要找其它的替代方案。 2、公网 IP 最方便的公网访问方式就是家里的宽带有公网 IP,无需转发直接访问,但不是所有宽带都能开通公网 IP。 这里的公网 IP 特指 IPv4 的公网 IP,因为 IPv4 的公网 IP 的兼容性最好,所有运营商都支持访问;IPv6 的公网 IP 甚至每个网口都能分配一个 IP,但目前来说应用还不是很广泛,有些运营商有些路由器都还不支持访问。 不同运营商情况大概如下: 如果家里宽带用的是电信,那么可以打电话给客服免费开通公网 IP,很大概率可以开通,如果开通不了就多打几次电话。电信宽带还不支持分配和访问 IPv6 公网 IP。 移动宽带则是完全不向个人开放 IPv4 的公网 IP,但是默认支持 IPv6 IP。 联通的话据说申请难度比电信要高,但我还没用过没有发言权。 我在广州家里用的是移动宽带,默认分配了 IPv6 的公网 IP,所以是可以直接 IPv6 IP 来访问我家里的 NAS。 但是访问 IPv6 的公网 IP 存在两个问题:...

May 7, 2022 · Darren Ou

Hugo 博客搭建

本博客使用 Hugo 搭建,这里记录一下搭建过程。 Hugo is one of the most popular open-source static site generators. With its amazing speed and flexibility, Hugo makes building websites fun again. 一、Hugo 基本使用 i. 命令使用 # Hugo 安装 brew install hugo # 新建博客 hugo new site hugo-blog # 添加主题(修改 config.yml 配置文件中 `theme: PaperMod`) git submodule add https://github.com/oudushu/hugo-PaperMod.git themes/PaperMod # 新建博文 hugo new posts/web-hugo-blog.md # 网站预览(http://localhost:1313/) hugo server # 生成静态文件(public 文件夹) hugo ii. 图片 图片资源存放在 static 文件夹中,我习惯每篇文章都新建一个文件夹存放图片,如:hugo-blog/static/image/web-hugo-blog/image-20220316160415439....

March 16, 2022 · Darren Ou

iOS 逆向入门 - 动态库注入原理

一、工具 在逆向的过程中,我们经常需要往目标执行文件中注入自己的逻辑,从而实现 hook 的目的。 我们常用 optool 工具实现动态库注入。 Command Line Tool for interacting with MachO binaries on OSX/iOS 了解这个工具的原理,有助于我们对 MachO 文件有更深入的了解。 二、源码解析 关键代码如下: BOOL insertLoadEntryIntoBinary(NSString *dylibPath, NSMutableData *binary, struct thin_header macho, uint32_t type) { // 判断 Load Command 类型 if (type != LC_REEXPORT_DYLIB && type != LC_LOAD_WEAK_DYLIB && type != LC_LOAD_UPWARD_DYLIB && type != LC_LOAD_DYLIB) { LOG("Invalid load command type"); return NO; } // 判断动态库是否已经注入 // parse load commands to see if our load command is already there uint32_t lastOffset = 0; if (binaryHasLoadCommandForDylib(binary, dylibPath, &lastOffset, macho)) { // there already exists a load command for this payload so change the command type uint32_t originalType = *(uint32_t *)(binary....

March 8, 2022 · Darren Ou

iOS 逆向入门 - 符号恢复及反汇编

在通过逆向分析竞品过程中,经常需要分析其实现逻辑。但由于没有符号,我们会遇到一些阻碍。 一、符号恢复 我们经常 hook 一个方法并加断点可快速获得参数值,但是使用 bt 命令打印堆栈信息时,只能看到 ___lldb_unnamed_symbol279180$$TikTok 的信息,原因是 Objective-C 在打包时会被 stripped out,导致无法看到具体符号。 1. restore-symbol 使用 可以利用 restore-symbol 工具恢复符号(只能恢复 Objective-C 符号,无法恢复 C/C++ 符号),具体使用如下: # git clone --recursive https://github.com/tobefuturer/restore-symbol.git # cd restore-symbol # make # ./restore-symbol TikTok -o TikTok_symbol 2. 错误处理 在运行时会报错:2022-01-06 18:07:15.103 restore-symbol[17534:7647405] *** Assertion failure in -[CDObjectiveC2Processor loadClassAtAddress:], CDObjectiveC2Processor.m:258,原因是使用了 Swift 语言,而解析 Swift 的方法已过期。我们可以简单粗暴地把抛出异常的代码注释掉,重新 make 即可成功恢复符号。 3. 验证 把 ipa 包里的 MachO 文件替换为恢复符号后的 MachO 文件,重签名后运行到手机上(MonkeyDev 工具已经集成重签名的功能,这里只需要替换 TargetApp 里面的 MachO 文件,clean 后 rebuild 即可)。...

January 6, 2022 · Darren Ou

2021 年终总结

今年总体来说过得挺顺利,阿 B 顺利出生,工作上加入了新团队,技术上有了更多的积累,只是投资上稍亏损,无伤大雅。 个人 今年最大的事情当属 BB 的出生,老婆从三月怀孕,到十一月顺利生下牛宝宝。无论是怀孕过程中老婆身体上的不适还是出生后对 BB 无微不至的照顾,都相当不容易,不由感叹母亲的伟大及生命的奇妙。 今年形成了两个比较好的习惯,一个是写博客,虽说不上高产,但今年的文章写得比往年都多,无论是记录生活还是记录技术,对自己来说都是一个积累;一个是刷算法,下半年开始,基本上能坚持每天至少刷一道题,感觉对思维灵活度上有一定帮助,以前提到算法都有恐惧感,现在已经好多了。 今年在兴趣上的投入比往年都多一些,打球的频率基本能保证每周一到两次,双十二时还买了一双羽毛球鞋,但是还舍不得穿。年初开始入坑 NAS,积累了一定的服务器运维能力,还折腾了下路由器。兴趣上的投入对自己还比较满意。 今年二月开始还房贷,原来还有车贷,阿 B 出生后有较多支出,公司取消大小周后没了加班工资,钱包有一定的压力。不过好消息是今年涨薪了两次,今年十月份已经还完了车贷,总体上来说压力不算太大,还有一些盈余。 购物上还是放不开手脚,今年新出的 MBP 还有 iPhone 13 都很吸引,但考虑到家庭较大的支出,还是忍下来了,希望明年有更多的收入满足自己的购物欲。 今年投资算是比较失败,基金、A 股、美股都有不同程度的亏损,估计明年我的投资会更加偏向保守。 工作 今年在公司职业发展上有个比较大的转变,四月份时从客户端开发转岗到 ToB 的业务,到八月份时 ToB 业务停止维护,加入到音视频 SDK 开发团队,负责跟 iOS 平台相关的开发维护工作。对自己的学习能力是一个考验,好在团队同事还有 leader 都会在工作上引导我,目前已经逐渐上手。加入到音视频 SDK 开发团队,自己在音视频上有了更多的了解,也开始 C ++ 的学习,技术上有了更多的积累。 今年年中时升了职级,薪资也稍上涨了一些,这也是比较值得开心的好消息。 2022 展望 希望阿 B 能健健康康茁壮成长,家里人都能身体健康。 希望能力上能有更多的长进,技术上有更多的积累,好好复习 iOS 技术栈,说不定能进入更好的公司。 坚持写博客、刷算法、打球。目标是养成读书的习惯。

December 31, 2021 · Darren Ou

Mac 装机必备

开发工具 iTerm2 iTerm2 is a terminal emulator for macOS that does amazing things. Tabby Tabby is an infinitely customizable cross-platform terminal app for local shells, serial, SSH and Telnet connections. Fig Fig adds VSCode-style autocomplete to your existing terminal. 终端自动补全工具,能在终端里有 VSCode 的自动补全体验,支持 iTerm2。如果你使用的是 zsh,也可以安装 zsh-autosuggestions 作为补充使用。 Homebrew The Missing Package Manager for macOS. Oh My Zsh Oh My Zsh is an open source, community-driven framework for managing your ### zsh configuration....

December 20, 2021 · Darren Ou

iOS 逆向入门 - 常用反逆向手段

在「iOS 逆向入门 - 绕过抖音反调试」中提到常用反调试手段,这里写下具体实现。 一、常用反逆向手段 1、反调试:ptrace ptrace 被常用于防止 lldb 依附,原理是一个进程只能被 ptrace 只能被一次,先于别人调用 ptrace 则可以防止别人依附。 ptrace 有几种方式进行调用: 1)直接调用 #import <sys/ptrace.h> ptrace(PT_DENY_ATTACH,0,0,0); iOS SDK 中不包含 ptrace.h 头文件,无法使用此方法调用,可使用以下方法。 2)通过 dlopen + dlsym 调用 #import <dlfcn.h> #import <sys/types.h> typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data); #if !defined(PT_DENY_ATTACH) #define PT_DENY_ATTACH 31 #endif void disable_attach() { void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW); ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace"); ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0); dlclose(handle); } 3)通过 syscall 调用 #import <sys/syscall....

December 9, 2021 · Darren Ou

iOS dSYM 文件 & 符号化

一、dSYM 文件生成 1、Xcode 自动生成,配置: Xcode -> Build Settings -> Code Generation -> Generate Debug Symbols -> Yes Xcode -> Build Settings -> Build Option -> Debug Information Format -> DWARF with dSYM File 2、手动生成: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil /Users/oudushu/Library/Developer/Xcode/DerivedData/YourApp-cqvijavqbptjyhbwewgpdmzbmwzk/Build/Products/Debug-iphonesimulator/YourApp.app/YourApp -o YourApp.dSYM 二、如何找到对应的 dSYM 文件: 从发布的归档包里面找: Xcode -> Window -> Organizer -> 找到打包好的文件(Show in Finder)-> 选中文件(右键显示包内容)-> dSYMs文件夹下就是了 从iTunes Connect里面找 mdfind工具:mdfind “com_apple_xcode_dsym_uuids == E30FC309-DF7B-3C9F-8AC5-7F0F6047D65F” 三、symbolicatecrash 1、查找 find /Applications/Xcode.app -name symbolicatecrash -type f /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash 2、使用 export DEVELOPER_DIR=/Applications/Xcode....

December 8, 2021 · Darren Ou

阿 B 出生记

这是一篇流水账,记录老婆怀胎十月到阿B出生的历程。 怀孕 2021年3月,有一天试纸出现两条杠,去到医院再次确认,确实是怀孕了。 把医生的化验单给老爸老妈看,他们也非常开心,老妈说道:明年过年我们家可就热闹了。 老婆说小孩子很小气,过了3个月才跟身边的朋友说这件事。 怀孕期间 多亏了外企的“福利”,老婆大部分时间都是在家办公,这就避免了上下班的麻烦,缺点是独自在家少人交流。 这里感慨一下外企对于孕妇的政策确实要比国内企业人性化,比如产假更多、补贴更多、还能在家办公。 得知怀孕前,老婆已经拿到SHEIN、小鹏等公司的offer,得知怀孕后,把offer都拒了。 冲刺 11月7日,把丈母娘接到广州,有丈母娘照顾老婆,我放心得多。 期间丈母娘煮饭做家务陪老婆散步陪老婆产检,真是辛苦。 计划 基于我老婆的情况,一家人讨论了一个星期,决定了剖腹产。计划阿B跟我老婆同一天生日,这该是多么美好的场景。 于是11月20日去医院让医生开了住院单,21日办理了入院手续,22日经过医生的确认,确定了23日早上七点的剖腹产手术 一切都按照计划去推进。 出生 2021年11月23日星期二,距离阿B的预产期只剩下两天,这天是我老婆的生日。 前一天医生安排了早上七点第一床手术。 3:36 老婆给我打电话,跟我说破羊水了,医生正在给她做检查。心里一惊,难道阿B想提前出生? 4:08 老婆宫口开得比较快,我赶紧起床。 4:16 跟丈母娘一起出发去医院。 5:03 到了医院,老婆已被推进分娩中心。 6:13 老婆已开5指,经医生讨论,决定尝试顺产,取消了手术。 8:55 阿B出生! 9:16 老婆给我打电话阿B顺利出生。我给家人朋友报喜。 阿B顺产出生,真是计划外的惊喜。 新生儿科 阿B出生后在分娩中心观察了两个小时,护士采取了各种措施,阿B体温还未恢复正常水平,医生决定让阿B在新生儿科住院观察几天。 护士推着阿B出来,我见了一面,拍了几张照片,就被送到新生儿科了。 第一次见到阿B,第一次听到听到阿B的声音,简直心都化了。 老婆出院 11月25日下午,去到医院给老婆办理出院手续。 看到老婆的状态挺好,心里不由感慨阿B醒目,真会挑时间出生,晚一个小时发动,可能就按照计划进行剖腹产了。 阿B回家 11月26日下午,医生给我打电话,阿B的各项指标都正常,符合出院的条件了。 11月27日上午,去到医院办理阿B的出院手续。 接到阿B的时候,让老婆去抱他下楼,老婆不会抱,折腾了几分钟。 月嫂说阿B身体素质好,哭声响亮,眼仔碌碌,压根不需要住新生儿科。 阿B美照

November 28, 2021 · Darren Ou

iOS 逆向入门 - 实现 TikTok 自动播放下一个视频

一、背景 经过之前对 iOS 逆向的初步了解,想了个实现 TikTok 自动播放下一个视频的小需求实践一下。 二、实现过程 1、使用 class-dump 工具获取类信息 class-dump 工具通过解析 MachO 文件生成类信息,包括 OC 方法、属性、成员变量等。 有几个点需要留意: C 语言函数无法 dump; OC 方法的参数如果是对象类型,则只会显示 id; dump 出来的 OC 方法包含了 .h .m 文件里面的。 2、通过视图堆栈找出对应文件 从视图堆栈里面可以很方便找出播放器相关的文件,从 class-dump 出来的文件中找到相关文件,在文件中找出相关方法。 比如我需要实现自动播放下一个视频的话,分为两个步骤:1.监听播放完一个视频的事件;2.播放下一个视频。 找到“播放下一个视频”的方法: 我从视图堆栈里定位到 AWEFeedTableViewController 类; 从 class-dump 出来的文件中打开 AWEFeedTableViewController.h; 在文件中搜索 NextVideo,很容易可以找到 - (void)scrollToNextVideo; 方法。 类似的方法找出“播放完一个视频的事件”。 3、快速验证 从上一步找到的类还有对应方法是否真的可以实现“播放下一个视频”呢?我们可以在代码中 Hook 对应方法验证,但是这样验证的方法比较低效。 使用 Cycript 可以动态调试 App,这里简单介绍如何通过 Cycript 快速验证: 越狱手机上通过 Cydia 安装 Cycript; 通过 SSH 连接手机; 找到进程:root# ps -e | grep 'TikTok'; 依附到进程:cycript -p 进程号; 打印视图堆栈,输入命令:UIApp....

September 18, 2021 · Darren Ou