24 研创赛 ezhtml

web assembly 逆向。

环境

调试方法

live server 打开浏览器,可以正确解析导入的 js 和 wasm。然后 f12 在 source 打断点,内存是一个局部变量,打了断点之后去 console 读memory

反编译

jeb 可以正确反编译,反编译得到的结果是 c 语言。

其中,反编译结果里 gvar_3, gvar_8 这一类变量的地址值就是 0x3, 0x8. 所以 &gvar_8 其实是常量 8 的意思。i32.load @Ch(4) 会被解释称 (int* )(var + &gvar8) +1,也就是 +12 取值。

逆向的 notes

strlen

反编译结果上来是完全没有符号的。像 print, read 这种很容易猜出来。

这个 func26 一开始并不知道是什么,只是结果 == 35 感觉像是算长度。追踪进去看的反编译结果是这样的:

一开始看到这个 0x1010101 和 0x80808080 把孩子吓到了,甚至感觉有加密什么的东西。第一段逻辑不知道在干什么,不过,如果假设开头的 if 是 false 的话(也就是地址没对齐到 word),函数就会走最后的 else。最后面那个肯定是算长度,所以 func26 大概率是算长度。

那回到分支的第一个代码块,问了下 gpt,这其实是 4-byte 时候的优化:

这段代码的主要目的是每次检查4个字节,而不是一次只检查一个字节,从而加快处理速度。

这个条件的原理是:

  • 如果一个字节是'\0'(值为0),那么 (该字节 - 1) 的最高位会是1。
  • v0 - 0x1010101 会使得任何为0的字节在相减后的对应位置产生一个值,其最高位为1。
  • ~v0 会使得原来为0的字节在结果中所有位都变为1。
  • & 0x80808080 只保留每个字节的最高位。

如果结果不为0,说明找到了一个空字符,循环结束。

这种方法比逐字节检查要快得多,特别是对于长字符串。它利用了整数运算和位操作的效率,一次性检查4个字节。

需要注意的是,这种方法假设了字符串的内存对齐,并且在不同的体系结构上可能需要调整(例如,在大端序系统上)。

逆向 check 的逻辑

观察结构,大概意思是把 input 按位异或然后和 template 比较,如果 true 就继续否则就 exit

那么,template 就在 +16540 这个内存地址。不过这里有一个弱智的地方,jeb 这个 +16540 是按 4-Byte 指针计算的,实际地址是 +16540*4……

从 console 把这个地方的 bytes 读出来,拿 python 枚举一下开头的字符,然后就解出来了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值