> l0x1c@blog:~/posts

xv6 环境配置 vmare or docker

xv6 环境配置问题 ( vmare or docker ) 配置的地址: https://pdos.csail.mit.edu/6.828/2020/tools.html 准备的系统: vmware + ubuntu vmare mit的实验代码: git clone git://g.csail.mit.edu/xv6-labs-2020 git checkout util 这边遇见的坑大概网上都有解答,唯一的一个位置是,如果出现 user/sh.c:58:1: error 的问题修改代码 加入__attribute__((noreturn)) 即可,后面直接目录下make qemu就可以启动了 配置gdb调试也有点繁琐,主要就是在这个目录下进行 make qemu-gdb,新开一个窗口,那个窗口运行 gdb 举个例子用sleep 这样就可以调试了,具体的一些命令可以看:https://pdos.csail.mit.edu/6.828/2019/lec/gdb_slides.pdf https://xv6.dgs.zone/tranlate_books/Use%20GUN%20Debugger.html docker 因为后面准备看csapp lab的适合还是得用到docker去配置环境,所以索性就直接学一下,后面就可以直接用了 直接网上下载docker就可以 docker pull ubuntu docker run -i -t -w /root --name ubuntu ubuntu bash # 连接ubuntu系统 docker start -i ubuntu apt-get update apt-get install vim 需要换个源 ...

October 12, 2025 · 2 min · L0x1c

Arm 汇编学习

ARM 汇编 由于开始好好的接触安卓这些东西,所以还是决定把所有的东西从头到尾的好好学习一下,也是开始记录生活的一种方式吧 主要的学习流程大概这两个: 看一下周壑老师的视频 辅助一下利用 https://azeria-labs.com/ 这个网站上的lab进行学习 ARM 汇编介绍 & 环境搭建 环境需要:Android studio ( 模拟器,ndk交叉编译环境,adb工具 ) ida( 远程调试 ),keypatch 插件 cemu 做辅助支持 : https://github.com/hugsy/cemu 在ubuntu下面折腾了一下,感觉还行 当然如果有真机做测试使用是最好的了 ( 这里我最后选择的真机,因为机器就在手里,hhhh ) Android studio & ida 的配置 勾选这几个选项即可,下载完会在上面表示的sdk Location的目录下 安装完之后自己在 .zshrc 中配置一下环境变量 export ANDROID_HOME="Android/sdk所在路径" export PATH=${PATH}:${ANDROID_HOME}/tools export PATH=${PATH}:${ANDROID_HOME}/platform-tools export PATH=${PATH}:${ANDROID_HOME}/ndk所在的路径 所需要的东西比如Emulator,ndk这些东西都在这个Location的目录下了 代码的头文件在 toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include 下 进到android studio中里面自带有一个arm64的emu,avd所在的位置 .android/avd/{emu:name} 以后避免每次都打开 android studio可以用emulator里面命令来启动avd ...

October 12, 2025 · 6 min · L0x1c

内存管理

VAD_私有内存 私有内存 像malloc, virtualalloc申请的内存都是私有内存, MapViewofFile, MapViewOfSize, mdl, 这种是映射的内存 这些内存是由一个叫做vadroot的节点来管理的, 可以看一下这个位置 这里如果后续想获取到这个位置的话, 因为每个版本的偏移可能不一样, 可以通过函数PsGetProcessExitStatus来获取对应的偏移 + 4就是vadRoot win10上的结构 +0x658 VadRoot : _RTL_AVL_TREE +0x660 VadHint : 0xffff900f`4bf43e10 Void +0x668 VadCount : 0xde VadRoot: _RTL_AVL_TREE 里面就是代表了二叉搜索树的节点, 而里面的每个节点的结构都是__MMVAD的结构, VadHint多次查询的节点会放在这里, VadCount代表vad节点的个数 kd> dt _RTL_AVL_TREE ffff900f4c129400+0x658 nt!_RTL_AVL_TREE +0x000 Root : 0xffff900f`4bf44810 _RTL_BALANCED_NODE kd> dt 0xffff900f`4bf44810 _RTL_BALANCED_NODE nt!_RTL_BALANCED_NODE +0x000 Children : [2] 0xffff900f`4b1dcb10 _RTL_BALANCED_NODE +0x000 Left : 0xffff900f`4b1dcb10 _RTL_BALANCED_NODE +0x008 Right : 0xffff900f`4bfe65c0 _RTL_BALANCED_NODE +0x010 Red : 0y0 +0x010 Balance : 0y00 +0x010 ParentValue : 0 !vad即可查询 其中start和End代表了开始和结束, 都需要乘上pagesize -> 0x1000其中end不一样(end + 1)*pagesize - 1, 里面的每一个节点都是_MMVAD的结构, 可以找一个私有内存看一下结构 ...

June 9, 2025 · 6 min · L0x1c

minifilter

这周主要看了一下minifilter的东西, 网吧, 杀软, 反作弊都会相应的用到这个 minifilter_Nt启动

June 8, 2025 · 1 min · L0x1c

D3CTF-WriteUp

很久没打ctf了, 正好碰见周末有一点空, 就看了一下d3ctf和windows相关的题目 locked-door 加的是vmp的壳子, 需要调试的话直接用TitanHide - > https://github.com/mrexodia/TitanHide就可以调试起来, download后自行加个签名即可, 发现题目有两个bin文件, 直接可以得到的思路是先dump, 因为一定要读取文件一定会调用readfile, 所以可以根据回溯找到关键位置进行调试 通过readfile回溯已经找到了关键位置, 然后用过函数特征入口点来dump, 正常编程的也就那几个软件, 这个问题在之前我发过看雪的文章可以看一下, 可以看到这里很像入口点了, 看一个正常vs编译出来的程序 比较后可以看很像入口点的位置, 直接dump设置oep, 这样dump后的逻辑就很清晰了 可以看到一个算法, 本身程序对他们的校验的算法是一样的 加密完的数据进行evp的校验 校验过了后才可以走到正确的流程, 参数是key+加密的bin里的data, 那直接替换一下, 就可以得到flag了 d3rpg-revenge 这是一个游戏, 正好我是一个游戏安全的从业者, 直接打开ce开始干, 进入一个房间后, 他让我输入密码, 那么可以对密码的位置进行访问断点, 可以看到可以被很好的断下来 d3rpg.dll+50DEA这里的地址, 这个字符串很可疑, 去搜一下 module Scene_RPG class Secret_Class DELTA = | (($de1ta + 1) * 0xf0000000) def initialize(new_key) @key = str_to_longs(new_key) if @key.length < 4 @key.length.upto(4) { |i| @key[i] = 0 } end end def self.str_to_longs(s, include_count = false) s = s.dup length = s.length ((4 - s.length % 4) & 3).times { s << "\0" } unpacked = s.unpack('V*').collect { |n| int32 n } unpacked << length if include_count unpacked end def str_to_longs(s, include_count = false) self.class.str_to_longs s, include_count end def self.longs_to_str(l, count_included = false) s = l.pack('V*') s = s[0...(l[-1])] if count_included s end def longs_to_str(l, count_included = false) self.class.longs_to_str l, count_included end def self.int32(n) n -= 4_294_967_296 while (n >= 2_147_483_648) n += 4_294_967_296 while (n <= -2_147_483_648) n.to_i end def int32(n) self.class.int32 n end def mx(z, y, sum, p, e) int32( ((z >> 5 & 0x07FFFFFF) ^ (y << 2)) + ((y >> 3 & 0x1FFFFFFF) ^ (z << 4)) ) ^ int32((sum ^ y) + (@key[(p & 3) ^ e] ^ z)) end def self.encrypt(key, plaintext) self.new(key).encrypt(plaintext) end def encrypt(plaintext) return '' if plaintext.length == 0 v = str_to_longs(plaintext, true) v[1] = 0 if v.length == 1 n = v.length - 1 z = v[n] y = v[0] q = (6 + 52 / (n + 1)).floor sum = $de1ta * DELTA p = 0 while(0 <= (q -= 1)) do sum = int32(sum + DELTA) e = sum >> 2 & 3 n.times do |i| y = v[i + 1]; z = v[i] = int32(v[i] + mx(z, y, sum, i, e)) p = i end p += 1 y = v[0]; z = v[p] = int32(v[p] + mx(z, y, sum, p, e)) end longs_to_str(v).unpack('a*').pack('m').delete("\n") end def self.decrypt(key, ciphertext) self.new(key).decrypt(ciphertext) end end end def validate_flag(input_flag) c_flag = input_flag + "\0" result = $check_flag.call(c_flag) result == 1 end def check flag = $game_party.actors[0].name key = Scene_RPG::Secret_Class.new('rpgmakerxp_D3CTF') cyphertext = key.encrypt(flag) if validate_flag(cyphertext) $game_variables[1] = 100 else $game_variables[1] = 0 end end def check1 flag = $game_party.actors[0].name if flag == "ImPsw" $game_variables[2] = 100 else $game_variables[2] = 0 end end 直接写python解密即可 ...

June 1, 2025 · 2 min · L0x1c
l0x1c@blog | ~/posts
hugo v0.152.2 |