手搓十六进制转二进制文件:“有手就行”背后的思考
题目:在某个不太正经的群里,咱看到群友发了一道非常简单的编程入门题目:有如下hexdump输出,请转换回二进制文件
123456789101112131415161718192021222324252627282930313233343536373800000000: 1f8b 0808 dfcd eb66 0203 6461 7461 322e .......f..data2.00000010: 6269 6e00 013e 02c1 fd42 5a68 3931 4159 bin..>...BZh91AY00000020: 2653 59ca 83b2 c100 0017 7fff dff3 f4a7 &SY.............00000030: fc9f fefe f2f3 cffe f5ff ffdd bf7e 5bfe .............~[.00000040: faff dfbe 97aa 6fff f0de edf7 b001 3b56 ......o.......;V00000050: 0400 0034 d000 0000 006 ...
如何优雅地从Lxc镜像偷rootfs
首先我们拿到一个lxc镜像的链接,咱觉得bfsu的速度就很不错。https://mirrors.bfsu.edu.cn/lxc-images/images点进去,顺着目录就能找到rootfs.tar.xz,下载就完了。本文完,就这么简单。当然不是啊喂!我们要做到自动获取rootfs链接。
镜像列表:12345678910111213141516171819202122232425262728LXC_MIRROR_MAIN="http://images.linuxcontainers.org"LXC_MIRROR_BFSU="https://mirrors.bfsu.edu.cn/lxc-images"LXC_MIRROR_TUNA="https://mirrors.tuna.tsinghua.edu.cn/lxc-images"LXC_MIRROR_NJU="https://mirror.nju.edu.cn/lxc-images"LXC_MIRROR_ISCAS="https://mirror. ...
rootless容器开发指北
前言:ruri前不久通过使用uidmap二进制的方式修好了rootless容器无法setgroups()的问题,差不多也该讲讲rootless容器的创建了。
rootless容器创建流程:1.设置uidmap我们可以通过读取/etc/subuid和/etc/subgid来获取uid_lower,uid_count和gid_lower,gid_count,他们的格式为:foo:lower:count.然后,我们的父进程fork出子进程,父进程unshare(CLONE_NEWUSER),子进程稍作等待,等父进程拥有了user ns后调用uidmap更改父进程的uidmap,然后父进程获得user ns中的root权限,继续容器创建过程。
123456789101112pid_t pid_1 = fork();if (pid_1 > 0) { // Enable user namespace. try_unshare(CLONE_NEWUSER); int stat = 0; waitpid(pid_1, &stat, ...
小型C语言项目:从手写configure脚本开始的构建系统编写
我们在开发C语言项目的构建系统部分时,单用Makefile可能会出现很多难题:我想使用一个CFLAG来提高安全性,可有些编译器不支持怎么办?我想用的头文件不同平台有不同版本怎么办?我想在编译前检查依赖库怎么办?老实说,一个build.sh或许是个很好的选择。或者你会说,为啥不用meson/CMake?因为咱是传统派23333GNU项目一般都用configure来生成项目配置,但咱懒得学autotools的用法,于是我们这篇文章的主题是:使用最原始的方法手写一个configure脚本!!!!
成品展示:输出:12345678910111213141516171819202122232425262728293031323334checking for make... /usr/bin/makechecking for strip... /usr/bin/stripchecking for compiler... aarch64-linux-gnu-gcc-11checking whether the compiler supports GNU C11... okchecking ...
浅析Dockerhub API:如何优雅地从dockerhub偷rootfs镜像
成品:https://github.com/Moe-hacker/docker_image_puller
前言:八月初的时候,咱无聊去扒了下dockerhub的接口,想通过网络请求直接从dockerhub偷镜像。然后写完才想起来dockkerhub在国内是被墙的,似乎这么一个功能用处也不大。。。。。然后咱就去旅游了,连项目Readme都没写(逃)。至于现在为啥写这篇文章,因为上课摸鱼。。。
前置函数:123456789101112131415161718def panic(message): print("\033[31m", end="") print(message) print("\033[0m", end="") exit(1)# Get the architecture of host.def get_host_arch(): # TODO: add more architecture support. arch = platform.machine() ...
C语言的一些`守序善良`的写法
很显然,这些写法大多并不规范,也不被提倡。很显然,咱并没有在windows下试过这些代码,而且实测大部分在线编程网站用的是Linux,可以接受GNU C扩展支持。如果有人问我为什么折腾,为什么以折腾这些无聊的东西作为目标,那他们完全可以问,为什么要登上最高峰?为什么人类要登月?………我选择去折腾,我,选择去折腾!(逃)
趋近符号:很出名的写法,比如:
1234567char *str=strdup("hello;");for(int i=strlen(str);i-->0;i=i){ if(str[i]==';'){ str[i]='\0'; break; }}
这将str中最后一个;的位置设置为结尾。
对指针解引用:C语言提供方便的指针解引用,于是:
12345if (strchr(p, ';') == NULL) { *strchr(p, '\n') = '\0'; } else { ...
在arm64设备上使用qemu(kvm)运行aarch64 ubuntu虚拟机
最近咱换了k40外观增强版,这一代联发科芯片漏洞不是一般的多,不仅有mtkclient中众所周知的bootrom漏洞,老版本系统lk中的cpu地址还是错的,真是“红米配天玑,越用越懵逼”。不过lk的漏洞导致这手机在miui12.5下是能开kvm的,嗯,不折腾会死星人狂喜。所以就有了这篇通用的在支持kvm的arm64设备上运行ubuntu虚拟机的文章,好了咱们开始:首先创建一个img镜像并格式化为ext4:
12dd if=/dev/zero of=ubuntu.img bs=1G count=16 status=progressmkfs.ext4 ubuntu.img
然后把它挂载:
1234LOOP_FILE=$(losetup -f)losetup $LOOP_FILE ubuntu.imgmkdir ubuntumount $LOOP_FILE ubuntu
然后咱还需要一个rootfs,去lxc mirror可以找到你需要的版本的rootfs.tar.xz下载后将rootfs解压:
1tar -xvf rootfs.tar.xz -C ubuntu
然后你需要把这个系统作为容器 ...
国产物理密钥Canokey踩坑记录
前段时间咱本着再不买以后就买不到了的心态购入了国产物理密钥Canokey,不得不说这价格是真的坚挺,至死不降那种。。。闪烁的蓝灯,优雅的签名,逼格算是拉满了,不过使用过程是真的曲折坎坷。咱主要是买来用于git签名与ssh认证的,配置过程前辈们已经写的很清楚了,写好了有奖励,写不好有惩罚(悲)所以咱就不怎么写了,主要写使用OpenPGP Card的过程中遇到的坑。
基本配置:配置SSH验证:编辑 ~/.gnupg/gpg-agent.conf,加入:
1enable-ssh-support
然后:
1gpg --list-keys --with-keygrip
将keygrip写入~/.gnupg/sshcontrol然后:
12export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)gpgconf --launch gpg-agent
git签名:12git config --global user.signingkey [key]git config --global commit ...
C语言实现基本的mount命令挂载磁盘/镜像/目录
mount(2)函数是个很简单的函数,原型如下:
123int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *_Nullable data);
对于目录和nodev文件系统(如proc和sysfs)的挂载,可以说是非常简单:
1234// 把'/' bind-mount到'/'mount("/", "/", NULL, MS_BIND, NULL);// 把proc文件系统挂载到/procmount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL);
可见mount(2)函数的使用非常简单。由于bind-mount对于type没有任 ...
论如何在Segmentation fault时优雅地结束程序
作为开发者,咱自然是不喜欢程序发生Segfault的“喜报”的,但是万一有些用户非闹着要在酒吧里点炒饭,程序还是大概率会崩。(不崩才怪呢喵!)glibc下还好,崩了最起码显示个cmdline,bionic就可能啥也没有了。于是,虽然咱不希望出问题,最起码出问题时程序走的安详点,不要出现啥信息也没有的“死不瞑目”的场面。然后就是捕捉段错误的原理了:众所周知,段错误是当前这段错误,程序其他段大概率还是能跑的。在发生段错误时,内核就会给进程发送相应SIGSEGV信号:这位进程你已经寄了,准备下后事吧喵~其它信号如SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGQUIT,SIGSYS,SIGTRAP,SIGXCPU和SIGXFSZ,对应了不同的异常情况,默认行为也是core dump,具体可以看signal(7)。事实上这些信号并不是说必须强制终止程序,当然你也可以选择直接忽略,然后内核会不停发送信号,最后就是死循环,核心思想便是“只要我不主动崩溃,我就没有崩溃”的精神胜利(逃)。。。收到相应信号后,进程是可以选择自己到底要干什么的,默认是按照系统配置生成core dump文件 ...