0%

idapython初探

也到了该系统学习idapython的阶段了!

之前看别人的wp用的idapython在新的版本中已经不能用来,idapython升级了!现大概学习一下怎么用,然后在文档中学习:

idapython官方函数文档:https://www.hex-rays.com/products/ida/support/idapython_docs/

旧版本和新版本差异:https://www.hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml

idapython图片集合版:https://github.com/inforion/idapython-cheatsheet/blob/master/IDAPython-7x_cheatsheet_web_en.png

1、获取函数地址

1
2
3
4
5
6
7
8
9
10
11
print(hex(idc.here()))/#获取当前在查看函数地址
print(hex(idc.get_screen_ea()))#获取当前在查看的函数地址
print(hex(ida_ida.inf_get_min_ea()))#获取这个程序最小的地址
print(hex(ida_ida.inf_get_max_ea()))#获取这个程序最大的地址
print(hex(idc.read_selection_start()))#如果你选择了某块地址 那么使用此函数则返回你选择的这块地址的起始地址,否则返回-1,选择的意思是光标选择其地址
print(hex(idc.read_selection_end()))#同上

if idaapi.BADADDR == idc.here():
print("BadAddress addr invalid")
else:
print("addr is ok")

idaapi.BADADDR,用来判断函数是否存在

2.获取数值

在之前看wp,用Byte永远是错的,今天才知道原来改了函数:

image-20220411155039777

1
2
3
4
idc.get_wide_byte(addr)//以字节为单位获取地址处的值
idc.get_wide_word(addr)//获取2字节的值
idc.get_wide_dword(addr)//获取4字节
idc.get_qword(addr)//获取8字节

下面进行一个获取当前地址下的数值操作,如果不是数据段,获得的是硬编码,在hex显示中能看到的

1
2
3
4
import idc
ea = idc.get_screen_ea()
value = idc.get_wide_byte(ea)
print("{}".format(hex(value)))
idc.isByte() Word Dwrd Qwrd ida_bytes.is_byte word dword qword

上面是对应的判断函数

3.修改数值操作

修改数值的方法,一般用patch,或者用python也行。

image-20220411162518089

当然修改的值韩式byte是1字节,word2字节,Dword4字节,Qword8字节

1
2
3
4
5
6
7
8
ea = idc.get_screen_ea()
value = idc.get_wide_byte(ea)
print("修改前{}".format(hex(value)))
ida_bytes.patch_byte(ea,0x90)
value = idc.get_wide_byte(ea)
print("修改前{}".format(hex(value)))
#修改前0x0
#修改前0x90

我们修改当前选中地址的数据

如果要将一段地址中所有0x0换成0x77,如何写呢?

1
2
3
4
5
6
7
8
9
10
import idc
import idaapi
import idautils
start_addr = 0x0040b1cd
end_addr = 0x0040b1ff
for i in range(end_addr - start_addr):
now_addr = i + start_addr
tmp = idc.get_wide_byte(now_addr)
if tmp == 0:
ida_bytes.patch_byte(now_addr,0x77)

我的建议是每次写的时候将三个import全部导入,反正就这三个。

4.汇编提取

image-20220411170422358

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import idc
import idaapi
import idautils

ea = idc.here()
print("当前模块基址{}".format(hex(idaapi.get_imagebase())))
print("当前汇编指令{}".format(idc.print_insn_mnem(ea)))
print("当前汇编语句{}".format(idc.GetDisasm(ea)))
print("当前操作数{}".format(idc.print_operand(ea,0)))
print("当前的操作数值为: {}".format(idc.get_operand_value(ea,0)))

#当前模块基址0x400000
#当前汇编指令xor
#当前汇编语句xor rsi, qword ptr [rsp+58h+PerformanceCount]
#当前操作数rsi
#当前的操作数值为: 6

5.段操作

image-20220411181105721

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import idc
import idaapi
import idautils

for seg in idautils.Segments():
segname = idc.get_segm_name(seg)
segstart = idc.get_segm_start(seg)
segend = idc.get_segm_end(seg)
print("段名 = {} 起始地址 = {} 结束地址 = {}".format(segname, hex(segstart), hex(segend)))
#段名 = .text 起始地址 = 0x401000 结束地址 = 0x404000
#段名 = .data 起始地址 = 0x404000 结束地址 = 0x405000
#段名 = .rdata 起始地址 = 0x405000 结束地址 = 0x406000
#段名 = .pdata 起始地址 = 0x406000 结束地址 = 0x407000
#段名 = .xdata 起始地址 = 0x407000 结束地址 = 0x408000
#段名 = .bss 起始地址 = 0x408000 结束地址 = 0x409000
#段名 = .idata 起始地址 = 0x4091dc 结束地址 = 0x40937c
#段名 = .CRT 起始地址 = 0x40a000 结束地址 = 0x40b000
#段名 = .tls 起始地址 = 0x40b000 结束地址 = 0x40c000

6.函数操作

image-20220411182506660

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import idc
import idaapi
import idautils

for seg in idautils.Segments():
segname = idc.get_segm_name(seg)
segstart = idc.get_segm_start(seg)
segend = idc.get_segm_end(seg)
print("段名 = {} 起始地址= {} 结束地址 = {} ".format(segname,hex(segstart),hex(segend)))
if segname == '.text':
for funcaddr in Functions(segstart, segend):
funname = idc.get_func_name(funcaddr)
funend = idc.find_func_end(funcaddr)
funnext = idc.get_next_func(funcaddr)
funnextname = idc.get_func_name(funnext)
print("当前函数名 = {} 当前结束地址 = {} 下一个函数地址 = {} 下一个函数名 = {}".format(funname, hex(funend), hex(funnext), funnextname))
ea = idc.get_screen_ea()
funnextoffset = idc.get_func_off_str(ea)
print("当前选择地址距离当前函数的偏移:{}".format(funnextoffset))
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
段名 = .text 起始地址= 0x401000 结束地址 = 0x404000 
当前函数名 = __mingw_invalidParameterHandler 当前结束地址 = 0x401001 下一个函数地址 = 0x401010 下一个函数名 = pre_c_init
当前函数名 = pre_c_init 当前结束地址 = 0x401121 下一个函数地址 = 0x401130 下一个函数名 = pre_cpp_init
当前函数名 = pre_cpp_init 当前结束地址 = 0x401179 下一个函数地址 = 0x401180 下一个函数名 = __tmainCRTStartup
当前函数名 = __tmainCRTStartup 当前结束地址 = 0x4014a6 下一个函数地址 = 0x4014b0 下一个函数名 = WinMainCRTStartup
当前函数名 = WinMainCRTStartup 当前结束地址 = 0x4014d2 下一个函数地址 = 0x4014e0 下一个函数名 = mainCRTStartup
当前函数名 = mainCRTStartup 当前结束地址 = 0x401502 下一个函数地址 = 0x401510 下一个函数名 = atexit
当前函数名 = atexit 当前结束地址 = 0x401529 下一个函数地址 = 0x401530 下一个函数名 = __gcc_register_frame
当前函数名 = __gcc_register_frame 当前结束地址 = 0x40153c 下一个函数地址 = 0x401540 下一个函数名 = __gcc_deregister_frame
当前函数名 = __gcc_deregister_frame 当前结束地址 = 0x401541 下一个函数地址 = 0x401550 下一个函数名 = input
当前函数名 = input 当前结束地址 = 0x40163d 下一个函数地址 = 0x40163d 下一个函数名 = output
当前函数名 = output 当前结束地址 = 0x401725 下一个函数地址 = 0x401725 下一个函数名 = Findmax
当前函数名 = Findmax 当前结束地址 = 0x4017a6 下一个函数地址 = 0x4017a6 下一个函数名 = sort
当前函数名 = sort 当前结束地址 = 0x4019a0 下一个函数地址 = 0x4019a0 下一个函数名 = main
当前函数名 = main 当前结束地址 = 0x401aeb 下一个函数地址 = 0x401af0 下一个函数名 = __do_global_dtors
当前函数名 = __do_global_dtors 当前结束地址 = 0x401b25 下一个函数地址 = 0x401b30 下一个函数名 = __do_global_ctors
当前函数名 = __do_global_ctors 当前结束地址 = 0x401b96 下一个函数地址 = 0x401ba0 下一个函数名 = __main
当前函数名 = __main 当前结束地址 = 0x401bbf 下一个函数地址 = 0x401bc0 下一个函数名 = my_lconv_init
当前函数名 = my_lconv_init 当前结束地址 = 0x401bc7 下一个函数地址 = 0x401bd0 下一个函数名 = _setargv
当前函数名 = _setargv 当前结束地址 = 0x401bd3 下一个函数地址 = 0x401be0 下一个函数名 = __security_init_cookie
当前函数名 = __security_init_cookie 当前结束地址 = 0x401cb6 下一个函数地址 = 0x401cc0 下一个函数名 = __report_gsfailure
当前函数名 = __report_gsfailure 当前结束地址 = 0x401db8 下一个函数地址 = 0x401dc0 下一个函数名 = __dyn_tls_dtor
当前函数名 = __dyn_tls_dtor 当前结束地址 = 0x401def 下一个函数地址 = 0x401df0 下一个函数名 = __dyn_tls_init
当前函数名 = __dyn_tls_init 当前结束地址 = 0x401e63 下一个函数地址 = 0x401e70 下一个函数名 = __tlregdtor
当前函数名 = __tlregdtor 当前结束地址 = 0x401e73 下一个函数地址 = 0x401e80 下一个函数名 = __mingw_raise_matherr
当前函数名 = __mingw_raise_matherr 当前结束地址 = 0x401ec1 下一个函数地址 = 0x401ed0 下一个函数名 = __mingw_setusermatherr
当前函数名 = __mingw_setusermatherr 当前结束地址 = 0x401edc 下一个函数地址 = 0x401ee0 下一个函数名 = _matherr
当前函数名 = _matherr 当前结束地址 = 0x401fdc 下一个函数地址 = 0x401fe0 下一个函数名 = fpreset
当前函数名 = fpreset 当前结束地址 = 0x401fe3 下一个函数地址 = 0x401ff0 下一个函数名 = _decode_pointer
当前函数名 = _decode_pointer 当前结束地址 = 0x401ff4 下一个函数地址 = 0x402000 下一个函数名 = _encode_pointer
当前函数名 = _encode_pointer 当前结束地址 = 0x402004 下一个函数地址 = 0x402010 下一个函数名 = __write_memory.part.0
当前函数名 = __write_memory.part.0 当前结束地址 = 0x4021dc 下一个函数地址 = 0x4021e0 下一个函数名 = _pei386_runtime_relocator
当前函数名 = _pei386_runtime_relocator 当前结束地址 = 0x40249a 下一个函数地址 = 0x4024a0 下一个函数名 = __mingw_SEH_error_handler
当前函数名 = __mingw_SEH_error_handler 当前结束地址 = 0x402640 下一个函数地址 = 0x402640 下一个函数名 = __mingw_init_ehandler
当前函数名 = __mingw_init_ehandler 当前结束地址 = 0x40272c 下一个函数地址 = 0x402920 下一个函数名 = __mingwthr_run_key_dtors.part.0
当前函数名 = __mingwthr_run_key_dtors.part.0 当前结束地址 = 0x40298a 下一个函数地址 = 0x402990 下一个函数名 = ___w64_mingwthr_add_key_dtor
当前函数名 = ___w64_mingwthr_add_key_dtor 当前结束地址 = 0x402a0f 下一个函数地址 = 0x402a10 下一个函数名 = ___w64_mingwthr_remove_key_dtor
当前函数名 = ___w64_mingwthr_remove_key_dtor 当前结束地址 = 0x402ab0 下一个函数地址 = 0x402ab0 下一个函数名 = __mingw_TLScallback
当前函数名 = __mingw_TLScallback 当前结束地址 = 0x402b8a 下一个函数地址 = 0x402b90 下一个函数名 = _ValidateImageBase.part.0
当前函数名 = _ValidateImageBase.part.0 当前结束地址 = 0x402bae 下一个函数地址 = 0x402bb0 下一个函数名 = _ValidateImageBase
当前函数名 = _ValidateImageBase 当前结束地址 = 0x402bc2 下一个函数地址 = 0x402bd0 下一个函数名 = _FindPESection
当前函数名 = _FindPESection 当前结束地址 = 0x402c14 下一个函数地址 = 0x402c20 下一个函数名 = _FindPESectionByName
当前函数名 = _FindPESectionByName 当前结束地址 = 0x402cad 下一个函数地址 = 0x402cb0 下一个函数名 = __mingw_GetSectionForAddress
当前函数名 = __mingw_GetSectionForAddress 当前结束地址 = 0x402d24 下一个函数地址 = 0x402d30 下一个函数名 = __mingw_GetSectionCount
当前函数名 = __mingw_GetSectionCount 当前结束地址 = 0x402d6e 下一个函数地址 = 0x402d70 下一个函数名 = _FindPESectionExec
当前函数名 = _FindPESectionExec 当前结束地址 = 0x402ddf 下一个函数地址 = 0x402de0 下一个函数名 = _GetPEImageBase
当前函数名 = _GetPEImageBase 当前结束地址 = 0x402e17 下一个函数地址 = 0x402e20 下一个函数名 = _IsNonwritableInCurrentImage
当前函数名 = _IsNonwritableInCurrentImage 当前结束地址 = 0x402eb1 下一个函数地址 = 0x402ec0 下一个函数名 = __mingw_enum_import_library_names
当前函数名 = __mingw_enum_import_library_names 当前结束地址 = 0x402f66 下一个函数地址 = 0x402f70 下一个函数名 = ___chkstk_ms
当前函数名 = ___chkstk_ms 当前结束地址 = 0x402fa2 下一个函数地址 = 0x402fb0 下一个函数名 = vfprintf
当前函数名 = vfprintf 当前结束地址 = 0x402fb6 下一个函数地址 = 0x402fb8 下一个函数名 = strncmp
当前函数名 = strncmp 当前结束地址 = 0x402fbe 下一个函数地址 = 0x402fc0 下一个函数名 = strlen
当前函数名 = strlen 当前结束地址 = 0x402fc6 下一个函数地址 = 0x402fc8 下一个函数名 = signal
当前函数名 = signal 当前结束地址 = 0x402fce 下一个函数地址 = 0x402fd0 下一个函数名 = scanf
当前函数名 = scanf 当前结束地址 = 0x402fd6 下一个函数地址 = 0x402fd8 下一个函数名 = printf
当前函数名 = printf 当前结束地址 = 0x402fde 下一个函数地址 = 0x402fe0 下一个函数名 = memcpy
当前函数名 = memcpy 当前结束地址 = 0x402fe6 下一个函数地址 = 0x402fe8 下一个函数名 = malloc
当前函数名 = malloc 当前结束地址 = 0x402fee 下一个函数地址 = 0x402ff0 下一个函数名 = fwrite
当前函数名 = fwrite 当前结束地址 = 0x402ff6 下一个函数地址 = 0x402ff8 下一个函数名 = free
当前函数名 = free 当前结束地址 = 0x402ffe 下一个函数地址 = 0x403000 下一个函数名 = fprintf
当前函数名 = fprintf 当前结束地址 = 0x403006 下一个函数地址 = 0x403008 下一个函数名 = exit
当前函数名 = exit 当前结束地址 = 0x40300e 下一个函数地址 = 0x403010 下一个函数名 = calloc
当前函数名 = calloc 当前结束地址 = 0x403016 下一个函数地址 = 0x403018 下一个函数名 = abort
当前函数名 = abort 当前结束地址 = 0x40301e 下一个函数地址 = 0x403020 下一个函数名 = _onexit
当前函数名 = _onexit 当前结束地址 = 0x403026 下一个函数地址 = 0x403028 下一个函数名 = _initterm
当前函数名 = _initterm 当前结束地址 = 0x40302e 下一个函数地址 = 0x403030 下一个函数名 = _cexit
当前函数名 = _cexit 当前结束地址 = 0x403036 下一个函数地址 = 0x403038 下一个函数名 = _amsg_exit
当前函数名 = _amsg_exit 当前结束地址 = 0x40303e 下一个函数地址 = 0x403040 下一个函数名 = __setusermatherr
当前函数名 = __setusermatherr 当前结束地址 = 0x403046 下一个函数地址 = 0x403048 下一个函数名 = __set_app_type
当前函数名 = __set_app_type 当前结束地址 = 0x40304e 下一个函数地址 = 0x403050 下一个函数名 = __lconv_init
当前函数名 = __lconv_init 当前结束地址 = 0x403056 下一个函数地址 = 0x403058 下一个函数名 = __getmainargs
当前函数名 = __getmainargs 当前结束地址 = 0x40305e 下一个函数地址 = 0x403060 下一个函数名 = __C_specific_handler
当前函数名 = __C_specific_handler 当前结束地址 = 0x403066 下一个函数地址 = 0x403070 下一个函数名 = __acrt_iob_func
当前函数名 = __acrt_iob_func 当前结束地址 = 0x40308f 下一个函数地址 = 0x403090 下一个函数名 = _get_invalid_parameter_handler
当前函数名 = _get_invalid_parameter_handler 当前结束地址 = 0x403098 下一个函数地址 = 0x4030a0 下一个函数名 = _set_invalid_parameter_handler
当前函数名 = _set_invalid_parameter_handler 当前结束地址 = 0x4030ab 下一个函数地址 = 0x4030b0 下一个函数名 = __p__acmdln
当前函数名 = __p__acmdln 当前结束地址 = 0x4030bb 下一个函数地址 = 0x4030c0 下一个函数名 = __p__fmode
当前函数名 = __p__fmode 当前结束地址 = 0x4030cb 下一个函数地址 = 0x4030d0 下一个函数名 = __iob_func
当前函数名 = __iob_func 当前结束地址 = 0x4030d6 下一个函数地址 = 0x4030e0 下一个函数名 = VirtualQuery
当前函数名 = VirtualQuery 当前结束地址 = 0x4030e6 下一个函数地址 = 0x4030e8 下一个函数名 = VirtualProtect
当前函数名 = VirtualProtect 当前结束地址 = 0x4030ee 下一个函数地址 = 0x4030f0 下一个函数名 = UnhandledExceptionFilter
当前函数名 = UnhandledExceptionFilter 当前结束地址 = 0x4030f6 下一个函数地址 = 0x4030f8 下一个函数名 = TlsGetValue
当前函数名 = TlsGetValue 当前结束地址 = 0x4030fe 下一个函数地址 = 0x403100 下一个函数名 = TerminateProcess
当前函数名 = TerminateProcess 当前结束地址 = 0x403106 下一个函数地址 = 0x403108 下一个函数名 = Sleep
当前函数名 = Sleep 当前结束地址 = 0x40310e 下一个函数地址 = 0x403110 下一个函数名 = SetUnhandledExceptionFilter
当前函数名 = SetUnhandledExceptionFilter 当前结束地址 = 0x403116 下一个函数地址 = 0x403118 下一个函数名 = RtlVirtualUnwind
当前函数名 = RtlVirtualUnwind 当前结束地址 = 0x40311e 下一个函数地址 = 0x403120 下一个函数名 = RtlLookupFunctionEntry
当前函数名 = RtlLookupFunctionEntry 当前结束地址 = 0x403126 下一个函数地址 = 0x403128 下一个函数名 = RtlCaptureContext
当前函数名 = RtlCaptureContext 当前结束地址 = 0x40312e 下一个函数地址 = 0x403130 下一个函数名 = RtlAddFunctionTable
当前函数名 = RtlAddFunctionTable 当前结束地址 = 0x403136 下一个函数地址 = 0x403138 下一个函数名 = QueryPerformanceCounter
当前函数名 = QueryPerformanceCounter 当前结束地址 = 0x40313e 下一个函数地址 = 0x403140 下一个函数名 = LeaveCriticalSection
当前函数名 = LeaveCriticalSection 当前结束地址 = 0x403146 下一个函数地址 = 0x403148 下一个函数名 = InitializeCriticalSection
当前函数名 = InitializeCriticalSection 当前结束地址 = 0x40314e 下一个函数地址 = 0x403150 下一个函数名 = GetTickCount
当前函数名 = GetTickCount 当前结束地址 = 0x403156 下一个函数地址 = 0x403158 下一个函数名 = GetSystemTimeAsFileTime
当前函数名 = GetSystemTimeAsFileTime 当前结束地址 = 0x40315e 下一个函数地址 = 0x403160 下一个函数名 = GetStartupInfoA
当前函数名 = GetStartupInfoA 当前结束地址 = 0x403166 下一个函数地址 = 0x403168 下一个函数名 = GetLastError
当前函数名 = GetLastError 当前结束地址 = 0x40316e 下一个函数地址 = 0x403170 下一个函数名 = GetCurrentThreadId
当前函数名 = GetCurrentThreadId 当前结束地址 = 0x403176 下一个函数地址 = 0x403178 下一个函数名 = GetCurrentProcessId
当前函数名 = GetCurrentProcessId 当前结束地址 = 0x40317e 下一个函数地址 = 0x403180 下一个函数名 = GetCurrentProcess
当前函数名 = GetCurrentProcess 当前结束地址 = 0x403186 下一个函数地址 = 0x403188 下一个函数名 = EnterCriticalSection
当前函数名 = EnterCriticalSection 当前结束地址 = 0x40318e 下一个函数地址 = 0x403190 下一个函数名 = DeleteCriticalSection
当前函数名 = DeleteCriticalSection 当前结束地址 = 0x403196 下一个函数地址 = 0x4031a0 下一个函数名 = .text_46
当前函数名 = .text_46 当前结束地址 = 0x403209 下一个函数地址 = 0x403210 下一个函数名 = register_frame_ctor
当前函数名 = register_frame_ctor 当前结束地址 = 0x403215 下一个函数地址 = 0xffffffffffffffff 下一个函数名 =
段名 = .data 起始地址= 0x404000 结束地址 = 0x405000
段名 = .rdata 起始地址= 0x405000 结束地址 = 0x406000
段名 = .pdata 起始地址= 0x406000 结束地址 = 0x407000
段名 = .xdata 起始地址= 0x407000 结束地址 = 0x408000
段名 = .bss 起始地址= 0x408000 结束地址 = 0x409000
段名 = .idata 起始地址= 0x4091dc 结束地址 = 0x40937c
段名 = .CRT 起始地址= 0x40a000 结束地址 = 0x40b000
段名 = .tls 起始地址= 0x40b000 结束地址 = 0x40c000
当前选择地址距离当前函数的偏移:__security_init_cookie+9B

7.搜索函数

image-20220411185445159

1
2
3
4
5
6
flag的取值:
SEARCH_DOWN 向下搜索
SEARCH_UP 向上搜索
SEARCH_NEXT 获取下一个找到的对象。
SEARCH_CASE 指定大小写敏感度
SEARCH_UNICODE 搜索 Unicode 字符串。
1
2
3
4
5
6
7
8
import idc
import idaapi
import idautils

ea = idc.here()
value = ida_search.find_binary(ea, SEARCH_DOWN, '8D 4D 08')
value1 = ida_search.find_code(ea, SEARCH_DOWN)
value2 = ida_search.find_data(ea, SEARCH_DOWN)

上述idc.find_binary已经不用了,被ida_search.find_binary代替了

8.数据检验函数

也就是相当于进行一个判断,判断是否传回正确的值!

image-20220411190928332

1
2
3
4
5
6
7
8
9
10
import idc
ea = here()
value1 = idc.find_code(ea,SEARCH_DOWN)
print(hex(value1))
flag = ida_bytes.get_full_flags(value1)
print(flag)
print(ida_bytes.is_code(flag))
#0x401c6e
#67465
#True

9.交叉引用

image-20220411191332094

1
2
3
4
import idc
ea = here()
for i in CodeRefsTo(ea,False):
print(hex(i))

这个一般是对着函数用的。

就先写这么多,什么时候遇到再补充,最起码现在遇见idapython不慌了!

VMproblem

这是一道vm+golong的题,我们主要学习vm的解题技巧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void __cdecl main_main()
{
__int64 v0; // rcx
__int64 v1; // [rsp+10h] [rbp-18h]
void *v2; // [rsp+18h] [rbp-10h]
void *retaddr; // [rsp+28h] [rbp+0h] BYREF

while ( (unsigned __int64)&retaddr <= *(_QWORD *)(*(_QWORD *)NtCurrentTeb()->NtTib.ArbitraryUserPointer + 16LL) )
runtime_morestack_noctxt();
v1 = runtime_newobject((__int64)&unk_4D3F60);
main___ptr_MzVm__init(v1);
v2 = (void *)runtime_newobject((__int64)&unk_4C3940);
qmemcpy(v2, &unk_57D8A0, 0x2EE0uLL);
if ( dword_5B97D0 )
{
runtime_gcWriteBarrier();
}
else
{
v0 = v1;
*(_QWORD *)(v1 + 4096) = v2;
}
main___ptr_MzVm__run(v0);
}

这是主函数,能猜测出unk_57D8A0,就是opcode,我个人认为opcode相当于是出题人在这台vm机器上做了什么事!

接下来我们进入函数main___ptr_MzVm__run(v0),

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
void __golang main___ptr_MzVm__run(__int64 a1)
{
__int64 v1; // rbx
__int64 v2; // rsi
unsigned __int64 v3; // rax
unsigned __int64 v4; // rdi
unsigned __int64 v5; // r8
unsigned int v6; // er8
unsigned __int64 v7; // rax
unsigned int v8; // esi
__int64 v9; // [rsp+0h] [rbp-18h]
void *retaddr; // [rsp+18h] [rbp+0h] BYREF

while ( (unsigned __int64)&retaddr <= *(_QWORD *)(*(_QWORD *)NtCurrentTeb()->NtTib.ArbitraryUserPointer + 16LL) )
runtime_morestack_noctxt();
v1 = a1;
while ( !*(_BYTE *)(v1 + 4904) )
{
v2 = *(_QWORD *)(v1 + 4096);
v3 = *(unsigned int *)(v1 + 4084);
if ( v3 >= 0xBB8 )
runtime_panicIndex(v9);
v4 = *(unsigned int *)(v2 + 4 * v3);
v5 = (unsigned int)(v3 + 1);
if ( v5 >= 0xBB8 )
runtime_panicIndex(v9);
v6 = *(_DWORD *)(v2 + 4 * v5);
v7 = (unsigned int)(v3 + 2);
if ( v7 >= 0xBB8 )
runtime_panicIndex(v9);
v8 = *(_DWORD *)(v2 + 4 * v7);
if ( v4 >= 0x64 ) //组合为64位
runtime_panicIndex(v9);
v9 = __PAIR64__(v8, v6);
(**(void (***)(void))(v1 + 8 * v4 + 4104))();//这个是opcode的地址,也就是func2的指令
v1 = a1;
*(_DWORD *)(a1 + 4084) += 3;//指令长度3字节
}
}

也就是说,我们通过对地址偏移的分析,就能够还原每个opcode的指令

先看init的函数,我们的opcode是在这里执行的

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
__int64 (__usercall **__usercall main___ptr_MzVm__init@<rax>(__int64 a1))@<rax>(__int64 a1)
{
__int64 (__usercall **result)@<rax>(__int64); // rax
__int64 v2; // [rsp+8h] [rbp-10h]
void *retaddr; // [rsp+18h] [rbp+0h] BYREF

while ( (unsigned __int64)&retaddr <= *(_QWORD *)(*(_QWORD *)NtCurrentTeb()->NtTib.ArbitraryUserPointer + 16LL) )
runtime_morestack_noctxt();
*(_BYTE *)(a1 + 4904) = 0;
*(_QWORD *)(a1 + 4084) = 0x3E800000000LL;
if ( dword_A197D0 )
runtime_gcWriteBarrierCX();
else
*(_QWORD *)(a1 + 4104) = &off_9462D0;//这个地址对应的是1,0,87,我们要将func2与其对应
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func2;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4112) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func3;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4120) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func4;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4128) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func5;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4136) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func6;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4144) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func7;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4152) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func8;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4160) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func9;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4168) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func10;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4176) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func11;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4184) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func12;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4192) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func13;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4200) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func14;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4208) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func15;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4216) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func16;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4224) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func17;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4232) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func18;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4880) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
*(_QWORD *)v2 = main___ptr_MzVm__init_func19;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4888) = v2;
}
runtime_newobject((__int64)&unk_9295E0);
result = (__int64 (__usercall **)@<rax>(__int64))v2;
*(_QWORD *)v2 = main___ptr_MzVm__init_func20;
if ( dword_A197D0 )
{
runtime_gcWriteBarrierCX();
return (__int64 (__usercall **)@<rax>(__int64))runtime_gcWriteBarrier();
}
else
{
*(_QWORD *)(v2 + 8) = a1;
*(_QWORD *)(a1 + 4896) = v2;
}
return result;
}

简单分析几个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int64 __usercall main___ptr_MzVm__init_func2@<rax>(__int64 a1)
{
__int64 v1; // rdx
__int64 v2; // rdx
__int64 result; // rax
__int64 v4; // [rsp+0h] [rbp-18h]

v2 = *(_QWORD *)(v1 + 8);
result = (unsigned int)a1;
if ( (unsigned int)a1 >= 0x15uLL )//存在0x14个寄存器
runtime_panicIndex(v4);
*(_DWORD *)(v2 + 4LL * (unsigned int)a1) = HIDWORD(a1);//取高位
return result;
}

func3 mov r[{Lnum}],r[{Rnum}]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
__int64 __usercall main___ptr_MzVm__init_func15@<rax>(__int64 a1)
{
__int64 v1; // rdx
__int64 v2; // rdx
__int64 result; // rax
__int64 v4; // [rsp+0h] [rbp-18h]

v2 = *(_QWORD *)(v1 + 8);
if ( (unsigned int)a1 >= 0x15uLL )
runtime_panicIndex(v4);
if ( HIDWORD(a1) >= 0x15uLL )
runtime_panicIndex(v4);
result = *(unsigned int *)(v2 + 4LL * HIDWORD(a1));
if ( (_DWORD)result != *(_DWORD *)(v2 + 4LL * (unsigned int)a1) )
{
result = (unsigned int)(3 * *(_DWORD *)(v2 + 76));
*(_DWORD *)(v2 + 4084) = result;
}
return result;
}

这个明显是个对比函数,cmp R[{num}] R[{right}], jne R[19]

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
op=[[0, 0, 0], [0, 0, 0], [1, 0, 87], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 108], [98, 0, 0], [1, 0, 99], [98, 0, 0], [1, 0, 111], [98, 0, 0], [1, 0, 109], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 116], [98, 0, 0], [1, 0, 111], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 86], [98, 0, 0], [1, 0, 78], [98, 0, 0], [1, 0, 67], [98, 0, 0], [1, 0, 84], [98, 0, 0], [1, 0, 70], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 48], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 33], [98, 0, 0], [1, 0, 10], [98, 0, 0], [1, 0, 105], [98, 0, 0], [1, 0, 110], [98, 0, 0], [1, 0, 112], [98, 0, 0], [1, 0, 117], [98, 0, 0], [1, 0, 116], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 102], [98, 0, 0], [1, 0, 108], [98, 0, 0], [1, 0, 97], [98, 0, 0], [1, 0, 103], [98, 0, 0], [1, 0, 58], [98, 0, 0], [1, 0, 10], [98, 0, 0], [1, 19, 73], [1, 3, 0], [1, 1, 43], [1, 2, 1], [97, 0, 0], [5, 0, 0], [8, 1, 2], [14, 1, 3], [1, 0, 0], [5, 0, 0], [0, 0, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [2, 0, 6], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [2, 0, 6], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [2, 0, 7], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [2, 0, 7], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [2, 0, 8], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [2, 0, 8], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [2, 0, 9], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [2, 0, 9], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [2, 0, 10], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [2, 0, 10], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [2, 0, 11], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [2, 0, 11], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [2, 0, 12], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [2, 0, 12], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [2, 0, 13], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [2, 0, 13], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [2, 0, 14], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [2, 0, 14], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [2, 0, 15], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [2, 0, 15], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [2, 0, 16], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [2, 0, 16], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [0, 0, 0], [5, 6, 0], [5, 7, 0], [5, 8, 0], [5, 9, 0], [5, 10, 0], [5, 11, 0], [5, 12, 0], [5, 13, 0], [5, 14, 0], [5, 15, 0], [5, 16, 0], [6, 1, 0], [6, 2, 0], [1, 20, 284], [1, 0, 340], [12, 0, 0], [1, 0, 3906065887], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 4125344020], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 295], [1, 0, 340], [12, 0, 0], [1, 0, 579781142], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 2312395361], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 306], [1, 0, 340], [12, 0, 0], [1, 0, 1700499305], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 612671610], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 317], [1, 0, 340], [12, 0, 0], [1, 0, 3655723000], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 977540402], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 328], [1, 0, 340], [12, 0, 0], [1, 0, 2443935368], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 1778148540], [14, 2, 0], [6, 1, 0], [1, 0, 8206181], [14, 1, 0], [1, 0, 393], [12, 0, 0], [99, 0, 0], [1, 3, 2654435769], [1, 4, 613452], [1, 5, 34589], [1, 6, 108471], [1, 7, 1230791], [1, 8, 0], [1, 17, 16], [1, 18, 32], [1, 19, 352], [1, 10, 0], [1, 11, 32], [1, 12, 1], [7, 8, 3], [2, 0, 2], [10, 0, 17], [7, 0, 4], [2, 14, 0], [2, 0, 2], [7, 0, 8], [2, 15, 0], [2, 0, 2], [9, 0, 18], [7, 0, 5], [2, 16, 0], [2, 0, 14], [11, 0, 15], [11, 0, 16], [7, 1, 0], [2, 0, 1], [10, 0, 17], [7, 0, 6], [2, 14, 0], [2, 0, 1], [7, 0, 8], [2, 15, 0], [2, 0, 1], [9, 0, 18], [7, 0, 7], [2, 16, 0], [2, 0, 14], [11, 0, 15], [11, 0, 16], [7, 2, 0], [8, 11, 12], [14, 11, 10], [12, 20, 0], [0, 0, 0], [1, 0, 110], [98, 0, 0], [1, 0, 111], [98, 0, 0], [12, 20, 0], [0, 0, 0], [1, 0, 121], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 115], [98, 0, 0], [12, 20, 0]]
f=[]
for i in range(0,len(op),1):
if op[i][0] not in f:
f.append(op[i][0])
print(f)
for i in range(0,len(op)):

adr=op[i][0]
Lnum=op[i][1]
Rnum=op[i][2]
if adr==0:
print("%s: "%hex(i)+f"nop")
elif adr==1:
print("%s: "%hex(i)+f"mov r[{Lnum}],{hex(Rnum)}")
elif adr==2:
print("%s: "%hex(i)+f"mov r[{Lnum}],r[{Rnum}]")
elif adr==5:
print("%s: "%hex(i)+f"push r[{Lnum}]")
elif adr==6:
print("%s: "%hex(i)+f"pop r[{Lnum}]")
elif adr==7:
print("%s: "%hex(i)+f"add r[{Lnum}],r[{Rnum}]")
elif adr==8:
print("%s: "%hex(i)+f"sub r[{Lnum}],r[{Rnum}]")
elif adr==9:
print("%s: "%hex(i)+f"div r[{Lnum}],r[{Rnum}]")
elif adr==10:
print("%s: "%hex(i)+f"mul r[{Lnum}],r[{Rnum}]")
elif adr==11:
print("%s: "%hex(i)+f"xor r[{Lnum}],r[{Rnum}]")
elif adr==12:
print("%s: "%hex(i)+f"jmp r[{Lnum}]")
elif adr==14:
print("%s: "%hex(i)+f"cmp r[{Lnum}],r[{Rnum}] -- jnz r[19]")
elif adr==0x61:
print("%s: "%hex(i)+f"getchar(r[{Lnum}])")
elif adr==0x62:
print("%s: "%hex(i)+f'putchar(r[{Lnum})]')
elif adr==0x63:
print("%s: "%hex(i)+f"exit()")

得到:

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
0x0: nop
0x1: nop
0x2: mov r[0],0x57
0x3: putchar(r[0)]
0x4: mov r[0],0x65
0x5: putchar(r[0)]
0x6: mov r[0],0x6c
0x7: putchar(r[0)]
0x8: mov r[0],0x63
0x9: putchar(r[0)]
0xa: mov r[0],0x6f
0xb: putchar(r[0)]
0xc: mov r[0],0x6d
0xd: putchar(r[0)]
0xe: mov r[0],0x65
0xf: putchar(r[0)]
0x10: mov r[0],0x20
0x11: putchar(r[0)]
0x12: mov r[0],0x74
0x13: putchar(r[0)]
0x14: mov r[0],0x6f
0x15: putchar(r[0)]
0x16: mov r[0],0x20
0x17: putchar(r[0)]
0x18: mov r[0],0x56
0x19: putchar(r[0)]
0x1a: mov r[0],0x4e
0x1b: putchar(r[0)]
0x1c: mov r[0],0x43
0x1d: putchar(r[0)]
0x1e: mov r[0],0x54
0x1f: putchar(r[0)]
0x20: mov r[0],0x46
0x21: putchar(r[0)]
0x22: mov r[0],0x32
0x23: putchar(r[0)]
0x24: mov r[0],0x30
0x25: putchar(r[0)]
0x26: mov r[0],0x32
0x27: putchar(r[0)]
0x28: mov r[0],0x32
0x29: putchar(r[0)]
0x2a: mov r[0],0x21
0x2b: putchar(r[0)]
0x2c: mov r[0],0xa
0x2d: putchar(r[0)]
0x2e: mov r[0],0x69
0x2f: putchar(r[0)]
0x30: mov r[0],0x6e
0x31: putchar(r[0)]
0x32: mov r[0],0x70
0x33: putchar(r[0)]
0x34: mov r[0],0x75
0x35: putchar(r[0)]
0x36: mov r[0],0x74
0x37: putchar(r[0)]
0x38: mov r[0],0x20
0x39: putchar(r[0)]
0x3a: mov r[0],0x66
0x3b: putchar(r[0)]
0x3c: mov r[0],0x6c
0x3d: putchar(r[0)]
0x3e: mov r[0],0x61
0x3f: putchar(r[0)]
0x40: mov r[0],0x67
0x41: putchar(r[0)]
0x42: mov r[0],0x3a
0x43: putchar(r[0)]
0x44: mov r[0],0xa
0x45: putchar(r[0)] //输出函数,下面要输入了
0x46: mov r[19],0x49
0x47: mov r[3],0x0
0x48: mov r[1],0x2b //循环43次,知道了字符串长度
0x49: mov r[2],0x1
0x4a: getchar(r[0])//获取输入
0x4b: push r[0]
0x4c: sub r[1],r[2] //循环递减
0x4d: cmp r[1],r[3] -- jnz r[19]
0x4e: mov r[0],0x0
0x4f: push r[0] //多push⼀个0,44个byte转成11个int
0x50: nop
0x51: nop // 检验flag
0x52: pop r[0]
0x53: mov r[5],0x100 // 2的8次⽅,⽤于代替位移运算
0x54: mul r[0],r[5] // r0=r0*256 -> << 8
0x55: mov r[6],r[0] // r6=r0
0x56: pop r[0] // 将输⼊从末尾取出来
0x57: add r[6],r[0] // 加上之前的
0x58: mov r[0],r[6]
0x59: mul r[0],r[5]
0x5a: mov r[6],r[0] // 再次位移后放到r6
0x5b: pop r[0]
0x5c: add r[6],r[0]
0x5d: mov r[0],r[6]
0x5e: mul r[0],r[5]
0x5f: mov r[6],r[0]
0x60: pop r[0]
0x61: add r[6],r[0]
0x62: nop //用nop分割,下面是重复上面的
0x63: pop r[0]
0x64: mov r[5],0x100
0x65: mul r[0],r[5]
0x66: mov r[7],r[0]
0x67: pop r[0]
0x68: add r[7],r[0]
0x69: mov r[0],r[7]
0x6a: mul r[0],r[5]
0x6b: mov r[7],r[0]
0x6c: pop r[0]
0x6d: add r[7],r[0]
0x6e: mov r[0],r[7]
0x6f: mul r[0],r[5]
0x70: mov r[7],r[0]
0x71: pop r[0]
0x72: add r[7],r[0]
0x73: nop
0x74: pop r[0]
0x75: mov r[5],0x100
0x76: mul r[0],r[5]
0x77: mov r[8],r[0]
0x78: pop r[0]
0x79: add r[8],r[0]
0x7a: mov r[0],r[8]
0x7b: mul r[0],r[5]
0x7c: mov r[8],r[0]
0x7d: pop r[0]
0x7e: add r[8],r[0]
0x7f: mov r[0],r[8]
0x80: mul r[0],r[5]
0x81: mov r[8],r[0]
0x82: pop r[0]
0x83: add r[8],r[0]
0x84: nop
0x85: pop r[0]
0x86: mov r[5],0x100
0x87: mul r[0],r[5]
0x88: mov r[9],r[0]
0x89: pop r[0]
0x8a: add r[9],r[0]
0x8b: mov r[0],r[9]
0x8c: mul r[0],r[5]
0x8d: mov r[9],r[0]
0x8e: pop r[0]
0x8f: add r[9],r[0]
0x90: mov r[0],r[9]
0x91: mul r[0],r[5]
0x92: mov r[9],r[0]
0x93: pop r[0]
0x94: add r[9],r[0]
0x95: nop
0x96: pop r[0]
0x97: mov r[5],0x100
0x98: mul r[0],r[5]
0x99: mov r[10],r[0]
0x9a: pop r[0]
0x9b: add r[10],r[0]
0x9c: mov r[0],r[10]
0x9d: mul r[0],r[5]
0x9e: mov r[10],r[0]
0x9f: pop r[0]
0xa0: add r[10],r[0]
0xa1: mov r[0],r[10]
0xa2: mul r[0],r[5]
0xa3: mov r[10],r[0]
0xa4: pop r[0]
0xa5: add r[10],r[0]
0xa6: nop
0xa7: pop r[0]
0xa8: mov r[5],0x100
0xa9: mul r[0],r[5]
0xaa: mov r[11],r[0]
0xab: pop r[0]
0xac: add r[11],r[0]
0xad: mov r[0],r[11]
0xae: mul r[0],r[5]
0xaf: mov r[11],r[0]
0xb0: pop r[0]
0xb1: add r[11],r[0]
0xb2: mov r[0],r[11]
0xb3: mul r[0],r[5]
0xb4: mov r[11],r[0]
0xb5: pop r[0]
0xb6: add r[11],r[0]
0xb7: nop
0xb8: pop r[0]
0xb9: mov r[5],0x100
0xba: mul r[0],r[5]
0xbb: mov r[12],r[0]
0xbc: pop r[0]
0xbd: add r[12],r[0]
0xbe: mov r[0],r[12]
0xbf: mul r[0],r[5]
0xc0: mov r[12],r[0]
0xc1: pop r[0]
0xc2: add r[12],r[0]
0xc3: mov r[0],r[12]
0xc4: mul r[0],r[5]
0xc5: mov r[12],r[0]
0xc6: pop r[0]
0xc7: add r[12],r[0]
0xc8: nop
0xc9: pop r[0]
0xca: mov r[5],0x100
0xcb: mul r[0],r[5]
0xcc: mov r[13],r[0]
0xcd: pop r[0]
0xce: add r[13],r[0]
0xcf: mov r[0],r[13]
0xd0: mul r[0],r[5]
0xd1: mov r[13],r[0]
0xd2: pop r[0]
0xd3: add r[13],r[0]
0xd4: mov r[0],r[13]
0xd5: mul r[0],r[5]
0xd6: mov r[13],r[0]
0xd7: pop r[0]
0xd8: add r[13],r[0]
0xd9: nop
0xda: pop r[0]
0xdb: mov r[5],0x100
0xdc: mul r[0],r[5]
0xdd: mov r[14],r[0]
0xde: pop r[0]
0xdf: add r[14],r[0]
0xe0: mov r[0],r[14]
0xe1: mul r[0],r[5]
0xe2: mov r[14],r[0]
0xe3: pop r[0]
0xe4: add r[14],r[0]
0xe5: mov r[0],r[14]
0xe6: mul r[0],r[5]
0xe7: mov r[14],r[0]
0xe8: pop r[0]
0xe9: add r[14],r[0]
0xea: nop
0xeb: pop r[0]
0xec: mov r[5],0x100
0xed: mul r[0],r[5]
0xee: mov r[15],r[0]
0xef: pop r[0]
0xf0: add r[15],r[0]
0xf1: mov r[0],r[15]
0xf2: mul r[0],r[5]
0xf3: mov r[15],r[0]
0xf4: pop r[0]
0xf5: add r[15],r[0]
0xf6: mov r[0],r[15]
0xf7: mul r[0],r[5]
0xf8: mov r[15],r[0]
0xf9: pop r[0]
0xfa: add r[15],r[0]
0xfb: nop
0xfc: pop r[0]
0xfd: mov r[5],0x100
0xfe: mul r[0],r[5]
0xff: mov r[16],r[0]
0x100: pop r[0]
0x101: add r[16],r[0]
0x102: mov r[0],r[16]
0x103: mul r[0],r[5]
0x104: mov r[16],r[0]
0x105: pop r[0]
0x106: add r[16],r[0]
0x107: mov r[0],r[16]
0x108: mul r[0],r[5]
0x109: mov r[16],r[0]
0x10a: pop r[0]
0x10b: add r[16],r[0]
0x10c: nop
0x10d: push r[6]
0x10e: push r[7]
0x10f: push r[8]
0x110: push r[9]
0x111: push r[10]
0x112: push r[11]
0x113: push r[12]
0x114: push r[13]
0x115: push r[14]
0x116: push r[15]
0x117: push r[16] //十个值在寄存器中,此时全部转化为了uint32 将他们全部压栈
0x118: pop r[1]
0x119: pop r[2] //调用两个参数
0x11a: mov r[20],0x11c
0x11b: mov r[0],0x154
0x11c: jmp r[0]
0x11d: mov r[0],0xe8d1d5df // 对⽐结果
0x11e: mov r[19],0x183 // 错误输出的地址
0x11f: mov r[20],0x153 // 返回地址,直接结束
0x120: cmp r[1],r[0] -- jnz r[19] // ⽐较,不同就到错误输出
0x121: mov r[0],0xf5e3c114
0x122: cmp r[2],r[0] -- jnz r[19] // ⽐较,不同就到错误输出
0x123: pop r[1] ---------------------------第⼆轮加密和比较以此类推
0x124: pop r[2]
0x125: mov r[20],0x127
0x126: mov r[0],0x154
0x127: jmp r[0]
0x128: mov r[0],0x228ec216
0x129: mov r[19],0x183
0x12a: mov r[20],0x153
0x12b: cmp r[1],r[0] -- jnz r[19]
0x12c: mov r[0],0x89d45a61
0x12d: cmp r[2],r[0] -- jnz r[19]
0x12e: pop r[1]
0x12f: pop r[2]
0x130: mov r[20],0x132
0x131: mov r[0],0x154
0x132: jmp r[0]
0x133: mov r[0],0x655b8f69
0x134: mov r[19],0x183
0x135: mov r[20],0x153
0x136: cmp r[1],r[0] -- jnz r[19]
0x137: mov r[0],0x2484a07a
0x138: cmp r[2],r[0] -- jnz r[19]
0x139: pop r[1]
0x13a: pop r[2]
0x13b: mov r[20],0x13d
0x13c: mov r[0],0x154
0x13d: jmp r[0]
0x13e: mov r[0],0xd9e5e7f8
0x13f: mov r[19],0x183
0x140: mov r[20],0x153
0x141: cmp r[1],r[0] -- jnz r[19]
0x142: mov r[0],0x3a441532
0x143: cmp r[2],r[0] -- jnz r[19]
0x144: pop r[1]
0x145: pop r[2]
0x146: mov r[20],0x148
0x147: mov r[0],0x154
0x148: jmp r[0]
0x149: mov r[0],0x91ab7e88
0x14a: mov r[19],0x183
0x14b: mov r[20],0x153
0x14c: cmp r[1],r[0] -- jnz r[19]
0x14d: mov r[0],0x69fc64bc
0x14e: cmp r[2],r[0] -- jnz r[19]
0x14f: pop r[1]
0x150: mov r[0],0x7d3765
0x151: cmp r[1],r[0] -- jnz r[19]
0x152: mov r[0],0x189
0x153: jmp r[0]
0x154: exit()
0x155: mov r[3],0x9e3779b9 //delta,太经典了
0x156: mov r[4],0x95c4c //key1
0x157: mov r[5],0x871d //key2
0x158: mov r[6],0x1a7b7 //key3
0x159: mov r[7],0x12c7c7 //key4
0x15a: mov r[8],0x0 // sum
0x15b: mov r[17],0x10 // 常量16 ⽤于位移4
0x15c: mov r[18],0x20 // 常量32 ⽤于位移5
0x15d: mov r[19],0x160
0x15e: mov r[10],0x0 //⽤来对⽐次数
0x15f: mov r[11],0x20 //循环次数32次 加密轮数
0x160: mov r[12],0x1 // 跳转回这⾥的下⼀⾏
0x161: add r[8],r[3] // sum += delta
0x162: mov r[0],r[2]
0x163: mul r[0],r[17]
0x164: add r[0],r[4]
0x165: mov r[14],r[0]
0x166: mov r[0],r[2]
0x167: add r[0],r[8]
0x168: mov r[15],r[0]
0x169: mov r[0],r[2]
0x16a: div r[0],r[18]
0x16b: add r[0],r[5]
0x16c: mov r[16],r[0]
0x16d: mov r[0],r[14]
0x16e: xor r[0],r[15]
0x16f: xor r[0],r[16]
0x170: add r[1],r[0]
0x171: mov r[0],r[1]
0x172: mul r[0],r[17]
0x173: add r[0],r[6]
0x174: mov r[14],r[0]
0x175: mov r[0],r[1]
0x176: add r[0],r[8]
0x177: mov r[15],r[0]
0x178: mov r[0],r[1]
0x179: div r[0],r[18]
0x17a: add r[0],r[7]
0x17b: mov r[16],r[0]
0x17c: mov r[0],r[14]
0x17d: xor r[0],r[15]
0x17e: xor r[0],r[16]
0x17f: add r[2],r[0]
0x180: sub r[11],r[12]
0x181: cmp r[11],r[10] -- jnz r[19]
0x182: jmp r[20] // jmp r20 函数返回
0x183: nop
0x184: mov r[0],0x6e
0x185: putchar(r[0)]
0x186: mov r[0],0x6f
0x187: putchar(r[0)]
0x188: jmp r[20]
0x189: nop
0x18a: mov r[0],0x79
0x18b: putchar(r[0)]

这个delta一出来,应该是个tea加密,key也有了,我们解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdint.h>
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
int main()
{
uint32_t v[12] = {0xe8d1d5df, 0xf5e3c114, 0x228ec216, 0x89d45a61, 0x655b8f69, 0x2484a07a, 0xd9e5e7f8, 0x3a441532, 0x91ab7e88, 0x69fc64bc, 0x7d3765, 0x00};
uint32_t k[4] = {0x95c4c, 0x871d, 0x1a7b7, 0x12c7c7};
for (int i = 0; i < 5; ++i) {
decrypt(v+i*2, k);
}
printf("%s", (char*)v);
}

得到flag:VNCTF{ecd63ae5-8945-4ac4-b5a5-34fc3ade81e7}

从这道题,还学会了稍微恢复一下vm,即创造结构体。

1
if ( HIDWORD(a1) >= 0x15uLL )//我们能推测出寄存器个数

还可以推测栈的大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct func
{
void *call;
vm *ptr;
};
struct REG
{
_DWORD R[21];
};
struct vm
{
REG reg;
_DWORD Memory[1000];
_DWORD rip;
_DWORD index;
void *data;
func *func[100];
_QWORD isExit;
};

从而创建结构体,然后更好的分析。

未完待续

wasm

WebAssembly是一种全新的Web编程语言,但是与JavaScript不同,它不是一种让你直接手动编写的语言,而是C / C ++,Rust,C#和TypeScript等不断增加的上层语言的编译目标。

wasm是基于堆栈的虚拟机的二进制指令格式

  • wat2wasm:从WebAssembly文本格式转换为 WebAssembly二进制格式
  • wasm2watwat2wasm的逆函数,从二进制格式转换回文本格式(也称为.wat)
  • wasm-objdump:显示有关wasm二进制文件的信息。与objdump类似。
  • wasm-interp:使用基于堆栈的解释器解码并运行WebAssembly二进制文件
  • wasm-decompile:将wasm二进制文件反编译为可读的类似C的语法。
  • wat- desugar:解析规范解释程序支持的.wat文本格式(S表达式,平面语法或混合格式)并打印“规范”平面格式
  • wasm2c:将WebAssembly二进制文件转换为C源代码和标头
  • wasm-strip:删除WebAssembly二进制文件的部分
  • wasm-validate:验证WebAssembly二进制格式的文件
  • wast2json:将wasm spec测试格式的文件转换为JSON文件和关联的wasm二进制文件
  • wasm-opcodecnt:计算指令的操作码使用量
  • spectest-interp:读取Spectest JSON文件,然后在解释器中运行其测

这种类型的题,主要是看处理阶段比较难办,分为两种方法

第一种就是静态分析

我们需要先下载wabt包,然后make一下,之后再进行对wasm文件的反编译

1
wasm2c xorwasm.wasm -o xorwasm.c

然后得到还原的c文件和h头文件,之后将wasm-rt.h和wasm-rt-impl.h头⽂件移动到我们反编译出来的.c和.h⽂件夹下,采用gcc编译

1
gcc -c xorwasm.c -o xorwasm.o

得到的文件虽然不能执行,但可以静态分析。

第二种是动态分析

如果给了html文件,我们可以在google中直接调试,我们先在终端中起个指令:

1
python -m http.server -b localhost

然后就能分析了,打开网址,f12中的source,可以下断点

下完断点就刷新,发现断在了下断点的地方,然后进行调试:F8执⾏(等价于IDA的F9),F10单步步过,F11单步步⼊ ,右侧还有stack中有memory可以看。

OLLVM

控制流平坦化

如果不把ollvm给恢复,那么就很麻烦了,这个ollvm浅层的理解就是将几个跳转转换成很多switch,再搞很多分支,这样就显得很麻烦看起来,我们一般先对这些进行去除控制流平坦化,我们采用deplat.py文件进行去除,这个python文件运行是基于angr环境的。

操作:

先将文件放在deflat-master/flat_control_flow目录下,然后更改deplat文件的第十二行,换成文件路径。

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
#!/usr/bin/env python3

import sys
sys.path.append("..")

import argparse
import angr
import pyvex
import claripy
import struct
from collections import defaultdict
sys.path.append('./normal12')//此处要更改
import am_graph
from util import *

import logging
logging.getLogger('angr.state_plugins.symbolic_memory').setLevel(logging.ERROR)
# logging.getLogger('angr.sim_manager').setLevel(logging.DEBUG)


def get_relevant_nop_nodes(supergraph, pre_dispatcher_node, prologue_node, retn_node):
# relevant_nodes = list(supergraph.predecessors(pre_dispatcher_node))
relevant_nodes = []
nop_nodes = []
for node in supergraph.nodes():
if supergraph.has_edge(node, pre_dispatcher_node) and node.size > 8:
# XXX: use node.size is faster than to create a block
relevant_nodes.append(node)
continue

进入ida找到main函数起始位置。

1
python deflat.py -f normal12 --addr 0x401040

使用上面命令,如果终端中出现success就行了,得到的文件很美妙!

socket

第一次减这样类型的题,而且这道题还很复杂。

给了两个文件,一个login一个check,很烦,先看login

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
void __fastcall __noreturn sub_401DB1(int a1, _QWORD *a2, __int64 a3, __int64 a4, int a5, int a6)
{
int v6; // edx
int v7; // ecx
int v8; // er8
int v9; // er9
__int64 v10; // rax
__int64 v11; // rax
char v12; // [rsp+0h] [rbp-810h]
unsigned int clientfd; // [rsp+10h] [rbp-800h]
int v14; // [rsp+14h] [rbp-7FCh]
__int64 v15; // [rsp+18h] [rbp-7F8h]
_QWORD server_addr[2]; // [rsp+20h] [rbp-7F0h] BYREF
__int64 v17[126]; // [rsp+30h] [rbp-7E0h] BYREF
u32 uaddr2[2]; // [rsp+420h] [rbp-3F0h] BYREF
__int64 v19; // [rsp+428h] [rbp-3E8h]
char v20[984]; // [rsp+430h] [rbp-3E0h] BYREF
unsigned __int64 v21; // [rsp+808h] [rbp-8h]

v12 = (char)a2;
v21 = __readfsqword(0x28u);
memset(v17, 0, 1000);
*(_QWORD *)uaddr2 = 0LL;
v19 = 0LL;
memset(v20, 0, sizeof(v20));
if ( a1 != 2 )
{
printf((unsigned int)"Usage: %s <IP Address>\n", *a2, (unsigned int)v20, 0, a5, a6, (char)a2);
sub_410400(1LL);
}
v15 = sub_454A70(a2[1], a2, v20);
if ( !v15 )
sub_410400(1LL);
clientfd = socket(2LL, 1LL, 0LL);
if ( clientfd == -1 )
sub_410400(1LL);
server_addr[0] = 2LL;
server_addr[1] = 0LL;
*(_DWORD *)((char *)server_addr + 2) = (unsigned __int16)sub_454A60((unsigned __int16)dword_4DA120);// 端口1234
HIDWORD(server_addr[0]) = ***(_DWORD ***)(v15 + 24);// ip
if ( (unsigned int)connect(clientfd, server_addr, 16LL) == -1 )// connect请求
sub_410400(1LL);
while ( 1 )
{
v14 = sub_454550(clientfd, v17, 1000LL, 0LL);
if ( v14 < 0 )
break;
*((_BYTE *)v17 + v14) = 0;
printf((unsigned int)"%s", (unsigned int)v17 + 1, v6, v7, v8, v9, v12);
if ( LOBYTE(v17[0]) == '0' )
{
sub_450F60(clientfd); // 退出
sub_410400(0LL);
}
if ( LOBYTE(v17[0]) == '2' )
{
v10 = sub_4011B0(a52096ad53036a5);
send(clientfd, a52096ad53036a5, v10, 0LL);// 发送过去hex字符串
}
scanf(uaddr2); // 输入
v11 = sub_4011B0(uaddr2);
send(clientfd, uaddr2, v11, 0LL); // 发送输入
}
sub_410400(1LL);
}

这是一个socket发送字符串的程序

socket编程是一门技术,它主要是在网络通信中经常用到,我的理解是用户在tcp/ip的基础上通过socket进行信息交互

image-20220329202342794

一般socket使用时先传送端口再传送ip,在发送connect请求

1
2
3
int socket(int domain, int type, int protocol);
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

connect函数反编译后:

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
unsigned __int64 __fastcall connect(int a1, struct sockaddr *a2, int a3)
{
unsigned __int64 result; // rax
unsigned __int64 v4; // rax
unsigned int v5; // er8
unsigned int fd; // [rsp+8h] [rbp-10h]

if ( __readfsdword(0x18u) )
{
sub_47CDF0();
v4 = sys_connect(a1, a2, a3);
if ( v4 > 0xFFFFFFFFFFFFF000LL )
{
__writefsdword(0xFFFFFFB0, -(int)v4);
LODWORD(v4) = -1;
}
fd = v4;
sub_47CE50(v5);
return fd;
}
else
{
result = sys_connect(a1, a2, a3);
if ( result > 0xFFFFFFFFFFFFF000LL )
{
__writefsdword(0xFFFFFFB0, -(int)result);
return 0xFFFFFFFFLL;
}
}
return result;
}

限定了我们第一个发过去的必须是2,如果不是就退出,我们查看发送的东西

image-20220329202855655

这个0x52很明显是aes的INV_SBOX,这个还是能看出来的。

看完login再看server的check

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
__int64 sub_405DA7()
{
int v0; // edx
int v1; // ecx
int v2; // er8
int v3; // er9
__int64 result; // rax
int v5; // [rsp+Ch] [rbp-44h] BYREF
int v6; // [rsp+10h] [rbp-40h] BYREF
unsigned int listenfd; // [rsp+14h] [rbp-3Ch]
unsigned int v8; // [rsp+18h] [rbp-38h]
int v9; // [rsp+1Ch] [rbp-34h]
_QWORD v10[2]; // [rsp+20h] [rbp-30h] BYREF
struct sockaddr clientaddr; // [rsp+30h] [rbp-20h] BYREF
unsigned __int64 v12; // [rsp+48h] [rbp-8h]

v12 = __readfsqword(0x28u);
listenfd = sub_55C220(2LL, 1LL, 0LL);
if ( listenfd == -1 )
exit(1);
v6 = 2;
sub_55C1F0(listenfd, 1LL, 2LL, &v6, 4LL);
v10[0] = 2LL;
v10[1] = 0LL;
WORD1(v10[0]) = sub_55CCC0((unsigned __int16)dword_609150);// 端口1234
HIDWORD(v10[0]) = sub_55CCB0(0LL);
if ( (unsigned int)sub_55C010(listenfd, v10, 16LL) == -1 )
exit(1);
if ( (unsigned int)sub_55C040(listenfd, 100LL) == -1 )
exit(1);
sub_4FDD90("\n----------------Welcome----------------");
v5 = 16;
while ( 1 )
{
v8 = accept(listenfd, &clientaddr, &v5);
if ( !v8 )
break;
if ( v8 == -1 )
exit(1);
v9 = fork(); // 创建子进程来处理接收到的内容
if ( v9 <= 0 )
{
if ( !v9 )
{
sub_559590(0, (unsigned int)&clientaddr, v0, v1, v2, v3);// 函数看不懂
close(listenfd);
sub_405F6A(v8, *(_QWORD *)&clientaddr.sa_family, *(_QWORD *)&clientaddr.sa_data[6]);// 这个是重点
exit(0);
}
exit(0);
}
close(v8);
}
result = 0LL;
if ( __readfsqword(0x28u) != v12 )
sub_55CC60();
return result;
}

经典fork函数

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
__int64 fork()
{
unsigned int v0; // ebp
_BOOL4 v1; // er12
unsigned __int64 v2; // rax
__int64 v3; // r9
unsigned int v4; // er13
__int64 i; // rbp
_QWORD *v6; // rax

v0 = __readfsdword(0x18u);
v1 = v0 != 0;
sub_571900(0LL, v0 != 0);
if ( v0 )
{
sub_507EF0();
if ( sub_50D8B0 )
sub_50D8B0();
}
v2 = sys_clone(0x1200011uLL, 0LL, 0LL, (void *)(__readfsqword(0x10u) + 720));
if ( v2 > 0xFFFFFFFFFFFFF000LL )
{
v4 = -1;
__writefsdword(0xFFFFFFC0, -(int)v2);
}
else
{
v4 = v2;
if ( !(_DWORD)v2 )
{
if ( qword_610A40 )
*(_QWORD *)qword_610A40 += 4LL;
*(__m128i *)(v3 + 728) = _mm_unpacklo_epi64(
(__m128i)(unsigned __int64)(v3 + 736),
(__m128i)(unsigned __int64)(v3 + 736));
if ( v0 )
{
if ( sub_50DA20 )
sub_50DA20();
for ( i = sub_507EB0(); i != sub_507EC0(); i = sub_507ED0(i) )
{
if ( (BYTE1(*(_DWORD *)sub_507EE0(i)) & 0x80u) == 0 )
{
v6 = *(_QWORD **)(sub_507EE0(i) + 136);
*v6 = 0LL;
v6[1] = 0LL;
}
}
sub_507FB0();
}
qword_60A660 = 0LL;
xmmword_60A650 = 0LL;
xmmword_60A640 = 0LL;
LODWORD(xmmword_60A650) = 1;
sub_571900(1LL, v1);
return v4;
}
}
if ( v0 )
{
if ( sub_50D960 )
sub_50D960();
sub_507F50();
}
sub_571900(2LL, v0 != 0);
return v4;
}

我们直接看主函数

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
unsigned __int64 __fastcall sub_405F6A(unsigned int connfd, __int64 a2, __int64 a3)
{
__int64 v3; // rax
__int64 *v4; // rsi
__int64 v5; // rax
__int64 v7; // rax
__int64 v8; // rax
unsigned __int64 result; // rax
int v12; // [rsp+28h] [rbp-898h]
int len; // [rsp+28h] [rbp-898h]
int lena; // [rsp+28h] [rbp-898h]
int v15; // [rsp+2Ch] [rbp-894h]
char token[32]; // [rsp+30h] [rbp-890h] BYREF
char psd[32]; // [rsp+50h] [rbp-870h] BYREF
char v18[48]; // [rsp+70h] [rbp-850h] BYREF
char v19[64]; // [rsp+A0h] [rbp-820h] BYREF
__int64 psd_1[126]; // [rsp+E0h] [rbp-7E0h] BYREF
__int64 token_1[125]; // [rsp+4D0h] [rbp-3F0h] BYREF
unsigned __int64 v22; // [rsp+8B8h] [rbp-8h]

v22 = __readfsqword(0x28u);
memset(psd_1, 0, 1000);
memset(token_1, 0, sizeof(token_1));
strcpy(token, "Please enter the token: "); // 输入token
strcpy(psd, "Please input the password: "); // 输入密码
strcpy(v19, "Login successful.\nNow, you can enter flag to verify: ");
strcpy(v18, "Forbidden, wrong token or password.\n");
send(connfd, "1", 1uLL, 0);
v3 = sub_401118((__int64)token);
send(connfd, token, v3, 0);
v4 = token_1;
v12 = sub_55C070(connfd, token_1, 1000LL, 0LL);// 接收token,应该是长度
if ( v12 >= 0 )
{
*((_BYTE *)token_1 + v12) = 0;
send(connfd, "1", 1uLL, 0);
v5 = sub_401118((__int64)psd);
send(connfd, psd, v5, 0);
v4 = psd_1;
len = sub_55C070(connfd, psd_1, 1000LL, 0LL);// 接受psd的
if ( len >= 0 )
{
*((_BYTE *)psd_1 + len) = 0;
if ( rsa((__int64)token_1) && (unsigned int)pswcheck((__int64)psd_1) )// psdcheck
{
send(connfd, "2", 1uLL, 0);
v7 = sub_401118((__int64)v19);
send(connfd, v19, v7, 0);
v4 = (__int64 *)INV_SBOX;
lena = sub_55C070(connfd, INV_SBOX, 1000LL, 0LL);// 接受发送过来的INV_SBOX
if ( lena >= 0 )
{
INV_SBOX[lena] = 0;
sub_4058DB((__int64)INV_SBOX); // hex字符串转换成值
v15 = fork();
if ( v15 <= 0 )
{
if ( !v15 )
{
check(connfd, a2, a3, token_1, psd_1);
exit(0);
}
exit(0);
}
close(connfd);
}
}
else
{
send(connfd, "0", 1uLL, 0);
v8 = sub_401118((__int64)v18);
v4 = (__int64 *)v18;
send(connfd, v18, v8, 0);
}
}
}
close(connfd);
result = __readfsqword(0x28u) ^ v22;
if ( result )
sub_55CC60(connfd, v4);
return result;
}

sub_55C070传入的三个参数分别是connfd,客户端的ip和端口,要输入两个东西,要进行三个函数的逆向

第一个checkrsa:

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
_BOOL8 __fastcall sub_405A10(__int64 a1)
{
__int64 v1; // rax
_BOOL8 result; // rax
char v3[16]; // [rsp+10h] [rbp-310h] BYREF
char v4[16]; // [rsp+20h] [rbp-300h] BYREF
char v5[16]; // [rsp+30h] [rbp-2F0h] BYREF
char v6[26]; // [rsp+40h] [rbp-2E0h] BYREF
char v7[70]; // [rsp+5Ah] [rbp-2C6h] BYREF
char v8[632]; // [rsp+A0h] [rbp-280h] BYREF
unsigned __int64 v9; // [rsp+318h] [rbp-8h]

v9 = __readfsqword(0x28u);
strcpy(
v8,
"13123058934861171416713230498081453101147538789122070079961388806126697916963123413431108069961369055630747412550900"
"23940271082784791796087035865396294828238135174112188452839936976453044650993624026229024830522655211710058472661625"
"52929639711415105186785526790332203152463777462705158539879031845129488013974521045545898037256190760663399689993089"
"10127885089547678968793196148780382182445270838659078189316664538631875879022325427220682805580410213245364855569367"
"70291915788136708567728312473287462156937990127266216202578060866957754654833327476605875578644949127700234991859897"
"1841605936268030140638579388226573929");
strcpy(&v7[6], "By reading we enrich the mind, by conversation we polish it.");
strcpy(v7, "10001"); // e的值
sub_406990(v3, v8, 10LL);
v1 = sub_4057A9(&v7[6]);
sub_406990(v4, v1, 16LL);
sub_406990(v5, v7, 16LL);
sub_406990(v6, a1, 10LL);
sub_4069B0(v6, v6, v5, v3);
result = (unsigned int)sub_406910(v6, v4) == 0;
if ( __readfsqword(0x28u) != v9 )
sub_55CC60();
return result;
}

这里要注意,m转换成16进制要是小端序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from gmpy2 import*
from libnum import*
from Crypto.Util.number import long_to_bytes
import gmpy2
e=0x10001
p=98197216341757567488149177586991336976901080454854408243068885480633972200382596026756300968618883148721598031574296054706280190113587145906781375704611841087782526897314537785060868780928063942914187241017272444601926795083433477673935377466676026146695321415853502288291409333200661670651818749836420808033
q=133639826298015917901017908376475546339925646165363264658181838203059432536492968144231040597990919971381628901127402671873954769629458944972912180415794436700950304720548263026421362847590283353425105178540468631051824814390421486132775876582962969734956410033443729557703719598998956317920674659744121941513
n=p*q
m=0x2e7469206873696c6f70206577206e6f697461737265766e6f63207962202c646e696d2065687420686369726e6520657720676e6964616572207942
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=pow(m,int(d),n)
print(flag)
#n=13123058934861171416713230498081453101147538789122070079961388806126697916963123413431108069961369055630747412550900239402710827847917960870358653962948282381351741121884528399369764530446509936240262290248305226552117100584726616255292963971141510518678552679033220315246377746270515853987903184512948801397452104554589803725619076066339968999308910127885089547678968793196148780382182445270838659078189316664538631875879022325427220682805580410213245364855569367702919157881367085677283124732874621569379901272662162025780608669577546548333274766058755786449491277002349918598971841605936268030140638579388226573929

第二个函数是一个矩阵:

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
__int64 __fastcall sub_405BDE(__int64 a1)
{
__int64 result; // rax
int i; // [rsp+10h] [rbp-80h]
int j; // [rsp+14h] [rbp-7Ch]
unsigned int v4; // [rsp+18h] [rbp-78h]
int k; // [rsp+1Ch] [rbp-74h]
__int64 v6[4]; // [rsp+20h] [rbp-70h]
int v7; // [rsp+40h] [rbp-50h]
__int64 v8; // [rsp+50h] [rbp-40h]
__int64 v9; // [rsp+58h] [rbp-38h]
__int64 v10; // [rsp+60h] [rbp-30h]
__int64 v11; // [rsp+68h] [rbp-28h]
int v12; // [rsp+70h] [rbp-20h]
unsigned __int64 v13; // [rsp+78h] [rbp-18h]

v13 = __readfsqword(0x28u);
v6[0] = 0xA34C0F7A2E25DB71LL;
v6[1] = 0x7AA91B6E29AA226ALL;
v6[2] = 0x56AA0EF0802F278ALL;
v6[3] = 0x9AF6F2A9005859F7LL;
v7 = -918021042;
v8 = 0xFCF1BE5355A297A3LL; // 这里的对比函数没有删除
v9 = 0xE2E91314526B79F9LL;
v10 = 0x275708561F8E512DLL;
v11 = 0x75778252D0D405A7LL;
v12 = -313878245;
sub_4058DB(a1);
for ( i = 0; i <= 5; ++i )
{
for ( j = 0; j <= 5; ++j )
{
v4 = 0;
for ( k = 0; k <= 5; ++k )
v4 += *((unsigned __int8 *)v6 + 6 * i + k) * *(unsigned __int8 *)(6 * k + j + a1);// 矩阵相乘
if ( v4 % 0x101 != (int)sub_4F1880() % 255 )
{
result = 0LL;
goto LABEL_13;
}
}
}
result = 1LL;
LABEL_13:
if ( __readfsqword(0x28u) != v13 )
sub_55CC60();
return result;
}

矩阵 * 我们要求的 == random() % 255,而这个random%255已经存在,听师傅说好像没删。
我们采用z3来搞:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from z3 import*
s = Solver()
flag = [Int('flag%d'%i) for i in range(36)]
g=0
arr2 = [0xA3, 0x97, 0xA2, 0x55, 0x53, 0xBE, 0xF1, 0xFC, 0xF9, 0x79, 0x6B, 0x52,0x14, 0x13, 0xE9, 0xE2, 0x2D, 0x51, 0x8E, 0x1F, 0x56, 0x08, 0x57, 0x27, 0xA7, 0x05, 0xD4, 0xD0, 0x52, 0x82,0x77, 0x75, 0x1B, 0x99, 0x4A, 0xED]
arr1 = [0x71, 0xDB, 0x25, 0x2E, 0x7A, 0x0F,0x4C, 0xA3, 0x6A, 0x22, 0xAA, 0x29, 0x6E, 0x1B, 0xA9, 0x7A, 0x8A, 0x27,0x2F, 0x80, 0xF0, 0x0E, 0xAA, 0x56,0xF7, 0x59, 0x58, 0x00, 0xA9, 0xF2, 0xF6, 0x9A, 0x4E, 0x1C, 0x48, 0xC9]
for i in range(6):
for j in range(6):
data = 0
for k in range(6):
data += arr1[i * 6 + k] * flag[6 * k + j]
s.add(data % 257 == arr2[g])
g += 1

if s.check() == sat: #检查机制,如果有解就输出,无解就错误
m = s.model()
res = []
for i in range(36):
res.append(chr(m[flag[i]].as_long()))
s=''.join(res)
print(s)
else:
print("nope")

或者采用syj师傅的sage脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
arr1 = [[0x71, 0xDB, 0x25, 0x2E, 0x7A, 0x0F], 
[0x4C, 0xA3, 0x6A, 0x22, 0xAA, 0x29],
[0x6E, 0x1B, 0xA9, 0x7A, 0x8A, 0x27],
[0x2F, 0x80, 0xF0, 0x0E, 0xAA, 0x56],
[0xF7, 0x59, 0x58, 0x00, 0xA9, 0xF2],
[0xF6, 0x9A, 0x4E, 0x1C, 0x48, 0xC9]]

dst = [[0xA3, 0x97, 0xA2, 0x55, 0x53, 0xBE],
[0xF1, 0xFC, 0xF9, 0x79, 0x6B, 0x52],
[0x14, 0x13, 0xE9, 0xE2, 0x2D, 0x51],
[0x8E, 0x1F, 0x56, 0x08, 0x57, 0x27],
[0xA7, 0x05, 0xD4, 0xD0, 0x52, 0x82],
[0x77, 0x75, 0x1B, 0x99, 0x4A, 0xED]]

arr1 = Matrix(Zmod(257), arr1)
dst = Matrix(Zmod(257), dst)
A = arr1.solve_right(dst)
print(A)

得到矩阵再转换成16进制5132d202c32d95b9f978d514e3294220513b15623482b4c02e9afde8bad5ec07486a5488

得到password

最后check分析,展示一下aes的函数:

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
unsigned __int64 __fastcall sub_4055C0(__int64 roundkeys, __int64 flag, __int64 a3, __int64 a4)
{
__int64 *v4; // rsi
int v5; // er8
int v6; // er9
unsigned __int64 result; // rax
int i; // [rsp+28h] [rbp-38h]
int j; // [rsp+28h] [rbp-38h]
int m; // [rsp+28h] [rbp-38h]
int k; // [rsp+2Ch] [rbp-34h]
__int64 v13[5]; // [rsp+30h] [rbp-30h] BYREF
unsigned __int64 v14; // [rsp+58h] [rbp-8h]
__int64 savedregs; // [rsp+60h] [rbp+0h] BYREF

v14 = __readfsqword(0x28u);
v13[0] = 0LL;
v13[1] = 0LL;
sub_404C1A(roundkeys, flag, a4); // flag的前16字节异或
sub_40554A(roundkeys, v13, flag); // 行列置换
sub_404F60(roundkeys, v13, roundkeys); // 轮密钥
for ( i = 1; ; ++i )
{
sub_404FF4(roundkeys, v13); // s盒字节代换
sub_405078(roundkeys, (__int64)v13); // 行移位
if ( i == 10 )
break;
sub_4053C8(roundkeys, v13); // 列混合
sub_404F60(roundkeys, v13, 16 * i + roundkeys);// 轮密钥加
}
v4 = v13;
sub_404F60(roundkeys, v13, roundkeys + 160);
for ( j = 0; j <= 3; ++j )
{
for ( k = 0; k <= 3; ++k )
*((_BYTE *)&savedregs + 4 * j + k - 32) = *((_BYTE *)&savedregs + 4 * k + j - 48);
}
for ( m = 0; m <= 15; ++m )
{
v4 = (__int64 *)"%02x";
roundkeys = a3 + 2 * m;
sub_4FC580(roundkeys, (unsigned int)"%02x", *((unsigned __int8 *)&v13[2] + m), roundkeys, v5, v6);
}
result = __readfsqword(0x28u) ^ v14;
if ( result )
sub_55CC60(roundkeys, v4);
return result;
}

这个第一次见还真不好搞出来是个aes

行列置换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__int64 __fastcall sub_40554A(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax
int i; // [rsp+20h] [rbp-8h]
int j; // [rsp+24h] [rbp-4h]

for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
result = i;
*(_BYTE *)(a2 + 4LL * j + i) = *(_BYTE *)(4 * i + j + a3);
}
}
return result;
}

轮密钥:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__int64 __fastcall sub_404F60(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax
int i; // [rsp+20h] [rbp-8h]
int j; // [rsp+24h] [rbp-4h]

for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
result = j;
*(_BYTE *)(a2 + 4LL * i + j) ^= *(_BYTE *)(4 * j + i + a3);
}
}
return result;
}

行移位:

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
bool __fastcall sub_405078(__int64 a1, __int64 a2)
{
int v2; // eax
bool result; // al
int i; // [rsp+10h] [rbp-10h]
int j; // [rsp+14h] [rbp-Ch]
int v6; // [rsp+18h] [rbp-8h]
char v7; // [rsp+1Ch] [rbp-4h]

for ( i = 1; i <= 3; ++i )
{
v6 = 0;
while ( 1 )
{
v2 = v6++;
result = i > v2;
if ( !result )
break;
v7 = *(_BYTE *)(4LL * i + a2);
for ( j = 1; j <= 3; ++j )
*(_BYTE *)(a2 + 4LL * i + j - 1) = *(_BYTE *)(a2 + 4LL * i + j);
*(_BYTE *)(a2 + 4LL * i + j - 1) = v7;
}
}
return result;
}

S盒替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__int64 __fastcall sub_404FF4(__int64 a1, __int64 a2)
{
__int64 result; // rax
int i; // [rsp+18h] [rbp-8h]
int j; // [rsp+1Ch] [rbp-4h]

for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
result = j;
*(_BYTE *)(a2 + 4LL * i + j) = INV_SBOX[*(unsigned __int8 *)(a2 + 4LL * i + j)];
}
}
return result;
}

列混合:

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
unsigned __int64 __fastcall sub_4053C8(__int64 a1, __int64 a2)
{
unsigned __int64 result; // rax
__int64 v3; // [rsp+0h] [rbp-40h]
__int64 v4; // [rsp+8h] [rbp-38h]
int i; // [rsp+14h] [rbp-2Ch]
int m; // [rsp+14h] [rbp-2Ch]
int j; // [rsp+18h] [rbp-28h]
int n; // [rsp+18h] [rbp-28h]
int k; // [rsp+1Ch] [rbp-24h]
__int64 v10; // [rsp+20h] [rbp-20h]
__int64 v11; // [rsp+28h] [rbp-18h]
unsigned __int64 v12; // [rsp+38h] [rbp-8h]
__int64 savedregs; // [rsp+40h] [rbp+0h] BYREF

v4 = a1;
v3 = a2;
v12 = __readfsqword(0x28u);
v10 = 0LL;
v11 = 0LL;
for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
for ( k = 0; k <= 3; ++k )
{
a2 = *(unsigned __int8 *)(v3 + 4LL * k + j);
a1 = v4;
*((_BYTE *)&savedregs + 4 * i + j - 32) ^= sub_405158(v4, a2, byte_5A4030[4 * i + k]);
}
}
}
for ( m = 0; m <= 3; ++m )
{
for ( n = 0; n <= 3; ++n )
*(_BYTE *)(4LL * m + v3 + n) = *((_BYTE *)&savedregs + 4 * m + n - 32);
}
result = __readfsqword(0x28u) ^ v12;
if ( result )
sub_55CC60(a1, a2);
return result;
}

轮密钥加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__int64 __fastcall sub_404F60(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax
int i; // [rsp+20h] [rbp-8h]
int j; // [rsp+24h] [rbp-4h]

for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
result = j;
*(_BYTE *)(a2 + 4LL * i + j) ^= *(_BYTE *)(4 * j + i + a3);
}
}
return result;
}

给出aes(256)解密脚本:

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define AES_BLOCK_SIZE 16
#define AES_ROUNDS 10 // 12, 14
#define AES_ROUND_KEY_SIZE 176 // AES-128 has 10 rounds, and there is a AddRoundKey before first round. (10+1)x16=176.

/*
* round constants
*/
static uint8_t RC[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};

/*
* Sbox
*/
static uint8_t SBOX[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};

/*
* Inverse Sboxs
*/
static uint8_t INV_SBOX[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};

void output_mem16(uint8_t* data)
{
int i;
for (i = 0; i < 16; ++i )
{
printf("%x ", *(data+i));
}
printf("\n");
}

static inline uint8_t mul2(uint8_t a)
{
return (a&0x80) ? ((a<<1)^0x1b) : (a<<1);
}

/*
0 1 2 3 《0
4 5 6 7 《1
8 9 10 11 《2
12 13 14 15 《3
*/
static void shift_rows(uint8_t *state) {
uint8_t temp;
// row1: 下标为1的行左移1
temp = *(state+4);
*(state+4) = *(state+5);
*(state+5) = *(state+6);
*(state+6) = *(state+7);
*(state+7) = temp;
// row2: 下标为2的行左移2
temp = *(state+8);
*(state+8) = *(state+10);
*(state+10) = temp;
temp = *(state+9);
*(state+9) = *(state+11);
*(state+11) = temp;
// row3: 下标为3的行左移3
temp = *(state+15);
*(state+15) = *(state+14);
*(state+14) = *(state+13);
*(state+13) = *(state+12);
*(state+12) = temp;
}

void aes_key_schedule_128(const uint8_t *key, uint8_t *roundkeys) {

uint8_t temp[4];
uint8_t *last4bytes; // point to the last 4 bytes of one round
uint8_t *lastround;
uint8_t i;

for (i = 0; i < 16; ++i) {
*roundkeys++ = *key++;
}

last4bytes = roundkeys-4;
for (i = 0; i < AES_ROUNDS; ++i) {
// k0-k3 for next round
temp[3] = SBOX[*last4bytes++];
temp[0] = SBOX[*last4bytes++];
temp[1] = SBOX[*last4bytes++];
temp[2] = SBOX[*last4bytes++];
temp[0] ^= RC[i];
lastround = roundkeys-16;
*roundkeys++ = temp[0] ^ *lastround++;
*roundkeys++ = temp[1] ^ *lastround++;
*roundkeys++ = temp[2] ^ *lastround++;
*roundkeys++ = temp[3] ^ *lastround++;
// k4-k7 for next round
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
// k8-k11 for next round
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
// k12-k15 for next round
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
*roundkeys++ = *last4bytes++ ^ *lastround++;
}
}

/**
* 列混合要用到的矩阵
*/
static const int colM[4][4] = { {2, 3, 1, 1},{1, 2, 3, 1},{1, 1, 2, 3},{3, 1, 1, 2 }};

static int GFMul2(int s) {
int result = s << 1;
int a7 = result & 0x00000100;

if(a7 != 0) {
result = result & 0x000000ff;
result = result ^ 0x1b;
}

return result;
}

static int GFMul3(int s) {
return GFMul2(s) ^ s;
}

static int GFMul4(int s) {
return GFMul2(GFMul2(s));
}

static int GFMul8(int s) {
return GFMul2(GFMul4(s));
}

static int GFMul9(int s) {
return GFMul8(s) ^ s;
}

static int GFMul11(int s) {
return GFMul9(s) ^ GFMul2(s);
}

static int GFMul12(int s) {
return GFMul8(s) ^ GFMul4(s);
}

static int GFMul13(int s) {
return GFMul12(s) ^ s;
}

static int GFMul14(int s) {
return GFMul12(s) ^ GFMul2(s);
}

/**
* GF上的二元运算
*/
static int GFMul(int n, int s) {
int result;

if(n == 1)
result = s;
else if(n == 2)
result = GFMul2(s);
else if(n == 3)
result = GFMul3(s);
else if(n == 0x9)
result = GFMul9(s);
else if(n == 0xb)//11
result = GFMul11(s);
else if(n == 0xd)//13
result = GFMul13(s);
else if(n == 0xe)//14
result = GFMul14(s);

return result;
}

void mixColumns(uint8_t array[4][4]) {

uint8_t tempArray[4][4];

for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
tempArray[i][j] = array[i][j];

for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++){
array[i][j] = GFMul(colM[i][0],tempArray[0][j]) ^ GFMul(colM[i][1],tempArray[1][j])
^ GFMul(colM[i][2],tempArray[2][j]) ^ GFMul(colM[i][3], tempArray[3][j]);
}
}

void aes_encrypt_128(const uint8_t *roundkeys, uint8_t *plaintext, uint8_t *ciphertext, uint8_t*iv)
{

uint8_t tmp[16];
uint8_t i, j, m, n;

//output_mem16(plaintext);
//和iv的16字节先进行异或
for ( i = 0; i < AES_BLOCK_SIZE; ++i )
{
*(plaintext+i) = *(plaintext+i) ^ *iv++;
}
//output_mem16(plaintext);

//矩阵转置
for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
tmp[4 * j + i] = plaintext[4 * i + j];
}
}
//output_mem16(tmp);

//first AddRoundKey
for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
tmp[4 * i + j] ^= roundkeys[4 * j + i];
}
}
//output_mem16(tmp);

// 9 rounds
for (j = 1; j < AES_ROUNDS; ++j)
{

// SubBytes
for (i = 0; i < AES_BLOCK_SIZE; ++i) {
*(tmp+i) = INV_SBOX[*(tmp+i)];
}

//shift_rows
shift_rows(tmp);

//MixColumns
mixColumns(tmp);

// AddRoundKey
for ( m = 0; m <= 3; ++m )
{
for ( n = 0; n <= 3; ++n )
{
tmp[4 * m + n] ^= roundkeys[16*j + 4 * n + m];
}
}
}

// last round
//output_mem16(tmp);
for (i = 0; i < AES_BLOCK_SIZE; ++i) {
*(ciphertext+i) = INV_SBOX[*(tmp+i)];
}
//output_mem16(ciphertext);
shift_rows(ciphertext);
//output_mem16(ciphertext);
for ( m = 0; m <= 3; ++m )
{
for ( n = 0; n <= 3; ++n )
{
ciphertext[4 * m + n] ^= roundkeys[16*j + 4 * n + m];
}
}

//output_mem16(ciphertext);
for ( m = 0; m <= 3; ++m ) //转置
{
for ( n = 0; n <= 3; ++n )
{
tmp[4 * n + m] = ciphertext[4 * m + n];
}
}

for ( i = 0; i < 16; ++i )
{
ciphertext[i] = tmp[i];
}
//output_mem16(ciphertext);
}

/**
* 逆列混合用到的矩阵
*/
static const int deColM[4][4] = {{0xe, 0xb, 0xd, 0x9},{0x9, 0xe, 0xb, 0xd},{0xd, 0x9, 0xe, 0xb},{0xb, 0xd, 0x9, 0xe}};

/**
* 逆列混合
*/
void deMixColumns(uint8_t array[4][4]) {
uint8_t tempArray[4][4];

for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
tempArray[i][j] = array[i][j];

for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++){
array[i][j] = GFMul(deColM[i][0],tempArray[0][j]) ^ GFMul(deColM[i][1],tempArray[1][j])
^ GFMul(deColM[i][2],tempArray[2][j]) ^ GFMul(deColM[i][3], tempArray[3][j]);
}
}

/*
0 1 2 3
5 6 7 4 4 5 6 7
10 11 8 9 8 9 10 11
15 12 13 14 12 13 14 15
*/
static void inv_shift_rows(uint8_t *state) {
uint8_t temp;
// row1
temp = *(state+4);
*(state+4) = *(state+7);
*(state+7) = *(state+6);
*(state+6) = *(state+5);
*(state+5) = temp;
// row2
temp = *(state+10);
*(state+10) = *(state+8);
*(state+8) = temp;
temp = *(state+11);
*(state+11) = *(state+9);
*(state+9) = temp;
// row3
temp = *(state+12);
*(state+12) = *(state+13);
*(state+13) = *(state+14);
*(state+14) = *(state+15);
*(state+15) = temp;
}

void aes_decrypt_128(const uint8_t *roundkeys, const uint8_t *ciphertext, uint8_t *plaintext, uint8_t*iv)
{

uint8_t tmp[16];
uint8_t t, u, v, m, n;
uint8_t i, j;

for ( m = 0; m <= 3; ++m ) //转置
{
for ( n = 0; n <= 3; ++n )
{
tmp[4 * n + m] = ciphertext[4 * m + n];
}
}
for ( m = 0; m <= 3; ++m )
{
for ( n = 0; n <= 3; ++n )
{
tmp[4 * m + n] ^= roundkeys[160 + 4 * n + m];
}
}
inv_shift_rows(tmp);
for (i = 0; i < AES_BLOCK_SIZE; ++i) {
*(plaintext+i) = SBOX[*(tmp+i)];
}

for (j = 9; j > 0; --j) {
// Inverse AddRoundKey
for ( m = 0; m <= 3; ++m )
{
for ( n = 0; n <= 3; ++n )
{
plaintext[4 * m + n] ^= roundkeys[16*j + 4 * n + m];
}
}
deMixColumns(plaintext);

// Inverse ShiftRows
inv_shift_rows(plaintext);

// Inverse SubBytes
for (i = 0; i < AES_BLOCK_SIZE; ++i) {
*(plaintext+i) = SBOX[*(plaintext+i)];
}
}

// last AddRoundKey
for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
plaintext[4 * i + j] ^= roundkeys[4 * j + i];
}
}
for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j <= 3; ++j )
{
tmp[4 * j + i] = plaintext[4 * i + j];
}
}
for ( i = 0; i < AES_BLOCK_SIZE; ++i )
{
*(plaintext+i) = *(tmp+i) ^ *iv++;
}
//output_mem16(plaintext);
}

int main(int argc, char *argv[])
{

uint8_t i, r;

uint8_t key[] =
{
50, 48, 7, 54, 106, 55, 120, 49, 72, 57, 66, 57, 20, 49, 213, 50
};
uint8_t iv1[16] = {98, 54, 249, 56, 66, 48, 195, 49, 106, 53, 72, 56, 52, 53, 84, 52};
uint8_t iv2[16] = {41, 52, 81, 54, 21, 57, 210, 56, 210, 57, 32, 49, 185, 50, 46, 48};
//uint8_t plaintext[] = {0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x37};//加密
uint8_t ciphertext1[AES_BLOCK_SIZE] = {254, 249, 231, 62, 246, 161, 35, 204, 87, 97, 193, 21, 119, 251, 156, 187};
uint8_t ciphertext2[AES_BLOCK_SIZE] = {202, 47, 177, 232, 79, 217, 7, 216, 12, 107, 234, 207, 232, 66, 162, 250};
uint8_t dec_data[AES_BLOCK_SIZE];
uint8_t roundkeys[AES_ROUND_KEY_SIZE];

// key schedule
aes_key_schedule_128(key, roundkeys);
printf("Round Keys:\n");
for ( r = 0; r <= AES_ROUNDS; r++ )
{
for (i = 0; i < AES_BLOCK_SIZE; i++) {
printf("%2x ", roundkeys[r*AES_BLOCK_SIZE+i]);
}
printf("\n");
}
printf("\n");

/*
//测试加密
aes_encrypt_128(roundkeys, plaintext, ciphertext, iv);
printf("Cipher data:\n");
for (i = 0; i < AES_BLOCK_SIZE; i++)
{
printf("%2x ", ciphertext[i]);
}
putchar(10);
*/

aes_decrypt_128(roundkeys, ciphertext1, dec_data, iv1);
printf("Decrypt data:\n");
for (i = 0; i < AES_BLOCK_SIZE; i++)
{
printf("%c", dec_data[i]);
}
aes_decrypt_128(roundkeys, ciphertext2, dec_data, iv2);
for (i = 0; i < AES_BLOCK_SIZE; i++)
{
printf("%c", dec_data[i]);
}
return 0;
}

得到:7026271d7bb5d404d63a72b88e6b4d63

Angr

有好几个题目,我们全部用angr来做,

00_angr_find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+1Ch] [ebp-1Ch]
char s1[9]; // [esp+23h] [ebp-15h] BYREF
unsigned int v6; // [esp+2Ch] [ebp-Ch]

v6 = __readgsdword(0x14u);
printf("Enter the password: ");
__isoc99_scanf("%8s", s1);
for ( i = 0; i <= 7; ++i )
s1[i] = complex_function(s1[i], i);
if ( !strcmp(s1, "ILIUFVJF") )
puts("Good Job.");
else
puts("Try again.");
return 0;
}

comlex函数中也就是一个if函数和return,并不难,如何用angr写脚本是一个难的问题

angr的使用也比较麻烦,因为angr带有z3,如果直接安装,会出现问题,这个z3与python的z3是由一点去别的,所以我们每次用都要搞一个虚拟环境,我们每次使用先打开虚拟环境:

其实只用后两个命令都行

1
2
3
4
5
6
cd
sudo apt-get install python-dev libffi-dev build-essential virtualenvwrapper
export WORKON_HOME=~/HOME
VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
mkvirtualenv --python=$(which python3) angr && pip install angr

这样就行了

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
import angr
import sys
def main(argv):
#目标文件路径
path_to_binary = './00_angr_find/00_angr_find'
#创建项目
project = angr.Project(path_to_binary)
#设置项目起点,entry_state是程序的入口处,相当于main
initial_state = project.factory.entry_state()
#设置模拟器
simulation = project.factory.simgr(initial_state)
#设置目标地址
print_good_addr = 0x08048694
simulation.explore(find=print_good_addr)

#如果到达目标地址,打印此时符号向量
if simulation.found:
solution_state = simulation.found[0]
print(solution_state.posix.dumps(sys.stdin.fileno()))

#无解或出错抛出异常
else:
raise Exception('Could not find solution')

if __name__ == '__main__':
main(sys.argv)
1
2
3
4
5
6
7
8
9
10
(angr) ┌─(~/syclover/angr/decode)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(jonathan@DESKTOP-4L3BSKM:pts/0)─┐
└─(12:51:45)──> python3 angr0.py
WARNING | 2022-03-12 12:53:13,212 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-12 12:53:13,212 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-12 12:53:13,212 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-12 12:53:13,212 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-12 12:53:13,212 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-12 12:53:13,213 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80486c1 (__libc_csu_init+0x1 in 00_angr_find (0x80486c1))
WARNING | 2022-03-12 12:53:14,270 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff50 with 4 unconstrained bytes referenced from 0x8186b80 (strcmp+0x0 in libc.so.6 (0x86b80))
b'IICLTGRK'

得到结果。

sys.argv

传递给Python脚本的命令行参数列表。argv[0]是脚本名称(依赖于操作系统,无论这是否是完整路径名)。如果使用-c解释器的命令行选项执行命令,argv[0]则将其设置为字符串’-c’。如果没有脚本名称传递给Python解释器,argv[0]则为空字符串。

这个就是命令行输入

if name == ‘main‘:

不能在import引用的脚本中执行。一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此 if name == ‘main’: 的作用就是控制这两种情况执行代码的过程,在 if name == ‘main’: 下的代码只有在第一种情况下

factory

angr中有许多使用时需要一个实例化的project的类,可以使用project.factory而不用把project到处传递。

states

Project对象只代表程序的一个初始化镜像,当你使用angr来执行时,你在使用一个表示模拟程序状态的一个特殊对象SimState

01_angr_avoid

通过字符串搜索到good job

这一题是明显让我们使用avoid,那么avoid其实就是告诉脚本不要走哪边。

主函数太大,无法反编译,估计是有很多别的路,所以要加avoid,我们可以用上一个脚本,但稍微改一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from doctest import FAIL_FAST
import angr
import sys

def main(argv):
path_to_binary = '../solutions/01_angr_avoid/01_angr_avoid'
project = angr.Project(path_to_binary)

initial_state = project.factory.entry_state()

simulation = project.factory.simgr(initial_state)
print_good_address = 0x080485FC
fail_address = 0x0804860E
simulation.explore(find=print_good_address,avoid=fail_address)
if simulation.found:
solution_state = simulation.found[0]
print(solution_state.posix.dumps(sys.stdin.fileno()))

else:
raise Exception('Could not find solution')

if __name__ == '__main__':
main(sys.argv)

我们只是在模拟器中添加了avoid。

1
2
3
4
5
6
7
8
9
WARNING | 2022-03-12 14:12:22,299 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-12 14:12:22,299 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-12 14:12:22,299 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-12 14:12:22,299 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-12 14:12:22,299 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-12 14:12:22,300 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80d45b1 (__libc_csu_init+0x1 in 01_angr_avoid (0x80d45b1))
WARNING | 2022-03-12 14:12:51,054 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff1d with 11 unconstrained bytes referenced from 0x8187170 (strncmp+0x0 in libc.so.6 (0x87170))
WARNING | 2022-03-12 14:12:51,054 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff40 with 4 unconstrained bytes referenced from 0x8187170 (strncmp+0x0 in libc.so.6 (0x87170))
b'JLVUSGJZ'

02_angr_find_condition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+18h] [ebp-40h]
int j; // [esp+1Ch] [ebp-3Ch]
char s1[20]; // [esp+24h] [ebp-34h] BYREF
char s2[20]; // [esp+38h] [ebp-20h] BYREF
unsigned int v8; // [esp+4Ch] [ebp-Ch]

v8 = __readgsdword(0x14u);
for ( i = 0; i <= 19; ++i )
s2[i] = 0;
qmemcpy(s2, "CAWMCZTB", 8);
printf("Enter the password: ");
__isoc99_scanf("%8s", s1);
for ( j = 0; j <= 7; ++j )
s1[j] = complex_function(s1[j], j + 8);
if ( !strcmp(s1, s2) )
puts("Good Job.");
else
puts("Try again.");
return 0;
}

这个题哦,看上去没啥区别,当我们找puts时,就会出现问题

这么多puts:good,应该怎么办,解决方法是通过判断控制台输出数据是不是”Good Job” 和”Try again” 来确认执行到了成功还是失败分支.即我们不再确认地址,我们只看输出是不是我们想要的

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
import sys
import angr
def main(argv):
path = '../solutions/02_angr_find_condition/02_angr_find_condition'
project = angr.Project(path)
state = project.factory.entry_state()
simulation = project.factory.simgr(state)

def good_job(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())

return 'Good Job' in str(stdout_output)
#含义就是在所有输出里找try again
def try_again(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())

return 'Try again' in str(stdout_output)

simulation.explore(find=good_job,avoid=try_again)

if simulation.found:
solution_state = simulation.found[0]
#下面是打印输入流,输出是stdout
print(solution_state.posix.dumps(sys.stdin.fileno()))
else:
raise Exception('NOooooooo!')

if __name__ == '__main__':
main(sys.argv)

1
2
3
4
5
6
7
8
9
WARNING | 2022-03-12 14:41:20,664 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-12 14:41:20,664 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-12 14:41:20,664 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-12 14:41:20,664 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-12 14:41:20,664 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-12 14:41:20,664 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x804d2a1 (__libc_csu_init+0x1 in 02_angr_find_condition (0x804d2a1))
WARNING | 2022-03-12 14:41:21,644 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff0d with 11 unconstrained bytes referenced from 0x8186b80 (strcmp+0x0 in libc.so.6 (0x86b80))
WARNING | 2022-03-12 14:41:21,644 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff30 with 4 unconstrained bytes referenced from 0x8186b80 (strcmp+0x0 in libc.so.6 (0x86b80))
b'OHYJUMBE'

03_angr_symbolic_registers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 user_input; // rax
int v5; // [esp+4h] [ebp-14h]
int v6; // [esp+8h] [ebp-10h]
int v7; // [esp+Ch] [ebp-Ch]
int v8; // [esp+Ch] [ebp-Ch]

printf("Enter the password: ");
user_input = get_user_input();
v7 = HIDWORD(user_input);
v5 = complex_function_1(user_input);
v6 = complex_function_2();
v8 = complex_function_3(v7);
if ( v5 || v6 || v8 )
puts("Try again.");
else
puts("Good Job.");
return 0;
}

三个complex,里面全是运算,有一点这三个函数只有两个有参数,但我们看汇编发现其实是有三个值,那么我们只需要求出eax,ebx,edx的值就行了

那么我们就要学会如何从寄存器中获得输入

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
import sys
import angr
import claripy
def main():
path = '../solutions/03_angr_symbolic_registers/03_angr_symbolic_registers'
project = angr.Project(path)
#自己设置项目起始地址
start_addr = 0x080488C7
state = project.factory.blank_state(addr=start_addr)

bit_lenth = 32
psd0 = claripy.BVS('psd0',bit_lenth)
psd1 = claripy.BVS('psd1',bit_lenth)
psd2 = claripy.BVS('psd2',bit_lenth)

state.regs.eax = psd0
state.regs.ebx = psd1
state.regs.edx = psd2

simulation = project.factory.simgr(state)

good_add = 0x0804892F
fail_add = 0x0804891D
simulation.explore(find=good_add,avoid=fail_add)

if simulation.found:
solution_state = simulation.found[0]
#如何进行寄存器输出
solution0 =solution_state.se.eval(psd0)
solution1 =solution_state.se.eval(psd1)
solution2 =solution_state.se.eval(psd2)
solution = ' '.join(map('{:x}'.format,[solution0,solution1,solution2]))
print(solution)
else:
raise Exception('Noooooooo!')
if __name__ == '__main__':
main()



最主要的是,如果我们要从寄存器中找数据,那么我们一定要自己把函数位置找到,因为寄存器是会变的。

初始化寄存器操作:

1
2
3
bit_length = 32
psd0 = claripy.BVS('psd0', bit_length)
initial_state.regs.eax = psd0

eval

是Python的一个内置函数,功能十分强大,这个函数的作用是,返回传入字符串的表达式的结果。就是说:将字符串当成有效的表达式 来求值 并 返回计算结果。

formamt

fotmat作为Python的的格式字符串函数,主要通过字符串中的花括号{},来识别替换字段,从而完成字符串的格式化。

上面主要是变成十六进制再连起来

1
2
3
4
5
6
7
8
WARNING | 2022-03-12 15:33:58,675 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-12 15:33:58,676 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-12 15:33:58,676 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-12 15:33:58,676 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-12 15:33:58,676 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-12 15:33:58,676 | angr.storage.memory_mixins.default_filler_mixin | Filling register ebp with 4 unconstrained bytes referenced from 0x80488c7 (main+0x26 in 03_angr_symbolic_registers (0x80488c7))
CRITICAL | 2022-03-12 15:33:59,119 | angr.sim_state | The name state.se is deprecated; please use state.solver.
e9b37483 7aab5fde 8f5b48ea

总结:

1
2
3
4
5
6
7
project.factory.blank_state(addr=start_address) => 创建自定义入口的状态上下文

initial_state.regs => 操作状态上下文的寄存器

claripy.BVS('变量名', 变量大小) => 创建求解变量

solution_state.se.eval(变量) => 求解符号变量

04_angr_symbolic_stack

这个题又不一样了,这个是局部变量

1
2
3
4
5
6
int __cdecl main(int argc, const char **argv, const char **envp)
{
printf("Enter the password: ");
handle_user();
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
int handle_user()
{
int v1; // [esp+8h] [ebp-10h] BYREF
int v2[3]; // [esp+Ch] [ebp-Ch] BYREF

__isoc99_scanf("%u %u", v2, &v1);
v2[0] = complex_function0(v2[0]);
v1 = complex_function1(v1);
if ( v2[0] == 2083606899 && v1 == -99478518 )
return puts("Good Job.");
else
return puts("Try again.");
}

我们知道局部变量是储存在栈中的,所以我们要构造栈上的内存

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
from mimetypes import init
import sys
import angr
import claripy


def main():
binary_path = '../solutions/04_angr_symbolic_stack/04_angr_symbolic_stack'
project = angr.Project(binary_path)

start_addr = 0x080486AE
initial_state = project.factory.blank_state(addr=start_addr)

initial_state.regs.ebp = initial_state.regs.esp # 初始化栈,令ebp等于esp

password0 = claripy.BVS('password0', 32) # 初始化两个位向量
password1 = claripy.BVS('password1', 32)

padding_length_in_bytes = 0x8 # 填充栈 integer * 2
initial_state.regs.esp -= padding_length_in_bytes

initial_state.stack_push(password0) # 将位向量压入栈中
initial_state.stack_push(password1)

simulation = project.factory.simgr(initial_state)

def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return b'Good Job' in stdout_output

def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return b'Try again' in stdout_output

simulation.explore(find=is_successful, avoid=should_abort)

if simulation.found:
solution_state = simulation.found[0]

solution0 = solution_state.se.eval(password0)
solution1 = solution_state.se.eval(password1)

solution = '%u %u' % (solution0, solution1)
print(solution)
else:
raise Exception('could not find the solution')

if __name__ == '__main__':
main()

符号化栈空间的运用:

1
2
3
4
5
6
initial_state.regs.ebp = initial_state.regs.esp # 初始化栈,令ebp等于esp

padding_length_in_bytes = 0xC # 填充栈
initial_state.regs.esp -= padding_length_in_bytes

initial_state.stack_push(password0) # 将位向量压入栈中

05_angr_symbolic_memory

这个题考的是bss段的输入,我们要构造bss段符号表示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+Ch] [ebp-Ch]

memset(user_input, 0, 0x21u);
printf("Enter the password: ");
__isoc99_scanf("%8s %8s %8s %8s", user_input, &unk_AB232C8, &unk_AB232D0, &unk_AB232D8);
for ( i = 0; i <= 31; ++i )
*(_BYTE *)(i + 179450560) = complex_function(*(char *)(i + 179450560), i);
if ( !strncmp(user_input, "OSIWHBXIFOQVSBZBISILSCLBIAXSEWUT", 0x20u) )
puts("Good Job.");
else
puts("Try again.");
return 0;
}
1
2
3
4
5
6
7
8
9
int __cdecl complex_function(int a1, int a2)
{
if ( a1 <= 64 || a1 > 90 )
{
puts("Try again.");
exit(1);
}
return (9 * a2 + a1 - 65) % 26 + 65;
}

给出脚本:

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
import angr
import sys
import claripy

def main(agrv):
path = '../solutions/05_angr_symbolic_memory/05_angr_symbolic_memory'
project = angr.Project(path)
adds = 0x08048618#scanf后
state = project.factory.blank_state(add=adds)
# 64 = 8(8个字符) * 1(每个字符一字节) * 8(每个字节8比特)
psd0 =claripy.BVS('psd0',64)
psd1 =claripy.BVS('psd1',64)
psd2 =claripy.BVS('psd2',64)
psd3 =claripy.BVS('psd3',64)

psd0_add = 0x0AB232C0
psd1_add = 0x0AB232C8
psd2_add = 0x0AB232D0
psd3_add = 0x0AB232D8

state.memory.store(psd0_add,psd0)#把位向量存入内存
state.memory.store(psd1_add,psd1)
state.memory.store(psd2_add,psd2)
state.memory.store(psd3_add,psd3)

simulation = project.factory.simgr(state)

def good_add(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job.' in str(stdout_output)

def fail_add(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again.' in str(stdout_output)

simulation.explore(find=good_add,avoid=fail_add)

if simulation.found:
solution_state = simulation.found[0]
solution0 = solution_state.se.eval(psd0)
solution1 = solution_state.se.eval(psd1)
solution2 = solution_state.se.eval(psd2)
solution3 = solution_state.se.eval(psd3)
solution = ' '.join(map('{:x}'.format, [ solution0, solution1,solution2,solution3 ]))
print(solution)
else:
raise Exception('Noooooooo!')

if __name__ == '__main__':
main(sys.argv)

1
2
3
4
5
6
7
8
9
10
11
12
WARNING | 2022-03-12 20:06:00,666 | angr.sim_state | Unused keyword arguments passed to SimState: add
WARNING | 2022-03-12 20:06:00,673 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-12 20:06:00,674 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-12 20:06:00,674 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-12 20:06:00,674 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-12 20:06:00,674 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-12 20:06:00,674 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7fff0000 with 4 unconstrained bytes referenced from 0x8048432 (_start+0x2 in 05_angr_symbolic_memory (0x8048432))
WARNING | 2022-03-12 20:06:00,675 | angr.storage.memory_mixins.default_filler_mixin | Filling register eax with 4 unconstrained bytes referenced from 0x8048438 (_start+0x8 in 05_angr_symbolic_memory (0x8048438))
WARNING | 2022-03-12 20:06:00,676 | angr.storage.memory_mixins.default_filler_mixin | Filling register edx with 4 unconstrained bytes referenced from 0x804843a (_start+0xa in 05_angr_symbolic_memory (0x804843a))
WARNING | 2022-03-12 20:06:00,746 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80486a1 (__libc_csu_init+0x1 in 05_angr_symbolic_memory (0x80486a1))
CRITICAL | 2022-03-12 20:06:05,988 | angr.sim_state | The name state.se is deprecated; please use state.solver.
0 0 0 0

06_angr_symbolic_dynamic_memory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+Ch] [ebp-Ch]

buffer0 = (char *)malloc(9u);
buffer1 = (char *)malloc(9u);
memset(buffer0, 0, 9u);
memset(buffer1, 0, 9u);
printf("Enter the password: ");
__isoc99_scanf("%8s %8s", buffer0, buffer1);
for ( i = 0; i <= 7; ++i )
{
buffer0[i] = complex_function(buffer0[i], i);
buffer1[i] = complex_function(buffer1[i], i + 32);
}
if ( !strncmp(buffer0, "OSIWHBXI", 8u) && !strncmp(buffer1, "FOQVSBZB", 8u) )
puts("Good Job.");
else
puts("Try again.");
free(buffer0);
free(buffer1);
return 0;
}

这次scanf() 有两个输入参数,数据保存的位置是通过全局变量的char* 指针来保存到buffer 中,大小为8 字节.我们主要是对buffer两个内存进行求解。我们如何将两块动态申请来的内存符号化,malloc申请的空间是动态的,但存放malloc的buffer是再bss段,属于静态,我们选择伪造指针使其指向一片可写的内存,将内存符号化

image-20220313151556700

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
import sys
import angr
import claripy
from operator import is_

def main():
path = '../solutions/06_angr_symbolic_dynamic_memory/06_angr_symbolic_dynamic_memory'
project = angr.Project(path)

start_address = 0x080486AF
state = project.factory.blank_state(addr=start_address)

psd0 = claripy.BVS('psd0',64)
psd1 = claripy.BVS('psd1',64)
fake_address0 = 0x0A2DEF30# 伪造malloc得来的内存,在bss上随便找的
pointer_to_address0 = 0x0A2DEF74# 指向伪造内存的指针
state.memory.store(pointer_to_address0,fake_address0,endness=project.arch.memory_endness)# 将指针指向伪造的内存
fake_address1 = 0x0A2DEF40
pointer_to_address1 = 0x0A2DEF7C
state.memory.store(pointer_to_address1,fake_address1,endness=project.arch.memory_endness)
state.memory.store(fake_address0,psd0)# 将伪造的内存符号化
state.memory.store(fake_address1,psd1)
simulation = project.factory.simgr(state)
simulation.explore(find=0x0804877A,avoid=0x08048768)

if simulation.found:
solution_state = simulation.found[0]
solution0 = solution_state.se.eval(psd0)
solution1 = solution_state.se.eval(psd1)
solution = ' '.join(map('{:x}'.format,[solution0,solution1]))
print(solution)
else:
raise Exception('Nooooooooo!')

if __name__ == '__main__':
main()


1
2
3
4
5
6
7
8
9
10
WARNING | 2022-03-13 15:07:11,666 | angr.storage.memory_mixins.bvv_conversion_mixin | Unknown size for memory data 0xa2def30. Default to arch.bits.
WARNING | 2022-03-13 15:07:11,667 | angr.storage.memory_mixins.bvv_conversion_mixin | Unknown size for memory data 0xa2def40. Default to arch.bits.
WARNING | 2022-03-13 15:07:11,672 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-13 15:07:11,672 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-13 15:07:11,672 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-13 15:07:11,672 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-13 15:07:11,672 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-13 15:07:11,672 | angr.storage.memory_mixins.default_filler_mixin | Filling register ebp with 4 unconstrained bytes referenced from 0x80486af (main+0x8c in 06_angr_symbolic_dynamic_memory (0x80486af))
CRITICAL | 2022-03-13 15:07:15,521 | angr.sim_state | The name state.se is deprecated; please use state.solver.
4f46494a484f5856 46425149534f5a4f

这节学到了符号化申请动态内存,通过伪造内存方式:

1
2
initial_state.memory.store(buffer0_addr, fake0_addr, endness=project.arch.memory_endness) # 将指针指向伪造的内存
initial_state.memory.store(fake0_addr, password0) # 将伪造的内存符号化

endness的参数是小端写入,因为angr默认大端。

07_angr_symbolic_file

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
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // [esp-14h] [ebp-30h]
int v4; // [esp-10h] [ebp-2Ch]
int v5; // [esp-Ch] [ebp-28h]
int v6; // [esp-8h] [ebp-24h]
int v7; // [esp-4h] [ebp-20h]
int v8; // [esp+0h] [ebp-1Ch]
int i; // [esp+0h] [ebp-1Ch]

memset(buffer, 0, sizeof(buffer));
printf("Enter the password: ");
__isoc99_scanf("%64s", buffer, v3, v4, v5, v6, v7, v8);
ignore_me((int)buffer, 0x40u);
memset(buffer, 0, sizeof(buffer));
fp = fopen("FOQVSBZB.txt", "rb");
fread(buffer, 1u, 0x40u, fp);
fclose(fp);
unlink("FOQVSBZB.txt");
for ( i = 0; i <= 7; ++i )
*(_BYTE *)(i + 134520992) = complex_function(*(char *)(i + 134520992), i);
if ( strcmp(buffer, "OSIWHBXI") )
{
puts("Try again.");
exit(1);
}
puts("Good Job.");
exit(0);
}

这个是将输入写入文件,然后再打开文件进行加密

所以要构建文件。

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
import sys
import claripy
import angr
import binascii
from libnum import n2s
def main():
path = '../solutions/07_angr_symbolic_file/07_angr_symbolic_file'
project = angr.Project(path)

start_address = 0x080488BC
initial_state = project.factory.blank_state(add=start_address)

filename = 'FOQVSBZB.txt'
symbolic_file_size_bytes = 0x40#64位

psd = claripy.BVS('psd',symbolic_file_size_bytes * 8)
psd_file = angr.SimFile(filename, content=psd, size=symbolic_file_size_bytes) # 符号化文件

initial_state = project.factory.blank_state(addr=start_address, fs={filename: psd_file}) # 再初始状态中添加一个虚拟的文件系统
simulation = project.factory.simgr(initial_state)
def good_job(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())

return 'Good Job' in str(stdout_output)

def try_again(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())

return 'Try again' in str(stdout_output)

simulation.explore(find=good_job,avoid=try_again)
if simulation.found:
solution_state = simulation.found[0]
solution = n2s(solution_state.solver.eval(psd))
print(solution)
else:
raise Exception('Nooooooo!!!')

if __name__ == '__main__':
main()

1
2
3
4
5
6
7
8
WARNING | 2022-03-13 15:50:33,858 | angr.sim_state | Unused keyword arguments passed to SimState: add
WARNING | 2022-03-13 15:50:33,908 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-13 15:50:33,909 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-13 15:50:33,909 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-13 15:50:33,909 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-13 15:50:33,909 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-13 15:50:33,909 | angr.storage.memory_mixins.default_filler_mixin | Filling register ebp with 4 unconstrained bytes referenced from 0x8048922 (main+0xc4 in 07_angr_symbolic_file (0x8048922))
OBAXRUZT

总结:

1
2
3
angr.storage.SimFile(文件名,文件内容, size = 文件大小) => 创建一个模拟文件,当有被执行的程序fopen 打开文件时,我们可以控制其里面的内容

initial_state.posix.fs => 状态上下文的文件系统对象

要注意点,但我们创建符号good_job其参数是state,所以我们在创建项目时,不能用state,可以用initial_state

08_angr_constraints

这道题的特点就是会一个一个字符比较,所以不能用之前的方法,否则会有2的16次方中可能,会爆炸的,我们要做的就是符号化buffer,然后进行加密加密后获得控制权,从而检查psd是否与对比的一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+Ch] [ebp-Ch]

qmemcpy(&password, "OSIWHBXIFOQVSBZB", 16);
memset(&buffer, 0, 0x11u);
printf("Enter the password: ");
__isoc99_scanf("%16s", &buffer);
for ( i = 0; i <= 15; ++i )
*(_BYTE *)(i + 134520896) = complex_function(*(char *)(i + 134520896), 15 - i);
if ( check_equals_OSIWHBXIFOQVSBZB(&buffer, 16) )
puts("Good Job.");
else
puts("Try again.");
return 0;
}

给出脚本:

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
import angr
import sys
import claripy
from libnum import n2s
def main():
path = '../solutions/08_angr_constraints/08_angr_constraints'
project = angr.Project(path)
start_add = 0x0804863C #scanf后面
initial_state = project.factory.blank_state(add=start_add)
buffer = claripy.BVS('buffer',0x10*8)#buffer的大小是0x10 字节,也就是0x10 * 8 比特
buffer_address = 0x0804A040
initial_state.memory.store(buffer_address,buffer)#buffer 是全局变量,地址是0x804A040
simulation = project.factory.simgr(initial_state)
address_to_check_constraint = 0x08048683
simulation.explore(find=address_to_check_constraint)# compilex_function() 计算结束位置
if simulation.found:
solution_state = simulation.found[0]
constrained_parameter_address = 0x0804A040 # 计算约束的内存位置
constrained_parameter_size_bytes = 0x10 # 计算约束的内存大小
constrained_parameter_bitvector = solution_state.memory.load( constrained_parameter_address,constrained_parameter_size_bytes) # 加载内存

constrained_parameter_desired_value = "OSIWHBXIFOQVSBZB"# Key-String
solution_state.add_constraints(constrained_parameter_bitvector == constrained_parameter_desired_value )# 添加约束
solution = solution_state.se.eval(buffer)
print(n2s(solution))
else:
raise Exception('nooooooooo!')

if __name__ == '__main__':
main()

学到:

1
2
3
solution_state.memory.load(内存地址,内存大小) => 加载内存

solution_state.add_constraints(约束条件) => 添加约束条件

09_angr_hooks

这个题主要是对比的时候在遍历分支的时候会用很长时间,我们直接hook掉,然后替换成我们自己对比函数就行

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
import sys
import claripy
import angr
def main():
path = '../solutions/09_angr_hooks/09_angr_hooks'
project = angr.Project(path)
initial_state = project.factory.entry_state()

check_equals = 0x080486CA
instruction_to_skip_lenth = 5
@project.hook(check_equals, length=instruction_to_skip_lenth)
def skip_check_equals(state):
user_input_buffer_addr = 0x0804A044#buffer地址
user_input_buffer_lenth = 16

user_input_string = state.memory.laod( user_input_buffer_addr,user_input_buffer_lenth)
check_against_string = 'OSIWHBXIFOQVSBZB'
state.regs.eax = claripy.If(user_input_string == check_against_string,claripy.BVV(1,32),claripy.BVV(0,32))
simulation = project.factory.simgr(initial_state)

def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job.' in str(stdout_output)

def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again.' in str(stdout_output)

simulation.explore(find=is_successful, avoid=should_abort) # Try Explore Execute Path

if simulation.found:
solution_state = simulation.found[0]
solution = solution_state.posix.dumps(sys.stdin.fileno()) # Get data ..
print(solution)
else:
raise Exception('Could not find the solution')

if __name__ == '__main__':
main()

上面脚本不如下面脚本:

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
import sys
import claripy
import angr
def main():
path = '../solutions/09_angr_hooks/09_angr_hooks'
project = angr.Project(path)

initial_state = project.factory.entry_state()

class ReplacementCheckEquals(angr.SimProcedure):
def run(self, check_data_address, check_data_length):
check_input_string = self.state.memory.load(check_data_address,check_data_length)
check_against_string = 'OSIWHBXIFOQVSBZB'

return claripy.If(check_input_string == check_against_string,claripy.BVV(1,32),claripy.BVV(0,32))

check_equals_symbol = 'check_equals_OSIWHBXIFOQVSBZB'
project.hook_symbol(check_equals_symbol,ReplacementCheckEquals())

simulation = project.factory.simgr(initial_state)

def good_job(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job' in str(stdout_output)

def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again' in str(stdout_output)

simulation.explore(find=good_job,avoid=should_abort)
if simulation.found:
solution_state = simulation.found[0]

solution = solution_state.posix.dumps(sys.stdin.fileno())
print(solution)
if __name__ == '__main__':
main()
1
2
3
4
5
6
7
8
WARNING | 2022-03-14 15:40:43,538 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-14 15:40:43,538 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-14 15:40:43,538 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-14 15:40:43,538 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-14 15:40:43,538 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-14 15:40:43,539 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80487a1 (__libc_csu_init+0x1 in 09_angr_hooks (0x80487a1))
WARNING | 2022-03-14 15:40:46,867 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
b'QREPXOHPJPOQKQLKNOBMULEMGMLNHNIH'

总结:

1
2
3
4
5
6
7
8
9
Hook回调函数格式:

@project.hook(Hook地址,执行完Hook函数后指令往后跳转n字节) def skip_check_equals_(state):

pass

claripy.If(条件,条件为True时的返回值,条件为False时的返回值) => 创建条件判断

claripy.BVV(值,值大小) => 创建一个数值

10_angr_simprocedures

还是一样,先输入flag然后循环运算,接下来函数中对比。逐字节比较太麻烦,我们仍需对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+20h] [ebp-28h]
char s[17]; // [esp+2Bh] [ebp-1Dh] BYREF
unsigned int v6; // [esp+3Ch] [ebp-Ch]

v6 = __readgsdword(0x14u);
memcpy(&password, "OSIWHBXIFOQVSBZB", 0x10u);
memset(s, 0, sizeof(s));
printf("Enter the password: ");
__isoc99_scanf("%16s", s);
for ( i = 0; i <= 15; ++i )
s[i] = complex_function(s[i], 18 - i);
if ( check_equals_OSIWHBXIFOQVSBZB(s, 16) )
puts("Good Job.");
else
puts("Try again.");
return 0;
}

本题跟9题的区别就在于,本题call equal指令太多,不像9题只有一个,所以我们需要多个hook

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
import sys
import claripy
import angr
def main():
path = '../solutions/10_angr_simprocedures/10_angr_simprocedures'
project = angr.Project(path)

initial_state = project.factory.entry_state()

class ReplacementCheckEquals(angr.SimProcedure):
def run(self, check_data_address, check_data_length):
check_input_string = self.state.memory.load(check_data_address,check_data_length)
check_against_string = 'OSIWHBXIFOQVSBZB'

return claripy.If(check_input_string == check_against_string,claripy.BVV(1,32),claripy.BVV(0,32))

check_equals_symbol = 'check_equals_OSIWHBXIFOQVSBZB'
project.hook_symbol(check_equals_symbol,ReplacementCheckEquals())

simulation = project.factory.simgr(initial_state)

def good_job(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job' in str(stdout_output)

def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again' in str(stdout_output)

simulation.explore(find=good_job,avoid=should_abort)
if simulation.found:
solution_state = simulation.found[0]

solution = solution_state.posix.dumps(sys.stdin.fileno())
print(solution)
if __name__ == '__main__':
main()
1
2
3
4
5
6
7
8
WARNING | 2022-03-14 15:02:40,607 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-14 15:02:40,607 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-14 15:02:40,607 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-14 15:02:40,607 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-14 15:02:40,607 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-14 15:02:40,607 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x804a9d1 (__libc_csu_init+0x1 in 10_angr_simprocedures (0x804a9d1))
WARNING | 2022-03-14 15:02:43,850 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
b'MTMDRONBBNSAAMNS'

这个题hook整个函数。采用SimProcedure类

1
2
3
4
5
6
7
8
9
10
11
Hook 回调函数格式:

class ReplacementCheckEquals(angr.SimProcedure):

def run(self, Hook的函数参数列表):

….

return 函数返回值 # 如果是void函数可以省略

project.hook_symbol(要Hook的函数名,SimProcedure类实例)

通过这个题,我在想上个题是否也能用这个回调函数呢,这个脚本会省去很多事,成功了!

11_angr_sim_scanf

本题加密的是对比数据,加密完再输入,然后对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+20h] [ebp-28h]
char s[20]; // [esp+28h] [ebp-20h] BYREF
unsigned int v7; // [esp+3Ch] [ebp-Ch]

v7 = __readgsdword(0x14u);
memset(s, 0, sizeof(s));
qmemcpy(s, "LOGMHXHI", 8);
for ( i = 0; i <= 7; ++i )
s[i] = complex_function(s[i], i);
printf("Enter the password: ");
__isoc99_scanf("%u %u", buffer0, buffer1);
if ( !strncmp(buffer0, s, 4u) && !strncmp(buffer1, &s[4], 4u) )
puts("Good Job.");
else
puts("Try again.");
return 0;
}

这道题是让我们模拟scanf

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
import sys
import angr
import claripy

def main():
path = '../solutions/11_angr_sim_scanf/11_angr_sim_scanf'
project = angr.Project(path)

initial_state = project.factory.entry_state()

class ReplacementScanf(angr.SimProcedure):
def run(self,format_string,scanf0_address,scanf1_address):
scanf0 = claripy.BVS('scanf0', 32)
scanf1 = claripy.BVS('scanf1', 32)

self.state.memory.store(scanf0_address,scanf0,endness=project.arch.memory_endness)
self.state.memory.store(scanf1_address,scanf1,endness=project.arch.memory_endness)

self.state.globals['solution0'] = scanf0
self.state.globals['solution1'] = scanf1

scanf_symbol = '__isoc99_scanf'
project.hook_symbol(scanf_symbol, ReplacementScanf())
simulation = project.factory.simgr(initial_state)
def good_job(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job.' in str(stdout_output)
def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again' in str(stdout_output)

simulation.explore(find=good_job,avoid=should_abort)
if simulation.found:
solution_state = simulation.found[0]
store_solution0 = solution_state.globals['solution0']
store_solution1 = solution_state.globals['solution1']
solution0 = solution_state.se.eval(store_solution0)
solution1 = solution_state.se.eval(store_solution1)
print(solution0,solution1)
if __name__ =='__main__':
main()


1
2
3
4
5
6
7
8
9
10
WARNING | 2022-03-14 16:09:33,831 | angr.project | Address is already hooked, during hook(0x81513a0, <SimProcedure ReplacementScanf>). Re-hooking.
WARNING | 2022-03-14 16:09:33,903 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-14 16:09:33,903 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-14 16:09:33,903 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-14 16:09:33,903 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-14 16:09:33,903 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-14 16:09:33,903 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x804fce1 (__libc_csu_init+0x1 in 11_angr_sim_scanf (0x804fce1))
WARNING | 2022-03-14 16:09:34,137 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff40 with 4 unconstrained bytes referenced from 0x8187170 (strncmp+0x0 in libc.so.6 (0x87170))
CRITICAL | 2022-03-14 16:09:34,334 | angr.sim_state | The name state.se is deprecated; please use state.solver.
1447907916 1146768724

这个题学到了构造scanf的hook:

1
2
3
4
5
#将位向量储存到当前状态并且获取位向量的方法
self.state.globals['solution0'] = scanf0
#保存当前状态
solution0 = solution_state.globals['solution0']
#去出scanf

12_angr_veritesting

如果说这个题跟第一题有什么区别的话,就是这个输入32位,很容易爆炸,所以有veritesting参数来表示是否合并路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import sys
import angr
def main():
path = '../solutions/12_angr_veritesting/12_angr_veritesting'
project = angr.Project(path)
initial_state = project.factory.entry_state()
simulation = project.factory.simgr(initial_state,veritesting = True)
def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job.' in str(stdout_output) # :boolean
def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again.' in str(stdout_output)

simulation.explore(find=is_successful,avoid=should_abort)
if simulation.found:
solution = simulation.found[0]
print(solution.posix.dumps(sys.stdin.fileno()))
if __name__ =='__main__':
main()
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
WARNING | 2022-03-14 16:30:57,745 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-14 16:30:57,745 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-14 16:30:57,745 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-14 16:30:57,745 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-14 16:30:57,745 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-14 16:30:57,746 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80486e1 (__libc_csu_init+0x1 in 12_angr_veritesting (0x80486e1))
WARNING | 2022-03-14 16:30:57,757 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:57,758 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
Deprecation warning: Use self.model.get_any_node() instead of get_any_node
WARNING | 2022-03-14 16:30:57,789 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:57,790 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:57,852 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:57,853 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:57,887 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:57,887 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:58,001 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:58,001 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:58,098 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:58,099 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:58,209 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:58,209 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:30:58,322 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:30:58,564 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:30:58,807 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:30:59,033 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:30:59,259 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:30:59,507 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:30:59,751 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:00,001 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:00,253 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:00,526 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:00,801 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:01,072 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:01,352 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:01,645 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:01,934 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:02,240 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:02,541 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:02,851 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:03,179 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:03,504 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:03,826 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:04,170 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:04,519 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:04,869 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:05,314 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:05,676 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:06,060 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:06,456 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:06,859 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:07,269 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:07,704 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:31:08,188 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
b'YNCRGVKZODSHWLAPETIXMBQFUJYNCRGV'

学习了如何自动合并路径:

1
simulation = project.factory.simgr(initial_state, veritesting=True) 

13_angr_static_binary

看起来很简单,用第一问的脚本就行了,实际不行,因为这个是用静态链接编译的,我们还要实现或者引用一些函数的hook

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [esp+1Ch] [ebp-3Ch]
int j; // [esp+20h] [ebp-38h]
char v6[20]; // [esp+24h] [ebp-34h] BYREF
char v7[20]; // [esp+38h] [ebp-20h] BYREF
unsigned int v8; // [esp+4Ch] [ebp-Ch]

v8 = __readgsdword(0x14u);
for ( i = 0; i <= 19; ++i )
v7[i] = 0;
qmemcpy(v7, "ELZXQOOQ", 8);
printf("Enter the password: ");
_isoc99_scanf("%8s", v6);
for ( j = 0; j <= 7; ++j )
v6[j] = complex_function(v6[j], j);
if ( j_strcmp_ifunc(v6, v7) )
puts("Try again.");
else
puts("Good Job.");
return 0;
}
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
import angr
import sys

def main():
path = '../solutions/13_angr_static_binary/13_angr_static_binary'
project = angr.Project(path)
initial_state = project.factory.entry_state()
simulation = project.factory.simgr(initial_state,veritesting = True)

project.hook(0x0804FAB0,angr.SIM_PROCEDURES['libc']['printf']())
project.hook(0x0804FB10,angr.SIM_PROCEDURES['libc']['scanf']())
project.hook(0x080503F0,angr.SIM_PROCEDURES['libc']['puts']())
project.hook(0x08048D60,angr.SIM_PROCEDURES['glibc']['__libc_start_main']())
def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job.' in str(stdout_output) # :boolean
def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again.' in str(stdout_output)

simulation.explore(find=is_successful,avoid=should_abort)
if simulation.found:
solution_state = simulation.found[0]
print(solution_state.posix.dumps(sys.stdin.fileno()))
if __name__ == '__main__':
main()
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
WARNING | 2022-03-14 16:55:19,180 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-14 16:55:19,180 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-14 16:55:19,180 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-14 16:55:19,180 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-14 16:55:19,181 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-14 16:55:19,181 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80497b1 (__libc_csu_init+0x1 in 13_angr_static_binary (0x80497b1))
WARNING | 2022-03-14 16:55:19,185 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,186 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
Deprecation warning: Use self.model.get_any_node() instead of get_any_node
WARNING | 2022-03-14 16:55:19,255 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,255 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,279 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,279 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,323 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,325 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,406 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,406 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,422 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,422 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,502 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,502 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,528 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,528 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,566 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:19,566 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:20,020 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:20,021 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:20,310 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:20,311 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:20,391 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:20,392 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:21,303 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:21,304 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:24,416 | angr.sim_manager | Cannot find states with common history line to merge. Fall back to the naive merging strategy and merge all states.
WARNING | 2022-03-14 16:55:25,412 | angr.storage.memory_mixins.default_filler_mixin | Filling register es with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
WARNING | 2022-03-14 16:55:25,412 | angr.storage.memory_mixins.default_filler_mixin | Filling register gs with 4 unconstrained bytes referenced from 0x0 (not part of a loaded object)
b'EADQYLAR'

我们学到了获取angr内部系统函数:

1
angr.SIM_PROCEDURES[ 系统库名 ] [ 系统函数名 ] () => 获取Angr 内部实现的系统函数

14_angr_shared_library

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[16]; // [esp+1Ch] [ebp-1Ch] BYREF
unsigned int v5; // [esp+2Ch] [ebp-Ch]

v5 = __readgsdword(0x14u);
memset(s, 0, sizeof(s));
printf("Enter the password: ");
__isoc99_scanf("%8s", s);
if ( validate(s, 8) )
puts("Good Job.");
else
puts("Try again.");
return 0;
}

好像很简单,但我们发现validate函数在另一个so文件,该题考的是动态链接的符号执行,我们只要搞出validate的符号执行就ok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import sys
import angr
import claripy

def main():
path = '../solutions/14_angr_shared_library/lib14_angr_shared_library.so'
base = 0x40000000#随意
project = angr.Project(path,load_options={'main_opts' : {'custom_base_addr' : base}})
buffer_pointer = claripy.BVV(0x30000000,32)#创建buffer指针
validate_function_address = base + 0x670 #在该文件中的调用地址
initial_state = project.factory.call_state(validate_function_address,buffer_pointer,claripy.BVV(8,32))
# 调用validate_function,因为函数声明validata_function(buffer_point,buffer_length) ,所以我们构造出调用validata_function(0x3000000,0x8) .
password = claripy.BVS('password', 64)

initial_state.memory.store(buffer_pointer,password)
simulation = project.factory.simgr(initial_state)
simulation.explore(find=base+0x71C)# 执行到validate 函数的RETN 指令
if simulation.found:
solution_state = simulation.found[0]
solution_state.add_constraints(solution_state.regs.eax !=0)
solution = solution_state.se.eval(password)
print(solution)
if __name__ == '__main__':
main()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CRITICAL | 2022-03-14 17:38:36,605 | cle.backends | Deprecation warning: the custom_base_addr parameter has been renamed to base_addr
WARNING | 2022-03-14 17:38:36,862 | angr.calling_conventions | Guessing call prototype. Please specify prototype.
WARNING | 2022-03-14 17:38:36,868 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-14 17:38:36,869 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-14 17:38:36,869 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-14 17:38:36,869 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-14 17:38:36,869 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-14 17:38:36,869 | angr.storage.memory_mixins.default_filler_mixin | Filling register ebp with 4 unconstrained bytes referenced from 0x40000670 (validate+0x0 in lib14_angr_shared_library.so (0x670))
WARNING | 2022-03-14 17:38:36,870 | angr.storage.memory_mixins.default_filler_mixin | Filling register ebx with 4 unconstrained bytes referenced from 0x40000673 (validate+0x3 in lib14_angr_shared_library.so (0x673))
WARNING | 2022-03-14 17:38:37,842 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x30000008 with 121 unconstrained bytes referenced from 0x40186b80 (strcmp+0x0 in libc.so.6 (0x86b80))
WARNING | 2022-03-14 17:38:37,911 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeffe8 with 4 unconstrained bytes referenced from 0x40186b80 (strcmp+0x0 in libc.so.6 (0x86b80))
WARNING | 2022-03-14 17:38:37,911 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7fff0000 with 77 unconstrained bytes referenced from 0x40186b80 (strcmp+0x0 in libc.so.6 (0x86b80))
CRITICAL | 2022-03-14 17:38:38,105 | angr.sim_state | The name state.se is deprecated; please use state.solver.
6076275416825026394

学习到了:

1
2
3
4
5
6
如何加载共享库
base = 0x40000000#随意
project = angr.Project(path,load_options={'main_opts' : {'custom_base_addr' : base}})
initial_state = project.factory.call_state(validate_function_address,buffer_pointer,claripy.BVV(8,32))
# 构造指针给函数使用.

15_angr_arbitrary_read

当if成立,s输出,以为会输出tryagain,但v4要写入20字节,就会有溢出,因为s到v4只有16字节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [esp+Ch] [ebp-1Ch] BYREF
char *s; // [esp+1Ch] [ebp-Ch]

s = try_again;
printf("Enter the password: ");
__isoc99_scanf("%u %20s", &key, &v4);
if ( key == 2358019 )
puts(s);
else
puts(try_again);
return 0;
}

脚本如下:

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
import sys
import angr
import claripy
def main():
path = '../solutions/15_angr_arbitrary_read/15_angr_arbitrary_read'
project = angr.Project(path)

initial_state = project.factory.entry_state()

class ReplacementScanf(angr.SimProcedure):# 实现Scanf Hook 函数

def run(self,format_string, check_key_address,input_buffer_address):
scanf0 = claripy.BVS('scanf0',32)#check_key
scanf1 = claripy.BVS('scanf1',160)#inputbuffer

for char in scanf1.chop(bits=8):
self.state.add_constraints(char >= '0', char <= 'z')# 对input_buffer 的输入约束

self.state.memory.store(check_key_address,scanf0 ,endness =project.arch.memory_endness)# 保存求解变量到指定的内存中

self.state.memory.store(input_buffer_address,scanf1 ,endness =project.arch.memory_endness)

self.state.globals['solution0'] = scanf0# 保存这两个变量到state 中,后续求解需要用到
self.state.globals['solution1'] = scanf1

scanf_symbol = '__isoc99_scanf'
project.hook_symbol(scanf_symbol,ReplacementScanf())
def check_puts(state):
puts_parameter = state.memory.load(state.regs.esp + 4,4,endness=project.arch.memory_endness)

if state.se.symbolic(puts_parameter):
good_job_string_address = 0x08048562#利用try again的函数调用
copied_state = state.copy() # 复制执行状态上下文进行约束求解,不影响原理的执行上下文
copied_state.add_constraints(puts_parameter == good_job_string_address)# puts 的参数地址是否可以被指定为 0x08048562 ,如果可以的话,那就证明这个值是可控的

if copied_state.satisfiable():# 判断添加了上面这个约束是否有解
state.add_constrains(puts_parameter == good_job_string_address) # 如果有解的话就保存到我们执行的那个状态对象
return True
else:
return False
else:
return False

simulation = project.factory.simgr(initial_state)
def is_successful(state):
puts_address = 0x0804854F# 当程序执行到puts() 函数时,我们就认为路径探索到了这里,然后再去通过check_puts() 判断这里是否存在漏洞,告诉Angr这是不是我们需要找的那条执行路径

if state.addr == puts_address:
return check_puts(state)
else:
return False
simulation.explore(find=is_successful)
if simulation.found:
solution_state = simulation.found[0]
solution0 = solution_state.se.eval(solution_state.globals['solution0'])
solution1 = solution_state.se.eval(solution_state.globals['solution1'],cast_to=bytes)
print(solution0,solution1)

if __name__ == '__main__':
main()
1
2
3
4
5
state.copy() => 复制状态上下文

state.satisfiable() => 判断当前的所有约束是否有解

solution_state.se.eval(求解变量,cast_to=bytes) => 序列化变量内容为字符串

16_angr_arbitrary_write

这个题很明显,password是不等于NEDVTNOP,所以我们可以用s溢出覆盖dest的值,使其指向password,这样就能修改其内容了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[16]; // [esp+Ch] [ebp-1Ch] BYREF
char *dest; // [esp+1Ch] [ebp-Ch]

dest = unimportant_buffer;
memset(s, 0, sizeof(s));
strncpy(password_buffer, "PASSWORD", 0xCu);
printf("Enter the password: ");
__isoc99_scanf("%u %20s", &key, s);
if ( key == 6712341 )
strncpy(dest, s, 0x10u);
else
strncpy(unimportant_buffer, s, 0x10u);
if ( !strncmp(password_buffer, "NEDVTNOP", 8u) )
puts("Good Job.");
else
puts("Try again.");
return 0;
}

我们输入20个字节是正好覆盖s的16个字节+的dest的字节的

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
import sys
import angr
import claripy

def main():
path = '../solutions/16_angr_arbitrary_write/16_angr_arbitrary_write'
project = angr.Project(path)
initial_state = project.factory.entry_state()

class ReplacementScanf(angr.SimProcedure):
def run(self,format_string,check_key,input_buffer):
scanf0 = claripy.BVS('scanf0',32)
scanf1 = claripy.BVS('scanf1',160)

for char in scanf1.chop(bits=8):
self.state.add_constraints(char >= 'a',char <= 'z')

self.state.memory.store(check_key,scanf0,endness=project.arch.memory_endness)
self.state.memory.store(input_buffer,scanf1,endness=project.arch.memory_endness)

self.state.globals['solution0'] = scanf0
self.state.globals['solution1'] = scanf1

scanf_symbol = '__isoc99_scanf'
project.hook_symbol(scanf_symbol,ReplacementScanf())
def check_strnpy(state):
strncpy_dest = state.memory.load(state.regs.esp + 4,4,endness=project.arch.memory_endness)
strncpy_src = state.memory.load(state.regs.esp + 8, 4, endness=project.arch.memory_endness)
strncpy_len = state.memory.load(state.regs.esp + 12, 4, endness=project.arch.memory_endness)
src_contents = state.memory.load(strncpy_src, strncpy_len)
# 因为参数中只保存了地址,我们需要根据这个地址去获取内容
if state.se.symbolic(strncpy_dest) and state.se.symbolic(src_contents):
# 判断dest 和src 的内容是不是符号化对象
if state.satisfiable(extra_constraints=(src_contents[-1:-64] == 'NEDVTNOP',strncpy_dest == 0x4D43523C)):
# 尝试求解,其中strncpy_dest == 0x4D43523C 的意思是判断dest 是否可控为password 的地址;src_contents[ -1 : -64 ] == 'KZYRKMKE' 是判断input_buffer 的内容是否可控为'KZYRKMKE' ,因为这块内存是倒序,所以需要通过[ -1 : -64 ] 倒转(contentes 的内容是比特,获取8 字节的大小为:8*8 = 64),然后判断该值是否为字符串'KZYRKMKE'
state.add_constraints(src_contents[ -1 : -64 ] == 'NEDVTNOP',strncpy_dest == 0x4D43523C)
return True
else:
return False
else:
return False
simulation = project.factory.simgr(initial_state)
def good_job(state):
strncpy_address = 0x0804860D
if state.addr == strncpy_address:
return check_strnpy(state)
else:
return False
simulation.explore(find=good_job)
if simulation.found:
solution_state = simulation.found[0]
solution0 = solution_state.se.eval(solution_state.globals['solution0'])
solution1 = solution_state.se.eval(solution_state.globals['solution1'],cast_to=bytes)
print(solution0,solution1)
if __name__ =='__main__':
main()

总结:state.satisfiable(extra_constraints=(条件1,条件2)) => 合并多个条件计算是否存在满足约束的解(注意两个或多个条件之间是And 合并判断,不是Or )

17_angr_arbitrary_jump

最后一题,在read_print中检查返回地址是否是godjob

1
2
3
4
5
6
7
int __cdecl main(int argc, const char **argv, const char **envp)
{
printf("Enter the password: ");
read_input();
puts("Try again.");
return 0;
}
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
import angr
import claripy

def main():
binary_path = '../solutions/17_angr_arbitrary_jump/17_angr_arbitrary_jump'
project = angr.Project(binary_path)

initial_state = project.factory.entry_state()
simulation = project.factory.simgr(
initial_state,
save_unconstrained=True,
stashes={
'active' : [initial_state],
'unconstrained' : [],
'found' : [],
'not_needed' : []
}
)

class ReplacementScanf(angr.SimProcedure):

def run(self, fmt, string_addr):
exploit = claripy.BVS('exploit', 8 * 64)

for char in exploit.chop(bits=8):
self.state.add_constraints(char >= '0', char <= 'z')

exploit_addr = string_addr
self.state.memory.store(exploit_addr, exploit)

self.state.globals['solution'] = exploit

scanf_symbol = '__isoc99_scanf'
project.hook_symbol(scanf_symbol, ReplacementScanf())

while (simulation.active or simulation.unconstrained) and (not simulation.found):
for unconstrained_state in simulation.unconstrained:
def should_move(s):
return s is unconstrained_state

simulation.move('unconstrained', 'found', filter_func=should_move)


simulation.step()

if simulation.found:
solution_state = simulation.found[0]

solution_state.add_constraints(solution_state.regs.eip == 0x4D435250)

solution = solution_state.se.eval(solution_state.globals['solution'],cast_to = bytes)
print(solution)
else:
raise Exception('Could not find the solution')


if __name__ == '__main__':
main()

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
WARNING | 2022-03-15 13:47:38,088 | angr.project | Address is already hooked, during hook(0x4d5513a0, <SimProcedure ReplacementScanf>). Re-hooking.
WARNING | 2022-03-15 13:47:38,226 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-03-15 13:47:38,226 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-03-15 13:47:38,226 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-03-15 13:47:38,226 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-03-15 13:47:38,226 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-03-15 13:47:38,226 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x4d4352e1 (__libc_csu_init+0x1 in 17_angr_arbitrary_jump (0x4d4352e1))
WARNING | 2022-03-15 13:47:38,229 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x4d4352e1 (__libc_csu_init+0x1 in 17_angr_arbitrary_jump (0x4d4352e1))
WARNING | 2022-03-15 13:47:38,340 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,340 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,341 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,342 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,343 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,344 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,345 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,346 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,347 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,348 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,349 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,350 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,350 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,350 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,350 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,350 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,350 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,351 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,351 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,351 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,351 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,351 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,351 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,352 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,353 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,354 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,354 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,354 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,354 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,393 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,394 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,394 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,394 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,394 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,394 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,395 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,396 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,397 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,398 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,399 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,400 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,401 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,402 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,403 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,404 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,405 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,406 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,407 | claripy.ast.bv | BVV value is being coerced from a unicode string, encoding as utf-8
WARNING | 2022-03-15 13:47:38,766 | angr.engines.successors | Exit state has over 256 possible solutions. Likely unconstrained; skipping. <BV32 Reverse(exploit_11_512[135:104])>
WARNING | 2022-03-15 13:47:39,144 | angr.engines.successors | Exit state has over 256 possible solutions. Likely unconstrained; skipping. <BV32 Reverse(exploit_12_512[135:104])>
CRITICAL | 2022-03-15 13:47:39,181 | angr.sim_state | The name state.se is deprecated; please use state.solver.
b'00000000000000000000000000000000000000000000000PRCM00@0000000000'

总结:

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
class ReplacementScanf(angr.SimProcedure):class ReplacementScanf(angr.SimProcedure):import angr
#导入文件
path = ''
#打开二进制文件
project = angr.Project(path)
#接下来两种选择
#第一种
initial_state = project.factory.entry_state()#直接创建空白的执行上下文环境
#第二种
start_address = xxxx
initial_state = project.factory.blank_state(addr=start_address)
#创建模拟器,第二个参数是指定是否合并路径,路径多会爆炸
simulation = project.factory.simgr(initial_state,veritesting = True)
#good和try有两种方法,第一个是找到call puts的地址不再说了
#第二种是进行函数定义
def is_successful(state):
#从输出中提取
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job' in str(stdout_output) # :boolean
def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again' in str(stdout_output) # :boolean
#执行搜索路径(里面是要到达的地址)
simulation.explore(find=print_good_address,avoid=print_try_avoid)
#打印出结果,搜索结果的集合,simulation.found是python的list集合
if simulation.found:
solution_state = simulation.found[0]
#获取标准输入
print(solution_state.posix.dumps(sys.stdin.fileno()))

#寄存器类,比如输入了好几个参数,我们能从寄存器下手找到输入源
#创建求解变量
password0 = claripy.BVS('password0', password0_size_in_bits)
#告诉符号执行,执行的寄存器是什么
initial_state.regs.eax = password0
#在if中进行求解符号变量
solution0 = solution_state.se.eval(password0)
#栈类,如果结果保存在栈中
#将创建的变量从stack中取出来
initial_state.stack_push(password0)
#变量存在bss段,符号化内存
#第一个参数是变量的地址
initial_state.memory.store(password0_address, password0)
#数字字节顺序,可以表示为:project.arch.memory_endness
initial_state.memory.store(地址,数据,endness = 数据字节顺序) => 设置初始化内存数据
#有关文件就是第七题
#多分支比较,建立比较机制
#先在if里进行约束
constrained_parameter_address = 0x804A050 # 计算约束的内存位置
constrained_parameter_size_bytes = 0x10 # 计算约束的内存大小
constrained_parameter_bitvector = solution_state.memory.load( # 加载内存
constrained_parameter_address,
constrained_parameter_size_bytes
)
#再用下述的进行字符串比较
solution_state.memory.load(内存地址,内存大小) => 加载内存
solution_state.add_constraints(约束条件) => 添加约束条件
#hook的写法
#连个参数分别是,hook的地址,执行后往后跳过几个字节
@project.hook(check_equals_called_address, length=instruction_to_skip_length)
def skip_check_equals_(state):
加载内存
claripy.If(条件,条件为True时的返回值,条件为False时的返回值) => 创建条件判断
claripy.BVV(值,值大小) => 创建一个数值
#另一种常见hook方法,常见于想hook的函数太多,无法定位情况
class ReplacementCheckEquals(angr.SimProcedure):
def run(self, Hook的函数参数列表):
加载内存
return 用claripy.If对比来返回值# 如果是void函数可以省略
#hook的函数名是真实函数名,第二个参数是ReplacementCheckEquals()
project.hook_symbol(要Hook的函数名,SimProcedure类实例)
#scanf太多,hookscanf
class ReplacementScanf(angr.SimProcedure):
def run(self, format_string, scanf0_address, scanf1_address ):
#创建求解变量
scanf0 = claripy.BVS('scanf0', 4 * 8)
#初始化内存
self.state.memory.store(scanf0_address, scanf0, endness=project.arch.memory_endness)
#保存当前状态
self.state.globals['solution0'] = scanf0
project.hook_symbol(要Hook的函数名,SimProcedure类实例)
#用angr自带hook程序
#用在simgr后
project.hook(0x804ed40, angr.SIM_PROCEDURES['libc']['printf']())
angr.SIM_PROCEDURES[ 系统库名 ] [ 系统函数名 ] () => 获取Angr 内部实现的系统函数
#遇到函数是动态链接的
#现设基地址
base = 0x40000000(随便)
#我们的path是指那个so文件
project = angr.Project(path_to_binary, load_options={
'main_opts' : {
'custom_base_addr' : base
}
})
initial_state = project.factory.call_state(validate_function_address, buffer_pointer,claripy.BVV(8, 32)) # 调用validate_function,因为函数声明validata_function(buffer_point,buffer_length) ,所以我们构造出调用validata_function(0x3000000,0x8)
#对于溢出而覆盖的题
#下面是约束的写法
for char in scanf1.chop(bits=8):
self.state.add_constraints(char >= '0', char <= 'z') # 对input_buffer 的输入约束
#约束完,存入内存,获取想要的puts
def check_puts(state):
puts_parameter = state.memory.load(state.regs.esp + 4, 4, endness=project.arch.memory_endness)
#检查这个参数是否为符号化对象
if state.se.symbolic(puts_parameter):
#复制执行状态上下文进行约束求解,不影响原理的执行上下文
copied_state = state.copy()
if copied_state.satisfiable(): # 判断添加了上面这个约束是否有解
state.add_constraints(puts_parameter == good_job_string_address) # 如果有解的话就保存到我们执行的那个状态对象
return True
else:
return False
else:
return False
#序列化变量内容为字符串
solution_state.se.eval(求解变量,cast_to=bytes)
#合并多个条件计算是否存在满足约束的解(注意两个或多个条件之间是And 合并判断,不是Or )
state.satisfiable(extra_constraints=(条件1,条件2))

动手写个虚拟机

​ 写这个东西首先要知道大概的分区,刚开始是头文件,然后是定义的一些东西(包括函数),然后是主函数,在主函数中我们需要用switch来对一些东西进行操作,我们不可能直接写什么vm虚拟机那种东西,所以先从LC-3这个虚拟机开始。不过https://justinmeiners.github.io/lc3-vm/文章是有些乱的,所以我再将文章整理一遍.

虚拟机:虚拟机就是像一台电脑那样运行的程序。它主要模拟了CPU以及其他一小部分硬件,让被模拟的CPU就做算术运算,读写内存,与I/O设备交互,就像一台真正的电脑一样。我们所写的虚拟机是LC-3,能够模仿一些简单的操作,在c语言编成的虚拟机的基础上运行一些程序。

1、读取文件

我们要在一台机器上加载文件,从而运行,那就必须开辟空间

代码1-1

1
2
#define UINT16_MAX 65536
uint16_t memory[UINT16_MAX];//创建2的16次方内存即128kb

代码1-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(int argc, const char* argv[])
{
if (argc < 2)
{
printf("lc3 [image-file1]...\n");
exit(2);
}
for (int j = 1; j < argc; ++j)
{
if (!read_image(argv[j]))
{
printf("failed to load image: %s\n",argv[j]);
exit(1);
}
}/*{Load Arguments,5}*/
...

}

这个主函数中最前面一段是牵扯到了内存,argc 和 argv 是 main 函数参数,第一个代表main参数个数,第二个代表为地址的参数;

该if函数是加载VM映像来使这台VM能够运行。如果命令行参数没有给出镜像路径的话就打印一条错误信息。

也就是运行程序的时候的路径要对:

1
.\16VM.exe C:/Users/86159/Downloads/2048.obj

用 read_image() 函数计算参数并判断,若返回值是0,就会说:装载映像失败;那么这个函数是什么呢:

代码1-3

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
uint16_t swap16(uint16_t x)
{
return (x << 8) | (x >> 8);/*改成小端序,交换前8位和后8位*/


void read_image_file(FILE* file)
{
uint16_t origin;
fread(&origin,sizeof(origin), 1, file);
origin = swap16(origin);
uint16_t max_read = UINT16_MAX - origin;
uint16_t* p = memory + origin;
size_t read = fread(p,sizeof(uint16_t), max_read,file);
while(read-- > 0)
{
*p = swap16(*p);
++p;
}
}



int read_image(const char* image_path)
{
FILE* file = fopen(image_path, "rb");
if(!file){return 0;};
read_image_file(file);
fclose(file);
return 1;
}

后者代码就是来判断是否读取到正确路径,没有就返回0,然后进入前者代码。

read_image_file() 函数的作用是将要在该虚拟机上运行的程序内存装入之前设定好的memory数组中;首先fread读取起始地址:origin,然后使用swap16函数进行大小端序的转换,在LC-3上采用大端序!!之后计算最大可容纳地址,并用p指针标记,最后使用循环不断缩小范围;

2、寄存器

我们需要模拟cpu中的寄存器,我们用枚举的方法来创建寄存器:

代码2-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum
{
R_R0 = 0,
R_R1,
R_R2,
R_R3,
R_R4,
R_R5,
R_R6,
R_R7,
R_PC, /*程序计数器,相当于rip*/
R_COND,
R_COUNT/*寄存器数量*/
};/*前10个为寄存器,前八个为通用寄存器,cond为条件标志寄存器*/

然后将其存放在数组里:

代码2-2

1
uint16_t reg[R_COUNT];

接下来还有flag的表示方法:

代码2-3

1
2
3
4
5
6
enum
{
FL_POS = 1 << 0,/*P*/
FL_ZRO = 1 << 1,/*Z*/
FL_NEG = 1 << 2,/*N*/
};

移位的值就是他们的意义!

3、指令集

指令集是对cpu中的寄存器发出命令的东西

代码3-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum
{
OP_BR = 0,/*分支*/
OP_ADD,/*添加*/
OP_LD,/*加载*/
OP_ST,/*存储*/
OP_JSR,/*跳转寄存器*/
OP_AND,/*按位和*/
OP_LDR,/*加载寄存器*/
OP_STR,/*存储寄存器*/
OP_RTI,/*未使用*/
OP_NOT,/*按位非*/
OP_LDI,/*加载间接*/
OP_STI,/*存储间接*/


OP_JMP,/*跳转*/
OP_RES,/*保留(未使用)*/
OP_LEA,/*加载有效地址*/
OP_TRAP/*执行陷阱*/
};

我们简单模拟了几个操作,要注意的是LC-3只有16种操作码。CPU所能做的只是执行一系列指令而已。每条指令都是16位长,高4位用来存放操作码,剩下的12位存放参数。所以在我们眼中只有前4位是有用的!

代码3-2

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
uint16_t sign_extend(uint16_t x, int bit_count)
{
if((x >> (bit_count - 1)) & 1)//判断输入数少了右边bit-1位后是否等于0
{
x |= (0xffff << bit_count);
}
return x;
}


void update_flags(uint16_t r)/*更新标志位*/
{
if (reg[r] == 0)
{
reg[R_COND] = FL_ZRO;
}
else if (reg[r] >> 15)/*最左侧1为负数*/
{
reg[R_COND] = FL_NEG;
}
else
{
reg[R_COND] = FL_POS;
}
}

第一个是符号拓展,符号拓展将正数前面补上0,负数前面补上1,这样得到的16位数字依然和我们最初赋的值相等。这样能使数全是16位,且值不变,很巧妙。下面的函数是对寄存器进行flags的赋值,即更新标志位

4、内存访问

代码4-1

1
2
3
4
5
enum
{
MR_KBSR = 0XFE00,/*键盘状态*/
MR_KBDR = 0XFE02/*键盘数据*/
};

上面是模拟LC-3 的两个内存寄存器;第一个为状态管理,第二个是数据管理;

代码4-2

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
uint16_t check_key()
{
return WaitForSingleObject(hStdin, 1000) == WAIT_OBJECT_0 && _kbhit();
}

void mem_write(uint16_t address, uint16_t val)
{
memory[address] = val;
}

uint16_t mem_read(uint16_t address)
{
if (address == MR_KBSR)
{
if (check_key())
{
memory[MR_KBSR] = (1 << 15);
memory[MR_KBDR] = getchar();
}
else
{
memory[MR_KBSR] = 0;
}
}
return memory[address];
}

这里有三个函数,这个属于调用了windows的api,第一个是设置windows终端输入的代码,第二个是写入内存的代码,第三个是读入内存的代码。

5、c语言模拟指令

ADD指令

代码5-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
uint16_t r0 = (instr >> 9) & 0x7;/*目标寄存器*/
uint16_t r1 = (instr >> 6) & 0x7;/*第一个操作数SR1*/
uint16_t imm_flag = (instr >> 5) & 0x1;/*是否是立即模式*/
if(imm_flag)
{
uint16_t imm5 =sign_extend(instr & 0x1f,5);
reg[r0] = reg[r1] + imm5; //立即模式
}
else
{
uint16_t r2 = instr & 0x7;
reg[r0] = reg[r1] + reg[r2]; //寄存器模式
}
update_flags(r0);
}

这是两种形式,其实从csapp里看是有三种形式的,这时两行开始出现不同,第一行第5位为0,而第二行为1。这个位表示ADD指令是立即模式还是寄存器模式,这就是判断是否用立即模式的标准!

1
ADD R2, R0, R1  ; R2 = R0 + R1   //寄存器模式
1
ADD R0, R0, 1 ; R0 = R0 + 1   //立即模式

AND指令:

代码5-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t r1 = (instr >> 6) & 0x7;
uint16_t imm_flag = (instr >> 5) & 0x1;

if (imm_flag)
{
uint16_t imm5 = sign_extend(instr & 0x1F, 5);
reg[r0] = reg[r1] & imm5;
}
else
{
uint16_t r2 = instr & 0x7;
reg[r0] = reg[r1] & reg[r2];
}
update_flags(r0);
}

按位和也是分两种模式,立即和寄存器。

NOT指令:

代码5-3

1
2
3
4
5
6
7
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t r1 = (instr >> 6) & 0x7;

reg[r0] = ~reg[r1];
update_flags(r0);
}

按位非不存在有立即数这一种说法。

BR指令:

代码5-4

1
2
3
4
5
6
7
8
{
uint16_t pc_offset = sign_extend(instr & 0x1FF, 9);
uint16_t cond_flag = (instr >> 9) & 0x7;
if (cond_flag & reg[R_COND])
{
reg[R_PC] += pc_offset;
}
}

JMP指令:

代码5-5

1
2
3
4
5
{
/* Also handles RET */
uint16_t r1 = (instr >> 6) & 0x7;
reg[R_PC] = reg[r1];
}

JSR指令:

代码5-6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
uint16_t long_flag = (instr >> 11) & 1;
reg[R_R7] = reg[R_PC];
if (long_flag)
{
uint16_t long_pc_offset = sign_extend(instr & 0x7FF, 11);
reg[R_PC] += long_pc_offset; /* JSR */
}
else
{
uint16_t r1 = (instr >> 6) & 0x7;
reg[R_PC] = reg[r1]; /* JSRR */
}
break;
}

这是寄存器跳转指令

LD指令:

代码5-7

1
2
3
4
5
6
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr & 0x1FF, 9);
reg[r0] = mem_read(reg[R_PC] + pc_offset);
update_flags(r0);
}

加载是在内存中进行,所以要算地址。

LDI指令:

代码5-8

1
2
3
4
5
6
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr &0x1ff,9);
reg[r0] = mem_read(mem_read(reg[R_PC] + pc_offset));
update_flags(r0);
}

LDR指令:

代码5-9

1
2
3
4
5
6
7
8
9
{
/* destination register (DR) */
uint16_t r0 = (instr >> 9) & 0x7;
/* PCoffset 9*/
uint16_t pc_offset = sign_extend(instr & 0x1FF, 9);
/* add pc_offset to the current PC, look at that memory location to get the final address */
reg[r0] = mem_read(mem_read(reg[R_PC] + pc_offset));
update_flags(r0);
}

LEA指令:

代码5-10

1
2
3
4
5
6
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr & 0x1FF, 9);
reg[r0] = reg[R_PC] + pc_offset;
update_flags(r0);
}

ST指令:

代码5-11

1
2
3
4
5
6
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr & 0x1FF, 9);
mem_write(reg[R_PC] + pc_offset, reg[r0]);
update_flags(r0);
}

加载寄存器

STI指令:

代码5-12

1
2
3
4
5
6
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr & 0x1ff,9);
mem_write(mem_read(reg[R_PC] + pc_offset),reg[r0]);
update_flags(r0);
}

加载地址

STR指令:

代码5-13

1
2
3
4
5
6
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t r1 = (instr >> 6) & 0x7;
uint16_t offset = sign_extend(instr & 0x3F, 6);
mem_write(reg[r1] + offset, reg[r0]);
}

6、I/O交互

LC-3提供了少量的预定义好的过程来完成一般的任务以及与I/O设备交互。比如有的过程可以读取键盘输入,有的可以在控制台上显示字符串。这些过程叫Trap过程,你可以理解为LC-3的操作系统或者API。每个Trap过程都有一个自己的编码(跟操作码类似)。为了执行Trap过程,需要用到TRAP指令,参数为需要的TRAP号。

代码6-1

1
2
3
4
5
6
7
8
enum {
TRAP_GETC = 0x20, /* get character from keyboard, not echoed onto the terminal */
TRAP_OUT = 0x21, /* output a character */
TRAP_PUTS = 0x22, /* output a word string */
TRAP_IN = 0x23, /* get character from keyboard, echoed onto the terminal */
TRAP_PUTSP = 0x24, /* output a byte string */
TRAP_HALT = 0x25 /* halt the program */
};

代码6-2

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
case OP_TRAP:
{
switch(instr & 0xff)
{
case TRAP_GETC:
{
reg[R_R0] = (uint16_t)getchar(); //输入字符
update_flags(R_R0);
}
break;
case TRAP_OUT:
{
putc((char)reg[R_R0],stdout); //输出字符
fflush(stdout);
}
break;
case TRAP_PUTS:
{
uint16_t* c = memory + reg[R_R0];
while(*c)
{
putc((char)*c,stdout);
++c;
}
fflush(stdout);
}
break;
case TRAP_IN:
{
printf("Enter a character: "); //准备输入字符
char c = getchar();
putc(c,stdout);
fflush(stdout);
reg[R_R0] = (uint16_t)c;
update_flags(R_R0);
}
break;
case TRAP_PUTSP: //输出字符串
{
uint16_t* c = memory + reg[R_R0];
while(*c)
{
char char1 = (*c) & 0xff;
putc(char1, stdout);
char char2 = (*c) >> 8;
if (char2) putc(char2,stdout);
++c;
}
fflush(stdout);
}
break;
case TRAP_HALT: //终止程序
{
puts("HALT");
fflush(stdout);
running = 0;
break;
}
}
}

上面是在trap中嵌套了switch

7、补全代码

代码7-1

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdint.h> // uint16_t
#include <stdio.h> // FILE
#include <signal.h> // SIGINT
/* windows only */
#include <Windows.h>
#include <conio.h> // _kbhit

HANDLE hStdin = INVALID_HANDLE_VALUE;

#define UINT16_MAX 65536

加入api:

代码7-2

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
DWORD fdwMode, fdwOldMode;

void disable_input_buffering()
{
hStdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hStdin, &fdwOldMode); /* save old mode */
fdwMode = fdwOldMode
^ ENABLE_ECHO_INPUT /* no input echo */
^ ENABLE_LINE_INPUT; /* return when one or
more characters are available */
SetConsoleMode(hStdin, fdwMode); /* set new mode */
FlushConsoleInputBuffer(hStdin); /* clear buffer */
}

void restore_input_buffering()
{
SetConsoleMode(hStdin, fdwOldMode);
}

void handle_interrupt(int signal)
{
restore_input_buffering();
printf("\n");
exit(-2);
}

初始化

代码7-3

1
2
signal(SIGINT, handle_interrupt);
disable_input_buffering();

释放

代码7-4

1
restore_input_buffering();

我直接给出脚本:

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<string.h>
#include<signal.h>
#include <Windows.h>
#include <conio.h>

HANDLE hStdin = INVALID_HANDLE_VALUE;

#define UINT16_MAX 65536

uint16_t memory[UINT16_MAX];//创建2的16次方内存即128kb
enum
{
R_R0 = 0,
R_R1,
R_R2,
R_R3,
R_R4,
R_R5,
R_R6,
R_R7,
R_PC, /*程序计数器,相当于rip*/
R_COND,
R_COUNT/*寄存器数量*/
};/*前10个为寄存器,前八个为通用寄存器,cond为条件标志寄存器*/

uint16_t reg[R_COUNT];

enum
{
OP_BR = 0,/*分支*/
OP_ADD,/*添加*/
OP_LD,/*加载*/
OP_ST,/*存储*/
OP_JSR,/*跳转寄存器*/
OP_AND,/*按位和*/
OP_LDR,/*加载寄存器*/
OP_STR,/*存储寄存器*/
OP_RTI,/*未使用*/
OP_NOT,/*按位非*/
OP_LDI,/*加载间接*/
OP_STI,/*存储间接*/

OP_JMP,/*跳转*/
OP_RES,/*保留(未使用)*/
OP_LEA,/*加载有效地址*/
OP_TRAP/*执行陷阱*/
};

enum
{
FL_POS = 1 << 0,/*P*/
FL_ZRO = 1 << 1,/*Z*/
FL_NEG = 1 << 2,/*N*/
};

enum
{
TRAP_GETC = 0X20,/*从键盘获取字符,不回显到终端*/
TRAP_OUT = 0X21,/*输出一个字符*/
TRAP_PUTS = 0X22,/*输出一个单词字符串*/
TRAP_IN = 0X23,/*获取来自键盘的字符,回显到终端*/
TRAP_PUTSP = 0X24,/*输出一个字符串*/
TRAP_HALT =0X25/*停止程序*/
};

enum
{
MR_KBSR = 0XFE00,/*键盘状态*/
MR_KBDR = 0XFE02/*键盘数据*/
};

uint16_t swap16(uint16_t x)
{
return (x << 8) | (x >> 8);/*改成小端序,交换前8位和后8位*/
}
uint16_t sign_extend(uint16_t x, int bit_count)
{
if((x >> (bit_count - 1)) & 1)
{
x |= (0xffff << bit_count);
}
return x;
}

void update_flags(uint16_t r)/*更新标志位*/
{
if (reg[r] == 0)
{
reg[R_COND] = FL_ZRO;
}
else if (reg[r] >> 15)/*最左侧1为负数*/
{
reg[R_COND] = FL_NEG;
}
else
{
reg[R_COND] = FL_POS;
}
}

void read_image_file(FILE* file)
{
uint16_t origin;
fread(&origin,sizeof(origin), 1, file);
origin = swap16(origin);

uint16_t max_read = UINT16_MAX - origin;
uint16_t* p = memory + origin;
size_t read = fread(p,sizeof(uint16_t), max_read,file);

while(read-- > 0)
{
*p = swap16(*p);
++p;
}
}

int read_image(const char* image_path)
{
FILE* file = fopen(image_path, "rb");
if(!file){return 0;};
read_image_file(file);
fclose(file);
return 1;
}

uint16_t check_key()
{
return WaitForSingleObject(hStdin, 1000) == WAIT_OBJECT_0 && _kbhit();
}

void mem_write(uint16_t address,uint16_t val)
{
memory[address] = val;
}

uint16_t mem_read(uint16_t address)
{
if(address == MR_KBSR)
{
if (check_key())
{
memory[MR_KBSR] = (1 << 15);
memory[MR_KBDR] = getchar();
}
else
{
memory[MR_KBSR] = 0;
}
}
return memory[address];
}

DWORD fdwMode, fdwOldMode;

void disable_input_buffering()
{
hStdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hStdin, &fdwOldMode); /* save old mode */
fdwMode = fdwOldMode
^ ENABLE_ECHO_INPUT /* no input echo */
^ ENABLE_LINE_INPUT; /* return when one or
more characters are available */
SetConsoleMode(hStdin, fdwMode); /* set new mode */
FlushConsoleInputBuffer(hStdin); /* clear buffer */
}

void restore_input_buffering()
{
SetConsoleMode(hStdin, fdwOldMode);
}

void handle_interrupt(int signal)
{
restore_input_buffering();
printf("\n");
exit(-2);
}

int main(int argc, const char* argv[])
{
if (argc < 2)
{
printf("lc3 [image-file1]...\n");
exit(2);
}

for (int j = 1; j < argc; ++j)
{
if (!read_image(argv[j]))
{
printf("failed to load image: %s\n",argv[j]);
exit(1);
}
}/*{Load Arguments,5}*/

signal(SIGINT,handle_interrupt);
disable_input_buffering();
reg[R_COND] = FL_ZRO;


enum { PC_START = 0x3000 };
reg[R_PC] = PC_START;

int running = 1;
while (running)
{

uint16_t instr = mem_read(reg[R_PC]++);
uint16_t op = instr >> 12;

switch (op)
{
case OP_ADD:
{
uint16_t r0 = (instr >> 9) & 0x7;/*目标寄存器*/
uint16_t r1 = (instr >> 6) & 0x7;/*第一个操作数SR1*/
uint16_t imm_flag = (instr >> 5) & 0x1;/*是否是立即模式*/

if(imm_flag)
{
uint16_t imm5 =sign_extend(instr & 0x1f,5);
reg[r0] = reg[r1] + imm5;
}
else
{
uint16_t r2 = instr & 0x7;
reg[r0] = reg[r1] + reg[r2];
}
update_flags(r0);
}
break;
case OP_AND:
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t r1 = (instr >> 6) & 0x7;/*第一个操作数SR1*/
uint16_t imm_flag = (instr >> 5) & 0x1;/*是否是立即模式*/

if(imm_flag)
{
uint16_t imm5 =sign_extend(instr & 0x1f,5);
reg[r0] = reg[r1] & imm5;
}
else
{
uint16_t r2 = instr & 0x7;
reg[r0] = reg[r1] & reg[r2];
}
update_flags(r0);
}
break;
case OP_NOT:
{

uint16_t r0 = (instr >> 9) & 0x7;
uint16_t r1 = (instr >> 6) & 0x7;
reg[r0] = ~reg[r1];
update_flags(r0);

}
break;
case OP_BR:
{
uint16_t pc_offset = sign_extend(instr & 0x1ff,9);
uint16_t cond_flag = (instr >> 9) & 0x7;
if(cond_flag & reg[R_COND])
{
reg[R_PC] += pc_offset;
}

}
break;
case OP_JMP:
{
uint16_t r1 = (instr >> 6) & 0x7;
reg[R_PC] = reg[r1];
}
break;
case OP_JSR:
{
uint16_t long_flag = (instr >> 11) & 1;
reg[R_R7] = reg[R_PC];
if(long_flag)
{
uint16_t long_pc_offset = sign_extend(instr & 0x7ff,11);
reg[R_PC] += long_pc_offset;
}
else
{
uint16_t r1 = (instr >> 6) & 0x7;
reg[R_PC] = reg[r1];
}
break;
}
break;
case OP_LD:
{
uint16_t r0 =(instr >> 9) & 0x7;
uint16_t pc_offset =sign_extend(instr & 0x1ff,9);
reg[r0] = mem_read(reg[R_PC] + pc_offset);
update_flags(r0);
}
break;
case OP_LDI:
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr &0x1ff,9);
reg[r0] = mem_read(mem_read(reg[R_PC] + pc_offset));
update_flags(r0);
}
break;
case OP_LDR:
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t r1 = (instr >> 6) & 0x7;
uint16_t offset =sign_extend(instr & 0x3f,6);
reg[r0] = mem_read(reg[r1] + offset);
update_flags(r0);
}
break;
case OP_LEA:
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr & 0x1FF, 9);
reg[r0] = reg[R_PC] + pc_offset;
update_flags(r0);
}
break;
case OP_ST:
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr & 0x1ff,9);
mem_write(reg[R_PC] + pc_offset,reg[r0]);
}
break;
case OP_STI:
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t pc_offset = sign_extend(instr & 0x1ff,9);
mem_write(mem_read(reg[R_PC] + pc_offset),reg[r0]);
}
break;
case OP_STR:
{
uint16_t r0 = (instr >> 9) & 0x7;
uint16_t r1 = (instr >> 6) & 0x7;
uint16_t offset = sign_extend(instr & 0x3F, 6);
mem_write(reg[r1] + offset, reg[r0]);
}
break;
case OP_TRAP:
{
switch(instr & 0xff)
{
case TRAP_GETC:
{
reg[R_R0] = (uint16_t)getchar();
update_flags(R_R0);
}
break;
case TRAP_OUT:
{
putc((char)reg[R_R0],stdout);
fflush(stdout);
}
break;
case TRAP_PUTS:
{
uint16_t* c = memory + reg[R_R0];
while(*c)
{
putc((char)*c,stdout);
++c;
}
fflush(stdout);
}
break;
case TRAP_IN:
{
printf("Enter a character: ");
char c = getchar();
putc(c,stdout);
fflush(stdout);
reg[R_R0] = (uint16_t)c;
update_flags(R_R0);
}
break;
case TRAP_PUTSP:
{
uint16_t* c = memory + reg[R_R0];
while(*c)
{
char char1 = (*c) & 0xff;
putc(char1, stdout);
char char2 = (*c) >> 8;
if (char2) putc(char2,stdout);
++c;
}
fflush(stdout);
}
break;
case TRAP_HALT:
{
puts("HALT");
fflush(stdout);
running = 0;
break;
}
}
}
break;
case OP_RES:
case OP_RTI:
default:
abort();
break;

}
}
restore_input_buffering();
}

我们下载2048软件,来验证是否建好了虚拟机。

成功!!

Buuctf

1、lucky_guy

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
unsigned __int64 get_flag()
{
unsigned int v0; // eax
int i; // [rsp+4h] [rbp-3Ch]
int j; // [rsp+8h] [rbp-38h]
__int64 s; // [rsp+10h] [rbp-30h] BYREF
char v5; // [rsp+18h] [rbp-28h]
unsigned __int64 v6; // [rsp+38h] [rbp-8h]

v6 = __readfsqword(0x28u);
v0 = time(0LL);
srand(v0);
for ( i = 0; i <= 4; ++i )
{
switch ( rand() % 200 )
{
case 1:
puts("OK, it's flag:");
memset(&s, 0, 0x28uLL);
strcat((char *)&s, f1);
strcat((char *)&s, &f2);
printf("%s", (const char *)&s);
break;
case 2:
printf("Solar not like you");
break;
case 3:
printf("Solar want a girlfriend");
break;
case 4:
s = 0x7F666F6067756369LL;
v5 = 0;
strcat(&f2, (const char *)&s);
break;
case 5:
for ( j = 0; j <= 7; ++j )
{
if ( j % 2 == 1 )
*(&f2 + j) -= 2;
else
--*(&f2 + j);
}
break;
default:
puts("emmm,you can't find flag 23333");
break;
}
}
return __readfsqword(0x28u) ^ v6;
}

这是主函数,switch中有5个case,case1中f1有半截字符串,我们要得到f2,拼起来才是我们要的flag,那么要f2肯定得从case4出发,到case5,才能得到f2,所以我们很清楚了,注意s是小端序

1
2
3
4
5
6
7
8
9
s=[0x69,0x63,0x75,0x67,0x60,0x6F,0x66,0x7F]
flag = ''
for i in range(8):
if(i%2==1):
flag+=chr(s[i]-2)
else:
flag+=chr(s[i]-1)
print("GXY{do_not_"+ flag)
#GXY{do_not_hate_me}

2、刮开有奖

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
INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
const char *v4; // esi
const char *v5; // edi
int v7[2]; // [esp+8h] [ebp-20030h] BYREF
int v8; // [esp+10h] [ebp-20028h]
int v9; // [esp+14h] [ebp-20024h]
int v10; // [esp+18h] [ebp-20020h]
int v11; // [esp+1Ch] [ebp-2001Ch]
int v12; // [esp+20h] [ebp-20018h]
int v13; // [esp+24h] [ebp-20014h]
int v14; // [esp+28h] [ebp-20010h]
int v15; // [esp+2Ch] [ebp-2000Ch]
int v16; // [esp+30h] [ebp-20008h]
CHAR String[65536]; // [esp+34h] [ebp-20004h] BYREF
char v18[65536]; // [esp+10034h] [ebp-10004h] BYREF

if ( a2 == 272 )
return 1;
if ( a2 != 273 )
return 0;
if ( (_WORD)a3 == 1001 )
{
memset(String, 0, 0xFFFFu);
GetDlgItemTextA(hDlg, 1000, String, 0xFFFF);
if ( strlen(String) == 8 )
{
v7[0] = 'Z';
v7[1] = 'J';
v8 = 83;
v9 = 69;
v10 = 'C';
v11 = 97;
v12 = 78;
v13 = 72;
v14 = 51;
v15 = 110;
v16 = 103;
sub_1710F0((int)v7, 0, 10);
memset(v18, 0, 0xFFFFu);
v18[0] = String[5];
v18[2] = String[7];
v18[1] = String[6];
v4 = sub_171000((int)v18, strlen(v18));
memset(v18, 0, 0xFFFFu);
v18[1] = String[3];
v18[0] = String[2];
v18[2] = String[4];
v5 = sub_171000((int)v18, strlen(v18));
if ( String[0] == v7[0] + 34
&& String[1] == v10
&& 4 * String[2] - 141 == 3 * v8
&& String[3] / 4 == 2 * (v13 / 9)
&& !strcmp(v4, "ak1w")
&& !strcmp(v5, "V1Ax") )
{
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
}
}
return 0;
}
if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
return 0;
EndDialog(hDlg, (unsigned __int16)a3);
return 1;
}

很简单,string长8位,从if中判断前两位分别是,U,J,然后,后六位是两个base64解密移位就出来了。

下面是base64反编译,没有换标

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
_BYTE *__cdecl sub_171000(int a1, int a2)
{
int v2; // eax
int v3; // esi
size_t v4; // ebx
_BYTE *v5; // eax
_BYTE *v6; // edi
int v7; // eax
_BYTE *v8; // ebx
int v9; // edi
int v10; // edx
int v11; // edi
int v12; // eax
int i; // esi
_BYTE *result; // eax
_BYTE *v15; // [esp+Ch] [ebp-10h]
_BYTE *v16; // [esp+10h] [ebp-Ch]
int v17; // [esp+14h] [ebp-8h]
int v18; // [esp+18h] [ebp-4h]

v2 = a2 / 3;
v3 = 0;
if ( a2 % 3 > 0 )
++v2;
v4 = 4 * v2 + 1;
v5 = malloc(v4);
v6 = v5;
v15 = v5;
if ( !v5 )
exit(0);
memset(v5, 0, v4);
v7 = a2;
v8 = v6;
v16 = v6;
if ( a2 > 0 )
{
while ( 1 )
{
v9 = 0;
v10 = 0;
v18 = 0;
do
{
if ( v3 >= v7 )
break;
++v10;
v9 = *(unsigned __int8 *)(v3 + a1) | (v9 << 8);
++v3;
}
while ( v10 < 3 );
v11 = v9 << (8 * (3 - v10));
v12 = 0;
v17 = v3;
for ( i = 18; i > -6; i -= 6 )
{
if ( v10 >= v12 )
{
*((_BYTE *)&v18 + v12) = (v11 >> i) & 0x3F;
v8 = v16;
}
else
{
*((_BYTE *)&v18 + v12) = 64;
}
*v8++ = byte_177830[*((char *)&v18 + v12++)];
v16 = v8;
}
v3 = v17;
if ( v17 >= a2 )
break;
v7 = a2;
}
v6 = v15;
}
result = v6;
*v8 = 0;
return result;
}

3、findit

有一说一这个题不太好猜。

image-20220210153616734

猜测第一个数组是就是flag,其实不是,第二个才是,但搞出来后发现是:

pvkq{m164675262033l4m49lnp7p9mnk28k75}

flag{c164675262033b4c49bdf7f9cda28a75}

然后又猜测是凯撒密码,有点难猜

4、pyre

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
#!/usr/bin/env python

# visit https://tool.lu/pyc/ for more information

print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128 + 128) % 128
code += num

for i in range(l - 1):
code[i] = code[i] ^ code[i + 1]

print code
code = [
'\x1f',
'\x12',
'\x1d',
'(',
'0',
'4',
'\x01',
'\x06',
'\x14',
'4',
',',
'\x1b',
'U',
'?',
'o',
'6',
'*',
':',
'\x01',
'D',
';',
'%',
'\x13']

这是一个pyc文件,所以在线反编译,逆向就行了

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
code = [
'\x1f',
'\x12',
'\x1d',
'(',
'0',
'4',
'\x01',
'\x06',
'\x14',
'4',
',',
'\x1b',
'U',
'?',
'o',
'6',
'*',
':',
'\x01',
'D',
';',
'%',
'\x13']
for i in range(len(code)-2,-1,-1):
code[i] = chr(ord(code[i])^ord(code[i+1]))
flag = ""
for i in range(23):
for j in range(27,127):
num = ((j + i) % 128 + 128) % 128
if num==ord(code[i]):
flag+=chr(j)
break
print(flag)

5 easyre

非常简单,就是一个在数组里寻数的问题,可以用类似爆破的脚本完成。

1
2
3
4
5
6
7
8
9
10
v4 = [42,70,39,34,78,44,34,40,73,63,43,64]
string = chr(0x7E)+"}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(" + chr(0x27) + '&%$# !"'
flag=""

for i in v4:
for j in range(1,len(string)):
if i == ord(string[j]):
flag+=chr(j+1)

print ("flag{"+flag+"}")

6 rsa

这个rsa难的地方在于,给了两个包,不好打开,注册表打开,可以将其后缀变成txt,或者直接在

http://tool.chacuo.net/cryptrsakeyparse进行n ,e的提取,还给了个enc文件,无法提取,因为这个c是乱码,所以,直接用文件提取来搞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import gmpy2
import rsa

e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463

phin = (q-1)*(p-1)
d = gmpy2.invert(e, phin)

key = rsa.PrivateKey(n, e, int(d), p, q)

with open("C:\\Users\\10245\\Desktop\\output\\flag.enc", "rb+") as f:
f = f.read()
print(rsa.decrypt(f, key))
#flag{decrypt_256}

7、rome

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
int func()
{
int result; // eax
int v1[4]; // [esp+14h] [ebp-44h]
unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREF
unsigned __int8 v3; // [esp+25h] [ebp-33h]
unsigned __int8 v4; // [esp+26h] [ebp-32h]
unsigned __int8 v5; // [esp+27h] [ebp-31h]
unsigned __int8 v6; // [esp+28h] [ebp-30h]
int v7; // [esp+29h] [ebp-2Fh]
int v8; // [esp+2Dh] [ebp-2Bh]
int v9; // [esp+31h] [ebp-27h]
int v10; // [esp+35h] [ebp-23h]
unsigned __int8 v11; // [esp+39h] [ebp-1Fh]
char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREF

strcpy(v12, "Qsw3sj_lz4_Ujw@l");
printf("Please input:");
scanf("%s", &v2);
result = v2;
if ( v2 == 'A' )
{
result = v3;
if ( v3 == 'C' )
{
result = v4;
if ( v4 == 'T' )
{
result = v5;
if ( v5 == 'F' )
{
result = v6;
if ( v6 == '{' )
{
result = v11;
if ( v11 == '}' )
{
v1[0] = v7;
v1[1] = v8;
v1[2] = v9;
v1[3] = v10;
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 64 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 90 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 51) % 26 + 65;
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 96 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 122 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 79) % 26 + 97;
++*(_DWORD *)&v12[17];
}
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
result = (unsigned __int8)v12[*(_DWORD *)&v12[17]];
if ( *((_BYTE *)v1 + *(_DWORD *)&v12[17]) != (_BYTE)result )
return result;
++*(_DWORD *)&v12[17];
}
return printf("You are correct!");
}
}
}
}
}
}
return result;
}

这个题就是flag经过变换,要和上面字符串一样,那么最好的办法就是爆破

1
2
3
4
5
6
7
8
9
10
11
12
x = [81,115,119,51,115,106,95,108,122,52,95,85,106,119,64,108]
flag = ''
for k in range(0,16):
for i in range(0,127):
z = i
if i > 64 and i <= 90:
i = (i-51)%26 + 65
if i > 96 and i <= 122:
i = (i-79)%26 + 97
if(i == x[k]):
flag += chr(z)
print(flag)

8 level1

这个题很显然直接逆向或者爆破都可以

读入文件而已,要注意读入的字符串长度是20,而不是文件里给的19,所以要加上个0

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
a=[0,198,
232,
816,
200,
1536,
300,
6144,
984,
51200,
570,
92160,
1200,
565248,
756,
1474560,
800,
6291456,
1782,
65536000,
]
flag=""
for i in range(19):
for j in range(27,127):
if((i&1)!=0):
c=j<<i
if c == a[i]:
flag+=chr(j)
break
else:
c=i*j
if c == a[i]:
flag+=chr(j)
break
print(flag)

tf2020{d9-dE6-20c,括号中就是。

9、TRANSFORM

我们要求的flag分别进行了移位和异或操作,有点简单。

1
2
3
4
5
6
7
8
9
a = [0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79, 0x57, 0x5E, 0x5D, 0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E, 0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E, 0x65, 0x3C, 0x5C, 0x45, 0x6F, 0x62, 0x4D,0x3F]
b=[0x00000009, 0x0000000A, 0x0000000F, 0x00000017, 0x00000007, 0x00000018, 0x0000000C, 0x00000006, 0x00000001, 0x00000010, 0x00000003, 0x00000011, 0x00000020, 0x0000001D, 0x0000000B, 0x0000001E, 0x0000001B, 0x00000016, 0x00000004, 0x0000000D, 0x00000013, 0x00000014, 0x00000015, 0x00000002, 0x00000019, 0x00000005, 0x0000001F, 0x00000008, 0x00000012, 0x0000001A, 0x0000001C, 0x0000000E,0x8]
c=[0]*33
for i in range(33):
a[i]^=b[i]
c[b[i]] = a[i]
for i in range(33):
print(chr(c[i]))
#flag{Tr4nsp0sltiON_Clph3r_1s_3z}

10、urual加密

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // esi
int v5[3]; // [esp+8h] [ebp-74h] BYREF
__int16 v6; // [esp+14h] [ebp-68h]
char v7; // [esp+16h] [ebp-66h]
char v8[100]; // [esp+18h] [ebp-64h] BYREF

sub_403CF8(&aGiveMeYourFlag[1]);
scanf("%s", v8);
memset(v5, 0, sizeof(v5));
v6 = 0;
v7 = 0;
sub_401080(v8, strlen(v8), v5); // BASE64未换表加密
v3 = 0;
while ( *((_BYTE *)v5 + v3) == byte_40E0E4[v3] )
{
if ( ++v3 > strlen((const char *)v5) )
goto LABEL_6;
}
sub_403CF8(aError);
LABEL_6:
if ( v3 - 1 == strlen(byte_40E0E4) )
return sub_403CF8(aAreYouHappyYes);
else
return sub_403CF8(aAreYouHappyNo);
}

然后我试图直接解密,发现不对,这里面还有一个函数

是进行将大小写互换的:secret = ‘zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9’.swapcase()

这样进行大小写互换

然后解密就行了

11、maze

这个题先upx搞一下,然后就是走迷宫,

1
2
3
4
5
6
*******+**
******* **
**** **
** *****
** **F****
** ****

很明显是从+到F,w表示上,a表示左,s表示下,d表示右。结束!


12、相册

这个安卓题还是很难的,有我三面的味了,很real

从字符串中查找,发现应该跟base64有关,我们找一下对应so文件用ida打开

NativeMethod在java里面通常用于调用外部非java的程序。Java有能力调用其他语言编写的函数or方法,这个通过JNI(Java Native Interfface)实现。使用时,通过native关键字告诉JVM这个方法是在外部定义的。

解出来就对了

hgame-week1

前言:有一说一,题质量是真高,好多逆向题,我用z3,爆破做不出来,人都快疯了,misc是真的出成全家福了。

RE

1、easyasm

这个题考察汇编能力,简单来说就是flag左移4位和flag右移4位再相加赋值给ax,然后再异或17h,这个题z3和爆破应该都行,但我没出来,1ens师傅说这就是高低位互换,所以给出脚本:

1
2
3
4
5
6
a=[0x91, 0x61, 0x01, 0xC1, 0x41, 0xA0, 0x60, 0x41, 0xD1, 0x21, 0x14, 0xC1, 0x41, 0xE2, 0x50, 0xE1, 0xE2, 0x54, 0x20, 0xC1, 0xE2, 0x60, 0x14, 0x30, 0xD1, 0x51, 0xC0, 0x17]
c=""
for i in range(28):
c += chr((((a[i]^0x17)&0xF)<<4)|(((a[i]^0x17)&0xF0)>>4))
print(c)
#hgame{welc0me_to_4sm_w0rld}

creakme

这个题

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // edx
int i; // esi
unsigned int v5; // edi
unsigned int v6; // ebx
int v7; // esi
int v8; // esi
_DWORD v10[17]; // [esp+Ch] [ebp-8Ch] BYREF
__int128 v11[2]; // [esp+50h] [ebp-48h]
char Arglist[32]; // [esp+70h] [ebp-28h] BYREF
int v13; // [esp+90h] [ebp-8h]
int v14; // [esp+94h] [ebp-4h]

memset(Arglist, 0, sizeof(Arglist));
sub_40103A("%s", (char)Arglist);
strcpy((char *)v10, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");
v3 = 0;
v14 = 0;
for ( i = 0; i < 32; v14 = i )
{
v5 = *(_DWORD *)&Arglist[i];
v6 = *(_DWORD *)&Arglist[i + 4];
v13 = 0;
v7 = 32;
do
{
v3 += 305419896;
v5 += v3 ^ (v3 + v6) ^ (v10[2] + 16 * v6) ^ (v10[3] + (v6 >> 5));
v6 += v3 ^ (v3 + v5) ^ (v10[0] + 16 * v5) ^ (v10[1] + (v5 >> 5));
--v7;
}
while ( v7 );
v8 = v14;
v3 = 0;
*(_DWORD *)&Arglist[v14] = v5;
*(_DWORD *)&Arglist[v8 + 4] = v6;
i = v8 + 8;
}
v11[0] = xmmword_402180;
v11[1] = xmmword_402170;
while ( Arglist[v3] == *((_BYTE *)v11 + v3) )
{
if ( ++v3 >= 32 )
{
sub_40100C("right!", v10[0]);
return 0;
}
}
sub_40100C("wrong!", v10[0]);
return 0;
}

按理说z3能跑出来的,但我没跑出来。这个题最重要的就是中间这两个运算,后来发现是tea魔改,但我没看出来,卡了好久才想出来

给出脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
void tea_decrypt(uint32_t* v, uint32_t* k) { 
uint32_t v0 = v[0], v1 = v[1], sum = 0x12345678 * 32, i; //注意sum的值
uint32_t delta = 0x12345678;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++)
{
v1 -= ((v0 << 4) + k0) ^ (v0 + sum) ^ ((v0 >> 5) + k1) ^ sum;
v0 -= ((v1 << 4) + k2) ^ (v1 + sum) ^ ((v1 >> 5) + k3) ^ sum;
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}

Flag checker

很简单的安卓逆向,先进行RC4解密,密钥是carol,然后进行base64,因为RC4是在存在的字符中进行运算的,所以先进行。

有些小简单。不多写了

猫头鹰是不是猫

这个题还好,很好理解,不过z3还是没跑出来,我真是快疯了,这题数出的怎么这么折磨人!!!!!!

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
int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+Ch] [rbp-154h]
int v5[64]; // [rsp+10h] [rbp-150h] BYREF
__int64 v6[10]; // [rsp+110h] [rbp-50h] BYREF

v6[9] = __readfsqword(0x28u);
memset(v6, 0, 64);
memset(v5, 0, sizeof(v5));
v5[0] = 1;
((void (__fastcall *)(__int64 *, char **, int *))((char *)&sub_11E8 + 1))(v6, a2, v5);
puts("Welcome to HGAME2022...");
puts("This is cat?");
sub_124E(&unk_4140);
puts("This is owl?");
sub_124E(&unk_8140);
fflush(stdout);
__isoc99_scanf("%64s", v6); //以上都没有用,画了两个图而已
for ( i = 0; i <= 63; ++i )
v5[i] = *((char *)v6 + i);
sub_1537(v5);
if ( (unsigned int)sub_12E6(v5, &unk_4040) )
puts("failed");
else
puts("win");
return 0LL;
}

我们看循环中的函数

1
2
3
4
5
6
7
int64 __fastcall sub_1537(__int64 a1)
{
sub_1347(a1, &unk_4140);
return sub_1347(a1, &unk_8140);
}


进行了两次该函数,

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
unsigned __int64 __fastcall sub_1347(__int64 a1, __int64 a2)
{
int v3; // [rsp+18h] [rbp-128h]
int i; // [rsp+1Ch] [rbp-124h]
int j; // [rsp+20h] [rbp-120h]
int k; // [rsp+24h] [rbp-11Ch]
int m; // [rsp+28h] [rbp-118h]
int n; // [rsp+2Ch] [rbp-114h]
int v9[66]; // [rsp+30h] [rbp-110h] BYREF
unsigned __int64 v10; // [rsp+138h] [rbp-8h]

v10 = __readfsqword(0x28u);
memset(v9, 0, 0x100uLL);
for ( i = 0; i <= 63; ++i )
{
for ( j = 0; j <= 63; ++j )
*(_DWORD *)(((__int64)i << 8) + a2 + 4LL * j) = *(_DWORD *)(a2 + ((__int64)i << 8) + 4LL * j) / 10;
}
for ( k = 0; k <= 63; ++k )
{
v3 = 0;
for ( m = 0; m <= 63; ++m )
v3 += *(_DWORD *)(4LL * m + a1) * *(_DWORD *)(a2 + ((__int64)m << 8) + 4LL * k);
v9[k] = v3;
}
for ( n = 0; n <= 63; ++n )
*(_DWORD *)(a1 + 4LL * n) = v9[n];
return __readfsqword(0x28u) ^ v10;
}

我们通过动调发现能看出a2,a2就是经过了移位,相当于矩阵移位了,然后进行矩阵相乘,我们只需要求逆矩阵,当然刚开始想的是z3,但是日啊,搞不出来啊,真烦人woc,开始用逆矩阵规规矩矩求逆。也学习了一下逆矩阵怎么求。

学习到:使用方法:round(number,digits)

  1. digits>0,四舍五入到指定的小数位
  2. digits=0, 四舍五入到最接近的整数
  3. digits<0 ,在小数点左侧进行四舍五入
  4. 如果round()函数只有number这个参数,等同于digits=0

矩阵取一个元素
X[i, j]—->取矩阵X的第 i 行第 j 列的元素

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
import numpy as np
a3=[0x0000000F,0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000C,
0x0000000A, 0x0000000D, 0x00000015, 0x00000011, 0x0000000E, 0x0000000B, 0x0000000A, 0x0000000B, 0x00000010,
0x00000011, 0x00000008, 0x00000008, 0x00000007, 0x0000000A, 0x0000000C, 0x0000000D, 0x0000000C, 0x00000010,
0x00000012, 0x00000009, 0x00000006, 0x00000007, 0x00000008, 0x00000007, 0x00000008, 0x00000009, 0x00000008,
0x00000009, 0x0000000A, 0x0000000C, 0x0000000C, 0x0000000E, 0x00000010, 0x00000010, 0x0000000E, 0x00000009,
0x00000004, 0x00000003, 0x00000005, 0x00000006, 0x00000006, 0x00000006, 0x00000003, 0x00000004, 0x00000006,
0x00000006, 0x00000005, 0x00000005, 0x00000005, 0x00000005, 0x00000004, 0x00000005, 0x00000007, 0x00000005,
0x00000004, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000D,
0x0000000C, 0x0000000B, 0x00000015, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000B, 0x0000000A, 0x00000008,
0x00000008, 0x0000000A, 0x00000008, 0x00000008, 0x00000007, 0x00000009, 0x0000000B, 0x0000000B, 0x0000000B,
0x00000013, 0x0000000D, 0x0000000C, 0x00000005, 0x00000006, 0x00000007, 0x00000007, 0x00000008, 0x00000009,
0x00000009, 0x0000000A, 0x0000000C, 0x0000000F, 0x00000011, 0x00000011, 0x00000011, 0x00000010, 0x0000000A,
0x00000004, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 0x00000007, 0x00000006, 0x00000004, 0x00000005,
0x00000007, 0x00000006, 0x00000006, 0x00000005, 0x00000005, 0x00000004, 0x00000003, 0x00000005, 0x00000006,
0x00000004, 0x00000003, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E,
0x0000000D, 0x0000000C, 0x00000013, 0x0000000F, 0x0000000D, 0x0000000F, 0x0000000E, 0x0000000C, 0x0000000A,
0x00000008, 0x00000008, 0x00000009, 0x00000008, 0x00000008, 0x00000007, 0x00000009, 0x0000000A, 0x00000009,
0x00000010, 0x0000000E, 0x00000008, 0x00000011, 0x00000005, 0x00000006, 0x00000009, 0x00000010, 0x00000011,
0x00000011, 0x00000012, 0x00000012, 0x00000013, 0x00000015, 0x00000016, 0x00000016, 0x00000015, 0x00000013,
0x0000000A, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 0x00000009, 0x00000009, 0x00000006, 0x00000005,
0x00000008, 0x00000008, 0x00000006, 0x00000006, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
0x00000004, 0x00000003, 0x00000003, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x00000013, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000D,
0x0000000C, 0x0000000A, 0x00000009, 0x00000009, 0x00000009, 0x00000008, 0x00000007, 0x00000009, 0x0000000A,
0x0000000C, 0x00000012, 0x0000000A, 0x00000008, 0x00000012, 0x00000006, 0x00000006, 0x00000007, 0x00000007,
0x00000006, 0x00000007, 0x00000008, 0x00000009, 0x0000000C, 0x0000000F, 0x00000014, 0x0000000E, 0x0000000A,
0x00000005, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 0x00000009, 0x0000000A, 0x0000000A, 0x00000007,
0x00000007, 0x00000009, 0x00000009, 0x00000007, 0x00000006, 0x00000006, 0x00000005, 0x00000006, 0x00000006,
0x00000006, 0x00000006, 0x00000005, 0x00000005, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x00000012, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000C, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000A, 0x0000000A, 0x0000000B,
0x0000000E, 0x00000017, 0x00000012, 0x00000012, 0x00000012, 0x00000014, 0x0000000C, 0x00000007, 0x00000007,
0x00000007, 0x00000006, 0x00000006, 0x00000008, 0x0000000A, 0x0000000D, 0x0000000E, 0x00000014, 0x0000000B,
0x00000006, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000A,
0x00000007, 0x00000009, 0x0000000B, 0x00000009, 0x00000007, 0x00000006, 0x00000006, 0x00000006, 0x00000007,
0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000006, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000E,
0x0000000D, 0x0000000E, 0x0000000F, 0x0000000E, 0x0000000C, 0x00000014, 0x00000008, 0x00000008, 0x0000000B,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D, 0x00000011, 0x00000016, 0x0000000F, 0x0000000C, 0x0000000C,
0x0000000E, 0x00000016, 0x0000000E, 0x0000000D, 0x0000000C, 0x00000009, 0x00000008, 0x00000013, 0x00000007,
0x00000007, 0x00000007, 0x00000006, 0x00000006, 0x00000007, 0x00000009, 0x0000000C, 0x0000000D, 0x00000014,
0x0000000A, 0x00000007, 0x00000006, 0x00000006, 0x00000008, 0x00000009, 0x0000000A, 0x0000000C, 0x0000000C,
0x0000000A, 0x00000009, 0x0000000B, 0x0000000B, 0x0000000A, 0x00000008, 0x00000007, 0x00000007, 0x00000007,
0x00000007, 0x00000008, 0x00000007, 0x00000007, 0x00000007, 0x00000006, 0x0000000F, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000D, 0x0000000E, 0x0000000F, 0x0000000D, 0x00000007, 0x0000000A, 0x00000010, 0x00000004,
0x00000005, 0x0000000C, 0x0000000F, 0x00000013, 0x00000016, 0x00000013, 0x0000000D, 0x0000000C, 0x0000000C,
0x0000000D, 0x00000016, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000C, 0x00000009, 0x00000007, 0x00000011,
0x0000000B, 0x00000008, 0x00000007, 0x00000006, 0x00000005, 0x00000006, 0x00000009, 0x0000000C, 0x0000000D,
0x00000014, 0x0000000B, 0x0000000A, 0x00000008, 0x00000008, 0x00000009, 0x0000000B, 0x0000000B, 0x0000000D,
0x0000000C, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000B, 0x0000000B, 0x00000009, 0x00000008, 0x00000007,
0x00000007, 0x00000008, 0x00000008, 0x00000008, 0x00000007, 0x00000007, 0x00000006, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000B, 0x00000003, 0x00000002, 0x00000009,
0x00000011, 0x00000012, 0x00000013, 0x00000013, 0x00000012, 0x0000000D, 0x0000000C, 0x0000000C, 0x0000000C,
0x0000000C, 0x00000010, 0x00000012, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000B, 0x00000009, 0x00000008,
0x0000000E, 0x0000000D, 0x00000007, 0x00000008, 0x00000006, 0x00000005, 0x00000006, 0x00000009, 0x0000000B,
0x0000000C, 0x00000014, 0x0000000C, 0x0000000B, 0x0000000A, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000C,
0x0000000D, 0x0000000C, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000C, 0x0000000B, 0x0000000A, 0x00000008,
0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000007, 0x00000007, 0x00000006, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000E, 0x00000007, 0x00000002, 0x00000004,
0x00000004, 0x00000004, 0x00000004, 0x00000003, 0x00000003, 0x00000009, 0x0000000A, 0x0000000A, 0x0000000B,
0x0000000B, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000B, 0x00000008,
0x00000007, 0x00000005, 0x00000004, 0x00000006, 0x00000007, 0x00000006, 0x00000005, 0x00000005, 0x00000008,
0x0000000A, 0x0000000B, 0x00000014, 0x0000000D, 0x0000000C, 0x0000000B, 0x0000000B, 0x0000000C, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000A,
0x00000009, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000007, 0x00000007, 0x00000006,
0x0000000F, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x00000003, 0x00000004,
0x00000005, 0x00000005, 0x00000005, 0x00000004, 0x00000003, 0x00000003, 0x00000003, 0x00000007, 0x00000009,
0x0000000B, 0x0000000C, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000C, 0x0000000C, 0x0000000B, 0x00000009,
0x00000007, 0x00000005, 0x00000005, 0x00000005, 0x00000005, 0x00000004, 0x00000003, 0x00000003, 0x00000003,
0x00000003, 0x00000004, 0x00000007, 0x0000000B, 0x0000000B, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000D,
0x0000000D, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000C,
0x0000000B, 0x00000009, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000007, 0x00000006,
0x00000005, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000B, 0x00000003,
0x00000005, 0x00000006, 0x00000006, 0x00000004, 0x00000004, 0x00000003, 0x00000003, 0x00000003, 0x00000003,
0x00000009, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000A, 0x0000000B, 0x00000009, 0x00000008,
0x00000007, 0x00000005, 0x00000004, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000004, 0x00000007, 0x0000000A, 0x0000000B, 0x0000000D,
0x0000000E, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D,
0x0000000C, 0x0000000B, 0x0000000A, 0x00000009, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000007,
0x00000006, 0x00000005, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x00000009,
0x00000003, 0x00000005, 0x00000006, 0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000002,
0x00000002, 0x00000004, 0x0000000B, 0x0000000C, 0x0000000A, 0x00000008, 0x00000007, 0x00000005, 0x00000004,
0x00000004, 0x00000004, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000003, 0x00000004, 0x00000004, 0x00000005,
0x00000009, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000C, 0x0000000B, 0x00000009, 0x00000009, 0x00000008, 0x00000008, 0x00000008, 0x00000008,
0x00000007, 0x00000005, 0x00000006, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D,
0x00000007, 0x00000004, 0x00000006, 0x00000006, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
0x00000002, 0x00000002, 0x00000002, 0x00000004, 0x00000009, 0x00000009, 0x00000005, 0x00000003, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000005, 0x00000005, 0x00000003,
0x00000002, 0x00000002, 0x00000006, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E,
0x0000000D, 0x0000000C, 0x0000000B, 0x00000009, 0x00000008, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
0x00000008, 0x00000007, 0x00000005, 0x00000006, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D,
0x0000000C, 0x00000004, 0x00000005, 0x00000007, 0x00000006, 0x00000005, 0x00000004, 0x00000004, 0x00000003,
0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000004, 0x00000004, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000002, 0x00000003, 0x00000003, 0x00000003, 0x00000003,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000004, 0x00000006, 0x00000006,
0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000005, 0x00000009, 0x0000000C, 0x0000000E, 0x0000000E,
0x0000000C, 0x00000008, 0x00000006, 0x00000005, 0x00000005, 0x00000006, 0x00000007, 0x00000006, 0x00000006,
0x00000006, 0x00000007, 0x00000006, 0x00000005, 0x00000006, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000D, 0x0000000B, 0x00000004, 0x00000005, 0x00000007, 0x00000006, 0x00000005, 0x00000005, 0x00000004,
0x00000004, 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000004,
0x00000007, 0x00000009, 0x0000000A, 0x00000009, 0x00000007, 0x00000004, 0x00000002, 0x00000004, 0x00000004,
0x00000004, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000004, 0x00000004,
0x00000004, 0x00000004, 0x00000004, 0x00000003, 0x00000003, 0x00000004, 0x00000005, 0x00000009, 0x0000000C,
0x0000000A, 0x00000004, 0x00000003, 0x00000004, 0x00000003, 0x00000003, 0x00000004, 0x00000006, 0x00000006,
0x00000007, 0x00000008, 0x00000007, 0x00000005, 0x00000004, 0x00000006, 0x0000000F, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000D, 0x0000000A, 0x00000003, 0x00000005, 0x00000007, 0x00000006, 0x00000005, 0x00000004,
0x00000004, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000007,
0x0000000D, 0x0000000D, 0x0000000C, 0x0000000D, 0x00000012, 0x0000000E, 0x0000000A, 0x00000005, 0x00000001,
0x00000004, 0x00000004, 0x00000004, 0x00000005, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000004,
0x00000004, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000005, 0x00000006, 0x00000006, 0x00000005,
0x00000006, 0x00000005, 0x00000004, 0x00000004, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000005,
0x00000007, 0x00000008, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000003, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000D, 0x00000009, 0x00000004, 0x00000006, 0x00000007, 0x00000007, 0x00000005,
0x00000005, 0x00000004, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000008,
0x00000010, 0x00000011, 0x0000000F, 0x0000000A, 0x00000007, 0x00000009, 0x0000000F, 0x0000000D, 0x0000000B,
0x00000005, 0x00000002, 0x00000003, 0x00000006, 0x00000006, 0x00000007, 0x00000004, 0x00000002, 0x00000002,
0x00000003, 0x00000001, 0x00000000, 0x00000001, 0x00000004, 0x00000003, 0x00000005, 0x00000004, 0x00000005,
0x00000006, 0x00000004, 0x00000003, 0x00000004, 0x00000004, 0x00000004, 0x00000005, 0x00000004, 0x00000003,
0x00000005, 0x00000009, 0x0000000A, 0x0000000A, 0x00000006, 0x00000003, 0x00000002, 0x00000002, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x00000007, 0x00000004, 0x00000005, 0x00000007, 0x00000007,
0x00000006, 0x00000005, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000003, 0x00000003, 0x00000006,
0x00000010, 0x00000012, 0x00000011, 0x00000006, 0x00000004, 0x00000002, 0x00000003, 0x00000003, 0x0000000D,
0x0000000E, 0x00000009, 0x00000003, 0x00000003, 0x00000003, 0x00000005, 0x00000004, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000004, 0x00000001,
0x00000001, 0x00000003, 0x00000002, 0x00000002, 0x00000004, 0x00000005, 0x00000006, 0x00000005, 0x00000005,
0x00000004, 0x00000004, 0x00000009, 0x0000000A, 0x00000008, 0x00000005, 0x00000002, 0x00000002, 0x00000003,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x00000006, 0x00000006, 0x00000005, 0x00000007,
0x00000007, 0x00000007, 0x00000006, 0x00000005, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000005,
0x00000009, 0x00000011, 0x00000013, 0x00000010, 0x00000005, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
0x0000000A, 0x0000000D, 0x0000000B, 0x00000004, 0x00000003, 0x00000003, 0x00000001, 0x00000002, 0x00000002,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x00000003,
0x00000000, 0x00000001, 0x00000003, 0x00000006, 0x00000007, 0x00000005, 0x00000004, 0x00000004, 0x00000005,
0x00000005, 0x00000005, 0x00000004, 0x0000000B, 0x0000000A, 0x00000007, 0x00000004, 0x00000003, 0x00000003,
0x00000005, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x00000006, 0x00000006, 0x00000006,
0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000003, 0x00000003,
0x00000004, 0x00000006, 0x00000008, 0x0000000C, 0x0000000B, 0x00000006, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000004, 0x00000003, 0x00000001, 0x00000001, 0x00000002, 0x00000003, 0x00000002,
0x00000003, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000001,
0x00000002, 0x00000001, 0x00000000, 0x00000003, 0x0000000C, 0x00000010, 0x0000000F, 0x0000000A, 0x00000006,
0x00000004, 0x00000005, 0x00000005, 0x00000004, 0x0000000C, 0x0000000C, 0x0000000A, 0x00000008, 0x00000006,
0x00000006, 0x00000008, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x00000006, 0x00000006,
0x00000007, 0x00000006, 0x00000006, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000003, 0x00000003,
0x00000003, 0x00000003, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x00000003,
0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000004, 0x00000001, 0x00000002, 0x00000006, 0x0000000B, 0x00000011, 0x00000011,
0x0000000B, 0x00000008, 0x00000005, 0x00000005, 0x00000004, 0x0000000B, 0x0000000D, 0x0000000B, 0x0000000B,
0x00000009, 0x00000008, 0x00000009, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x00000005,
0x00000004, 0x00000007, 0x00000006, 0x00000006, 0x00000005, 0x00000004, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x00000002,
0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000001, 0x00000001, 0x00000002, 0x00000003,
0x00000003, 0x00000002, 0x00000003, 0x00000003, 0x00000003, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
0x0000000B, 0x00000010, 0x0000000E, 0x00000008, 0x00000005, 0x00000004, 0x0000000A, 0x0000000B, 0x0000000B,
0x0000000C, 0x0000000B, 0x00000009, 0x00000008, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000A,
0x00000002, 0x00000003, 0x00000005, 0x00000006, 0x00000006, 0x00000004, 0x00000003, 0x00000002, 0x00000002,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000003, 0x00000002, 0x00000003,
0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000003, 0x00000003, 0x00000002, 0x00000003, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000005,
0x00000004, 0x00000002, 0x0000000E, 0x00000011, 0x0000000E, 0x00000005, 0x00000004, 0x00000009, 0x0000000A,
0x0000000A, 0x0000000B, 0x0000000B, 0x00000009, 0x00000009, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000C,
0x0000000A, 0x00000004, 0x00000003, 0x00000003, 0x00000005, 0x00000005, 0x00000003, 0x00000002, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000003,
0x00000005, 0x00000003, 0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000002, 0x00000003,
0x00000005, 0x00000005, 0x00000005, 0x0000000B, 0x00000013, 0x00000011, 0x00000006, 0x00000005, 0x0000000B,
0x0000000C, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000A, 0x0000000A, 0x0000000C, 0x0000000C, 0x0000000C,
0x0000000C, 0x00000009, 0x00000005, 0x00000004, 0x00000002, 0x00000004, 0x00000004, 0x00000002, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000004,
0x00000003, 0x00000002, 0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000003,
0x00000002, 0x00000002, 0x00000003, 0x00000001, 0x00000001, 0x00000002, 0x00000003, 0x00000003, 0x00000002,
0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000008, 0x00000011, 0x00000013, 0x00000007, 0x00000005,
0x0000000C, 0x0000000C, 0x0000000C, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B,
0x0000000B, 0x0000000B, 0x00000009, 0x00000003, 0x00000003, 0x00000004, 0x00000003, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000003,
0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004,
0x00000003, 0x00000003, 0x00000003, 0x00000004, 0x00000005, 0x00000005, 0x00000007, 0x0000000C, 0x00000006,
0x00000005, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000C,
0x0000000C, 0x0000000D, 0x0000000C, 0x00000009, 0x00000002, 0x00000002, 0x00000003, 0x00000003, 0x00000002,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000003,
0x00000002, 0x00000002, 0x00000001, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000002,
0x00000002, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
0x00000003, 0x00000003, 0x00000005, 0x0000000A, 0x0000000B, 0x0000000B, 0x0000000B, 0x0000000C, 0x0000000C,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000C, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000002, 0x00000002,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000004, 0x00000005, 0x00000008, 0x0000000A, 0x0000000B, 0x0000000C, 0x00000008, 0x00000005,
0x00000003, 0x00000002, 0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000003, 0x00000004, 0x00000004,
0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000004, 0x0000000B, 0x0000000C, 0x0000000C, 0x0000000C,
0x0000000D, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D, 0x00000003, 0x00000002,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000001,
0x00000003, 0x0000000A, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x00000011, 0x00000010,
0x0000000E, 0x0000000C, 0x0000000B, 0x00000008, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000003,
0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x0000000A, 0x0000000C, 0x0000000C,
0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000D, 0x00000004,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000002, 0x00000009, 0x0000000C, 0x00000011, 0x00000012, 0x00000011, 0x00000010, 0x0000000F, 0x00000011,
0x00000011, 0x00000010, 0x00000010, 0x0000000F, 0x00000010, 0x0000000F, 0x00000004, 0x00000002, 0x00000002,
0x00000002, 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000003, 0x0000000A, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000D,
0x00000004, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000002, 0x00000008, 0x0000000C, 0x00000012, 0x00000013, 0x00000011, 0x0000000F,
0x00000011, 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000011, 0x0000000F, 0x00000004, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x0000000A,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000E,
0x0000000B, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000002, 0x00000009, 0x0000000C, 0x0000000E, 0x00000010,
0x0000000E, 0x00000011, 0x00000010, 0x00000010, 0x00000011, 0x0000000F, 0x0000000D, 0x0000000A, 0x00000001,
0x00000002, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000003, 0x00000002, 0x00000001, 0x00000003,
0x0000000B, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000F, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000E, 0x00000007, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000009, 0x0000000B,
0x0000000C, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000A, 0x00000003,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002,
0x00000004, 0x0000000D, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000F, 0x00000010, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000C, 0x00000004, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000002,
0x00000006, 0x00000009, 0x0000000B, 0x0000000A, 0x0000000B, 0x0000000B, 0x0000000A, 0x00000009, 0x00000004,
0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001,
0x00000002, 0x00000004, 0x0000000C, 0x0000000E, 0x0000000F, 0x0000000F, 0x00000010, 0x00000011, 0x00000010,
0x0000000F, 0x00000010, 0x00000010, 0x00000003, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000000, 0x00000002, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000001,
0x00000002, 0x00000001, 0x00000002, 0x00000004, 0x00000006, 0x00000006, 0x00000005, 0x00000003, 0x00000001,
0x00000000, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002,
0x00000002, 0x00000001, 0x00000004, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000F, 0x00000010, 0x00000010,
0x00000012, 0x00000013, 0x00000013, 0x00000012, 0x00000006, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000002,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000001,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000001,
0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000005, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x0000000C, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000002,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000006, 0x0000000C, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000010, 0x00000002, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001,
0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000008, 0x00000011, 0x0000000F, 0x00000010,
0x00000012, 0x00000012, 0x00000013, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010, 0x00000003,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x0000000C, 0x00000012, 0x00000014,
0x00000012, 0x00000011, 0x00000014, 0x00000013, 0x00000014, 0x00000014, 0x00000014, 0x00000013, 0x00000011,
0x00000006, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x0000000C, 0x00000014,
0x00000014, 0x00000014, 0x00000014, 0x00000012, 0x00000013, 0x00000013, 0x00000014, 0x00000013, 0x00000013,
0x00000012, 0x0000000A, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000005, 0x00000010,
0x00000011, 0x00000014, 0x00000014, 0x00000015, 0x00000015, 0x00000012, 0x00000012, 0x00000012, 0x00000013,
0x00000013, 0x00000012, 0x0000000C, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001,
0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000009,
0x00000012, 0x00000013, 0x00000012, 0x00000015, 0x00000014, 0x00000015, 0x0000000D, 0x0000000E, 0x0000000F,
0x0000000F, 0x00000011, 0x00000012, 0x0000000F, 0x00000004, 0x00000001, 0x00000001, 0x00000000, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002,
0x0000000E, 0x00000014, 0x00000013, 0x00000014, 0x00000013, 0x00000015, 0x00000014, 0x00000009, 0x0000000C,
0x0000000C, 0x00000009, 0x0000000B, 0x00000010, 0x0000000E, 0x00000006, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000003, 0x00000010, 0x00000015, 0x00000015, 0x00000013, 0x00000014, 0x00000012, 0x00000015, 0x0000000A,
0x0000000A, 0x0000000A, 0x0000000A, 0x0000000C, 0x0000000D, 0x0000000D, 0x00000007, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x0000000A, 0x00000011, 0x00000014, 0x00000015, 0x00000014, 0x00000013, 0x00000014, 0x00000013,
0x0000000B, 0x0000000C, 0x0000000E, 0x0000000E, 0x00000010, 0x00000011, 0x0000000D, 0x00000008, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000002, 0x0000000F, 0x00000014, 0x00000013, 0x00000014, 0x00000015, 0x00000014, 0x00000014,
0x00000014, 0x00000011, 0x00000012, 0x00000011, 0x00000013, 0x00000014, 0x00000013, 0x00000012, 0x0000000C,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001,
0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000006, 0x00000013, 0x00000014, 0x00000013, 0x00000014, 0x00000014, 0x00000015,
0x00000014, 0x00000015, 0x00000013, 0x00000012, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000013,
0x0000000D, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000002, 0x0000000F, 0x00000014, 0x00000015, 0x00000014, 0x00000013, 0x00000015,
0x00000015, 0x00000016, 0x00000014, 0x00000013, 0x00000013, 0x00000014, 0x00000014, 0x00000014, 0x00000013,
0x00000012, 0x0000000E, 0x00000003, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000001, 0x00000005, 0x00000014, 0x00000015, 0x00000015, 0x00000015, 0x00000013,
0x00000015, 0x00000016, 0x00000016, 0x00000015, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000013,
0x00000013, 0x00000012, 0x0000000D, 0x00000003, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000009, 0x00000015, 0x00000015, 0x00000015, 0x00000015,
0x00000015, 0x00000013, 0x00000016, 0x00000016, 0x00000016, 0x00000014, 0x00000014, 0x00000014, 0x00000014,
0x00000013, 0x00000013, 0x00000011, 0x00000009, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x0000000E, 0x00000016, 0x00000016, 0x00000016,
0x00000016, 0x00000015, 0x00000014, 0x00000016, 0x00000016, 0x00000016, 0x00000013, 0x00000014, 0x00000014,
0x00000014, 0x00000014, 0x00000012, 0x0000000D, 0x00000004, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000005, 0x00000012, 0x00000016, 0x00000016,
0x00000016, 0x00000015, 0x00000015, 0x00000015, 0x00000014, 0x00000016, 0x00000016, 0x0000000F, 0x00000010,
0x00000011, 0x00000011, 0x00000011, 0x0000000E, 0x00000007, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x0000000C, 0x00000016, 0x00000018,
0x00000017, 0x00000016, 0x00000017, 0x00000017, 0x00000015, 0x00000014, 0x00000016, 0x00000016, 0x0000000D,
0x0000000C, 0x0000000C, 0x0000000B, 0x0000000B, 0x00000008, 0x00000003, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000015, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000015, 0x00000014, 0x00000014, 0x00000015,
0x0000000D, 0x0000000C, 0x0000000C, 0x0000000A, 0x00000007, 0x00000003, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000005, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000015, 0x00000014, 0x00000011,
0x00000012, 0x0000000C, 0x0000000C, 0x0000000B, 0x00000008, 0x00000005, 0x00000001, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000B,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000018, 0x00000013, 0x00000014,
0x0000000D, 0x0000000C, 0x0000000C, 0x0000000B, 0x00000009, 0x00000005, 0x00000002, 0x00000001, 0x00000001,
0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,
0x00000013, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000017, 0x00000019,
0x00000019, 0x00000018, 0x0000000F, 0x0000000B, 0x00000009, 0x00000006, 0x00000002, 0x00000001, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000007, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x0000000A, 0x00000006, 0x00000003, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x0000000C, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000007, 0x00000003, 0x00000002, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000001, 0x00000016, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000005, 0x00000002, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x0000000A, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000003, 0x00000001,
0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000015, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000002,
0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000000D, 0x00000019, 0x00000019, 0x00000018, 0x00000019,
0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0x00000019,
0x00000019]
a=[]
for i in range(0,len(a3),64): #每行64个数据
a.append(a3[i:i+64]) #划分行列
a2 = [0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000012,
0x00000013, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000010, 0x0000000F, 0x00000012, 0x00000014,
0x00000014, 0x00000012, 0x00000010, 0x00000013, 0x00000013, 0x00000012, 0x00000014, 0x00000014, 0x00000013,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000012, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000012, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000F,
0x0000000F, 0x00000010, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000B, 0x0000000B, 0x0000000D, 0x0000000D,
0x0000000F, 0x00000011, 0x00000012, 0x0000000C, 0x0000000C, 0x0000000E, 0x0000000C, 0x00000010, 0x00000011,
0x0000000E, 0x0000000E, 0x00000012, 0x00000011, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000012, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000010, 0x00000010,
0x0000000E, 0x0000000E, 0x0000000D, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000A, 0x0000000B, 0x00000011,
0x00000009, 0x0000000B, 0x0000000D, 0x0000000F, 0x0000000A, 0x00000009, 0x00000009, 0x0000000A, 0x0000000D,
0x0000000F, 0x0000000D, 0x00000011, 0x00000011, 0x00000013, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000012, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000010, 0x0000000E,
0x0000000E, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000F, 0x00000014, 0x00000010, 0x0000000E, 0x0000000E,
0x00000012, 0x00000010, 0x00000009, 0x0000000E, 0x0000000E, 0x0000000B, 0x0000000B, 0x00000007, 0x00000007,
0x0000000A, 0x0000000C, 0x0000000F, 0x00000012, 0x00000014, 0x00000013, 0x00000012, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000012, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000011, 0x0000000F,
0x0000000D, 0x0000000D, 0x0000000D, 0x00000010, 0x0000000E, 0x00000011, 0x00000012, 0x00000010, 0x0000000E,
0x00000011, 0x0000000E, 0x00000011, 0x0000000C, 0x0000000A, 0x0000000E, 0x0000000E, 0x0000000A, 0x0000000B,
0x00000007, 0x00000008, 0x0000000C, 0x00000011, 0x00000015, 0x00000014, 0x00000015, 0x00000015, 0x00000011,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000012, 0x00000011,
0x0000000D, 0x0000000C, 0x00000009, 0x00000009, 0x00000008, 0x00000007, 0x0000000D, 0x00000011, 0x00000012,
0x0000000F, 0x0000000E, 0x0000000F, 0x00000011, 0x0000000F, 0x0000000A, 0x0000000D, 0x0000000C, 0x00000009,
0x0000000A, 0x00000009, 0x0000000C, 0x0000000E, 0x00000011, 0x00000014, 0x00000014, 0x00000015, 0x00000014,
0x00000011, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000010, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000013, 0x00000013,
0x00000011, 0x0000000C, 0x0000000B, 0x0000000A, 0x0000000B, 0x00000007, 0x00000007, 0x00000007, 0x00000009,
0x0000000E, 0x0000000F, 0x0000000B, 0x00000009, 0x0000000E, 0x00000011, 0x0000000D, 0x0000000A, 0x0000000D,
0x0000000C, 0x0000000C, 0x0000000F, 0x00000011, 0x0000000F, 0x00000010, 0x00000011, 0x00000012, 0x00000012,
0x00000012, 0x00000012, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000010, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000013,
0x00000010, 0x00000010, 0x0000000B, 0x00000007, 0x0000000F, 0x0000000D, 0x0000000B, 0x00000009, 0x00000007,
0x00000007, 0x00000008, 0x00000008, 0x00000008, 0x00000009, 0x0000000A, 0x0000000D, 0x00000011, 0x0000000F,
0x0000000F, 0x0000000D, 0x00000010, 0x00000013, 0x00000011, 0x0000000E, 0x0000000F, 0x0000000F, 0x00000010,
0x0000000E, 0x00000010, 0x00000011, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000010,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000011,
0x00000013, 0x00000010, 0x0000000E, 0x00000009, 0x00000008, 0x00000007, 0x00000006, 0x0000000B, 0x0000000B,
0x0000000A, 0x00000006, 0x00000004, 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000007, 0x0000000E,
0x00000011, 0x00000010, 0x0000000F, 0x00000010, 0x00000013, 0x00000011, 0x00000009, 0x00000005, 0x00000009,
0x0000000D, 0x0000000D, 0x00000012, 0x00000014, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010,
0x00000010, 0x0000000E, 0x0000000B, 0x0000000B, 0x00000009, 0x00000007, 0x00000008, 0x00000008, 0x00000007,
0x00000009, 0x0000000B, 0x00000006, 0x00000002, 0x00000005, 0x00000008, 0x00000009, 0x00000006, 0x00000001,
0x00000008, 0x0000000E, 0x00000011, 0x0000000F, 0x0000000E, 0x00000012, 0x00000008, 0x00000008, 0x0000000A,
0x00000005, 0x0000000B, 0x0000000E, 0x00000011, 0x00000014, 0x00000011, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000E, 0x00000010, 0x0000000C, 0x0000000D, 0x00000008, 0x0000000A, 0x00000009, 0x00000008,
0x00000009, 0x0000000B, 0x00000009, 0x00000006, 0x00000006, 0x00000000, 0x00000003, 0x00000008, 0x00000005,
0x00000006, 0x00000004, 0x0000000C, 0x00000011, 0x00000012, 0x00000011, 0x0000000F, 0x00000007, 0x00000008,
0x00000007, 0x0000000F, 0x0000000E, 0x00000010, 0x00000012, 0x00000012, 0x00000012, 0x00000011, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000010, 0x00000010, 0x00000011,
0x00000011, 0x00000011, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x00000010, 0x00000010, 0x0000000C, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000A, 0x00000009, 0x0000000A,
0x0000000A, 0x0000000B, 0x0000000B, 0x0000000A, 0x00000004, 0x00000006, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000009, 0x00000004, 0x0000000A, 0x00000010, 0x00000013, 0x00000012, 0x0000000C, 0x00000004,
0x00000000, 0x00000000, 0x00000009, 0x0000000F, 0x00000011, 0x00000011, 0x00000012, 0x00000012, 0x00000011,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000012, 0x00000015,
0x00000015, 0x00000017, 0x00000013, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00000010,
0x00000011, 0x00000011, 0x00000011, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000010, 0x0000000E, 0x0000000F, 0x00000010, 0x0000000B, 0x00000009, 0x0000000A, 0x0000000A,
0x0000000A, 0x0000000A, 0x0000000A, 0x0000000C, 0x0000000C, 0x00000006, 0x00000007, 0x00000000, 0x00000000,
0x00000000, 0x00000002, 0x0000000A, 0x00000004, 0x0000000C, 0x00000010, 0x00000010, 0x00000012, 0x00000011,
0x00000007, 0x00000000, 0x00000000, 0x0000000A, 0x00000010, 0x00000012, 0x00000012, 0x00000015, 0x00000014,
0x00000012, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000015, 0x00000014,
0x00000011, 0x00000010, 0x00000012, 0x00000013, 0x00000015, 0x00000011, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000011, 0x00000010, 0x00000011, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000E, 0x00000010, 0x00000011, 0x0000000F, 0x0000000D, 0x0000000B, 0x0000000B,
0x0000000B, 0x00000008, 0x00000009, 0x0000000C, 0x0000000E, 0x0000000E, 0x0000000C, 0x00000006, 0x00000007,
0x00000002, 0x00000004, 0x0000000B, 0x00000006, 0x00000005, 0x0000000D, 0x0000000F, 0x00000011, 0x00000012,
0x00000012, 0x0000000E, 0x00000006, 0x00000007, 0x0000000D, 0x00000012, 0x00000011, 0x0000000E, 0x00000010,
0x00000014, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x00000010, 0x00000010, 0x00000012, 0x00000014,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000015, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000D, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000B, 0x0000000A,
0x0000000A, 0x0000000A, 0x0000000B, 0x00000009, 0x0000000B, 0x0000000D, 0x0000000D, 0x0000000F, 0x0000000C,
0x00000006, 0x0000000A, 0x0000000A, 0x00000005, 0x00000009, 0x0000000A, 0x0000000D, 0x0000000E, 0x0000000C,
0x00000013, 0x00000011, 0x0000000E, 0x0000000C, 0x0000000B, 0x0000000E, 0x00000015, 0x00000012, 0x00000011,
0x00000012, 0x00000013, 0x00000012, 0x00000010, 0x0000000F, 0x0000000F, 0x00000010, 0x00000010, 0x00000014,
0x00000011, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000015, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000D, 0x0000000C, 0x0000000B, 0x0000000A, 0x00000009,
0x0000000A, 0x00000009, 0x0000000A, 0x00000008, 0x00000007, 0x00000008, 0x0000000B, 0x0000000D, 0x0000000F,
0x00000010, 0x0000000E, 0x0000000B, 0x0000000B, 0x0000000C, 0x0000000A, 0x0000000A, 0x0000000C, 0x0000000C,
0x0000000A, 0x00000012, 0x00000010, 0x00000013, 0x00000010, 0x00000010, 0x00000011, 0x00000014, 0x00000011,
0x00000010, 0x0000000E, 0x00000012, 0x00000012, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010,
0x00000016, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000015, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000E, 0x0000000A, 0x00000008, 0x00000008,
0x00000008, 0x00000008, 0x00000007, 0x0000000A, 0x00000008, 0x00000005, 0x00000006, 0x00000007, 0x0000000C,
0x00000010, 0x0000000F, 0x0000000F, 0x0000000D, 0x0000000B, 0x0000000A, 0x00000005, 0x00000006, 0x0000000A,
0x0000000B, 0x00000007, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000B, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000010, 0x00000010, 0x0000000F, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x00000010, 0x00000015, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000015,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000E, 0x00000009, 0x00000007,
0x00000007, 0x0000000A, 0x00000009, 0x00000006, 0x0000000A, 0x0000000C, 0x00000006, 0x00000003, 0x00000007,
0x0000000A, 0x0000000D, 0x00000010, 0x0000000A, 0x00000006, 0x00000006, 0x00000008, 0x00000006, 0x00000003,
0x00000002, 0x00000005, 0x00000003, 0x00000009, 0x0000000F, 0x0000000B, 0x00000007, 0x00000008, 0x0000000D,
0x00000012, 0x0000000E, 0x0000000F, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000010, 0x00000015, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011,
0x00000015, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000011,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000D, 0x00000009,
0x0000000A, 0x0000000B, 0x0000000A, 0x00000008, 0x00000004, 0x00000008, 0x0000000C, 0x00000009, 0x00000007,
0x00000006, 0x00000006, 0x0000000C, 0x0000000D, 0x00000007, 0x00000007, 0x00000007, 0x00000009, 0x00000009,
0x00000006, 0x00000004, 0x00000001, 0x00000001, 0x00000004, 0x0000000D, 0x0000000C, 0x00000009, 0x00000005,
0x00000005, 0x0000000A, 0x0000000D, 0x0000000D, 0x00000010, 0x00000012, 0x00000010, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x00000011, 0x00000016, 0x00000014, 0x00000013, 0x00000013, 0x00000014,
0x00000016, 0x00000011, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000011, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000C,
0x0000000A, 0x0000000F, 0x0000000D, 0x0000000A, 0x0000000A, 0x00000006, 0x00000003, 0x00000007, 0x0000000C,
0x00000009, 0x00000005, 0x00000005, 0x0000000B, 0x0000000B, 0x00000009, 0x0000000B, 0x0000000D, 0x0000000D,
0x0000000A, 0x00000007, 0x00000005, 0x00000001, 0x00000001, 0x00000002, 0x0000000E, 0x00000012, 0x00000011,
0x00000009, 0x00000006, 0x00000008, 0x0000000A, 0x0000000E, 0x0000000F, 0x00000012, 0x00000010, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000011, 0x00000012, 0x00000012,
0x00000012, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000C, 0x0000000D, 0x0000000D, 0x0000000F, 0x0000000A, 0x0000000B, 0x00000009, 0x00000004, 0x00000007,
0x0000000B, 0x0000000A, 0x00000009, 0x00000005, 0x0000000A, 0x0000000B, 0x0000000E, 0x0000000D, 0x0000000E,
0x0000000D, 0x0000000A, 0x00000009, 0x00000008, 0x00000007, 0x00000005, 0x00000003, 0x00000009, 0x0000000F,
0x00000013, 0x00000014, 0x0000000D, 0x00000009, 0x00000009, 0x0000000A, 0x0000000D, 0x00000013, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000011, 0x00000011, 0x0000000B, 0x0000000E, 0x0000000A, 0x0000000A, 0x00000007, 0x00000006,
0x00000003, 0x00000006, 0x0000000A, 0x0000000C, 0x00000006, 0x00000007, 0x0000000E, 0x0000000D, 0x0000000E,
0x0000000C, 0x00000010, 0x0000000E, 0x0000000C, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000006,
0x00000009, 0x00000011, 0x00000014, 0x00000014, 0x0000000B, 0x00000006, 0x00000009, 0x0000000C, 0x00000015,
0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x00000013, 0x00000011, 0x00000009, 0x0000000B, 0x00000008, 0x00000006, 0x00000008,
0x00000009, 0x00000005, 0x00000005, 0x00000006, 0x00000008, 0x00000009, 0x0000000B, 0x0000000A, 0x0000000D,
0x0000000B, 0x0000000C, 0x0000000D, 0x00000011, 0x0000000F, 0x00000009, 0x00000006, 0x00000003, 0x00000004,
0x00000006, 0x00000010, 0x00000012, 0x00000013, 0x00000014, 0x0000000F, 0x00000007, 0x00000008, 0x0000000D,
0x00000013, 0x00000011, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x00000012, 0x0000000D, 0x0000000B, 0x00000009, 0x00000007, 0x00000006,
0x00000009, 0x0000000A, 0x0000000A, 0x0000000B, 0x0000000E, 0x00000009, 0x00000009, 0x0000000E, 0x0000000A,
0x0000000C, 0x00000008, 0x00000008, 0x0000000D, 0x0000000C, 0x0000000F, 0x0000000B, 0x00000006, 0x00000009,
0x00000007, 0x00000008, 0x00000011, 0x00000015, 0x00000015, 0x00000015, 0x00000010, 0x0000000C, 0x0000000F,
0x0000000F, 0x00000012, 0x00000013, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000E, 0x00000009, 0x00000006,
0x00000007, 0x0000000A, 0x0000000E, 0x0000000C, 0x00000009, 0x0000000B, 0x0000000B, 0x0000000D, 0x0000000C,
0x00000008, 0x00000006, 0x00000007, 0x00000008, 0x0000000C, 0x0000000A, 0x00000009, 0x0000000B, 0x0000000E,
0x0000000C, 0x00000008, 0x00000006, 0x0000000A, 0x0000000B, 0x0000000B, 0x00000011, 0x00000013, 0x0000000E,
0x0000000E, 0x00000010, 0x00000012, 0x00000012, 0x00000012, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000E, 0x00000011, 0x0000000E, 0x0000000F, 0x0000000B,
0x00000007, 0x00000006, 0x0000000B, 0x0000000A, 0x00000007, 0x00000004, 0x00000007, 0x0000000A, 0x0000000E,
0x0000000E, 0x0000000C, 0x00000008, 0x00000006, 0x00000003, 0x00000004, 0x00000003, 0x00000002, 0x00000006,
0x00000008, 0x00000005, 0x00000005, 0x00000002, 0x00000006, 0x00000006, 0x00000007, 0x0000000D, 0x00000011,
0x0000000E, 0x0000000A, 0x0000000D, 0x0000000F, 0x0000000F, 0x00000011, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000F,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000B, 0x0000000E,
0x0000000D, 0x0000000A, 0x00000008, 0x00000005, 0x00000007, 0x00000005, 0x00000003, 0x00000004, 0x00000008,
0x0000000E, 0x00000010, 0x00000009, 0x00000005, 0x00000007, 0x00000008, 0x00000008, 0x00000005, 0x00000002,
0x00000006, 0x00000008, 0x00000006, 0x00000005, 0x00000007, 0x0000000A, 0x00000005, 0x00000005, 0x0000000C,
0x0000000C, 0x00000008, 0x00000008, 0x00000008, 0x0000000D, 0x00000010, 0x00000011, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x0000000F, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000A, 0x00000008,
0x0000000C, 0x0000000B, 0x00000010, 0x00000007, 0x00000005, 0x00000003, 0x00000004, 0x00000002, 0x00000002,
0x00000005, 0x00000009, 0x0000000D, 0x0000000A, 0x00000003, 0x00000004, 0x0000000A, 0x0000000D, 0x0000000A,
0x00000005, 0x00000006, 0x00000009, 0x00000006, 0x00000005, 0x0000000C, 0x00000008, 0x00000005, 0x00000006,
0x0000000C, 0x00000009, 0x00000006, 0x00000006, 0x00000005, 0x0000000A, 0x0000000F, 0x00000010, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
0x00000010, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000C, 0x00000008,
0x00000006, 0x00000008, 0x0000000D, 0x0000000F, 0x00000004, 0x00000004, 0x00000003, 0x00000002, 0x00000000,
0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000008, 0x00000002, 0x00000003, 0x00000007, 0x0000000D,
0x0000000B, 0x0000000A, 0x00000007, 0x00000009, 0x00000005, 0x00000009, 0x0000000B, 0x00000006, 0x00000004,
0x0000000A, 0x0000000A, 0x00000008, 0x00000004, 0x00000007, 0x00000004, 0x00000009, 0x0000000D, 0x00000010,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x00000010,
0x00000010, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000C, 0x00000009,
0x00000006, 0x00000005, 0x00000007, 0x0000000D, 0x0000000C, 0x00000002, 0x00000002, 0x00000004, 0x00000001,
0x00000000, 0x00000000, 0x00000001, 0x00000004, 0x00000008, 0x00000007, 0x00000002, 0x00000003, 0x00000005,
0x00000007, 0x0000000C, 0x0000000F, 0x0000000A, 0x00000009, 0x00000006, 0x0000000A, 0x00000008, 0x00000003,
0x00000003, 0x0000000C, 0x00000008, 0x00000004, 0x00000005, 0x00000008, 0x00000004, 0x00000007, 0x0000000D,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x00000010, 0x00000010, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000A,
0x00000006, 0x00000005, 0x00000006, 0x00000007, 0x0000000F, 0x00000008, 0x00000001, 0x00000002, 0x00000004,
0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000004, 0x00000005, 0x00000005, 0x00000005, 0x00000008,
0x00000005, 0x00000005, 0x0000000C, 0x00000010, 0x0000000B, 0x0000000C, 0x0000000B, 0x0000000A, 0x00000007,
0x00000005, 0x00000005, 0x0000000B, 0x00000005, 0x00000005, 0x00000005, 0x00000009, 0x00000008, 0x0000000B,
0x0000000B, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000F, 0x00000010, 0x00000015, 0x00000010, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000014, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000B,
0x00000008, 0x00000005, 0x00000006, 0x00000006, 0x00000009, 0x0000000F, 0x00000004, 0x00000002, 0x00000005,
0x00000004, 0x00000001, 0x00000005, 0x00000003, 0x00000001, 0x00000005, 0x00000004, 0x00000004, 0x00000007,
0x00000008, 0x00000006, 0x00000007, 0x0000000B, 0x00000010, 0x0000000D, 0x0000000F, 0x0000000C, 0x00000009,
0x00000007, 0x00000008, 0x0000000B, 0x00000008, 0x00000007, 0x00000007, 0x00000005, 0x00000009, 0x0000000C,
0x0000000C, 0x0000000A, 0x00000012, 0x0000000F, 0x0000000E, 0x0000000F, 0x00000015, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000015, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000D,
0x00000008, 0x00000007, 0x00000005, 0x00000005, 0x00000008, 0x0000000E, 0x0000000B, 0x00000005, 0x0000000B,
0x00000009, 0x00000002, 0x00000004, 0x00000007, 0x00000003, 0x00000002, 0x00000004, 0x00000002, 0x00000003,
0x00000006, 0x00000008, 0x00000007, 0x00000008, 0x0000000B, 0x0000000C, 0x00000010, 0x00000010, 0x0000000D,
0x0000000B, 0x00000008, 0x00000009, 0x0000000C, 0x0000000A, 0x00000007, 0x0000000C, 0x00000004, 0x00000009,
0x00000010, 0x0000000A, 0x00000008, 0x00000012, 0x0000000F, 0x0000000E, 0x00000012, 0x00000012, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000015,
0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E,
0x00000009, 0x00000007, 0x00000005, 0x00000004, 0x00000007, 0x0000000F, 0x0000000F, 0x00000008, 0x0000000C,
0x0000000D, 0x00000003, 0x00000002, 0x00000005, 0x00000007, 0x00000002, 0x00000004, 0x00000006, 0x00000002,
0x00000002, 0x00000005, 0x00000009, 0x0000000B, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x00000011,
0x00000010, 0x0000000C, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000A, 0x00000009, 0x0000000F, 0x00000003,
0x00000007, 0x00000010, 0x0000000D, 0x00000008, 0x00000011, 0x00000010, 0x0000000F, 0x00000016, 0x0000000E,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x00000015, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000E, 0x0000000E,
0x0000000B, 0x00000009, 0x00000004, 0x00000003, 0x00000009, 0x0000000E, 0x0000000B, 0x00000008, 0x00000006,
0x0000000E, 0x00000008, 0x00000002, 0x00000002, 0x00000006, 0x00000004, 0x00000002, 0x00000006, 0x00000007,
0x00000003, 0x00000004, 0x00000004, 0x00000009, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000C,
0x00000010, 0x00000011, 0x0000000B, 0x0000000D, 0x0000000E, 0x0000000C, 0x0000000B, 0x00000009, 0x0000000F,
0x00000003, 0x00000004, 0x0000000C, 0x00000011, 0x00000009, 0x0000000F, 0x00000011, 0x00000011, 0x00000013,
0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000013, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000015, 0x00000010, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000E,
0x0000000E, 0x0000000A, 0x0000000B, 0x00000004, 0x00000002, 0x0000000C, 0x00000007, 0x0000000E, 0x00000004,
0x00000006, 0x0000000E, 0x0000000C, 0x00000004, 0x00000001, 0x00000004, 0x00000003, 0x00000004, 0x00000005,
0x00000007, 0x00000005, 0x00000006, 0x00000003, 0x00000006, 0x0000000C, 0x0000000C, 0x0000000B, 0x0000000A,
0x0000000C, 0x0000000C, 0x00000011, 0x0000000B, 0x0000000E, 0x00000010, 0x00000008, 0x00000009, 0x0000000A,
0x00000011, 0x00000007, 0x00000005, 0x00000007, 0x00000011, 0x0000000A, 0x00000010, 0x00000012, 0x00000012,
0x00000012, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x00000018, 0x00000011, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x00000015, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x00000010,
0x0000000E, 0x0000000D, 0x0000000C, 0x00000007, 0x00000005, 0x00000005, 0x00000007, 0x0000000A, 0x0000000E,
0x00000005, 0x00000005, 0x0000000A, 0x0000000E, 0x00000003, 0x00000001, 0x00000004, 0x00000006, 0x00000004,
0x00000002, 0x00000008, 0x00000008, 0x00000007, 0x00000002, 0x00000005, 0x00000008, 0x0000000A, 0x0000000A,
0x00000009, 0x0000000C, 0x0000000A, 0x00000010, 0x0000000B, 0x0000000D, 0x0000000D, 0x00000006, 0x00000007,
0x0000000A, 0x00000011, 0x0000000E, 0x00000007, 0x00000005, 0x0000000D, 0x00000009, 0x00000010, 0x00000012,
0x0000000F, 0x00000016, 0x00000012, 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000014, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x00000016, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x00000010, 0x0000000E, 0x0000000D, 0x0000000F, 0x00000005, 0x00000001, 0x00000007, 0x00000005, 0x0000000A,
0x00000007, 0x00000006, 0x00000006, 0x0000000D, 0x0000000A, 0x00000001, 0x00000001, 0x00000006, 0x00000008,
0x00000003, 0x00000002, 0x00000008, 0x00000009, 0x00000008, 0x00000003, 0x00000003, 0x00000007, 0x00000009,
0x00000008, 0x00000008, 0x0000000A, 0x00000009, 0x0000000C, 0x0000000C, 0x0000000A, 0x0000000A, 0x00000005,
0x00000005, 0x00000008, 0x0000000F, 0x00000012, 0x00000005, 0x00000008, 0x0000000B, 0x0000000B, 0x00000011,
0x00000010, 0x0000000E, 0x0000000F, 0x00000012, 0x00000013, 0x00000013, 0x00000012, 0x0000000F, 0x00000014,
0x00000015, 0x00000013, 0x00000014, 0x00000016, 0x00000012, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000010, 0x0000000E, 0x0000000D, 0x0000000C, 0x00000004, 0x00000009, 0x00000002, 0x00000005,
0x00000009, 0x00000009, 0x00000006, 0x00000008, 0x0000000A, 0x00000008, 0x00000002, 0x00000005, 0x00000007,
0x00000006, 0x00000001, 0x00000002, 0x00000006, 0x00000007, 0x00000009, 0x00000005, 0x00000001, 0x00000005,
0x00000009, 0x00000005, 0x00000004, 0x00000008, 0x00000009, 0x0000000F, 0x0000000A, 0x00000007, 0x00000005,
0x00000003, 0x00000004, 0x00000006, 0x0000000D, 0x00000010, 0x00000009, 0x0000000B, 0x0000000F, 0x0000000F,
0x00000013, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F,
0x0000000F, 0x00000010, 0x00000011, 0x00000011, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000A, 0x00000005, 0x00000009, 0x00000003,
0x00000005, 0x00000008, 0x0000000D, 0x00000009, 0x0000000B, 0x0000000B, 0x0000000A, 0x00000006, 0x00000005,
0x00000006, 0x00000004, 0x00000002, 0x00000003, 0x00000004, 0x00000004, 0x0000000A, 0x00000008, 0x00000001,
0x00000003, 0x0000000A, 0x00000007, 0x00000003, 0x00000008, 0x0000000A, 0x0000000A, 0x0000000A, 0x00000003,
0x00000003, 0x00000004, 0x00000003, 0x00000007, 0x0000000B, 0x0000000D, 0x0000000A, 0x0000000E, 0x0000000F,
0x00000013, 0x00000012, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x00000010, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000C, 0x0000000C,
0x00000005, 0x00000006, 0x0000000D, 0x0000000E, 0x0000000B, 0x0000000B, 0x0000000A, 0x00000008, 0x00000004,
0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000006, 0x00000003, 0x00000001, 0x00000008, 0x0000000B,
0x00000003, 0x00000002, 0x00000007, 0x00000009, 0x00000006, 0x00000008, 0x0000000C, 0x00000008, 0x00000009,
0x00000002, 0x00000005, 0x00000005, 0x00000003, 0x00000009, 0x00000009, 0x0000000B, 0x0000000C, 0x00000010,
0x0000000F, 0x00000012, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000D, 0x0000000D, 0x00000010, 0x00000011,
0x0000000B, 0x00000007, 0x0000000A, 0x0000000F, 0x0000000D, 0x0000000B, 0x00000008, 0x00000007, 0x00000009,
0x00000006, 0x00000004, 0x00000006, 0x00000003, 0x00000002, 0x00000007, 0x00000007, 0x00000001, 0x00000004,
0x0000000B, 0x00000006, 0x00000001, 0x00000003, 0x00000008, 0x00000008, 0x00000008, 0x0000000A, 0x00000008,
0x00000003, 0x00000002, 0x00000004, 0x00000007, 0x00000006, 0x0000000A, 0x00000005, 0x0000000A, 0x00000010,
0x00000015, 0x00000014, 0x00000011, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000D, 0x0000000D, 0x00000011,
0x00000012, 0x00000010, 0x0000000B, 0x00000012, 0x00000012, 0x00000010, 0x0000000D, 0x00000009, 0x00000007,
0x00000007, 0x00000002, 0x00000005, 0x00000007, 0x00000004, 0x00000002, 0x00000005, 0x0000000A, 0x00000007,
0x00000001, 0x0000000A, 0x00000009, 0x00000002, 0x00000001, 0x00000005, 0x00000008, 0x00000008, 0x0000000A,
0x00000007, 0x00000002, 0x00000002, 0x00000004, 0x00000009, 0x00000006, 0x00000009, 0x00000006, 0x00000009,
0x00000012, 0x00000017, 0x00000015, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000D, 0x0000000D,
0x00000011, 0x00000012, 0x00000010, 0x0000000E, 0x00000016, 0x00000013, 0x00000010, 0x0000000A, 0x00000008,
0x00000008, 0x00000004, 0x00000002, 0x00000005, 0x00000007, 0x00000007, 0x00000004, 0x00000003, 0x00000009,
0x0000000D, 0x0000000A, 0x00000006, 0x0000000B, 0x00000005, 0x00000000, 0x00000003, 0x00000008, 0x0000000A,
0x0000000A, 0x00000004, 0x00000001, 0x00000001, 0x00000006, 0x00000005, 0x00000006, 0x00000009, 0x0000000B,
0x0000000A, 0x00000011, 0x00000016, 0x00000011, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x00000014, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000D,
0x0000000D, 0x00000012, 0x00000013, 0x00000011, 0x0000000E, 0x00000013, 0x0000000C, 0x0000000C, 0x0000000A,
0x0000000A, 0x00000006, 0x00000004, 0x00000004, 0x00000007, 0x00000008, 0x00000008, 0x00000005, 0x00000002,
0x00000008, 0x0000000B, 0x0000000B, 0x00000009, 0x0000000C, 0x00000009, 0x00000003, 0x00000003, 0x00000008,
0x0000000A, 0x00000006, 0x00000003, 0x00000001, 0x00000003, 0x00000005, 0x00000002, 0x00000008, 0x0000000B,
0x0000000A, 0x0000000D, 0x0000000E, 0x00000012, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000E, 0x0000000E, 0x0000000E, 0x00000014, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000D, 0x0000000D, 0x00000010, 0x00000013, 0x00000012, 0x00000010, 0x00000011, 0x00000009, 0x0000000B,
0x0000000B, 0x00000009, 0x00000006, 0x00000007, 0x00000007, 0x00000008, 0x00000008, 0x00000006, 0x00000005,
0x00000001, 0x00000005, 0x0000000A, 0x0000000A, 0x00000008, 0x00000006, 0x00000007, 0x00000005, 0x00000004,
0x00000008, 0x00000007, 0x00000002, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000004, 0x00000007,
0x0000000A, 0x0000000A, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x00000011, 0x00000012, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000D, 0x0000000D, 0x0000000F, 0x00000014, 0x00000013, 0x0000000F, 0x00000012, 0x0000000B,
0x0000000C, 0x0000000A, 0x00000009, 0x00000004, 0x00000007, 0x00000006, 0x00000007, 0x00000007, 0x00000006,
0x00000004, 0x00000002, 0x00000003, 0x00000007, 0x0000000A, 0x0000000A, 0x00000007, 0x00000007, 0x00000004,
0x00000007, 0x00000007, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000005, 0x00000006,
0x00000009, 0x00000009, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E, 0x00000013, 0x0000000F, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000F, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000D, 0x00000013, 0x00000014, 0x0000000E, 0x00000011,
0x0000000E, 0x0000000D, 0x0000000B, 0x0000000A, 0x00000004, 0x00000007, 0x00000004, 0x00000006, 0x00000006,
0x00000007, 0x00000005, 0x00000003, 0x00000004, 0x00000005, 0x00000008, 0x0000000A, 0x0000000A, 0x00000005,
0x00000001, 0x00000005, 0x00000002, 0x00000001, 0x00000003, 0x00000004, 0x00000002, 0x00000004, 0x00000007,
0x00000009, 0x00000008, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000D, 0x00000015, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000F, 0x0000000F, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000F, 0x0000000D,
0x00000011, 0x00000011, 0x0000000D, 0x0000000D, 0x0000000A, 0x00000003, 0x00000006, 0x00000005, 0x00000007,
0x00000006, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000005, 0x00000005, 0x00000007, 0x0000000A,
0x00000009, 0x00000005, 0x00000004, 0x00000003, 0x00000004, 0x00000003, 0x00000001, 0x00000003, 0x00000008,
0x0000000D, 0x00000009, 0x00000008, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000F, 0x00000015, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000F, 0x0000000F,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000E, 0x00000012, 0x0000000C, 0x00000008, 0x00000009, 0x00000003, 0x00000006, 0x00000006,
0x00000008, 0x00000008, 0x00000005, 0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000006, 0x00000008,
0x00000007, 0x00000006, 0x00000006, 0x00000005, 0x00000003, 0x00000001, 0x00000002, 0x00000003, 0x00000008,
0x0000000D, 0x0000000B, 0x00000007, 0x00000010, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x00000011, 0x00000012,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x00000010, 0x0000000B, 0x00000005, 0x00000007, 0x00000005, 0x00000006,
0x00000006, 0x00000007, 0x00000007, 0x00000008, 0x00000003, 0x00000001, 0x00000004, 0x00000004, 0x00000004,
0x00000006, 0x00000009, 0x00000008, 0x00000006, 0x00000006, 0x00000004, 0x00000001, 0x00000003, 0x00000008,
0x0000000A, 0x00000007, 0x00000008, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x00000013,
0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x00000012, 0x0000000D, 0x0000000D, 0x0000000C,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x00000008, 0x00000007, 0x00000009,
0x00000006, 0x00000003, 0x00000004, 0x00000006, 0x00000008, 0x00000007, 0x00000002, 0x00000002, 0x00000007,
0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000006, 0x00000005, 0x00000003, 0x00000000, 0x00000004,
0x00000006, 0x00000003, 0x00000006, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x00000015, 0x0000000E, 0x0000000E, 0x0000000E, 0x00000010, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E,
0x0000000E, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000F, 0x00000013, 0x00000014, 0x0000000D, 0x0000000C,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000B, 0x0000000A,
0x00000009, 0x0000000A, 0x00000005, 0x00000001, 0x00000002, 0x00000003, 0x00000007, 0x00000005, 0x00000002,
0x00000003, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000005, 0x00000003, 0x00000001, 0x00000002,
0x00000003, 0x00000003, 0x00000005, 0x00000009, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x00000015, 0x0000000E, 0x0000000E, 0x0000000E, 0x00000015, 0x0000000E, 0x0000000E, 0x0000000E,
0x00000010, 0x00000012, 0x00000014, 0x00000012, 0x0000000F, 0x00000012, 0x00000015, 0x00000015, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C,
0x0000000E, 0x0000000E, 0x0000000C, 0x0000000A, 0x00000002, 0x00000003, 0x00000002, 0x00000002, 0x00000003,
0x00000004, 0x00000004, 0x00000004, 0x00000005, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000002, 0x00000006, 0x0000000A, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000E, 0x00000015, 0x0000000E, 0x0000000E, 0x00000010, 0x00000014, 0x00000010, 0x00000016,
0x00000017, 0x00000016, 0x00000017, 0x00000017, 0x00000018, 0x00000017, 0x00000014, 0x00000018, 0x00000016,
0x0000000D, 0x0000000C, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000E, 0x0000000E, 0x0000000E, 0x0000000B, 0x00000009, 0x00000008, 0x00000005, 0x00000004,
0x00000002, 0x00000004, 0x00000005, 0x00000007, 0x00000008, 0x00000009, 0x00000008, 0x00000008, 0x00000005,
0x00000003, 0x00000002, 0x00000002, 0x00000006, 0x00000004, 0x0000000B, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x00000014, 0x0000000F, 0x0000000D, 0x00000015, 0x0000000F, 0x0000000E,
0x00000013, 0x00000016, 0x00000017, 0x00000017, 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00000018,
0x00000015, 0x0000000D, 0x0000000C, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000F, 0x0000000F, 0x0000000E, 0x00000009, 0x00000007, 0x00000006,
0x00000002, 0x00000003, 0x00000007, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000B, 0x0000000A, 0x0000000A,
0x00000008, 0x00000004, 0x00000003, 0x00000002, 0x00000004, 0x00000005, 0x0000000C, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000F, 0x00000014, 0x00000011, 0x00000013, 0x0000000D,
0x0000000F, 0x00000014, 0x00000015, 0x00000016, 0x00000016, 0x00000016, 0x00000013, 0x00000017, 0x00000018,
0x00000018, 0x00000018, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000A, 0x00000006,
0x00000003, 0x00000002, 0x00000007, 0x00000008, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000C, 0x0000000C,
0x0000000D, 0x0000000D, 0x00000005, 0x00000003, 0x00000002, 0x00000003, 0x00000008, 0x0000000C, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x00000011, 0x00000014, 0x0000000E,
0x0000000D, 0x0000000E, 0x00000012, 0x00000013, 0x00000014, 0x00000014, 0x00000015, 0x00000014, 0x00000014,
0x00000015, 0x00000016, 0x00000014, 0x0000000D, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000A,
0x00000006, 0x00000006, 0x00000006, 0x0000000A, 0x0000000B, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
0x0000000F, 0x00000010, 0x00000010, 0x00000008, 0x00000006, 0x00000004, 0x00000005, 0x00000009, 0x0000000B,
0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000E, 0x0000000F,
0x0000000E, 0x0000000F, 0x0000000F, 0x00000011, 0x00000012, 0x00000013, 0x00000013, 0x00000013, 0x00000013,
0x00000013, 0x00000014, 0x00000014, 0x00000013, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000C, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E,
0x0000000C, 0x00000009, 0x00000008, 0x0000000A, 0x0000000A, 0x0000000C, 0x0000000E, 0x0000000E, 0x00000010,
0x00000012, 0x00000013, 0x00000013, 0x00000012, 0x0000000D, 0x0000000A, 0x0000000A, 0x00000007, 0x00000009,
0x0000000F, 0x00000013, 0x00000011, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000E, 0x0000000E, 0x00000012, 0x00000011, 0x00000013,
0x00000013, 0x00000013, 0x00000013, 0x0000000F, 0x00000010, 0x0000000E, 0x0000000D, 0x00000013, 0x00000012,
0x00000012, 0x00000012, 0x0000000D, 0x00000010, 0x00000011, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x00000012, 0x00000010, 0x0000000C, 0x0000000B, 0x00000010, 0x00000010, 0x00000011, 0x00000012,
0x00000014, 0x00000014, 0x00000016, 0x00000014, 0x00000012, 0x00000010, 0x0000000D, 0x0000000D, 0x0000000C,
0x00000008, 0x00000009, 0x0000000E, 0x00000013, 0x00000012, 0x00000011, 0x00000013, 0x00000012, 0x0000000E,
0x0000000D, 0x0000000E, 0x0000000F, 0x0000000E, 0x0000000E, 0x00000012, 0x00000011, 0x00000011, 0x00000011,
0x00000011, 0x00000011, 0x00000011, 0x00000010, 0x00000010, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000C,
0x0000000E, 0x0000000F, 0x00000010, 0x00000011, 0x00000011, 0x00000012, 0x0000000C, 0x0000000C, 0x0000000C,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x00000015, 0x00000012, 0x0000000D, 0x0000000B, 0x00000011, 0x00000013, 0x00000014,
0x00000015, 0x00000014, 0x00000012, 0x00000013, 0x00000012, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000D,
0x0000000D, 0x00000009, 0x00000007, 0x0000000C, 0x00000012, 0x00000012, 0x00000010, 0x00000010, 0x00000013,
0x00000014, 0x00000011, 0x00000010, 0x00000010, 0x00000012, 0x00000011, 0x0000000F, 0x0000000E, 0x0000000D,
0x0000000C, 0x0000000D, 0x0000000E, 0x0000000D, 0x0000000C, 0x0000000A, 0x0000000A, 0x00000009, 0x0000000C,
0x00000010, 0x00000010, 0x00000012, 0x00000013, 0x00000012, 0x00000012, 0x00000013, 0x0000000C, 0x0000000C,
0x0000000C, 0x0000000C, 0x0000000D, 0x0000000C, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x00000011, 0x00000015, 0x00000014, 0x00000010, 0x0000000D, 0x0000000E, 0x0000000E,
0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x0000000E, 0x0000000F, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000C, 0x00000007, 0x0000000A, 0x0000000E, 0x00000014, 0x0000000D, 0x0000000E,
0x00000010, 0x00000014, 0x00000014, 0x00000011, 0x00000010, 0x0000000C, 0x0000000E, 0x0000000B, 0x0000000E,
0x0000000F, 0x0000000A, 0x0000000B, 0x0000000D, 0x0000000A, 0x00000008, 0x00000009, 0x00000009, 0x00000008,
0x0000000E, 0x00000013, 0x00000013, 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000013, 0x0000000C,
0x0000000C, 0x0000000C, 0x0000000D, 0x0000000C, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000D, 0x0000000D, 0x0000000F, 0x00000016, 0x00000016, 0x00000014, 0x0000000F, 0x0000000D, 0x0000000D,
0x0000000A, 0x00000009, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000B, 0x00000009, 0x0000000A, 0x0000000D,
0x0000000C, 0x0000000B, 0x0000000A, 0x0000000A, 0x00000009, 0x0000000A, 0x00000009, 0x00000013, 0x00000011,
0x00000008, 0x00000008, 0x0000000F, 0x00000015, 0x00000010, 0x0000000B, 0x0000000A, 0x0000000A, 0x0000000C,
0x0000000A, 0x00000009, 0x00000008, 0x0000000B, 0x00000008, 0x00000008, 0x00000006, 0x00000009, 0x0000000D,
0x00000009, 0x00000009, 0x0000000C, 0x00000010, 0x00000012, 0x00000011, 0x00000010, 0x00000012, 0x00000014,
0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
0x0000000E, 0x0000000F, 0x00000014, 0x00000016, 0x00000016, 0x00000016, 0x00000016, 0x00000010, 0x0000000C,
0x00000008, 0x00000008, 0x00000006, 0x00000006, 0x00000008, 0x00000007, 0x00000007, 0x00000006, 0x00000007,
0x0000000A, 0x00000008, 0x00000009, 0x00000008, 0x0000000B, 0x00000009, 0x00000008, 0x00000006, 0x0000000C,
0x00000010, 0x0000000A, 0x00000006, 0x0000000B, 0x0000000F, 0x0000000E, 0x0000000A, 0x0000000C, 0x0000000B,
0x0000000B, 0x0000000B, 0x00000009, 0x00000007, 0x00000009, 0x00000008, 0x0000000B, 0x0000000A, 0x00000008,
0x00000007, 0x00000008, 0x00000009, 0x00000012, 0x00000014, 0x00000014, 0x00000013, 0x00000013, 0x00000011,
0x00000013]
b=[]
for i in range(0,len(a2),64):
b.append(a2[i:i+64])
c = [0x025D15D4, 0x024C73B4, 0x0243CF71, 0x0230134C, 0x02132CFE, 0x01BE2FCA, 0x0142CA26, 0x00D61955, 0x009427A8, 0x009B8674, 0x0090C832, 0x008812C7, 0x0080BA58, 0x007981E1, 0x0072AB68, 0x0074CB4B, 0x00723F3F, 0x007CC258, 0x0089CD5C, 0x0088E2A2, 0x008E8906, 0x008B88A0, 0x008EEC8D, 0x008F3573, 0x008B746F, 0x00912C82, 0x008D7CF2, 0x00832099, 0x007F45A5, 0x00685AFF, 0x0050A4D2, 0x00526FE2, 0x0058923B, 0x00529EC1, 0x00516D1A, 0x005B7453, 0x007028E6, 0x0089C6FA, 0x00A5D6AE, 0x00D37A14, 0x00B8CFAA, 0x00B0BB4B, 0x00AE69A4, 0x00A1154B, 0x009DCBE7, 0x00A1DC20, 0x00AA07E3, 0x00B25CB1, 0x00B2FD98, 0x00B12F29, 0x00E428A0, 0x011B2184, 0x01615722, 0x01A502F3, 0x01C0AA9D, 0x01D4169F, 0x01EF8B76, 0x0233E5BB, 0x0275A6F0, 0x02A9CA35, 0x02A8904C, 0x02A194EF, 0x02926F39, 0x028E92C3]
j=np.mat(a) #构造三个矩阵
k=np.mat(b)
l=np.mat(c)
h=k*j #矩阵相乘,左右不能颠倒
n = np.linalg.inv(h) #求逆矩阵
m=l*n #反解flag
for i in range(64):
print(chr(int(round(m[0,i],0))),end='')

#hgame{100011100000110000100000000110001010110000100010011001111}

misc

好康的流量

wirshark找到base64编码图片,右键导出字节选用base64图像编码直接另存为,然后binwalk什么都没,

接下来用LSB来尝试,

扫描后出现半个flag:hgame{ez_1mg_

再调一下,出现后面的flag

hgame{ez_1mg_Steg4n0graphy}

群青(其实是幽灵东京)

太恶心了这个题,先得到一个wav文件,我们用audacity搞一下,出来

再用010打开,提示用silenteye

猜测第一个是密码,搞出来第二个wav文件,叫做S_S_T_V显然想到sstv,但虚拟机上无法操作,不知道为什么

找到一个牛逼的软件直接边听变出结果,音乐太刺耳了!!!

hgame{1_c4n_5ee_the_wav}

这个压缩包有点麻烦

太麻烦我了,前两层分别用数字爆破,字典爆破,然后很显然是个明文攻击,然后binwalk一下,最后伪代码,出结果,这么难的题怎么这么多人出结果!!!

crypto

Easy RSA

这个题就不用说了吧,白给。给出我的经典脚本!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from gmpy2 import*
from libnum import*
from Crypto.Util.number import long_to_bytes
import gmpy2
e=18861
p=149
q=191
n=p*q
m=5139
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=chr(pow(m,int(d),n))
print(flag)
#hgame{L00ks_l1ke_y0u've_mastered_RS4!}

English Novel

我觉得就是明文攻击,找到key,但是key有很多,不知道怎么搞,大佬太多了!!等wp

Matryoshka

刚开始是盲文,然后我们转换一下就行,

‘..-/–…/–..–/—–/–…/–..–/—../…–/–..–/.-../….-/–..–/..—/….-/–..–/..—/–…/–..–/.-.-/-…./–..–/…-/….-/–..–/….-/–…/–..–/—../…../–..–/—../–…/–..–/…-/-…./–..–/—../…–/–..–/.—-/–…/–..–/–…/…–/–..–/…-/….-/–..–/-./….-/–..–/—-./–…/–..–/–…/…../–..–/..-/-…./–..–/.-../….-/–..–/.—-/–…/–..–/./-…./–..–/—-./…../–..–/—../…–/–..–/.—-/–…/–..–/..-/….-/–..–/…-/….-/–..–/.—-/…–/–..–/.-.-/….-/–..–/–…/…../–..–/-…./….-/–..–/–…/….-/–..–/—–/–…/–..–/./-…./–..–/.—-/….-/–..–/-…./–…/–..–/—–/…–/–..–/—../–…/–..–/..—/…../–..–/….-/–…/–..–/.-.-/-…./–..–/-…./…–/–..–/.—-/…../–..–/.—-/….-/–..–/–…/…–/–..–/–…/–…/–..–/-…./-…./–..–/….-/–…/–..–/–…/…–/–..–/.-.-/-…./–..–/..-/….-/–..–/./….-/–..–/….-/-…./–..–/…../-…./–..–/….-/….-/–..–/…../…–/–..–/—../-…./–..–/….-/….-/–..–/….-/-….’

转成莫斯密码,换成16进制

46,66,42,75,66,45,46,6E,6D,4C,73,36,44,33,73,69,59,74,4C,36,58,32,70,34,69,4E,30,63,64,53,6C,79,6B,6D,39,72,51,4E,39,6F,4D,53,31,6A,6B,73,39,72,4B,32,52,36,6B,4C,38,68,6F,72,30,3D

得到字符串:FfBufEFnmLs6D3siYtL6X2p4iN0cdSlykm9rQN9oMS1jks9rK2R6kL8hor0=

维吉尼亚密钥hgame,YzBibXZnaHl6X3swUmF6X2d4eG0wdGhrem9fMG9iMG1fdm9rY2N6dF8hcn0=

base64:c0bmvghyz_{0Raz_gxxm0thkzo_0ob0m_vokcczt_!r}

凯撒21位:h0gralmde_{0Wfe_lccr0ympet_0tg0r_atphhey_!w}

栅栏两次:hgame{Welc0me_t0_the_w0rld_0f_crypt0graphy!}

Dancing Line

往右走是0,往下走是1,得到hgame{Danc1ng_L1ne_15_fun,_15n’t_1t?}

IOT

010EDITOR打开就是flag

hgame-week2

该过年了,就写了几道题

re

xD MAZE

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
int v4; // esi
__int64 v5; // rax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11[4]; // [rsp+20h] [rbp-30h] BYREF
int v12; // [rsp+40h] [rbp-10h]
int i; // [rsp+48h] [rbp-8h]
int v14; // [rsp+4Ch] [rbp-4h]

sub_401980(argc, argv, envp);
memset(v11, 0, sizeof(v11));
v12 = 0;
v14 = 0;
std::operator>><char,std::char_traits<char>>(&std::cin, v11);
v3 = sub_401550(v11);
v4 = sub_401550("hgame{");
if ( v3 == v4 + (unsigned int)sub_401550("}") + 28 )
{
if ( (unsigned int)sub_40158F(v11, "hgame{", 6i64) || BYTE2(v12) != 125 )
{
LABEL_8:
v8 = std::operator<<<std::char_traits<char>>(&std::cout, "Forbidden format");
std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
return 1;
}
else
{
for ( i = 6; i <= 33; ++i )
{
switch ( *((_BYTE *)v11 + i) )
{
case '0':
v14 += 512;
break;
case '1':
v14 += 64;
break;
case '2':
v14 += 8;
break;
case '3':
++v14;
break;
default:
goto LABEL_8;
}
if ( byte_404020[v14] != 32 || v14 > 4095 )
{
v9 = std::operator<<<std::char_traits<char>>(&std::cout, "Failed");
std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);
return 1;
}
}
v10 = std::operator<<<std::char_traits<char>>(&std::cout, "Win");
std::ostream::operator<<(v10, &std::endl<char,std::char_traits<char>>);
return 0;
}
}
else
{
v5 = std::operator<<<std::char_traits<char>>(&std::cout, "length err");
std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
return 1;
}
}

我们直接看对比,要求除了hgame{},要32长度,且v14要大于4095,进入v14这个数组

发现就是算步长,这些加起来长度是4095,所以我们要走出去,且只能走到20h这个地方,那么switch就是我们要选择的,从0-3选走几步能到20h即可,soeasy!

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
int64 __fastcall sub_400B8D(__int64 a1, __int64 a2, int a3, int a4, int a5, int a6)
{
int v6; // edx
int v7; // ecx
int v8; // er8
int v9; // er9
__int64 result; // rax
int i; // [rsp+4h] [rbp-1ACh]
int v12; // [rsp+8h] [rbp-1A8h]
int j; // [rsp+Ch] [rbp-1A4h]
int v14[32]; // [rsp+10h] [rbp-1A0h] BYREF
int v15[52]; // [rsp+90h] [rbp-120h] BYREF
__int64 v16[6]; // [rsp+160h] [rbp-50h] BYREF
__int16 v17; // [rsp+190h] [rbp-20h]
unsigned __int64 v18; // [rsp+198h] [rbp-18h]

v18 = __readfsqword(0x28u);
memset(v16, 0, sizeof(v16));
v17 = 0;
sub_40FAC0((unsigned int)"%40s", (unsigned int)v16, a3, a4, a5, a6);
if ( sub_4004E0(v16) != 32 )
{
sub_40F940((unsigned int)"length error", (unsigned int)v16, v6, v7, v8, v9);
sub_40ED20(0LL);
}
for ( i = 0; i < (unsigned __int64)sub_4004E0(v16); ++i )
{
v12 = *((char *)v16 + i) << 8;
for ( j = 0; j <= 7; ++j )
{
if ( (v12 & 0x8000) != 0 )
v12 = (2 * v12) ^ 0x1021;
else
v12 *= 2;
}
v15[i] = (unsigned __int16)v12;
}
v14[0] = 36200;
v14[1] = 40265;
v14[2] = 10770;
v14[3] = 43802;
v14[4] = 52188;
v14[5] = 47403;
v14[6] = 11826;
v14[7] = 40793;
v14[8] = 56781;
v14[9] = 40265;
v14[10] = 43274;
v14[11] = 3696;
v14[12] = 62927;
v14[13] = 2640;
v14[14] = 23285;
v14[15] = 65439;
v14[16] = 40793;
v14[17] = 48395;
v14[18] = 22757;
v14[19] = 14371;
v14[20] = 48923;
v14[21] = 30887;
v14[22] = 43802;
v14[23] = 18628;
v14[24] = 43274;
v14[25] = 11298;
v14[26] = 40793;
v14[27] = 23749;
v14[28] = 24277;
v14[29] = 30887;
v14[30] = 9842;
v14[31] = 22165;
if ( (unsigned int)sub_400490(v15, v14, 32LL) )
sub_4107A0("Wrong");
else
sub_4107A0("Great,your input is flag");
result = 0LL;
if ( __readfsqword(0x28u) != v18 )
sub_44B8A0();
return result;
}

这个题很好搞吗,爆破或者直接动态调试,我爆破没出来,动调了一下,只要能跟v14相等就行了,然后解出flag才发现这个题爆破不出来是因为里面牵扯了crc16这个东西,然后修改了一下异或的值就出来了。

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
flag = ""
p = [36200,40265,10770,43802,52188,47403,11826,40793,56781,40265,43274,3696,62927,2640,23285,65439,40793,48395,22757,14371,48923,30887,43802,18628,43274,11298,40793,23749,24277,30887,9842,22165]
for i in range(32):
for j in range(27,127):
a = j << 8
for m in range(8):
if (a & 0x8000) != 0:
a = (2 * a) ^ 0x11021 #异或的值是变化了的
else:
a *= 2
if a&0xffff == p[i]:
print(chr(j))
[0x00003653, 0x00002672, 0x00001611, 0x00000630, 0x000076D7, 0x000066F6, 0x00007C87, 0x00004CE4, 0x00005CC5, 0x00002C22, 0x00003C03,
0x00000C60, 0x00001C41, 0x0000EDAE, 0x0000FD8F, 0x0000CDEC, 0x0000DDCD, 0x0000AD2A, 0x0000BD0B, 0x00008D68, 0x00009D49, 0x00007E97,
0x00006EB6, 0x00005ED5, 0x00004EF4, 0x00003E13, 0x00002E32, 0x00001E51, 0x00000E70, 0x0000FF9F, 0x0000EFBE, 0x0000DFDD, ]
#012345abcdefghijklmnopqrstuvwxyz
[0x00005695, 0x000046B4, 0x0000B75B, 0x0000A77A, 0x0000AB1A, 0x000058E5, 0x00006886, 0x000078A7, 0x00000840, 0x00001861, 0x00002802,
0x00003823, 0x0000C9CC, 0x0000D9ED, 0x0000E98E, 0x0000F9AF, 0x00008948, 0x00009969, 0x0000A90A, 0x0000B92B, 0x00005AF5, 0x00004AD4,
0x00007AB7, 0x00006A96, 0x00001A71, 0x00000A50, 0x00003A33, 0x00002A12, 0x0000DBFD, 0x0000CBDC, 0x0000FBBF, 0x00008528, ]
#6789_ABCDEFGHIJKLMNOPQRSTUVWXYZ*
[0x00003443, 0x00000420, 0x00001401, 0x000064E6, 0x000074C7, 0x000044A4, 0x00005485, 0x0000A56A, 0x0000B54B, 0x00009509, 0x0000E5EE,
0x0000F5CF, 0x0000C5AC, 0x0000D58D, 0x00009719, 0x00008738, 0x0000F7DF, 0x0000E7FE, 0x0000D79D, 0x0000C7BC, 0x000048C4, 0x0000EB9E,
0x00009B79, 0x00008B58, 0x0000BB3B, 0x0000CFFC, 0x0000AF3A, 0x00003653, 0x00003653, 0x00003653, 0x00003653, 0x00003653, ]
#!"#$%&'()+,-./:;<=>?@[\]^{}00000
#hgame{noW_YOu~koNw-UPx~mAG|C_@Nd~crC16}

fake shell

出题人做了个很吊的shell,我们不管那么多,直接定位到最重要的函数

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
int64 __fastcall sub_176C(__int64 *a1)
{
size_t v1; // rax
__int64 v2; // rdx
__int64 v3; // rdx
int i; // [rsp+1Ch] [rbp-164h]
__int64 v6[4]; // [rsp+20h] [rbp-160h] BYREF
__int64 v7[4]; // [rsp+40h] [rbp-140h]
char v8; // [rsp+60h] [rbp-120h]
__int64 v9[34]; // [rsp+70h] [rbp-110h] BYREF

v9[33] = __readfsqword(0x28u);
memset(v9, 0, 256);
v1 = strlen(aHappyhg4me);
sub_1358(v9, aHappyhg4me, v1);
v2 = a1[1];
v6[0] = *a1;
v6[1] = v2;
v3 = a1[3];
v6[2] = a1[2];
v6[3] = v3;
sub_1635(v9, v6, 32LL);
v7[0] = 0xE0B25F3D8FFA94B6LL;
v7[1] = 0xE79D6C9866D20FEALL;
v7[2] = 0x6D6FBEC57140081BLL;
v7[3] = 0xF6F3BDA88D097B7CLL;
v8 = 0;
for ( i = 0; i <= 31; ++i )
{
if ( *((_BYTE *)v7 + i) != *((_BYTE *)v6 + i) )
return 0LL;
}
return 1LL;
}
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
unsigned __int64 __fastcall sub_1358(__int64 a1, __int64 a2, unsigned __int64 a3)
{
char v4; // [rsp+27h] [rbp-119h]
int i; // [rsp+28h] [rbp-118h]
int j; // [rsp+28h] [rbp-118h]
int v7; // [rsp+2Ch] [rbp-114h]
__int64 v8[33]; // [rsp+30h] [rbp-110h] BYREF
unsigned __int64 v9; // [rsp+138h] [rbp-8h]

v9 = __readfsqword(0x28u);
v7 = 0;
memset(v8, 0, 256);
for ( i = 0; i <= 255; ++i )
{
*(_BYTE *)(i + a1) = i;
*((_BYTE *)v8 + i) = *(_BYTE *)(i % a3 + a2);
}
for ( j = 0; j <= 255; ++j )
{
v7 = (*((char *)v8 + j) + v7 + *(unsigned __int8 *)(j + a1)) % 256;
v4 = *(_BYTE *)(j + a1);
*(_BYTE *)(j + a1) = *(_BYTE *)(v7 + a1);
*(_BYTE *)(a1 + v7) = v4;
}
return __readfsqword(0x28u) ^ v9;
}

很明显是rc4加密,根据源码我发现并没有改,但解密不对,怀疑是改了密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
unsigned __int64 sub_1C27()
{
int fd; // [rsp+4h] [rbp-7Ch]
char *i; // [rsp+8h] [rbp-78h]
char buf[104]; // [rsp+10h] [rbp-70h] BYREF
unsigned __int64 v4; // [rsp+78h] [rbp-8h]

v4 = __readfsqword(0x28u);
fd = open("/proc/self/status", 0);
read(fd, buf, 0x64uLL);
for ( i = buf; *i != 84 || i[1] != 114 || i[2] != 97 || i[3] != 99 || i[4] != 101 || i[5] != 114; ++i )
;
if ( !atoi(i + 11) )
strcpy(aHappyhg4me, "w0wy0ugot1t");
return __readfsqword(0x28u) ^ v4;
}

果然是在init段改了密钥,解密就行了,注意是小端序

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
import base64
def rc4_main(key="init_key", message="init_message"):
print("RC4解密主函数调用成功")
print('\n')
s_box = rc4_init_sbox(key)
crypt = rc4_excrypt(message, s_box)
return crypt
def rc4_init_sbox(key):
s_box = list(range(256))
print("原来的 s 盒:%s" % s_box)
print('\n')
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
print("混乱后的 s 盒:%s" % s_box)
print('\n')
return s_box
def rc4_excrypt(plain, box):
print("调用解密程序成功。")
print('\n')
plain = base64.b64decode(plain.encode('utf-8'))
plain = bytes.decode(plain)
res = []
i = j = 0
for s in plain:
i = (i + 1) % 256
j = (j + box[i]) % 256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j]) % 256
k = box[t]
res.append((ord(s) ^ k))
print("res用于解密字符串,解密后是:%res" % res)
print('\n')
cipher = "".join(res)
print("解密后的字符串是:%s" % cipher)
print('\n')
return cipher
\#a=[0xE0,0xB2,0x5F,0x3D,0x8F,0xFA,0x94,0xB6,0xE7,0x9D,0x6C,0x98,0x66,0xD2,0x0F,0xEA,0x6D,0x6F,0xBE,0xC5,0x71,0x40,0x08,0x1B,0xF6,0xF3,0xBD,0xA8,0x8D,0x09,0x7B,0x7C]
a = [0xB6,0x94,0xFA,0x8F,0x3D,0x5F,0xB2,0xE0,0xEA,0x0f,0xd2,0x66,0x98,0x6c,0x9d,0xe7,0x1b,0x08,0x40,0x71,0xc5,0xbe,0x6f,0x6d,0x7c,0x7b,0x09,0x8d,0xa8,0xbd,0xf3,0xf6]
s = ""
for i in a:
s += chr(i)
s = str(base64.b64encode(s.encode('utf-8')), 'utf-8')
rc4_main("w0wy0ugot1t", s)

creakme2

这个题

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
const char *v4; // rcx
int Buf2[8]; // [rsp+20h] [rbp-19h] BYREF
char Buf1[8]; // [rsp+40h] [rbp+7h] BYREF
char v8[8]; // [rsp+48h] [rbp+Fh] BYREF
char v9[8]; // [rsp+50h] [rbp+17h] BYREF
char v10[16]; // [rsp+58h] [rbp+1Fh] BYREF
int v11[10]; // [rsp+68h] [rbp+2Fh] BYREF

v11[9] = 0;
v11[0] = 1;
v11[1] = 2;
v11[2] = 3;
v11[3] = 4;
v11[4] = 5;
v11[5] = 6;
v11[6] = 7;
v11[7] = 8;
v11[8] = 9;
sub_140001008("%32s");
sub_140001070(0x20u, (unsigned int *)Buf1, (__int64)v11);
sub_140001070(0x20u, (unsigned int *)v8, (__int64)v11);
sub_140001070(0x20u, (unsigned int *)v9, (__int64)v11);
sub_140001070(0x20u, (unsigned int *)v10, (__int64)v11);
Buf2[0] = 0x457E62CF;
Buf2[1] = 0x9537896C;
Buf2[2] = 528383858;
Buf2[3] = -140479528;
Buf2[4] = -1902548888;
Buf2[5] = 1085255577;
Buf2[6] = 261688884;
Buf2[7] = 426721414;
v3 = memcmp(Buf1, Buf2, 0x20ui64);
v4 = "Congratulations!";
if ( v3 )
v4 = "Try again!";
puts(v4);
return 0;
}

我们只用看sub_140001070函数就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int64 __fastcall sub_140001070(unsigned int a1, unsigned int *a2, __int64 a3)
{
__int64 result; // rax
int v4; // [rsp+20h] [rbp-38h]
unsigned int v5; // [rsp+24h] [rbp-34h]
unsigned int v6; // [rsp+28h] [rbp-30h]
unsigned int i; // [rsp+2Ch] [rbp-2Ch]

v5 = *a2;
v6 = a2[1];
v4 = 0;
for ( i = 0; i < a1; ++i )
{
v5 += (*(_DWORD *)(a3 + 4i64 * (v4 & 3)) + v4) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
v4 += dword_140003034;
v6 += (*(_DWORD *)(a3 + 4i64 * ((v4 >> 11) & 3)) + v4) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));
}
*a2 = v5;
result = 4i64;
a2[1] = v6;
return result;
}

显然是个xtea,在delta处进行魔改,然后解密,发现不行。动调后发现有异常处理装置。

无语

找到fileter,进入call后的函数

看汇编知道,解决方法是判断数据循环中计算后是否为正数,为正数则与0x1234567进行一次异或。

写脚本

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
#include <stdio.h>
#include <stdint.h>
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0=v[0], v1=v[1], delta=0x9E3779B1, sum=0xc78e4d05; //这里加密逻辑变了初始sam值可以跑正向逻辑得到
for (i=0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
if((sum >> 31) == 0){
sum ^= 0x1234567;
}
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
}
v[ 0]=v0; v[1]=v1;
}
int main()
{
int i;
uint32_t v[8]={0x457E62CF,0x9537896C,0x1F7E7F72,0x0F7A073D8,0x8E996868,0x40AFAF99,0x0F990E34,0x196F4086};
uint32_t const k[4]={1,2,3,4};
unsigned int r=32;
for (i = 0; i < 4;i++){
decipher(r, (v+i*2), k);
printf("解密后的数据:%x %x\n",v[i*2],v[i*2+1]);
}
return 0;
}

注意解出来的是小端序!

CRYPTO

rsa attack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from gmpy2 import*
from libnum import*
from Crypto.Util.number import long_to_bytes
import gmpy2
n=700612512827159827368074182577656505408114629807
c=122622425510870177715177368049049966519567512708
e=65537
p=715800347513314032483037
q=978782023871716954857211
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=pow(c,int(d),n)
print(n2s(flag))
#b'hgame{SHorTesT!fLAg}'


rsa attack2

first、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from gmpy2 import *
n1 = 14611545605107950827581005165327694782823188603151768169731431418361306231114985037775917461433925308054396970809690804073985835376464629860609710292181368600618626590498491850404503443414241455487304448344892337877422465715709154238653505141605904184985311873763495761345722155289457889686019746663293720106874227323699288277794292208957172446523420596391114891559537811029473150123641624108103676516754449492805126642552751278309634846777636042114135990516245907517377320190091400729277307636724890592155256437996566160995456743018225013851937593886086129131351582958811003596445806061492952513851932238563627194553
c1 = 965075803554932988664271816439183802328812013694203741320763105376036912584995031647672348468111310423680858101990670067065306237596121664884353679987689532305437801346923070145524106271337770666947677115752724993307387122132705797012726237073550669419110046308257408484535063515678066777681017211510981429273346928022971149411064556225001287399141306136081722471075032423079692908380267160214143720516748000734987068685104675254411687005690312116824966036851568223828884335112144637268090397158532937141122654075952730052331573980701136378212002956719295192733955673315234274064519957670199895100508623561838510479
n2 = 20937478725109983803079185450449616567464596961348727453817249035110047585580142823551289577145958127121586792878509386085178452171112455890429474457797219202827030884262273061334752493496797935346631509806685589179618367453992749753318273834113016237120686880514110415113673431170488958730203963489455418967544128619234394915820392908422974075932751838012185542968842691824203206517795693893863945100661940988455695923511777306566419373394091907349431686646485516325575494902682337518438042711296437513221448397034813099279203955535025939120139680604495486980765910892438284945450733375156933863150808369796830892363
c2 = 11536506945313747180442473461658912307154460869003392732178457643224057969838224601059836860883718459986003106970375778443725748607085620938787714081321315817144414115589952237492448483438910378865359239575169326116668030463275817609827626048962304593324479546453471881099976644410889657248346038986836461779780183411686260756776711720577053319504691373550107525296560936467435283812493396486678178020292433365898032597027338876045182743492831814175673834198345337514065596396477709839868387265840430322983945906464646824470437783271607499089791869398590557314713094674208261761299894705772513440948139429011425948090
n=[n1,n2]
c=[c1,c2]
for i in range(len(n)):
for j in range(len(n)):
if(i!=j):
if(gcd(n[i],n[j])!=1): #对不同的n进行 欧几德得 算法,以求出最大公约数
print(i,j)
print("p =",gcd(n[i],n[j]))
#如果有多个n,c那么用此来求某n与n的最大公因数然后用first-2中的来算q,从而求出密文
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from gmpy2 import*
import libnum
n1 = 507419170088344932990702256911694788408493968749527614421614568612944144764889717229444020813658893362983714454159980719026366361318789415279417172858536381938870379267670180128174798344744371725609827872339512302232610590888649555446972990419313445687852636305518801236132032618350847705234643521557851434711389664130274468354405273873218264222293858509477860634889001898462547712800153111774564939279190835857445378261920532206352364005840238252284065587291779196975457288580812526597185332036342330147250312262816994625317482869849388424397437470502449815132000588425028055964432298176942124697105509057090546600330760364385753313923003549670107599757996810939165300581847068233156887269181096893089415302163770884312255957584660964506028002922164767453287973102961910781312351686488047510932997937700597992705557881172640175117476017503918294534205898046483981707558521558992058512940087192655700351675718815723840568640509355338482631416345193176708501897458649841539192993142790402734898948352382350766125000186026261167277014748183012844440603384989647664190074853086693408529737767147592432979469020671772152652865219092597717869942730499507426269170189547020660681363276871874469322437194397171763927907099922324375991793759
e = 77310199867448677782081572109343472783781135641712597643597122591443011229091533516758925238949755491395489408922437493670252550920826641442189683907973926843505436730014899918587477913032286153545247063493885982941194996251799882984145155733050069564485120660716110828110738784644223519725613280140006783618393995138076030616463398284819550627612102010214315235269945251741407899692274978642663650687157736417831290404871181902463904311095448368498432147292938825418930527188720696497596867575843476810225152659244529481480993843168383016583068747733118703000287423374094051895724494193455175131120243097065270804457787026492578916584536863548445813916819417857064037664101684455000184987531252344582899589746272173970083733130106407810619258077266603898529285634495710846838011858287024329514491058790557305041389614650730267774482954666726949886313386881066593946789460028399523245777171320319444673551268379126203862576627540177888290265714418064334752499940587750374552330008143708562065940245637685833371348603338834447212248648869514585047871442060412622164276894766238383894693759347590977926306581080390685360615407766600573527565016914830132066428454738135380178959590692145577418811677639050929791996313180297924833690095
c1 = 165251729917394529793163344300848992394021337429474789711805041655116845722480301677817165053253655027459227404782607373107477419083333844871948673626672704233977397989843349633720167495862807995411682262559392496273163155214888276398332204954185252030616473235814999366132031184631541209554169938146205402400412307638567132128690379079483633171535375278689326189057930259534983374296873110199636558962144635514392282351103900375366360933088605794654279480277782805401749872568584335215630740265944133347038070337891035560658434763924576508969938866566235926587685108811154229747423410476421860059769485356567301897413767088823807510568561254627099309752215808220067495561412081320541540679503218232020279947159175547517811501280846596226165148013762293861131544331444165070186672186027410082671602892508739473724143698396105392623164025712124329254933353509384748403154342322725203183050328143736631333990445537119855865348221215277608372952942702104088940952142851523651639574409075484106857403651453121036577767672430612728022444370874223001778580387635197325043524719396707713385963432915855227152371800527536048555551237729690663544828830627192867570345853910196397851763591543484023134551876591248557980182981967782409054277224
p = mpz(46731919563265721307105180410302518676676135509737992912625092976849075262192092549323082367518264378630543338219025744820916471913696072050291990620486581719410354385121760761374229374847695148230596005409978383369740305816082770283909611956355972181848077519920922059268376958811713365106925235218265173085)
q = n1//p #“//” 整除
phi = (p-1)*(q-1)
d = invert(e,phi)
m = pow(c1,d,n1)
print(m) # "n2s" (数值转字符串)
print(hex(m))
print(bytes.fromhex(hex(m)[2:]))
#b'hgame{RsA@hAS!a&VArIETY?of.'

second

1
2
3
4
5
6
7
8
9
import binascii
import gmpy2
e = 7
n = 14157878492255346300993349653813018105991884577529909522555551468374307942096214964604172734381913051273745228293930832314483466922529240958994897697475939867025561348042725919663546949015024693952641936481841552751484604123097148071800416608762258562797116583678332832015617217745966495992049762530373531163821979627361200921544223578170718741348242012164115593777700903954409103110092921578821048933346893212805071682235575813724113978341592885957767377587492202740185970828629767501662195356276862585025913615910839679860669917255271734413865211340126544199760628445054131661484184876679626946360753009512634349537
c = 10262871020519116406312674685238364023536657841034751572844570983750295909492149101500869806418603732181350082576447594766587572350246675445508931577670158295558641219582729345581697448231116318080456112516700717984731655900726388185866905989088504004805024490513718243036445638662260558477697146032055765285263446084259814560197549018044099935158351931885157616527235283229066145390964094929007056946332051364474528453970904251050605631514869007890625
m=gmpy2.iroot(c, 7)[0]
print(binascii.unhexlify(hex(m)[2:].strip("L")))
#b'AttacK^mEThodS^whAT:other!A'
#本题是e给的很小,n无法分解。小明文攻击小明文攻击是基于低加密指数的,主要分成两种情况。明文过小,导致明文的e次方仍然小于n。这种情况直接对密文e次开方,即可得到明文

third

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
import sys
import binascii
sys.setrecursionlimit(1000000)
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
n = 18819509188106230363444813350468162056164434642729404632983082518225388069544777374544142317612858448345344137372222988033366528086236635213756227816610865045924357232188768913642158448603346330462535696121739622702200540344105464126695432011739181531217582949804939555720700457350512898322376591813135311921904580338340203569582681889243452495363849558955947124975293736509426400460083981078846138740050634906824438689712748324336878791622676974341814691041262280604277357889892211717124319329666052810029131172229930723477981468761369516771720250571713027972064974999802168017946274736383148001865929719248159075729
e1 = 2519901323
c1 = 3230779726225544872531441169009307072073754578761888387983403206364548451496736513905460381907928107310030086346589351105809028599650303539607581407627819797944337398601400510560992462455048451326593993595089800150342999021874734748066692962362650540036002073748766509347649818139304363914083879918929873577706323599628031618641793074018304521243460487551364823299685052518852685706687800209505277426869140051056996242882132616256695188870782634310362973153766698286258946896866396670872451803114280846709572779780558482223393759475999103607704510618332253710503857561025613632592682931552228150171423846203875344870
e2 = 3676335737
c2 = 940818595622279161439836719641707846790294650888799822335007385854166736459283129434769062995122371073636785371800857633841379139761091890426137981113087519934854663776695944489430385663011713917022574342380155718317794204988626116362865144125136624722782309455452257758808172415884403909840651554485364309237853885251876941477098008690389600544398998669635962495989736021020715396415375890720335697504837045188626103142204474942751410819466379437091569610294575687793060945525108986660851277475079994466474859114092643797418927645726430175928247476884879817034346652560116597965191204061051401916282814886688467861
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
if s1<0:
s1 = - s1
c1 = modinv(c1, n)
elif s2<0:
s2 = - s2
c2 = modinv(c2, n)
m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
print(m)
print (binascii.unhexlify(hex(m)[2:].strip("L")))
#b'ttACK|METHOdS~do@you_KNOW}'
#共模攻击,两个c,两个e,n不可分解

hgame-week3

有点摆烂这一周,做了一点题

re

1、Answer’s Windows

我们直接字符串定位,搜索answer,发现有一处地方很有问题

跟进一下

我们发现经过加密后对比一下就可以出现正确的图片,我们先看函数中的加密算法,是base64,我们动调发现其实并没有变化,所以没有魔改,但怎么也不会出现对比的字符串,所以猜测是base64表被改了,所以交叉引用一波。

动调一下发现规律:

!”#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`a

这个换表是真的不好猜,然后我们解密就行了,但memcmp中的字符串还有转义字符。有点坑

1
2
3
4
5
6
import base64
import string
str1 = ";'>B<76\\=82@-8.@=T\"@-7ZU:8*F=X2J<G>@=W^@-8.@9D2T:49U@1aa"
string1 = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))

用上面脚本避免转义字符情况

2、creakme3

本题是用ppc汇编写的,所以我的ida不能汇编,但据说ida7.5可以用插件搞,我选择用 Ghidra

https://blog.csdn.net/u012501842/article/details/107634080?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164472536016780274167836%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164472536016780274167836&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-107634080.pc_search_result_positive&utm_term=ghidra+%E5%AE%89%E8%A3%85&spm=1018.2226.3001.4187

使用方法讲的很好,定位到main之后看反编译结果,很清楚。

输入flag,然后如果左边大于右边就往后走,左侧是a的结构体,其中第一个 int 为字符的 ASCII 码,第二个 int 为字符的顺序,使用猴子排序算法来对数据进行排序,如果排序成功就会输出flag。

猴子排序就是乱排,直到有序为止。

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
struct alpha
{
int ch;
int index;
};
struct alpha a[89] =
{
{ 48, 20093 }, { 48, 26557 }, { 48, 31304 }, { 48, 33442 }, { 48, 37694}, { 49, 39960 }, { 50, 23295 }, { 50, 27863 }, { 50, 42698 }, { 50,48505 }, { 50, 52925 }, { 51, 12874 }, { 51, 12946 }, { 51, 14597 }, {51, 17041 }, { 51, 23262 }, { 51, 28319 }, { 51, 42282 }, { 51, 48693 },{ 51, 52067 }, { 53, 32571 }, { 56, 14612 }, { 56, 45741 }, { 57, 14554 },{ 57, 20048 }, { 57, 27138 }, { 57, 45327 }, { 66, 30949 }, { 95, 32502}, { 95, 35235 }, { 95, 36541 }, { 95, 38371 }, { 97, 29658 }, { 100,21388 }, { 100, 25403 }, { 100, 40604 }, { 100, 46987 }, { 100, 51302 },{ 101, 12974 }, { 101, 30329 }, { 102, 10983 }, { 102, 19818 }, { 102,22280 }, { 102, 26128 }, { 102, 41560 }, { 102, 47116 }, { 102, 51333 },{ 103, 28938 }, { 103, 31988 }, { 104, 16246 }, { 104, 28715 }, { 104,41966 }, { 104, 44368 }, { 104, 47815 }, { 105, 16420 }, { 105, 35362 },{ 105, 49237 }, { 106, 11090 }, { 106, 50823 }, { 107, 24320 }, { 107,50199 }, { 108, 24962 }, { 109, 30171 }, { 110, 15457 }, { 110, 18838 },{ 110, 24001 }, { 111, 11638 }, { 111, 32023 }, { 111, 43291 }, { 112,39661 }, { 114, 17872 }, { 114, 33895 }, { 114, 43869 }, { 115, 20611 },{ 115, 25122 }, { 115, 36243 }, { 115, 37434 }, { 115, 38686 }, { 115,46266 }, { 115, 51077 }, { 116, 13656 }, { 116, 34493 }, { 116, 38712 },{ 117, 14096 }, { 117, 38777 }, { 119, 12095 }, { 119, 17629 }, { 123,30945 }, { 125, 40770 }
};

#include<stdio.h>
int main()
{
for(int i=0;i<89;i++){
for(int j=0;j<89;j++){
if(a[i].index<a[j].index){
struct alpha temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
for(int i=0;i<89;i++){
putchar(a[i].ch);
}
}

//fjow33etu938nhi3wrnf90sdf32nklsdf0923hgame{B0go_50rt_is_s0_stup1d}fh32orh98sdfh23ikjsdf32

3、无调试器寄

4、fishman

这个题是pyd,昨天做了到pyc混淆,有点搞,pyd相当于dll文件直接ida反编译,我们用插件查到时blowfish算法。

找到key,既然有key,那么我们可以通过动态调试直接找出p盒和s盒,因为key是用来变换p盒和s盒的。

如何动调调试pyd脚本呢,pyd脚本就相当于dll脚本,我们将其放入\python39-x64\Lib\site-packages,有一说一,我没找到vscode下的,但找到vs中的了,但没有3.9版本的。。。然后在vs中设断点进行调试,然后再在ida中attach中找到进行的程序就可以进行动态调试了.

如何引用头文件呢,我们将头文件,即.h文件与.c文件放在同一目录下,然后就行了。

blowfish.h

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef BLOWFISHH

#define BLOWFISHH
#include<stdlib.h>
#include<string.h>

void blowfish_encrypt(void*, void*);
void blowfish_decrypt(void*, void*);
void getkey(char*);
unsigned long f(unsigned long);

#endif

直接解密脚本

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#include"blowfish_head.h"
#include<stdio.h>
//变换后的P盒
unsigned long pbx[18] =
{
0x6af74079, 0xc87db4da, 0x064b77a4, 0x33a56687, 0x73924432, 0x3a78e859, 0xa0f9451e, 0x6e99ea5f, 0xcb62f79c,
0xec009d50, 0x46b85709, 0x3b2bfdf6, 0xd0a0f937, 0x67c4c3e1, 0x80d02257, 0x4162d4de, 0x814dce61, 0x227bde9b

};
//变换后的S盒
unsigned long sbx[4][256] =
{
{ 0x857e5597, 0x326dad20, 0x2d507f8e, 0x2b80ba2c, 0xd711e661, 0x4b7e9667, 0x7a4b2509, 0x5117c0a3, 0x537791d2,
0xbda0ec99, 0x9f5d600, 0x97d7453e, 0x6c3dede1, 0xefbec2ec, 0x31f20650, 0x86ea7ee1, 0x4a380c4e, 0x688500c0,
0xc939e94b, 0xee64fe1f, 0xdae4a7bd, 0xafdfe274, 0xef95a497, 0xca5e8fc8, 0xa16220a, 0x9c85d82f, 0x3f411e1f,
0x199cd133, 0x52ecbaa8, 0x68886557, 0xf8d4ca71, 0x729c0def, 0x5d6d4eb4, 0x550b9697, 0x77a9b569, 0xae8aacd5,
0xa48c80d0, 0xb171f834, 0xd6828c5f, 0xf5219b37, 0x260e8a36, 0x9a8fbeba, 0xdf6ca01, 0x5f5ee56f, 0xc2e21a2f,
0x87d75493, 0x87ef74ef, 0xfe01a2da, 0x8326e260, 0x7b3f0f, 0xc21ab19, 0x589f28be, 0x9ff0636, 0x2ac6affc, 0xb8e547d,
0x91fa13e2, 0xde9a211f, 0x70b95314, 0x5879cad1, 0x8d38aa78, 0xffae559e, 0x132d25af, 0x4244c5f1, 0x7831cb8d,
0x5625d8a2, 0xa99878b6, 0x44dfa664, 0x5b4e43c7, 0xfde79c18, 0xa8f89efb, 0x96a65669, 0xfa7ec977, 0x6438138b,
0x63098e28, 0x7048ba4b, 0xc6f0e94, 0xabc7ae87, 0xdce4560, 0x2ee85291, 0xa7e24dd8, 0xdf0b5970, 0x3d8fcbe5,
0x55b43ae4, 0x9eceee50, 0x6542e890, 0x4f70b16b, 0x778b58dc, 0xf3f830e4, 0x1b9d5867, 0x7076b41c, 0x6b8386de,
0x8b148ce, 0x31c2fb7d, 0x42fe87c5, 0x108eb334, 0x7c40206, 0x2f783c90, 0xe593491f, 0x2b4ace07, 0xeba73a3c,
0x44fa6586, 0x56ed2871, 0xd9b3ed4f, 0xb04d3c81, 0x93c1656c, 0xc8044fcb, 0x127ff622, 0x159d9dcf, 0x2fc79936,
0x8549ee27, 0x262156cb, 0x721d3364, 0xf5a6f15e, 0x7fe8b137, 0x6cb075da, 0xfaa54cf4, 0x634519ec, 0xde79d57d,
0x8b728797, 0x4b994f3e, 0x242eb5e6, 0x274f5cec, 0xc0f072e0, 0xb6928b6f, 0x8922972b, 0x2207de1e, 0xc0236ffa,
0xc9dca5e5, 0x8d1286f, 0x90729fa3, 0x6a6ed134, 0x4369fae7, 0xf9ae5610, 0x13398b9e, 0xfdd59299, 0x21a3a98b,
0xae6a4a80, 0x6b6e89a6, 0xce85be83, 0xda4c3800, 0x867af755, 0x26b3fb41, 0x96141cce, 0xf176999a, 0x1d844757,
0xe27ce11f, 0x18638c21, 0x960ccbf2, 0xe4ccbbae, 0xaa0fab55, 0xf093bd6f, 0x4cb18fad, 0xf27853df, 0x5d5d925b,
0xc389a234, 0xa9e9b90b, 0x6f06d9e4, 0xf0389646, 0xc75f5884, 0x9961dd6b, 0x44b1dc6a, 0x7ef092, 0xa4ca52a6,
0x5342115d, 0x31d445bb, 0x6cb0b744, 0xd1abcf6, 0x95c6f259, 0xdf719b5d, 0xea51c785, 0xc7303253, 0x1e6a034e,
0xf60989f1, 0x93f55b8d, 0xde786239, 0x9d01dfc5, 0xa4cd54ba, 0xfa60804a, 0x3da55ae7, 0x64d673a, 0x5ee1a39c,
0x6daa769a, 0xec57802a, 0x7acdc0b0, 0xcdfedc6d, 0x72cb1321, 0x42d07041, 0xa45aa294, 0xdbf5b287, 0xca681d73,
0x8d302710, 0x2b1ad68d, 0xc1c6521d, 0x4f40a81c, 0xf4762cb1, 0x8962117f, 0xe33e8bc2, 0xffa7db53, 0xd617f8af,
0xd8b1563b, 0x1ed7d3b4, 0x9f998ca6, 0x1c32a736, 0x3513f35f, 0x7a4da8a8, 0x93f43a38, 0x6bf2eac7, 0xfe3041fd,
0x8853f184, 0x81c00f3e, 0xc601a409, 0x1ceba826, 0x94bc26cd, 0xd07aaf4e, 0x46884d2, 0x5d4ec036, 0xe5587bf2,
0xa3482f3f, 0xdbecc4b2, 0xe5a8e81e, 0x1287e1a3, 0x6e4ef861, 0xb4560ada, 0x5f18f3d5, 0xd9299202, 0xbab5cc00,
0x18464f47, 0x58877430, 0xb4335a0a, 0x7a6e33e, 0xe62e23b4, 0x648e0251, 0xdd94b375, 0x719a409f, 0x5d45064d,
0x243af927, 0xfbd3ab12, 0xdc74bb88, 0x21a563a8, 0x37b0a314, 0x5da98b1f, 0xfc4d4869, 0xbf0c7320, 0xebf308d3,
0x714a3f9a, 0x6606297c, 0x28ff2689, 0xa6779947, 0xfb556d94, 0xb6413de2, 0x21519c0f, 0xb1052485, 0x69c2624b,
0xde9cc548, 0xce36df75, 0x5dbfa8a7 },
{ 0xaee3df14, 0x399d3136, 0x1c0b3ea1, 0xf8416210, 0x719b0d88, 0x908ce2e5, 0x623e46a2, 0xef7772ec, 0xdbc4da3a,
0xe88f6e2e, 0x7fb80562, 0x1a33bfa7, 0xb972b27c, 0xfccb67ab, 0xb53bc933, 0xad99167e, 0x1831a7f0, 0x295e3c91,
0x6afb6529, 0xb1d2c1eb, 0x38702ff1, 0xfb03fc16, 0xf85c29e8, 0x154bbcbf, 0xfc10c6d8, 0x1a07656, 0x9ec55090,
0x52201a4a, 0x9b0ee83f, 0xe08b560a, 0xaff5a8bc, 0x35c5d6d7, 0x8d1f52f, 0x7b2becf0, 0xaf01ac97, 0x3b8700c9,
0xfe56cea4, 0x1c4b14f6, 0xef86351c, 0x27a382c9, 0x28f51829, 0xcdeeee51, 0x3d73d792, 0x152c4a00, 0x7122ccea,
0xbe459436, 0x624f6a81, 0xba728d6f, 0xdf7f103d, 0x7faf6a84, 0xd91174e1, 0xef9ca2f5, 0xa0675400, 0x9e0129,
0x276f61d4, 0xf6e0bbb, 0x2f5e103d, 0x3d24363f, 0x36f1d769, 0xddabaa4d, 0xbd209d7b, 0x38898cda, 0x59aa0a47,
0x3dc28a3b, 0x9374f915, 0x7164635e, 0xa09379f0, 0x462da24e, 0x7a6cd48d, 0xde20ce, 0xeac2f361, 0x9796cbc3,
0x2cc87742, 0x2220d2f5, 0xab17e0c2, 0x16cb3b75, 0x5dc0d229, 0x7d14b8c8, 0x86ad060c, 0xfc1ac21c, 0xa25f8e37,
0x23e553f1, 0xcfca2eb5, 0xda61f278, 0x7a6d0c2c, 0x10f72c33, 0xb9e7da31, 0xf0271ef1, 0xf6d8d0da, 0xccb9fb54,
0x9c16adcc, 0x9c793e5d, 0x308dbae0, 0x8152f53d, 0xb8b02ea8, 0xbb7a73ef, 0x5b52b6e7, 0xda7691a1, 0x6f15166f,
0x1bcf2abf, 0xed9eb801, 0xcc07f0d1, 0x30fd146a, 0xed552ed1, 0xfe280048, 0xca519936, 0xc6bb62d3, 0x78eb0ca9,
0xde25bf1e, 0x377099d1, 0x9e3d9a2a, 0x58d4fdc5, 0x9ef6d4ba, 0x4c4b801c, 0x8d5c098c, 0x84cad315, 0x43b323ca,
0xaff0262, 0x2b3be91f, 0xfd49761b, 0x93671206, 0x2460dd5e, 0x1328fc3, 0xa87f6e1a, 0xceebf4dc, 0x21f7d1d6,
0x8dafb785, 0x1f058aa4, 0xf636282e, 0xf5d5c6a2, 0xdcb85ea1, 0xea4ce0f2, 0xb37fcdaa, 0xadb4cd12, 0xa51b34b3,
0xb2aa712e, 0xa15f5bd, 0x617f127c, 0x7a5dbd16, 0x8aee5420, 0x4d0af701, 0xb2e113d9, 0xb4d09dcb, 0xd258e319,
0x704ec155, 0x533c80be, 0x400c952d, 0xc0dd74a1, 0xa9e5599f, 0xada9e64, 0xa775ef10, 0x35abb495, 0x238b1eb3,
0x5c8ea9e9, 0xd63ac5e, 0xecb22c6f, 0x836879b, 0xdb4958b0, 0x26606a34, 0x33fa456d, 0x91dc9940, 0xccbd103, 0x644cf9a7,
0x80165230, 0xb0e45576, 0x4d28c64d, 0x8d9841cc, 0x3d42c9d1, 0x6fce26aa, 0xe5bd6421, 0xd0e1eb58, 0xfd61f403,
0xdeff165, 0xd5a1bfb1, 0xb3323bbe, 0xdb641c02, 0xbfca7536, 0xb8f5820f, 0xda30db7b, 0xd76a9581, 0x61b8a87f,
0x5d8410c2, 0x4b2df093, 0xc96447e9, 0xc4ba2487, 0xb24afc5a, 0x797db008, 0xc362253a, 0xc6bbe115, 0x1cc0ed71,
0xabe73320, 0xc4364688, 0x5adef1c2, 0x59af22fb, 0xa9aca101, 0x4b5bac9b, 0xb121e519, 0xd8fcf69e, 0x2f0f0f89,
0xef615692, 0xd9fac700, 0x6729f5e, 0x15b5965f, 0x83a0e48a, 0xd80cd549, 0xc85443c6, 0xdb051d9e, 0x8646780f,
0x7e1bcd54, 0x7746aafa, 0xbc85c57a, 0x42430bc6, 0x36ab5fb6, 0x92e892ed, 0x87b8897f, 0xefcf526c, 0x6b10f264,
0xe72e284, 0x6fe2966, 0x42f18a1f, 0xdff79c2a, 0x77fbe8e7, 0x942c9858, 0x637710f, 0xad12b3b8, 0xcf786ed1, 0xd7cda884,
0x2cb1dcf1, 0x94f76ac0, 0xf7c4ebbe, 0x6d5591de, 0x6524ea76, 0x200d037e, 0xeb51ac71, 0x8b37601, 0xc9ac832,
0x7721b2a4, 0xca23beee, 0x328c7019, 0xd27fd8c8, 0xc5be7325, 0xe9244524, 0x5b1ea918, 0x74c75201, 0x37621445,
0xae75bef7, 0x174937dc, 0xf71c7cef, 0xf41d6ed3, 0x94c2d289, 0x7d68c2f0, 0xbddfcee6, 0x51d86ee8, 0x97379f95,
0x4275b8c2, 0xf9b3122c },
{ 0x6dbfa6dd, 0x6808c4be, 0x65fb06bd, 0xfde21a89, 0xf4c126b7, 0x438a1cc0, 0x850a843, 0x377114b2, 0x259c0fd,
0x5881f166, 0x6e9fa190, 0x899a312e, 0x8001b123, 0x56d91bd5, 0x31b9a6db, 0x5a4f1940, 0x98140dee, 0x73ad8506,
0x6649c267, 0x6fd7daa8, 0x682bb9e5, 0x7f9061dc, 0x27732a88, 0xa2755af7, 0x54b1b2ec, 0xc171fe6d, 0x33a31667,
0x9afc41e2, 0x396678d5, 0x83cb861, 0xfc473f10, 0x575a023e, 0xfe11cafc, 0xe8ea4057, 0x1289aaa7, 0xa38ef05a,
0x502c3f4a, 0xcb0928e9, 0x8d521829, 0x24c29091, 0xc07fbd37, 0x30cad78f, 0xcd8dba45, 0xc8ccbce8, 0xfdaee556,
0x2a1fc86f, 0x8206edd4, 0x14c2ec89, 0xf0050d48, 0x31f5c320, 0xa5626fd9, 0x19ca606d, 0x65f46320, 0x43e58985,
0xe3f777da, 0x4b9fa89e, 0xf3532d19, 0x1e63ee86, 0xa4c0f1b1, 0x56e691ed, 0xc79b5aa3, 0x1d005b01, 0x7ff86805,
0xed4f0ce3, 0x167128ab, 0x96702d6b, 0x6f2cb666, 0x40d6b43d, 0x7f2e27f9, 0x25813783, 0xf06f47fe, 0xa1eb246e,
0xe11c9c3f, 0x165237ab, 0xa9719981, 0xe0c072ef, 0xbc1430c8, 0x319018e0, 0x65323013, 0xa6337184, 0xe1c06cf0,
0x2c99ecdc, 0xd682f79f, 0x2ebde8d2, 0xbdeca5a8, 0xb85ab458, 0xabc0be15, 0x5ed69b9d, 0x28bf53d3, 0x791d867b,
0x86e6a98a, 0xba722e1c, 0x2311281a, 0xc8cce88d, 0x6c2d3743, 0xf868a752, 0xe0b86a8a, 0x70058bb9, 0xba926231,
0x86a5a32c, 0x3e907ed6, 0x6f03f61e, 0xa87fbe48, 0xa09e8eaa, 0xdd78f5b, 0x622c29eb, 0x26cce112, 0x57215e0f,
0xf9d9b37d, 0xc195133e, 0x703bd721, 0x27f1319b, 0xdccf0b77, 0xb73b7af4, 0xc9f75f9e, 0xf5c62fcb, 0x7293703,
0xeed8b98f, 0x4a9bf102, 0x7349d5c7, 0xda6f8b23, 0x34529af2, 0x968579a9, 0x986d4e5f, 0x8d1903a2, 0x8960df2e,
0x4dccb15c, 0x6a87f919, 0x8bc8e948, 0x82c8274c, 0x52f8bb80, 0xb3b5512c, 0x6b51a116, 0x16abf8e9, 0x99e48bf6,
0xea03be4e, 0xa0766e91, 0x75e2c7e, 0x237be6a5, 0x8c1bd482, 0x473541f5, 0xc4af608b, 0xed686762, 0x1bf0cfc1,
0x4844f0ca, 0x6a9a1980, 0x9d01dbf5, 0x10660435, 0x72fb5e04, 0xbf3de5a3, 0x21fbb319, 0xd303ed2f, 0xa30d610a,
0x76ff38bb, 0x87136fca, 0xa4d11a77, 0xe6c197fd, 0x4e6bc1d1, 0xf2a87aa9, 0xcc795622, 0xb82be2b4, 0x77487ed2,
0x2e7719ad, 0x142854f3, 0xe501258d, 0xb8556c95, 0x4e1a1309, 0x3d74b894, 0xfc1b626d, 0xcff955ec, 0x33bdc46f,
0xed6091ef, 0x645f4f02, 0x7707e28a, 0x556f385a, 0xf8758408, 0xb06b762e, 0xa698d074, 0x46147980, 0x22668afc,
0xdc1f5fa9, 0x245dc1d5, 0x32c87ded, 0xcfa4f49d, 0x734187b5, 0x700bc670, 0x97beeab3, 0x70f6ad54, 0xf0d6535d,
0x76e34811, 0xb734677, 0x7ddbb9d3, 0x2bd695ab, 0xdb2daa29, 0x35c9f605, 0xfc4be706, 0x6e44a54b, 0xa96c5fbe,
0x51e51ba6, 0xc4ebe8c7, 0xe103a24a, 0x842b0bac, 0xdfac2d6d, 0x1aed355d, 0xbdeafbde, 0x32338f9d, 0xaa634582,
0xe152c83a, 0x84be8504, 0x46291ed, 0x7b863e96, 0xdb6776f8, 0x20f815f2, 0xa82af75d, 0xab76c0f5, 0xd550efa2,
0xfd0330f1, 0x22e1fab0, 0x5f4407a3, 0x9b8e9e11, 0xeb1cadde, 0x3d104b1f, 0xc3054713, 0x982eb7fb, 0x543314da,
0x13ae6d5d, 0x56594d93, 0x7af9ddb3, 0x5dbd0b3c, 0xeca553d0, 0x5f892e42, 0xdc466104, 0xf3b8fe09, 0xea63cc0e,
0xe8187fa1, 0xf587d222, 0x762e3246, 0xe3134afd, 0xc8a909a3, 0x2a1b8843, 0xbcf88b37, 0x106d829d, 0xbc6cb72b,
0xba700358, 0x4419c67b, 0x298e5b99, 0x53633710, 0xb4676dfb, 0x5003bfdd, 0x4b1f3fd6, 0xbff5676e, 0xfe221749,
0x22769dec, 0xfa874d3f, 0xe3ab93a1, 0x7e7eac49 },
{ 0xda47873d, 0xb4067196, 0x35629fff, 0x5f9ba741, 0xfc3b885c, 0x7db96275, 0x4be65d7c, 0xaac5aaff, 0xc48e069f,
0xa2b51d88, 0x68efc326, 0x5dc94059, 0xf8fa7b3d, 0xc3e21cc2, 0xa619a16f, 0x46dec824, 0x399fea6, 0x8fc7db62,
0x184569be, 0xc5f04731, 0x90c0dea5, 0xc180bf5f, 0xfccbd6c9, 0x49d7a598, 0x96425151, 0xe53c49fb, 0x15713840,
0xcea6a8a0, 0x5c360e6b, 0x8278ef53, 0xa45ce852, 0xaf1fa60d, 0xd1d357d4, 0xcac8c677, 0x1258a65b, 0x561cc841,
0xe73da602, 0x907e2447, 0xe62e297f, 0x107a743, 0xb0d19719, 0x84bb247a, 0xf8077268, 0xd5f63d60, 0xd9a141de,
0x3486e6a4, 0xbe1052bf, 0x5be4fa46, 0xe792c9c8, 0xb9fbf3b0, 0xcfd36c94, 0x726aa896, 0x683cd337, 0x392a533a,
0x223657a2, 0xf83da285, 0x16c1a03f, 0x68bdbcf5, 0xada3c5ab, 0x124148a8, 0xe7d2a95c, 0xd11922ac, 0x4c6899fd,
0x7d8edf38, 0x118e9247, 0x15c6f2f0, 0x9056dd9f, 0x33520052, 0x7204913c, 0x3171d62d, 0x25d9ff0b, 0x8b629a57,
0xc3ea9218, 0x699e2abf, 0xa9ff8e0f, 0x14dd1c3e, 0xee95bbe7, 0xa2e277c9, 0xd3966991, 0xce4fb1c6, 0x62f9c9,
0x24bee229, 0xc677cc3e, 0x2163ca36, 0xbf6dd3f1, 0x7ae4222f, 0x4322f038, 0x692542df, 0x6692aca0, 0xf6d4946f,
0x89154cfd, 0x9f6a7dbc, 0x104ea9f0, 0x89e3289, 0x87c95990, 0xf945a420, 0xb6a20072, 0x5b630e87, 0x848636c0,
0xa48bb210, 0x4d5494bb, 0x7b7fb94f, 0xc48841b7, 0x422a2e4, 0x6d915a09, 0xcdabb5a5, 0xa36a9dd3, 0x2b321655,
0xe7bd69cf, 0x8c5a8dd8, 0x74615473, 0x8c143ade, 0x6cb1ce59, 0x4396f842, 0xfccbf901, 0xf39018b0, 0x576ba9f5,
0x97aeb15d, 0x6f7df74, 0x30f10bb9, 0x214789d7, 0xdf5edc71, 0xcdd4d413, 0x4e26b481, 0xa96771c4, 0xfbbf9600,
0x61b03c10, 0xb41ec41b, 0x50e85e2c, 0x9ae79ae9, 0x1bffa793, 0x18402dde, 0x3a896084, 0x604aca05, 0xf0370269,
0x83f6b326, 0xfb64099a, 0xabf943bf, 0xe9aa8b99, 0x54ec3adb, 0xa56b3a46, 0x71c05f89, 0x4a7f1444, 0xdf991094,
0x8f5efd28, 0x9ad00ad5, 0x3cbee3c, 0xf5898fc4, 0x692ba57, 0x1928304a, 0x2978de0f, 0x64f85786, 0x62b4f525,
0xda78ad05, 0xb3da431b, 0xdde89dde, 0xcc7da3d9, 0xbde46885, 0xd26c42cf, 0xa7850e7c, 0xff3b73d, 0xd60665a5,
0x825b2d8c, 0xbce1ba7, 0x12be55de, 0x7cf29faa, 0x71a29eca, 0xbd067b1a, 0x2e33857, 0xf0c7e782, 0x9ac9f181,
0x61d9b196, 0x288412eb, 0x756010ba, 0x20f99e06, 0x67e6cb96, 0xd1efb6, 0x1a4dfffb, 0x9d097c31, 0x6890b138,
0xa162f385, 0x5038a02a, 0xdcca2edc, 0xd68af382, 0xed5c9bb, 0xe88cf6c4, 0x4c031e98, 0xca08127b, 0xc67a831f,
0x306fb3f6, 0x9d7315c5, 0x2c72ae76, 0xdd3b3ecc, 0x2ab71490, 0x6e79ef13, 0xe6aa6316, 0x3729bfbc, 0xa13c9bea,
0xa4fa53c, 0xdbafeec6, 0x57a11cc2, 0x8f1be1ba, 0x542a4d3b, 0x8f9c90c4, 0xa2b3ad9f, 0x8951b50, 0xda0641dd,
0xd7cdf19b, 0xebe79e9b, 0x7d6ae548, 0x2ae7eb6f, 0x3ebefb7f, 0xb9cf555d, 0x22b46357, 0x963e79b5, 0x81729e6f,
0xa0657b30, 0x297d0ea1, 0x2d722676, 0xd7c263c7, 0x8fd31545, 0x74b4d545, 0xc9ddb768, 0xd7af1a95, 0x3b41452d,
0xeaa84874, 0x3094af86, 0xc71461f6, 0x8cd49c9b, 0x9d6f96b1, 0x9b45bb4c, 0x58742714, 0x29b19a6a, 0xa85bddc6,
0xb1e0cf54, 0xb55e81d4, 0xcb219b85, 0xcea74b66, 0xd28a041e, 0xe28c4803, 0x490de006, 0x19bb91b1, 0x14d67500,
0x80243406, 0x1ed8b3e, 0xef5636b3, 0x956f13bd, 0x9ae34304, 0xaea37a2c, 0xc90fe0b9, 0x2301fb8f, 0x55716d77,
0xc50297f7, 0x3cabc6a4, 0xa0764bb0, 0xcf38a2a2 }
};

/*
P盒和S盒根据密钥进行变换
因为我们直接替换成变换后的P盒和S盒,所以不需要调用
*/
void getkey(char *keytext)
{
int i = -1, j = 0;
unsigned long key[18];
while (keytext[++i]);
while (i<72) keytext[i++] = 0;
memcpy(key, keytext, 72);
for (i = 0; i<18; i++) pbx[i] ^= key[i];
key[0] = key[1] = 0;
for (i = 0; i<18; i += 2)
{
blowfish_encrypt(key, key);
memcpy(&pbx[i], key, 8);
}
for (i = 0; i<4; i++)
{
for (j = 0; j<256; j += 2)
{
blowfish_encrypt(key, key);
memcpy(&sbx[i][j], key, 8);
}
}
}


void blowfish_encrypt(void *protext, void *ciptext)
{
int i = 0;
unsigned long x[2], temp;
memcpy(x, protext, 8);
for (i = 0; i<16; i++)
{
x[0] ^= pbx[i];
x[1] ^= f(x[0]);
temp = x[1];
x[1] = x[0];
x[0] = temp;
}
temp = x[1];
x[1] = x[0];
x[0] = temp;
x[0] ^= pbx[17];
x[1] ^= pbx[16];
memcpy(ciptext, x, 8);
printf("0x%x,0x%x\n", x[0], x[1]);
}

void blowfish_decrypt(void *protext, void *ciptext)
{
int i = 0;
unsigned long x[2], temp;
memcpy(x, ciptext, 8);
for (i = 17; i >= 2; i--)
{
x[0] ^= pbx[i];
x[1] ^= f(x[0]);
temp = x[1];
x[1] = x[0];
x[0] = temp;
}
temp = x[1];
x[1] = x[0];
x[0] = temp;
x[0] ^= pbx[0];
x[1] ^= pbx[1];
memcpy(protext, x, 8);
printf("0x%x,0x%x\n", x[0], x[1]);
}

unsigned long f(unsigned long x)
{
unsigned long a, b, c, d;
a = (x & 0xff000000) >> 24;
b = (x & 0x00ff0000) >> 16;
c = (x & 0x0000ff00) >> 8;
d = (x & 0x000000ff) >> 0;
return(((sbx[0][a] + sbx[1][b]) ^ sbx[2][c]) + sbx[3][d]);
}

int main()
{
char data[] = "abcdefgh";
char cipher[]={ 0xBF, 0x4E, 0x6F, 0x54, 0x7B, 0x93, 0xED, 0xB4 };//0x6d616768,0x30447b65
//0x7E, 0xA0, 0xD2, 0x82, 0xDD, 0xEF, 0xD3, 0x13->0x7530795f,0x3465725f
//0x0F, 0xAE, 0x09, 0x22, 0x61, 0xDF, 0x4E, 0x59->0x5f563131,0x336b3131
//0x2C, 0x78, 0x33, 0xB9, 0x32, 0xE5, 0x07, 0x1C->0x7456395f,0x7d6e6f68
//blowfish_encrypt(data, cipher);
blowfish_decrypt(data, cipher);
}

为什么密钥什么都行,因为我们动态调试过后找到了p和s盒,如果没找到就要用到密钥了.

misc

卡中毒

镜像分析,先找到可疑文件flag.txt.txt.WannaRen

用filedump下来

然后用网上wannaren解密,得到佛说的话,解密就行

crypto

Multi Prime RSA

这个题我感觉我做的有点问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import binascii
import gmpy2
p = 61789932148719477384027458333380568978056286136137829092952317307711908353477
q = 91207969353355763685633284378833506319794714507027332929290701748727534193861
r = 105471299607375388622347272479207944509670502835651250945203397530010861809367
s = 83153238748903772448138307505579799277162652151244477391465130504267171881437
n = 1039344372165087100001063920598151812324151064684841845250974758525265148567706103784958424873181721352440209284812493753972556519482026327282644619091466886523804841248277210353173383407944598453848113815866908595335619458549486958764490103808475329598085842184963065068499489886467911087295087163762599284622055185456905774507245781667293199205317692029829495961487347944813874415423771980660778986211145841712412631156369129146470119135136378158203459576596246169191419488560832734046076107673091995860021863239882608638458149930255944184863801278386551031980146460231515747754411678651752698881001464973981424240781413084941947261875289725538959720572496329348499870580057997540844488309111059240745081048324762866572948371222839278718034435739827677190025500802453626872356208612718417249649474571197167076916403582394186357812640566250930361276229969553128128312736245440129556020108188835966131425956431796417720436474093381770796431629523054378258497546013222494974549262140415585158985940966415459478150722832119691308697510189026447359189994055885090735411738332296254011208547676914004864732327863884217733456287369771087094514708468685641820375220835485053482570852619363091173324203334503461823983610886849930944250553928855506012684504211525542998575275626784129736345142772399109273619522445919
e = 65537
c = 844677395496466411520394190869787261209960246734415406217975986418865760680024542119231873259131861208878522030009923057991526761346423130242121884493257732067700857897379859545356609151834223804262174935191718271211809221730601602827122249238086030580971376104724987801049500689134122609834321586609223761140538079460830213824674361601046367637227094018381901291488659642720549583856812747877519600804325570421770575999289389175021646347371879234023647657507178519047236746071420327155188213839293382288787853777540226192644761028822256165706787395891134765908229036044468473519166141610604791485071702808854944672418124203289328124793348198048601338476086482318248264508789781967910205393740835345086784345145351367491197717933757414967811594913692588314161669333147733048171044386546892346475181197482702164468542430187885074163177843285948999943328049159021873821254267471067523609151007885131921896462161216356454116929796355815756642621369974260365378070336290542971599886325232821981080341858950609157813769416455337935096696635623426418166316737131174435618543058086342714723330814586496030805366321181723292731710369013923285787724941830672247377301048663929453294620044701627159066468762709113137517559435822623284148112827473010030736329596829357275518641576798298066541516764673029908084962144713
n=p*q*r*s
phi=(p-1)*(q-1)*(r-1)*(s-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(binascii.unhexlify(hex(m)[2:].strip("L")))
#b'hgame{EulEr:fUNcTIon;iS.So*IMpORTaNt*In&RsA}'
#很懵逼,不知道为什么

我不理解为啥这样对了??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import libnum

p = 109056753224725357860050862987465749131702509174531265860789564184166504627089
q = 64871884070495743485110397060920534297122908609816622599229579748089451488127
r = 73817195552029165561107245309535744382442021553254903166961729774806232509583
s = 89907870347457693114161779597928900080173728317019344960807644151097370118553
n = 337945247991531188630780631650822497552908401425959508214145019590891175999570651678385514599227649321033438265588883204645721459926338248032512615537333971869461679586403649697114789385472197685140603238299768873935137939123021910982793481655218061907401584383081422244812725080939394854989735528833013780919908024635812696998644603525843637686545709789908672408993923182946718279531020289767042649725545073526307769817097790005360720650079676982379162926484355121626302801800589993422729725583400678081766553017405965706770238634252836827793877622715474210575752508172785712202444441372140501379422725172250199713113954442223362073485143579617841236442644760494913432967541691532709842303408702693199269606594116690052170245340072114122287646793344327315326489574192325790848798131621842606487734721409882742631176999703502149639410263361145441889337623403361569958342141903891414217371443118527025041591219747780100510414268546884029077010164415049298406632069845430841542680166802473749172801804659277821899576403669845353379213803866969800665351300325701817179936198902427032684058452719607840314873315299975603264092020097224735237221994922702705781103002327285724125001893421030923788361576161461965707958695720464547129911053732747399113017747456439027947305796290572816318795181398935020951025833913
e = 65537
c = 281020926647419736778465777714512241989738235339105762863874725870511725155101862585192241287617168165290485944476735304459717602798728005687755713662466866091315959960168862035396245078850168822145228676116894754613436735897122137945552880864031115366493898382809812977280234389519365119627504653135151731589924405933589175425427189436855517194951589952822691774400942764910734054237756669945324833759799471068481769516338068810710333940167779043544371586185132920304774984746129764220081092726473696111126293966890901487735046101991609292612206984184161394385767762455321150541601949740631911175736268756408775307673610842645555513631617648877296855194327486811545670357137463942744122553468603244298691801028147147418563982169678640270746871085722092365159546820433098926679284504740402248142173715649451061037156261913601096905601577932894877435316535261789072594174871292814951406337447799051502635390866434813419165738873787323716033378045850292413169255965421404580559241351577058726176436504950558398769061998430771982995850759810867299728407860522399699076192754977454139708618158667289120827143703464056583125568576691058753072898162981956883451252542611323974071518397220203389962420073122776649094369816178685947397943358134020598211306649724455966463885765977564934172273334309312046278116760547


flag = ''
phi = (p**2-p)* (q**3-q**2) * (r**5-r**4) * (s**7-s**6)
d = libnum.invmod(e,phi)
flag = libnum.n2s(pow(c,d,n))
print(flag)

大佬们的脚本是这样的

RSA Attack 3

维纳攻击

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
import gmpy2
def transform(x,y): #使用辗转相处将分数 x/y 转为连分数的形式
res=[]
while y:
res.append(x//y)
x,y=y,x%y
return res
def continued_fraction(sub_res):
numerator,denominator=1,0
for i in sub_res[::-1]: #从sublist的后面往前循环
denominator,numerator=numerator,i*numerator+denominator
return denominator,numerator #得到渐进分数的分母和分子,并返回
\#求解每个渐进分数
def sub_fraction(x,y):
res=transform(x,y)
res=list(map(continued_fraction,(res[0:i] for i in range(1,len(res))))) #将连分数的结果逐一截取以求渐进分数
return res



def get_pq(a,b,c): #由p+q和pq的值通过维达定理来求解p和q

par=gmpy2.isqrt(b*b-4*a*c) #由上述可得,开根号一定是整数,因为有解

x1,x2=(-b+par)//(2*a),(-b-par)//(2*a)

return x1,x2



def wienerAttack(e,n):

for (d,k) in sub_fraction(e,n): #用一个for循环来注意试探e/n的连续函数的渐进分数,直到找到一个满足条件的渐进分数

if k==0: #可能会出现连分数的第一个为0的情况,排除
continue
if (e*d-1)%k!=0: #ed=1 (mod φ(n)) 因此如果找到了d的话,(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n)
continue
phi=(e*d-1)//k #这个结果就是 φ(n)
px,qy=get_pq(1,n-phi+1,n)
if px*qy==n:
p,q=abs(int(px)),abs(int(qy)) #可能会得到两个负数,负负得正未尝不会出现
d=gmpy2.invert(e,(p-1)*(q-1)) #求ed=1 (mod φ(n))的结果,也就是e关于 φ(n)的乘法逆元d
return d

print("该方法不适用")

n = 507419170088344932990702256911694788408493968749527614421614568612944144764889717229444020813658893362983714454159980719026366361318789415279417172858536381938870379267670180128174798344744371725609827872339512302232610590888649555446972990419313445687852636305518801236132032618350847705234643521557851434711389664130274468354405273873218264222293858509477860634889001898462547712800153111774564939279190835857445378261920532206352364005840238252284065587291779196975457288580812526597185332036342330147250312262816994625317482869849388424397437470502449815132000588425028055964432298176942124697105509057090546600330760364385753313923003549670107599757996810939165300581847068233156887269181096893089415302163770884312255957584660964506028002922164767453287973102961910781312351686488047510932997937700597992705557881172640175117476017503918294534205898046483981707558521558992058512940087192655700351675718815723840568640509355338482631416345193176708501897458649841539192993142790402734898948352382350766125000186026261167277014748183012844440603384989647664190074853086693408529737767147592432979469020671772152652865219092597717869942730499507426269170189547020660681363276871874469322437194397171763927907099922324375991793759

e = 77310199867448677782081572109343472783781135641712597643597122591443011229091533516758925238949755491395489408922437493670252550920826641442189683907973926843505436730014899918587477913032286153545247063493885982941194996251799882984145155733050069564485120660716110828110738784644223519725613280140006783618393995138076030616463398284819550627612102010214315235269945251741407899692274978642663650687157736417831290404871181902463904311095448368498432147292938825418930527188720696497596867575843476810225152659244529481480993843168383016583068747733118703000287423374094051895724494193455175131120243097065270804457787026492578916584536863548445813916819417857064037664101684455000184987531252344582899589746272173970083733130106407810619258077266603898529285634495710846838011858287024329514491058790557305041389614650730267774482954666726949886313386881066593946789460028399523245777171320319444673551268379126203862576627540177888290265714418064334752499940587750374552330008143708562065940245637685833371348603338834447212248648869514585047871442060412622164276894766238383894693759347590977926306581080390685360615407766600573527565016914830132066428454738135380178959590692145577418811677639050929791996313180297924833690095

d=wienerAttack(e,n)

print("d=",d)

#d= 13094612077654083919

#e特别大,先求d
1
2
3
4
5
6
7
8
import libnum
d= 13094612077654083919
c = 165251729917394529793163344300848992394021337429474789711805041655116845722480301677817165053253655027459227404782607373107477419083333844871948673626672704233977397989843349633720167495862807995411682262559392496273163155214888276398332204954185252030616473235814999366132031184631541209554169938146205402400412307638567132128690379079483633171535375278689326189057930259534983374296873110199636558962144635514392282351103900375366360933088605794654279480277782805401749872568584335215630740265944133347038070337891035560658434763924576508969938866566235926587685108811154229747423410476421860059769485356567301897413767088823807510568561254627099309752215808220067495561412081320541540679503218232020279947159175547517811501280846596226165148013762293861131544331444165070186672186027410082671602892508739473724143698396105392623164025712124329254933353509384748403154342322725203183050328143736631333990445537119855865348221215277608372952942702104088940952142851523651639574409075484106857403651453121036577767672430612728022444370874223001778580387635197325043524719396707713385963432915855227152371800527536048555551237729690663544828830627192867570345853910196397851763591543484023134551876591248557980182981967782409054277224
n = 507419170088344932990702256911694788408493968749527614421614568612944144764889717229444020813658893362983714454159980719026366361318789415279417172858536381938870379267670180128174798344744371725609827872339512302232610590888649555446972990419313445687852636305518801236132032618350847705234643521557851434711389664130274468354405273873218264222293858509477860634889001898462547712800153111774564939279190835857445378261920532206352364005840238252284065587291779196975457288580812526597185332036342330147250312262816994625317482869849388424397437470502449815132000588425028055964432298176942124697105509057090546600330760364385753313923003549670107599757996810939165300581847068233156887269181096893089415302163770884312255957584660964506028002922164767453287973102961910781312351686488047510932997937700597992705557881172640175117476017503918294534205898046483981707558521558992058512940087192655700351675718815723840568640509355338482631416345193176708501897458649841539192993142790402734898948352382350766125000186026261167277014748183012844440603384989647664190074853086693408529737767147592432979469020671772152652865219092597717869942730499507426269170189547020660681363276871874469322437194397171763927907099922324375991793759
m = pow(c,d,n)
print (libnum.n2s(m))
#有n,c,d就用这个
#b'hgame{dO|YOU:kNOw!tHE*PRINcIplE*bEhInd%WInNEr#aTTacK}'

hgame-week4

crypto

ECC

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
from Crypto.Util.number import getPrime
from libnum import s2n
from secret import flag

p = getPrime(256)
a = getPrime(256)
b = getPrime(256)
E = EllipticCurve(GF(p),[a,b])
m = E.random_point()
G = E.random_point()
k = getPrime(256)
K = k * G
r = getPrime(256)
c1 = m + r * K
c2 = r * G
cipher_left = s2n(flag[:len(flag)//2]) * m[0]
cipher_right = s2n(flag[len(flag)//2:]) * m[1]

print(f"p = {p}")
print(f"a = {a}")
print(f"b = {b}")
print(f"k = {k}")
print(f"E = {E}")
print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f"cipher_left = {cipher_left}")
print(f"cipher_right = {cipher_right}")

这个题就是将flag分成了两份,我们只用求出m就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
p = 74997021559434065975272431626618720725838473091721936616560359000648651891507
a = 61739043730332859978236469007948666997510544212362386629062032094925353519657
b = 87821782818477817609882526316479721490919815013668096771992360002467657827319
k = 93653874272176107584459982058527081604083871182797816204772644509623271061231
E = EllipticCurve(GF(p),[a,b])
c1 = E(14455613666211899576018835165132438102011988264607146511938249744871964946084, 25506582570581289714612640493258299813803157561796247330693768146763035791942)
c2 = E(37554871162619456709183509122673929636457622251880199235054734523782483869931, 71392055540616736539267960989304287083629288530398474590782366384873814477806)
cipher_left = 68208062402162616009217039034331142786282678107650228761709584478779998734710
cipher_right = 27453988545002384546706933590432585006240439443312571008791835203660152890619
m = c1 - k*c2
cipher_left = cipher_left * inverse_mod(int(m[0]), p) % p
cipher_right = cipher_right * inverse_mod(int(m[1]), p) % p
print(cipher_left, cipher_right)

这个要用sage来解,并不是python。。。。坑死我,找到了个在线解。https://sagecell.sagemath.org/

得到:493033149237009446036260 127480900256551022095393917

用n2s解密一下,就行。

hgame{Ecc$is!sO@HaRd}

PRNG

这个题极客也有,也没有魔改,直接那脚本:from libnum import n2s

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
from libnum import n2s
from PRNG import PRNG
class TemperInverser:
def __inverse_right_shift_xor(self, value, shift):
i, result = 0, 0
while i * shift < 32:
part_mask = ((0xffffffff << (32 - shift)) & 0xffffffff) >> (i * shift)
part = value & part_mask
value ^= part >> shift
result |= part
i += 1
return result
def __inverse_left_shift_xor(self, value, shift, mask):
i, result = 0, 0
while i * shift < 32:
part_mask = (0xffffffff >> (32 - shift)) << (i * shift)
part = value & part_mask
value ^= (part << shift) & mask
result |= part
i += 1
return result
def __call__(self, tempered):
value = tempered
value = self.__inverse_right_shift_xor(value, 18)
value = self.__inverse_left_shift_xor(value, 15, 0xefc60000)
value = self.__inverse_left_shift_xor(value, 7, 0x9d2c5680)
value = self.__inverse_right_shift_xor(value, 11)
return value

class MersenneTwisterCracker:
def __init__(self, data):
inverser = TemperInverser()
self.__mt = PRNG(0)
self.__mt.load_register(list(map(inverser, data)))

def __call__(self):
return self.__mt()
data = [888058162, 3094055443, 1404990361, 1012543603, 448723884, 2580444236, 201608779, 1062995809, 1348787313, 2980019361, 2245025385, 494977308, 4042503808, 275744301, 406611131, 142226472, 3871761759, 3888795536, 2617489687, 1220227074, 342928858, 3728958896, 1477077966, 1433151407, 1119405037, 330145973, 3547181160, 2123007249, 3739964132, 1794129718, 2739743522, 2291585121, 3013727731, 1536788463, 247633572, 408079265, 3025555185, 1604681922, 2848997116, 3646041955, 1059445774, 2849764176, 2638965889, 1232303180, 759521642, 2257008531, 3932082254, 1052428413, 4017559916, 3505694223, 1418363972, 477751107, 4266295945, 3832138928, 245251422, 1964323108, 2453472918, 3029032760, 323619451, 2548825339, 3410027991, 278143595, 816124107, 245705463, 4173686519, 4100831820, 3599257115, 2274885516, 3954736394, 198254482, 1050449178, 3933150558, 899220021, 597474632, 1823539097, 3340511318, 2144918682, 2310527451, 264391694, 69923676, 3266017310, 3199627722, 4035962745, 932969905, 2832951013, 2182887504, 1374919242, 2978944795, 1840647233, 3510878043, 3250544991, 4255542321, 804377010, 1286980519, 1980427321, 2893246724, 1745353148, 1406140332, 4101848568, 3227434698, 1869729934, 2638181242, 1270111849, 2387910792, 3411542702, 2793303435, 2455337459, 2802808043, 2418872990, 1043274549, 144911746, 2312236858, 780373658, 1527499811, 3402753408, 2617924770, 1659648360, 2714315441, 4202103851, 244677433, 1963258902, 3851363324, 3454195559, 813228826, 3944899734, 3697685234, 1613584167, 1874570879, 1592343033, 4194241173, 551902434, 3460909265, 4122075287, 176665387, 152849760, 3593212904, 952880017, 1793357635, 2052902220, 807859486, 334839380, 3485132343, 2113403566, 3259106798, 1443078482, 2434820318, 1347902400, 2344061487, 141766876, 2641586235, 287277458, 2385094526, 1510128758, 348957861, 2861038633, 1135611795, 4289024199, 1021202791, 2460872523, 3837050794, 4092005952, 52622948, 387056916, 3102913460, 4098715316, 154916530, 2890197932, 1441566957, 2368779800, 271808452, 3566810840, 2227022452, 316480679, 603893066, 2121889912, 4208763743, 3098334580, 721958838, 3848020801, 1029884135, 832405094, 2276817394, 981553190, 246940442, 1069231974, 3275216531, 58945988, 4100121200, 230446475, 2396021649, 4608139, 3468707911, 3249498323, 315898153, 3280797960, 388108494, 1110548082, 2357147660, 2336724751, 4047583630, 2108667879, 2784078579, 1170844412, 3920262445, 3564073655, 590490534, 1645945278, 2487463163, 434409966, 1563546251, 888601967, 1913513318, 1327448740, 2504517969, 304688984, 1443685450, 4040619940, 3601250858, 4097529433, 4260590151, 575843085, 1114360271, 2186035374, 2821388594, 3763206347, 4283149630, 4097168778, 1924538037, 3272064650, 1689166701, 1352331676, 520525342, 2954296222, 2629516330, 3674317458, 231784130, 1930132422, 4169222397, 1638784833, 1245667959, 1253759350, 1154928813, 66021172, 3217915692, 4159785573, 3798512628, 2945489695, 700725579, 3940231312, 1960713279, 3289722468, 2970919839, 1356139680, 1141841193, 629177162, 3696263539, 1084872874, 4294077062, 1115547807, 3421092527, 611575307, 7808529, 2784523837, 1267307982, 1538837032, 4038330055, 3262951566, 3139820067, 1249725729, 757191354, 3025188720, 291705345, 575676661, 3023956263, 1045504889, 205204207, 1777650027, 1956698897, 996147619, 1470431, 2275722398, 2666078800, 470333070, 1306693906, 2968672077, 2476023772, 2645573325, 3939390068, 2874886754, 4226430090, 2290851636, 3707585663, 109770347, 127373916, 815817847, 1565834917, 636869794, 4062053412, 583594822, 3782553071, 3293311273, 2801932604, 2647080862, 1514083254, 3534640458, 342361004, 3266111849, 2157351044, 1851728420, 3412596866, 2793236910, 3758306563, 1799548561, 952631672, 912455646, 2894404493, 2194084105, 119615608, 2071058651, 1524462411, 900936180, 3697554830, 3501838982, 2874465656, 2501478689, 1069024222, 3135689372, 1168458702, 1966524629, 36400028, 2704775319, 4030739700, 3985599923, 2778920518, 2669538325, 1951594393, 795749079, 665593501, 3007338649, 1535343068, 2031873237, 3202423789, 560224943, 1290838890, 2545130826, 695695377, 3048615291, 1957903923, 1986693779, 2594986519, 3396211122, 2625687092, 575329062, 2852671310, 3472799759, 715985207, 1660331651, 958648594, 305711662, 75621441, 548447557, 2473842353, 2110558182, 3321750402, 2415793078, 815198061, 1258834500, 972966677, 3267046345, 2923564883, 518207679, 1662309775, 278933232, 4294256390, 2444117793, 2241879973, 3915962245, 3836532482, 3449260219, 1092128833, 3177300913, 874588042, 1185436845, 2064537788, 364292705, 3802247898, 3122264959, 186651829, 2789447523, 797964681, 897671294, 1504956985, 2294012382, 3916152546, 177325516, 2741945226, 4188655695, 2738134558, 557326292, 1625014790, 2945266389, 1843516240, 644046640, 3853456819, 3456105042, 3467742754, 2885173326, 812088996, 1238970324, 766072156, 2675925963, 1667463511, 2808303112, 1638756770, 260047996, 1117661655, 346883777, 2268712532, 1904918136, 513102466, 1024624509, 2154277089, 4147814745, 3681688842, 2233642964, 3135674550, 1259551210, 3286048484, 4271168802, 4227197378, 3310884772, 2063705584, 791399172, 4069266828, 1511606526, 1047713396, 615906401, 2805111822, 499223767, 740832370, 351782725, 2258776891, 1837046713, 3969757168, 2873152110, 4214869805, 3416771254, 2527945969, 3279116532, 1217038009, 4014402228, 3696705795, 1877774112, 3928347956, 959715122, 1612979629, 4045688071, 2403021083, 424891533, 1887765641, 2090726432, 2897940431, 268403838, 3447542890, 575011346, 2559143209, 532649938, 3625398853, 2077769196, 1598653066, 3104923961, 3594500739, 675029389, 579180583, 2024117612, 1351780728, 654841863, 769835263, 1431012736, 2369300321, 4157341752, 1968305076, 2086919554, 3075265115, 2128974418, 3144501489, 3993066430, 1121959765, 1373765135, 4232964375, 2264170351, 11814235, 1797654983, 3382686935, 2541491040, 3540726136, 1330685654, 4123114026, 2521290625, 3357439706, 3331159097, 2298656231, 3446738535, 290996369, 3020977553, 849241175, 3469792522, 4119898263, 1339695718, 2125209134, 3620160106, 1063375386, 1656465852, 2505508266, 3958528861, 3497875682, 3112358345, 3675237811, 1109625127, 2672368219, 1983461371, 3579663373, 1969195060, 225618775, 653511251, 3508369415, 4127429853, 828877800, 4286770015, 1474706143, 870777512, 804917422, 3913439258, 2433991646, 2742831709, 4289045475, 2899508500, 185462457, 4178107803, 2671443073, 2701796854, 1170522896, 1599880638, 1410722361, 3977867960, 1263177666, 2159508450, 2704509681, 1540819416, 1836499452, 1667451095, 3799477506, 157146600, 3717470672, 89865758, 3815588203, 1929105788, 861643665, 684514017, 3519778437, 2712956097, 1004423983, 1540346552, 2617389519, 2754800020, 870994822, 1702399767, 3526294475, 3251290865, 2365820957, 1915675760, 1828371367, 3737352795, 2511512700, 1080446781, 2565191059, 2412448535, 3719988291, 1434643780, 4163492408, 1359345746, 1457543102, 2389534435, 2800945892, 2646700564, 1719588203, 999665519, 3120652917, 1800116770, 3247314137, 4261164550, 1503462948, 3017762189, 263481701, 1754772485, 869168639, 604192231, 498759780, 2602535702, 3346756344, 2836267314, 2073734260, 3445425559, 4051271696, 1647518162, 401835417, 1968629992, 2854677838, 2381566661, 3144829468, 519547510, 3058642603, 3944140819, 1248923220, 1050321901, 3218172519, 376999645, 184187381, 3837095155, 3363256702, 751966993, 3419533016, 4028456468, 1156797460]
cipher = [3437104340, 508103176, 1635844121, 878522509, 1923790547, 1727955782, 1371509208, 3182873539, 156878129, 1757777801, 1472806960, 3486450735, 2307527058, 2950814692, 1817110380, 372493821, 729662950, 2366747255, 774823385, 387513980, 1444397883]
mt = MersenneTwisterCracker(data)
print(b"".join(map(n2s,[part ^ mt() for part in cipher])))

参考wp的脚本

RE

由于最后太忙了,没打,做个复现,这周属实没上周难。

WOW

我们能看出flag是32位,那么我们先输入一个flag动调一下,发现是要和48行的数组进行比对,然后进行完,发现buf2又恢复输入了,那么可猜测第二次循环是解密过程,那么属于很想rc4的动调。

我们在48行设断点,然后输入32个a,然后找到buf2的位置,将unk中的值pasta data一下,然后调试到后面就出来了。

后悔没做,这500分不是轻轻松松。。。

ezvm

这道题很恶心,步骤很多,要一步一步调试,

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax

sub_401A40(argc, argv, envp);
std::__ostream_insert<char,std::char_traits<char>>(&libstdc___6__ZSt4cout, "input your flag:", 16i64);
std::endl<char,std::char_traits<char>>(&libstdc___6__ZSt4cout);
while ( 1 )
{
v3 = dword_404020[dword_404020[0] + 109];
if ( v3 == -1 )
return 0;
switch ( v3 )
{
case 0:
sub_401550(&dword_404020[3], (unsigned int *)&dword_404020[2]);
break;
case 1:
sub_401555(&dword_404020[2]);
break;
case 2:
sub_401559(&dword_404020[2]);
break;
case 3:
sub_40156C(&dword_404020[3], &dword_404020[7]);
break;
case 4:
sub_401578();
break;
case 5:
sub_40159B();
break;
case 6:
sub_4015BE();
break;
case 7:
sub_401605();
break;
case 8:
sub_40161B();
break;
case 9:
sub_401631();
break;
case 10:
sub_401647();
break;
case 11:
sub_40165D();
break;
case 12:
sub_40169E((unsigned int)dword_404020[6]);
break;
case 13:
sub_4016AE(dword_404020[6]);
break;
case 14:
sub_401571((unsigned int)dword_404020[2]);
break;
case 15:
sub_401673(dword_404020[3], dword_404020[5]);
break;
case 16:
sub_4016BE(&dword_404020[3]);
break;
case 17:
sub_4016D3(&dword_404020[3]);
break;
case 18:
sub_4016E4();
break;
case 19:
sub_40171A();
break;
case 20:
sub_401733();
break;
case 21:
sub_40155D();
break;
default:
break;
}
++dword_404020[0];
}
}

第一次先经过一波4 —> 1 —> 15 —> 13 —> 16,而这个会经历你输入的flag长度的次数,由于后面有一个0x20,那么可以推测flag长度为32位,那么这些步骤总的来说我认为是将我们输入的flag传到规定的地址。

下面是16函数:

1
2
3
4
5
6
7
8
int __fastcall sub_4016BE(int *a1)
{
int result; // eax

result = getchar();
*a1 = result;
return result;
}

很显然是输入单字符。

下面是15函数,显然是个compare函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void __fastcall sub_401673(int a1, int a2)
{
if ( a1 == a2 )
{
dword_404040 = 0;
}
else if ( a1 >= a2 )
{
if ( a1 > a2 )
dword_404040 = 1;
}
else
{
dword_404040 = -1;
}
}

在前31次的调试中我发现a2这个是0xA,即回车。

然后经过32次后,我们能在虚拟地址中看到上传的flag。

接下来进行2 —> 18 —> 8 —> 18 —> 9 —> 0 —> 4 —> 15 —> 13,只进行了一次,对于input并无改变。

接下来在调试发现又是循环而且,input处的值发生了变化!

18 —> 9 —> 18 —> 10 —> 19 —> 18 —> 11 —> 21 —> 3 —> 20 —> 1 —> 0 —> 15 —> 13 —> 19 —→ 18 —> 11 —> 21 —> 3 —> 20 —> 1 —> 0 —> ……

我们直接找到几个重要的函数比如21

下面是21的函数:

1
2
3
4
5
6
7
8
int64 sub_40155D()
{
__int64 result; // rax

result = (unsigned int)(2 * dword_40402C);
dword_40402C *= 2;
return result;
}

经过动调发现这个地方是对输入进行乘2,即左移1位

然后再

进行跟进,发现3函数进行了异或:

1
2
3
4
5
6
7
8
int64 __fastcall sub_40156C(_DWORD *a1, unsigned int *a2)
{
__int64 result; // rax

result = *a2;
*a1 ^= result;
return result;
}

但这个异或的值好像并没有给数组,然后我在存入input后面的地址处发现了逐渐出现的数组

后来我又在后面的地址发现了数组。。。。。

1
[0x0000005E, 0x00000046, 0x00000061, 0x00000043, 0x0000000E, 0x00000053, 0x00000049, 0x0000001F, 0x00000051, 0x0000005E, 0x00000036, 0x00000037, 0x00000029, 0x00000041, 0x00000063, 0x0000003B, 0x00000064, 0x0000003B, 0x00000015, 0x00000018, 0x0000005B, 0x0000003E, 0x00000022, 0x00000050, 0x00000046, 0x0000005E, 0x00000035, 0x0000004E, 0x00000043, 0x00000023, 0x00000060, 0x0000003B]//异或的数组

再调试下去,将32位调试完成后,又进行13 —> 18 —> 10 —> 18 —> 18 —> 18 —> 8 —> 19 —> 15 —>

这个是对比,那么对比的数据在哪呢,对比的数据就在上面异或数据下:

1
[0x0000008E, 0x00000088, 0x000000A3, 0x00000099, 0x000000C4, 0x000000A5, 0x000000C3, 0x000000DD, 0x00000019, 0x000000EC, 0x0000006C, 0x0000009B, 0x000000F3, 0x0000001B, 0x0000008B, 0x0000005B, 0x0000003E, 0x0000009B, 0x000000F1, 0x00000086, 0x000000F3, 0x000000F4, 0x000000A4, 0x000000F8, 0x000000F8, 0x00000098, 0x000000AB, 0x00000086, 0x00000089, 0x00000061, 0x00000022, 0x000000C1]//最后对比数据

那么很容易写出脚本:

1
2
3
4
5
6
xor = [0x0000005E, 0x00000046, 0x00000061, 0x00000043, 0x0000000E, 0x00000053, 0x00000049, 0x0000001F, 0x00000051, 0x0000005E, 0x00000036, 0x00000037, 0x00000029, 0x00000041, 0x00000063, 0x0000003B, 0x00000064, 0x0000003B, 0x00000015, 0x00000018, 0x0000005B, 0x0000003E, 0x00000022, 0x00000050, 0x00000046, 0x0000005E, 0x00000035, 0x0000004E, 0x00000043, 0x00000023, 0x00000060, 0x0000003B]
data = [0x0000008E, 0x00000088, 0x000000A3, 0x00000099, 0x000000C4, 0x000000A5, 0x000000C3, 0x000000DD, 0x00000019, 0x000000EC, 0x0000006C, 0x0000009B, 0x000000F3, 0x0000001B, 0x0000008B, 0x0000005B, 0x0000003E, 0x0000009B, 0x000000F1, 0x00000086, 0x000000F3, 0x000000F4, 0x000000A4, 0x000000F8, 0x000000F8, 0x00000098, 0x000000AB, 0x00000086, 0x00000089, 0x00000061, 0x00000022, 0x000000C1]
flag = ""
for i in range(32):
flag += chr((data[i]^xor[i])//2)
print(flag)

这个题刚开始很难,但越做越爽越清晰,出的太好了!

server

这个题有点难度,我连rsa都没看出来,然后后面有两个异或还不好搞。

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
void main_HttpHandleFunc()
{
__int64 v0; // rax
__int64 v1; // rcx
__int64 v2; // r14
const char *v3; // rbx
__int64 v4; // rax
__int64 v5; // rcx
__int64 v6; // rdx
__int64 v7; // rsi
__int64 v8; // rbx
__int64 v9; // rax
__int64 v10; // [rsp+0h] [rbp-1368h]
__int64 v11; // [rsp+0h] [rbp-1368h]
__int64 v12; // [rsp+0h] [rbp-1368h]
__int64 v13; // [rsp+0h] [rbp-1368h]
__int64 v14; // [rsp+0h] [rbp-1368h]
__int64 v15[154]; // [rsp+8h] [rbp-1360h] BYREF
const char *v16; // [rsp+4D8h] [rbp-E90h]
__int64 v17; // [rsp+4E0h] [rbp-E88h]
__int64 v18; // [rsp+4E8h] [rbp-E80h]
__int64 v19; // [rsp+4F0h] [rbp-E78h]
char v20[1216]; // [rsp+4F8h] [rbp-E70h] BYREF
__int64 v21; // [rsp+9B8h] [rbp-9B0h]
char v22[1216]; // [rsp+9C0h] [rbp-9A8h] BYREF
__int64 v23; // [rsp+E80h] [rbp-4E8h]
char v24[1216]; // [rsp+E88h] [rbp-4E0h] BYREF
__int64 v25; // [rsp+1348h] [rbp-20h]
__int64 v26; // [rsp+1350h] [rbp-18h]
__int64 v27; // [rsp+1358h] [rbp-10h]
void *retaddr; // [rsp+1368h] [rbp+0h] BYREF
__int64 v30; // [rsp+1370h] [rbp+8h]
__int64 v33; // [rsp+1380h] [rbp+18h]

while ( (unsigned __int64)&retaddr < 0x12E8 || (unsigned __int64)&v15[15] <= *(_QWORD *)(v2 + 16) )
{
v30 = v0;
v33 = v1;
runtime_morestack_noctxt();
v0 = v30;
v1 = v33;
}
v27 = v1;
v10 = net_http___ptr_Request__ParseForm();
v3 = "flag";
v15[2] = net_http___ptr_Request__FormValue(v10, v15[0], v15[1]);
if ( "flag" )
{
v16 = "flag";
v25 = v4;
v5 = 0LL;
v6 = 0LL;
v7 = 0LL;
while ( (__int64)v3 > v5 )
{
v26 = v7;
v17 = v5;
v18 = v6;
v15[1] = strconv_FormatInt(v11, v15[0]);
v8 = v26;
v15[4] = runtime_concatstring2(v13, v15[0], v15[1], v15[2], v15[3]);
v5 = v17 + 1;
v6 = v8;
v7 = v9;
v3 = v16;
}
v19 = 99LL;
qmemcpy(v20, "U", sizeof(v20));
main_encrypt(); //加密过程
v23 = v11;
qmemcpy(v24, v15, sizeof(v24));
v21 = v19;
qmemcpy(v22, v20, sizeof(v22));
runtime_memequal();
v15[2] = runtime_convI2I(v11, v15[0], v15[1]);
v15[6] = fmt_Fprintf(v14, v15[0], v15[1], v15[2], v15[3], v15[4], v15[5]);
}
else
{
v15[2] = runtime_convI2I(v11, v15[0], v15[1]);
v15[6] = fmt_Fprintf(v12, v15[0], v15[1], v15[2], v15[3], v15[4], v15[5]);
}
}

我们进入这个加密

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
int64 __usercall main_encrypt@<rax>(__int64 a1, __int64 a2)
{
unsigned __int64 v2; // rax
unsigned __int64 v3; // rbx
__int64 v4; // r14
__int128 v5; // xmm15
__int64 v6; // rax
__int64 v7; // rax
__int64 v8; // rax
__int64 v9; // rax
unsigned __int64 v10; // rbx
const char *v11; // rax
unsigned __int64 v12; // rax
const char *v13; // rdx
__int64 v14; // rax
__int64 v15; // rcx
__int64 v16; // r8
__int64 i; // rax
__int64 v18; // rdx
__int64 result; // rax
__int64 v20; // [rsp-28h] [rbp-5F0h]
__int64 v21; // [rsp-28h] [rbp-5F0h]
__int64 v22; // [rsp-28h] [rbp-5F0h]
__int64 v23; // [rsp-28h] [rbp-5F0h]
__int64 v24; // [rsp-20h] [rbp-5E8h]
__int64 v25; // [rsp-20h] [rbp-5E8h]
__int64 v26; // [rsp-20h] [rbp-5E8h]
__int64 v27; // [rsp-18h] [rbp-5E0h]
__int64 v28; // [rsp+20h] [rbp-5A8h]
char v29[1216]; // [rsp+28h] [rbp-5A0h] BYREF
__int64 v30; // [rsp+4E8h] [rbp-E0h]
__int64 v31; // [rsp+4F0h] [rbp-D8h]
__int64 v32; // [rsp+4F8h] [rbp-D0h]
char v33; // [rsp+500h] [rbp-C8h]
__int64 v34; // [rsp+508h] [rbp-C0h]
__int128 v35; // [rsp+510h] [rbp-B8h]
char v36; // [rsp+520h] [rbp-A8h]
__int64 v37; // [rsp+528h] [rbp-A0h]
__int128 v38; // [rsp+530h] [rbp-98h]
char v39; // [rsp+540h] [rbp-88h]
__int64 v40; // [rsp+548h] [rbp-80h]
__int128 v41; // [rsp+550h] [rbp-78h]
char v42; // [rsp+560h] [rbp-68h]
__int64 v43; // [rsp+568h] [rbp-60h]
__int128 v44; // [rsp+570h] [rbp-58h]
char v45; // [rsp+580h] [rbp-48h]
__int64 v46; // [rsp+588h] [rbp-40h]
__int128 v47; // [rsp+590h] [rbp-38h]
char v48; // [rsp+5A0h] [rbp-28h]
__int64 v49; // [rsp+5A8h] [rbp-20h]
__int128 v50; // [rsp+5B0h] [rbp-18h]

while ( (unsigned __int64)&v29[48] <= *(_QWORD *)(v4 + 16) )
{
STACK[0xA98] = v2;
STACK[0xAA0] = v3;
runtime_morestack_noctxt();
v2 = STACK[0xA98];
v3 = STACK[0xAA0];
}
STACK[0xAA0] = v3;
STACK[0xA98] = v2;
memset(&a2, 0, 0x4C0uLL);
v48 = 0;
v49 = 0LL;
v50 = v5;
math_big___ptr_Int__SetString();
v30 = v6;
v45 = 0;
v46 = 0LL;
v47 = v5;
v20 = math_big___ptr_Int__SetString();
v42 = 0;
v43 = 0LL;
v44 = v5;
v24 = math_big___ptr_Int__Mul(v20);
v31 = v7;
v39 = 0;
v40 = 0LL;
v41 = v5;
math_big___ptr_Int__SetString();
v32 = v8;
v36 = 0;
v37 = 0LL;
v38 = v5;
v21 = math_big___ptr_Int__SetString();
v33 = 0;
v34 = 0LL;
v35 = v5;
v27 = math_big___ptr_Int__Exp(v21, v24);
if ( v9 )
{
math_big_nat_itoa(v22, v25, v27);
v10 = v12;
runtime_slicebytetostring(v23, v26, v27);
}
else
{
v10 = 5LL;
v11 = "<nil>";
}
v28 = 0LL;
v13 = v11;
memset(v29, 0, sizeof(v29));
v14 = 0LL;
v15 = 102LL;
while ( v14 < 153 )
{
if ( v14 >= v10 )
runtime_panicIndex();
v16 = (unsigned __int8)v13[v14];
*(_QWORD *)&v29[8 * v14++ - 8] = v16 ^ v15;
v15 = v16;
}
for ( i = 0LL; i < 153; ++i )
{
v18 = *(_QWORD *)&v29[8 * i - 8];
*(_QWORD *)&v29[8 * i - 8] = v18 ^ v15;
v15 = v18;
}
result = v28;
qmemcpy(&a2, v29, 0x4C0uLL);
return result;
}

我们现在知道了p,q,e,那么我们只需要知道密文即可,这道题的密文缺了最后一位,因为我们无法得知最后一位异或的值,所以才用爆破的方法,我找了两位师傅写的,我认为写的非常好

舍去不能转换成可见字符的。

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
# -*- coding:utf-8 -*-
import gmpy2
from Crypto.Util.number import long_to_bytes
# res 相当于 round_2
res=[0x63,0x55,0x4,0x3,0x5,0x5,0x5,0x3,0x7,0x7,0x2,0x8,0x8,0xb,0x1,0x2,0xa,0x4,0x2,0xd,0x8,0x9,0xc,0x9,0x4,0xd,0x8,0x0,0xe,0x0,0xf,0xd,0xe,0xa,0x2,0x2,0x1,0x7,0x3,0x5,0x6,0x4,0x6,0x7,0x6,0x2,0x2,0x5,0x3,0x3,0x9,0x6,0x0,0xb,0xd,0xb,0x0,0x2,0x3,0x8,0x3,0xb,0x7,0x1,0xb,0x5,0xe,0x5,0x0,0xa,0xe,0xf,0xd,0x7,0xd,0x7,0xe,0x1,0xf,0x1,0xb,0x5,0x6,0x2,0xc,0x6,0xa,0x4,0x1,0x7,0x4,0x2,0x6,0x3,0x6,0xc,0x5,0xc,0x3,0xc,0x6,0x0,0x4,0xf,0x2,0xe,0x7,0x0,0xe,0xe,0xc,0x4,0x3,0x4,0x2,0x0,0x0,0x2,0x6,0x2,0x3,0x6,0x4,0x4,0x4,0x7,0x1,0x2,0x3,0x9,0x2,0xc,0x8,0x1,0xc,0x3,0xc,0x2,0x0,0x3,0xe,0x3,0xe,0xc,0x9,0x1,0x7,0xf,0x5,0x7,0x2,0x2,0x4]
p=92582184765240663364795767694262273105045150785272129481762171937885924776597
q=107310528658039985708896636559112400334262005367649176746429531274300859498993
n=p*q
e=950501
phin=(p-1)*(q-1)
d=gmpy2.invert(e,phin)
# i 相当于 cipher[len(cipher)-1],爆破的目标
for i in range(0x30,0x3a):
tmp1=[res[0]^i] # tmp1 相当于 round_1
for j in range(1,len(res)):
tmp1.append(res[j]^tmp1[j-1])
tmp2=[tmp1[0]^102]# tmp2 相当于 cipher
for j in range(1,len(tmp1)):
tmp2.append(tmp1[j]^tmp2[j-1])
wrong=0
for m in tmp2: # cipher 中每个元素都必须是十进制数字字符
if m<0x30 or m>0x39:
wrong=1
break
if wrong:
continue
if i==tmp2[len(tmp2)-1]:# 验证爆破的目标和还原出来的cipher[len(cipher)-1]是否相同
cipher=""
for k in tmp2:
cipher+=chr(k)
cipher_num=int(cipher)
m=gmpy2.powmod(cipher_num,d,n)# RSA解密
print(long_to_bytes(m))
# hgame{g0_and_g0_http_5erv3r_nb}

P1umH0师傅属实牛。go语言的逆向现在ida已经足够强大到可以搞定,没必要再用那些软件了。

hardasm

属实太难了,我参考了P1umH0师傅的解答,我学到了很多东西,这个7000行的代码审计真的离谱。

从此看出flag长度为32,

其实从上图我们或许能猜到,这个验证是对每一位进行的,输入后直接对比,对比完就跳转,我们输入hgame{aaaaaaaaaaaaaaaaaaaaaaaaaaaa},然后进入[rsp+70h+var_50]中发现似乎是正确的地方会返回0FFh,我们跟进jz这个条件

很显然对的就success,错的就error,error是通过rcx寄存器进行储存,下面一个函数是通过调用call printf实现打印正确或者错误,我们完全可以使用patch的方法,将printf打印的结果变成[rsp+70h+var_50]上的数据。

如何改呢:

首先用ida自带的assembled,改不了,这里面缺少很多汇编,我下了个keypatch还是不行,不知道什么问题,然后手撸字节码,

接下来我们要做的就是将可视字符串进行尝试,看对应位置是哪个ascii,通过0xff来进行判断!

那么现在我有两种方法,一个是手动试,另一种是写代码自动化,subprocess是再父进程里开子进程,将我们修改过的hardasm.exe作为子进程,代码如下:

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
# -*- coding:utf-8 -*-
import subprocess
real_flag="hgame{"#绝对正确的前6个字符
cur_index=6#当前爆破的位置
while cur_index<32:
for i in range(32,128):#当前爆破的位置上的字符
real_flag_arr = [0] * 32
for j in range(len(real_flag)):#正确的先复制一下
real_flag_arr[j]=ord(real_flag[j])
real_flag_arr[len(real_flag_arr)-1]=ord("}")#最后一个字符"}"固定
for j in range(len(real_flag_arr)-2,cur_index,-1):#除了当前爆破的位置,其他位置上都设置为32
real_flag_arr[j]=32
real_flag_arr[cur_index]=i#设置当前爆破的位置上的字符
real_flag_arr_s="".join(chr(k) for k in real_flag_arr)#输入到程序中的字符串
p = subprocess.Popen(["C:\\Users\\86159\\Documents\\Tencent Files\\506611735\\FileRecv\\Hgame2022\\week4\\hardasm.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(real_flag_arr_s.encode())
p.stdin.close()
out = p.stdout.read()
if len(out)>cur_index:#判断程序打印出的0xFF的个数是否增加,增加则说明当前爆破的位置上的字符设置的是正确的
real_flag+=chr(i)
cur_index+=1
print(real_flag)
break

# hgame{r
# hgame{ri
# hgame{rig
# hgame{righ
# hgame{right
# hgame{right_
# hgame{right_y
# hgame{right_yo
# hgame{right_you
# hgame{right_your
# hgame{right_your_
# hgame{right_your_a
# hgame{right_your_as
# hgame{right_your_asm
# hgame{right_your_asm_
# hgame{right_your_asm_i
# hgame{right_your_asm_is
# hgame{right_your_asm_is_
# hgame{right_your_asm_is_g
# hgame{right_your_asm_is_go
# hgame{right_your_asm_is_goo
# hgame{right_your_asm_is_good
# hgame{right_your_asm_is_good!
# hgame{right_your_asm_is_good!!
# hgame{right_your_asm_is_good!!}
# hgame{right_your_asm_is_good!!}

总结来说,学到了很多,需要学的还有很多!加油吧!

misc

摆烂

先binwalk,发现里面有图片

提取出来

用01editor查看,发现里面有acTLfcTLfdTL数据块,便知道这张图片为 APNG 格式,即 PNG 动图

我们用

https://products.aspose.app/imaging/zh-hans/image-view 在线分离帧

找到两张图片,猜测是盲水印

记住bwm是py2,要用下一个软件,flag中发现密码:4C*9wfg976

密码输入压缩包内,有二维码

拼一下

得到一串汉字:

在这种困难的抉择下,本人思来想去‌‌‌‌‍‬‬‌,寝食难安。 既然如此‌‌‌‌‍‬‍, 亚伯拉罕·林肯在不经意间这样说过,你活了多少岁不算什么‌‌‌‌‍‬‌‍,‌‌‌‌‍‬‍重要的是你是如何度过这些岁月的。‌‌‌‌‍‬‍‍这启发了我,‌‌‌‌‍‬ CTF‌‌‌‌‌‌‍好难,到底应该如何实现。‌‌‌‌‍‍‌‌‌‌‍‍‍ ‌‌‌‌‌‍‌‌‌‌‌‍‬‬总结的来说‌‌‌‌‍‍‍‌‌‌‌‌‍‍, ‌‌‌‌‍‍‍‌‌‌‌‌‌‌‌‌‌‌‌‍‍‌‌‌‌‍‌‌我们都知道‌‌‌‌‌‌‍‌‌‌‌‍‌‌‍,只要有意义‌‌‌‌‍‬‍,‌‌‌‌‍‍那么就必须慎重考虑‌‌‌‌‍‌‬。‌‌‌‌‌‌‌‌‌‌‌‍‍‍‌‌‌‌‌‍‍‌ 我认为, 每个人都不得不面对这些问题‌‌‌‌‍‬‍‍。‌‌‌‌‍‬‬ 在面对这种问题时,‌‌‌‌‍‍ CTF好难,到底应该如何实现。

在vs中里面很不整齐,猜测为0宽字符加密,使用网站 http://330k.github.io/misc_tools/unicode_steganography.html 解密

CSAPP-1:计算机系统漫游

1.1位与上下文

源程序是由0和1的位组成的序列,8位为1字节,对于程序是如何运行的:我们写的c语言每一个字符都用ascii来表示,被叫做文本文件。通过这个实例我们知道,在计算机中所有信息都是由一串比特所构成。

1.2高级到低级

我们的源代码由上图所示进行编译,预处理阶段是进行引用头文件,编译阶段是编译成汇编语言,文件后缀是.s,汇编阶段是编译成机器语言,这是最底层的语言,链接阶段,是将我们引用头文件中的函数进行调用。

在linux上我们在terminal中输入gcc -o file.c进行编译

1.3处理器读写并解释储存在内存中的指令

在UNIX系统上运行可执行文件,我们需要shell:shell是命令届时请,它输出提示符,我们输入命令,如果该命令行的第一个单词不是shell内置的命令,那么shell会认为这是个文件,运行后等待下一个指令的输入。

1.3.1系统的硬件

1.总线

总线是贯穿系统的一组电子管道,它可以用来携带信息字节,从而穿梭在各个部件之间串联起来整个系统。通常被设计成传送定长的字节块,我们成为字。字是一个参数,一般有32位和64位。

2、I/O设备

这是输入输出的设备每个设备都通过适配器或者控制器与总线相连。

适配器是一块插在主板上的卡,如显示屏。

控制器是I/O设备或者是系统主印制电路板(主板)上的芯片组。

3、主存

主存是临时储存设备,当CPU执行程序时,用来存放程序和程序处理数据,主存是由一组动态随机存取存储器DRAM芯片组成,每个字节上都有唯一的地址。

4、处理器

处理器就是cpu,是解释和存储在主存中的指令引擎,核心是寄存器,使其指向下一条指令,叫做pc,pc总指向某条机器语言的地址。

加载:由主存开始copy一个字节或一个字到寄存器,并覆盖寄存器内容

存储:从寄存器copy一个字节或一个字到主存,覆盖原来内容

操作:把两个寄存器的值copy到算数逻辑单元(ALU)中,ALU进行运算,并把结果给一个寄存器,覆盖其内容

跳转:从指令本身抽取一个字,并将该字copy到pc中,覆盖pc中的值

1.3.2运行程序

当我在shell中按下回车,代码被加载到主存,处理器执行程序机器语言,将字符串从主存复制到寄存器中,由寄存器在显示到显示设备中

1.4高速缓存

机械原理:较大存储设备要比较小存储设备运行的慢,而快速设备“造价”高,所以如何加快且消耗少。处理器存储信息少,速度fast,主存相反,我们采用高速缓存存储器,作为暂时集结区,比如cpu上L1高速缓存容量数万字节,访问速度和寄存器差不多,一个数百w的L2存储器通过总线连接到处理器,虽然L2不是那么fast,但仍比原来fast10倍。L1,L2是由静态随机访问存储器SRAM硬件技术实现,利用率高速缓存的局部性原理

1.5存储设备形成层次结构

上一级是下一级的高速缓存。

1.6操作系统功能

两个功能:1、防止硬件被失控的app滥用

2、向应用程序提供简单的机制来控制复杂且不同的低级硬件设备,操作系统通过抽象的概念实现功能

1.6.1进程

进程是操作系统对一个正在进行的程序的一种抽象,在一个系统上可以同时运行多个进程,而每个进程都在使用hardware,即我们的CPU是在不断进行交错执行,如下图。

操作系统保持跟踪进程运行所需的所有状态信息,这种状态称为上下文,切到另一个程序叫做上下文切换,保存上面进程恢复下面进程

一个进程转移另一个进程是由内核kernel管理的,shell是进程,但kernel并不是进程,他是系统管理全部进程所用代码和数据结构的集合

1.6.2线程

一般认为一个进程只有一个线程控制,但实际上一个进程由多个线程控制。

1.6.3虚拟内存

虚拟内存是个抽象概念,为每个进程提供给假象,,每个进程看到的内存都一样,成为虚拟地址空间

1.6.4文件

文件就是字节序列,所有的输入输出甚至设备都能看成文件。

1.7系统之间利用网络通信

如果将网络视为一个I/O设备,那么能得到下面的图片。

1.8.1Amdahl定律

1.8.2并发和并行

并发是指一个同时具有多个活动的系统

并行是指用并发使一个系统运行更快

1.线程级并发

使用线程我们能在一个进程中执行多个控制流

1.8.3指令级并行

如果cpu能达到比一个周期一条指令更快的执行速度,就称为超标量处理器。

1.8.4单指令、多数据并行

csapp-2:信息的表示和处理

2.1、信息存储

大多数计算器采用8位的块,或者字节,作为最小的可寻址的内存单位,而不是访问内存中单独的位。机器级程序将内存视为非常大的字节数组,成为虚拟内存。

程序对象:包括程序数据、指令和控制信息。

2.1.1、16进制表示法

二进制转换16进制,先分成4个一组,如果不足四个,最左侧可以不足4位前方补0,然后每4个转换成一个16进制数。

2.1.2、字数据大小

每个计算机都有一个字长,指明指针数据的标称大小,因为虚拟地址是以这一个字来编码的,字长决定系统参数也就是虚拟地址空间的最大大小

char虽然是单字节,但也能存储整数值,long在32位是4字节,在64是8字节,int32_t和int64_t分别是4和8字节,float是单精度,double是双精度,分别4字节和8字节

2.1.3、寻址和字节顺序

小端序和大端序:

通过实验我们知道,在linux 32、windows和linux 64用的都是小端序,sun用的是大端序

2.1.4、字符串

字符串在任何系统上都是一样的

2.1.5、代码

2.1.6、布尔代数

&:位上都是1才是1,其余是0

|:有1就是1,全0才是0

^:相同就是0

~:取反

2.1.7、c语言中的移位运算

向左移动x位,去掉前x位右边补0

向右移动分两种情况

加法的优先级高于移位,牵扯到移位要加括号

2.2、整数表示

2.2.1、整形数据类型

注意负数是比正数多一位的,因为有0.

2.2.2、无符号数的编码(B2U)

无符号数的编码是具有唯一性的,每一个二进制都完全等于一个整数,反过来同理。

2.2.3、补码编码(B2T)

表示负数,采用补码,当第一位是1,那么这个数就是负数,如果是0,那么这个表示正数

第一位是1,那么第1位就是负数,剩下的是整数相加

2.2.4、有符号数和无符号数转换

规则是,先把数据转换成二进制,如果是转换层无符号数,那么就按其标准转换,即不看第一位

如果是转换成有符号数,我们要考虑补码

2.2.5、c中的有符号和无符号数

创建无符号数必须要在字符后加‘u’或者’U’,其他声明都是有符号。当在运算时,一个是有符号,另一个没有符号,那么会强制把有符号转换成无符号,并假设两个数都是非负,在大于小于的比较中

2.2.6、拓展一个数字的位显示

将无符号数转换成一个更大的数据类型,我们只需要在开头加0,这叫做零拓展

前提是全部是有符号数

2.2.7、截断数字

截断无符号数:

留下后k位(k位截断数)

截断补码数:

2.3整数运算

从上述文字,我们知道,当x,y在定义域内,但x+y可不一定,若x+y溢出了区域,我们直接将二进制的第一位移除,或者用整数减去x定义域的最大值。判断是否溢出,用x+y是否小于x。

2.3.2、补码加法

与上面是一样的,如果超出则减去,低于则加上位数,即加法后的结果不能够超出本身的位数,否则截断!

2.3.3、补码的非

x=-(-x(非)+1)(负号)

2.3.4、无符号乘法

超出范围,用截断。

2.3.5、补码乘法

一样

2.3.6、乘常数

在位的模式下进行左移位,如果溢出,截断即可。乘法的使用代价是加法等的10倍

2.3.7、除以2的幂

除以2的幂我们需要将数据右移,无符号和补码数需要使用逻辑移位和算数移位来达到目的。

对于补码数,分为两种情况,若最高位0,即正数,直接移位,若是1,左侧补1,其他位右移即可。

如果用x/2**k,那么如果是小数,那么就向下取整

2.4 浮点数

2.4.1 二进制小数

上述例子很好的反映了什么是二进制小数.

2.4.2 IEEE浮点表示

简单来说就是,将一个数分为三段,先看第一个值判断是正数还是负数,第三个部分是从右侧开始的0一直到左侧不为0的数,剩余的为第二部分.

2.4.3 数字示例

2.4.4、舍入

有4种规则

2.4.5、c语言的浮点数

默认32位int

CSAPP-3

从这章开始,开始接触汇编和机器语言!这章比上一章看的舒服点。

3.1、程序编码

在linux系统编码c语言指令需要掌握:

1
linux> gcc -Og -o p p1.c

3.1.1、机器代码

程序计数器:通常称为P,在x86-64通常用%rip来表示。

整数寄存器文件包含16个命名的位置,分别存储64位的值

条件码寄存器保存最近执行的算数或者逻辑运算,如实现if或while语句

一组向量寄存器可存放一个或多个整数或浮点数

3.2数据格式

在intel中规定字代表16位,双字代表32位,四字代表64位

计算机永远是占用内存越小越好,比如一个数是int,只用不到4位,那么这个数就是按4个位算。用不到32位。

3.3、操作数

三种操作数:

1.立即数,用$555表示

2.寄存器,16位寄存器用低字节寄存器作为操作数

3.内存引用,用【】表示内存引用

这样的运算是需要掌握的

3.3.1、数据传送指令

mov指令,mov a,b:是将a传送到b。

我们把指令后的第一个数据称为源操作数,第二个数据为目的操作数,下面是5种用法

访问寄存器比访问内存快,所以一般将局部变量保存在寄存器中

3.3.2、压入和弹出栈数据

栈是一种数据结构,可以添加或者删除值,要遵循后进先出的原则,用push将数据压入栈中,用pop删除数据,存在属性:弹出之永远是最近被压入而且仍然在栈中的值。,永远记得这个只有一个操作数:

push %rbp完全等价于sub 8,%rsp mov %rbp, (%rsp),也就是说在push的时候就已经开辟了空间

3.4、算数和逻辑操作

add一样也是4个指令addb,addw,addl,addq

其中lea主要是加载地址,上述所有运算几乎都是将源操作数与目的操作数进行运算后存入目的操作数。

3.4.1、加载有效地址

lea目的操作数必须是一个寄存器

3.4.2、一元和二元操作数

这个操作数既是源操作数还是目的操作数,比如inc(%rsp)让栈顶+1,相当于++

二元操作,第二个操作数既是源又是目的,很像x-=y sub %rax,%rdx是让rdx-rax的值

3.4.3、移位操作

左移:sal,shl无差别

右移:sar(算数移位)shr(逻辑移位)

3.4.4、特殊算数操作

3.5、控制

3.5.1、条件码

CF:进位标志。最近的操作使最高位产生进位。可用来检查无符号操作的溢出

ZF:零标志。最近的操作得出结果为0.

SF:符号标志。最近的操作得到的结果为负数。

OF:溢出标志。最近的操作导致一个补码溢出–正溢出活着负溢出

比如test %rax,%rax就是检查%rax是负数,0,还是正数。

如cmp的比较可以确定范围从而进行循环

3.5.2、访问条件码

条件码使用三种方法:

1.可以根据条件码的某种组合,将一个字节设为0或者1

2.可以跳转到程序的其他部分

3.可以有条件的传送数据

3.5.3、跳转指令

jmp是无条件跳转

3.5.4、跳转编码

分为两种,最常用的是PC相对的,会将跳转指令的地址与紧邻在跳转指令后面的那条指令的差作为编码,还有一种是给出绝对地址,用4个字节直接跳转到目标地址

3.5.5、用条件控制来实现条件分支

类似于goto的写法,就是先对比,对比来决定是否goto

3.5.6、用条件传送来实现条件分支

上面用条件控制实现是非常低效的。我们这种方法是将两种结果都进行计算,然后再根据条件满足与否来选择结果

3.5.7、循环

上述是讲的if这样的判断,但其实循环跟上面的原理是差不多的

先看do-while

这个底层的逻辑跟上层逻辑是一样的,先do然后判断

while函数与do-while是不同的,先对while中的参数进行求值,然后根据条件码进行是否进入循环体的判断

当然还有第二种方法,称之为guard-do,先用条件分支,如果初始条件不成立就跳过循环,然后变成do-while循环

for循环程序先对第一个参数求值,然后进入循环,再循环中测试第二个参数,在判断是否进入第三个参数是否继续到循环里执行2,通过不同的优化等级,也有两种汇编来执行,不再赘述。

switch语句,switch可通过一个整数索引值进行多重分支,通过跳转表来实现,相当于跳转表是数组,然后那个整数值就是索引值

jmp指令的操作数前有*代表是见解跳转。rodata叫做只读数据。

3.6、过程

过程是一种抽象,提供一种封装代码方法,简单来说就是由一组参数经过过程来产生一个返回值过程有很多种:函数,方法,子过程,子例程,处理函数等

3.6.1、运行时栈

栈是后进先出的,在过程p调用q过程的时候:

在x86-64过程中,若需要的存储空间超过寄存器能存放的大小时,就会在栈上分配空间,这个过程叫栈帧

一般的在过程中超过6个参数就需要栈了

3.6.2、转移控制

将控制从p转移到q只需要将PC设置成q代码起始地址,但仍要记得p当前指令地址

3.6.3、数据传送

传入参数不一定一定用r开头寄存器,可以根据传入参数位数选择寄存器,数据传送讲的就是6个以上参数,从第七开始会转移到栈上

3.6.4、栈上的局部存储

有几种情况局部内存必须放在内存中:
寄存器不足够存放所有本地数据

对一个局部变量使用地址运算符‘&’,因此必须要有地址

某些局部变量是数组或者结构,因此必须能够通过数组或结构引用访问

3.6.5、寄存器中的局部存储空间

寄存器是唯一被所有过程共享的资源,过程中的被调用者不会覆盖调用者稍后会使用寄存器

3.7、数组分配和访问

3.7.1、基本原则

3.7.2、指针运算

&和*可以产生和间接引用指针,我们要知道的就是下面这个表

3.7.3、嵌套的数组

对于二维数组

上面数组的以下面来解释:

我们从汇编求出来C就是列,L就是T的字节大小

3.7.4、定长数组

3.7.5、变长数组

3.8、异质的数据结构

主要介绍struct和union

3.8.1、结构

struct将不同类型的对象聚合到一个对象中,类似数组,一幅图直接理解

3.8.2、联合

一个联合总的大小等于它最大字段的大小,总之联合可以带来的节省很小

3.8.3、数据对齐

主要就是一个处理器要是从内存取8字节,那么地址必须是8的倍数

3.9、安全漏洞

3.9.1、gdb操作

3.9.2、内存越界和缓冲区溢出

这是pwn里的攻击方法,比如gets来输入字符串,超出输入范围那么就叫缓冲区溢出,当字符串边长,就会覆盖栈上存储的某些信息,比如未被使用的栈空间,返回地址,caller里保存的状态。。。当返回被破坏,那么我们完全可以ret到我们想要的地方,比如shell中

3.9.3、对抗缓冲区溢出

比如我们会在文件中加入防护措施。

1、栈随机化也叫ALSR

这个很常见,原理:在程序开始时,在栈上分配一段0~n字节的随机大小空间,程序不需要这段空间,所以每次栈空间都是随机的。

2、栈破坏检测也叫canary

我们尝试在数组即将越界时检测到它,其思想是在栈帧任何局部缓冲区与栈状态之间存储一个特殊的canary值,这个值随机产生,这个值是只读。

如果存贮值与canary值相同异或就为0,那么程序继续

3、限制可执行代码区域NX

这一招是消除攻击者插入代码的权力,只有保存在编译器产生的代码的那部分内存才是可执行的,其余只能读和写。

3.9.4、支持变长栈帧

%rbp作为帧指针,或者叫做基地址.

3.10、浮点代码

处理器的浮点体系结构包括多个方面:

如何存储和访问浮点数值。通常是通过某种寄存器方式完成

对浮点数据操作的指令

向函数传递浮点数参数和从函数返回浮点数结果的规则

函数调用过程中保存寄存器的规则:一些寄存器被指定为调用者保存,而其他的被指定为被调用者保存

历史问题:

3.10.1、浮点传送和转换操作

若把浮点数转换成整数时,指令进行截断,向0舍入。

上面忽略第二个操作数,因为他只会影响结果的高位字节,一半第二个操作数跟目的操作数是一样的。

vunpcklps通常交叉放置来自两个xmm寄存器的值,储存在第三个寄存器

3.10.2、过程中的浮点代码

过程:xmm寄存器用来向函数传参,然后返回值

image-20220309165638590

image-20220309165653801

若函数包含指针,整数和浮点数混合参数时,指针和整数通过寄存器传递,而浮点值通过xmm寄存器传递

3.10.3、浮点数运算操作

第一个源操作数可以是一个xmm寄存器或内存位置,第二个源操作数和目的操作数必须是xmm寄存器。每个操作都有一条针对单精度的指令和一条针对双精度的指令,结果存放在目的寄存器。

image-20220309170014341

3.10.4、定义和使用浮点数

与整数操作不同,AVX浮点操作不能以立即数作为操作数。

3.10.5、在浮点代码中使用位级操作

3.10.6、浮点比较操作

类似于cmp指令

也有三个条件码

结束:

这篇学到了很多汇编知识,理解了底层的逻辑。

收获很多,继续加油!

CSAPP-LAB

DataLab

我只能说,太难想了。

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/*

* CS:APP Data Lab
*
* <Please put your name and userid here>
*
* bits.c - Source file with your solutions to the Lab.
* This is the file you will hand in to your instructor.
*
* WARNING: Do not include the <stdio.h> header; it confuses the dlc
* compiler. You can still use printf for debugging without including
* <stdio.h>, although you might get a compiler warning. In general,
* it's not good practice to ignore compiler warnings, but in this
* case it's OK.
*/

#if 0
/*

* Instructions to Students:
*
* STEP 1: Read the following instructions carefully.
*/

You will provide your solution to the Data Lab by
editing the collection of functions in this source file.

INTEGER CODING RULES:

Replace the "return" statement in each function with one
or more lines of C code that implements the function. Your code
must conform to the following style:

int Funct(arg1, arg2, ...) {
/* brief description of how your implementation works */
int var1 = Expr1;
...
int varM = ExprM;

​ varJ = ExprJ;
​ ...
​ varN = ExprN;
return ExprR;
}

Each "Expr" is an expression using ONLY the following:

1. Integer constants 0 through 255 (0xFF), inclusive. You are
not allowed to use big constants such as 0xffffffff.
2. Function arguments and local variables (no global variables).
3. Unary integer operations ! ~
4. Binary integer operations & ^ | + << >>

Some of the problems restrict the set of allowed operators even further.
Each "Expr" may consist of multiple operators. You are not restricted to
one operator per line.

You are expressly forbidden to:

1. Use any control constructs such as if, do, while, for, switch, etc.
2. Define or use any macros.
3. Define any additional functions in this file.
4. Call any functions.
5. Use any other operations, such as &&, ||, -, or ?:
6. Use any form of casting.
7. Use any data type other than int. This implies that you
cannot use arrays, structs, or unions.


You may assume that your machine:

1. Uses 2s complement, 32-bit representations of integers.
2. Performs right shifts arithmetically.
3. Has unpredictable behavior when shifting if the shift amount
is less than 0 or greater than 31.


EXAMPLES OF ACCEPTABLE CODING STYLE:
/*

* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
*/
int pow2plus1(int x) {
/* exploit ability of shifts to compute powers of 2 */
return (1 << x) + 1;
}

/*

* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
*/
int pow2plus4(int x) {
/* exploit ability of shifts to compute powers of 2 */
int result = (1 << x);
result += 4;
return result;
}

FLOATING POINT CODING RULES

For the problems that require you to implement floating-point operations,
the coding rules are less strict. You are allowed to use looping and
conditional control. You are allowed to use both ints and unsigneds.
You can use arbitrary integer and unsigned constants. You can use any arithmetic,
logical, or comparison operations on int or unsigned data.

You are expressly forbidden to:

1. Define or use any macros.
2. Define any additional functions in this file.
3. Call any functions.
4. Use any form of casting.
5. Use any data type other than int or unsigned. This means that you
cannot use arrays, structs, or unions.
6. Use any floating point data types, operations, or constants.


NOTES:

1. Use the dlc (data lab checker) compiler (described in the handout) to
check the legality of your solutions.
2. Each function has a maximum number of operations (integer, logical,
or comparison) that you are allowed to use for your implementation
of the function. The max operator count is checked by dlc.
Note that assignment ('=') is not counted; you may use as many of
these as you want without penalty.
3. Use the btest test harness to check your functions for correctness.
4. Use the BDD checker to formally verify your functions
5. The maximum number of ops for each function is given in the
header comment for each function. If there are any inconsistencies
between the maximum ops in the writeup and in this file, consider
this file the authoritative source.

/*

* STEP 2: Modify the following functions according the coding rules.
*
* IMPORTANT. TO AVOID GRADING SURPRISES:
* 1. Use the dlc compiler to check that your solutions conform
* to the coding rules.
* 2. Use the BDD checker to formally verify that your solutions produce
* the correct answers.
*/


#endif
//1
/*

* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) {

return (~((~x) & (~y))) & (~(x & y));//int是4位,~4就是-5,前面的操作得到0b0101,我们只需0b1011即可,后面构造出来
}
/*

* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {

return 0x80 << 24;//0x80 == 0b1000 0000

}
//2
/*

* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
int i = x + 1;/*我们知道最大值+1就越界了,其实会等于最小值*/
x = x + i;/*最大值加最小值= -1 ,即0xffff ffff*/
x = ~x;/*因为0xffff ffff是全1,取反就是0*/
i = !i;//针对x=-1的情况进行再次运算!
x = x + 1;
return !x;
}
/*
* allOddBits - return 1 if all odd-numbered bits in word set to 1
* where bits are numbered from 0 (least significant) to 31 (most significant)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x)////如果x奇数位全为1,返回1;否则返回0
{
return !((~x) & 0XAAAAAAAA);//0XAAAAAAAA就是奇数位是1
//若x奇数位上全是1,~x奇数位上全是0,(~X) & 0XAAAAAAAA则奇数位全是0,取!则为1
//若x奇数位不全为1,~x总有奇数位为0,(~X) & 0XAAAAAAAA一定不为0,取!则为0。
}
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) //求x的相反数,我们知道~x + x = -1
{
return (~x + 1);
}
//3
/*
* isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
* Example: isAsciiDigit(0x35) = 1.
* isAsciiDigit(0x3a) = 0.
* isAsciiDigit(0x05) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 3
*/
int isAsciiDigit(int x) //计算输入值是否是数字 0-9 的 ASCII 值
{
return (!(x + ((~0x30) + 1)) >> 31) & ((x + ((~0x3a) + 1)) >> 31);//这个可以利用上面的求相反数来写,我们主要是拿x来与0~9的比较大小
// ((~0x30) + 1))是求0x30的相反数,然后用x-0x30,再右移31位取符号位,如果符号位是1,则是负数。
}
/*
* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z) ////x为0返回z;否则返回y
{
int mask;
mask = (!x + (~1) + 1);
return (mask & y) | (~mask & z);
//mask=(!x + (~1) + 1),求的是!x-1,要么等于0,要么等于-1,等于-1就可以用补码!
}
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y) ////x<=y返回1,否则返回0
{
int negX = ~x + 1;//求-x
int addX = negX + y;//y-x,要和0,1比
int checksign = (addX >> 31) &1;//看符号位
int leftBit = 1 << 31;
int xLeft = x & leftBit;//求x的符号
int yLeft = y & leftBit;//求y的符号
int bitXor = xLeft ^ yLeft;//x和y符号相同标志位,相同为0不同为1
bitXor = (bitXor >> 31) & 1;//符号相同标志位格式化为0或1
return ((!bitXor) & (!checksign)) | (bitXor & (xLeft >> 31)); //返回1有两种情况:符号相同标志位为0(相同)位与 y-x 的符号为0(y-x>=0)结果为1;符号相同标志位为1(不同)位与x的符号位为1(x<0)
}//bitXor是判断x,y是否是同号。
//4
/*
* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) //不用!的条件下实现!运算
{
return ((~x & ~(~x + 1)) >> 31) & 1;//(~x & ~(~x + 1))这个当x=0这个值就是1,当x为最小值,这个为0,其他情况,x和-x符号不同,所以等于0.
}
/* howManyBits - return the minimum number of bits required to represent x in
* two's complement
* Examples: howManyBits(12) = 5
* howManyBits(298) = 10
* howManyBits(-5) = 4
* howManyBits(0) = 1
* howManyBits(-1) = 1
* howManyBits(0x80000000) = 32
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 90
* Rating: 4
*/
int howManyBits(int x) //一个数用补码表示最少需要几位?*******
{
int b16,b8,b4,b2,b1,b0;
int sign = x >> 31;
x = (sign & ~x) | (~sign & x);//如果x为正则不变,否则按位取反(这样好找最高位为1的,原来是最高位为0的,这样也将符号位去掉了)
b16 = !!(x >> 16) << 4;//高十六位是否有1
x = x >> b16; //如果有(至少需要16位),则将原数右移16位
b8 = !!(x >> 8) << 3; //剩余位高8位是否有1
x = x >> b8; //如果有(至少需要16+8=24位),则右移8位
b4 = !!(x >> 4) << 2;
x = x >> b4;
b2 = !!(x >> 2) << 1;
x = x >> b2;
b1 = !!(x >> 1);
x = x >> b1;
b0 = x;
return b16 + b8 + b4 + b2 + b1 + b0 + 1;
}
//float
/*
* floatScale2 - Return bit-level equivalent of expression 2*f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, but
* they are to be interpreted as the bit-level representation of
* single-precision floating point values.
* When argument is NaN, return argument
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatScale2(unsigned uf) //求2乘一个浮点数 ******
{
int exp_ = (uf & 0x7f800000) >> 23;
int s_ = uf & 0x80000000;
if (exp_ == 0)
return (uf << 1) | s_;
if (exp_ == 255)
return uf;
++exp_;
if (exp_ == 255)
return 0x7f800000 | s_;
return (uf & 0x807fffff) | (exp_ << 23);
}
/*
* floatFloat2Int - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf)//将浮点数转换为有符号整数,float_f2i
{
int s_ = uf >> 31;
int exp_ = ((uf & 0x7f800000) >> 23) - 127;
int frac_ = (uf & 0x007fffff) | 0x00800000;
if (!(uf & 0x7fffffff))
return 0;

if (exp_ > 31)
return 0x80000000;
if (exp_ < 0)
return 0;

if (exp_ > 23)
frac_ <<= (exp_ - 23);
else
frac_ >>= (23 - exp_);

if (!((frac_ >> 31) ^ s_))
return frac_;
else if (frac_ >> 31)
return 0x80000000;
else
return ~frac_ + 1;
}
/*

* floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) //计算浮点数2.0^x
{
if (x < -127)
return 0;
if (x > 128)
return 0x7f800000;
x += 127;
x = x << 23;
return x;
}

Bomb Lab

在gdb中进行反汇编调试,输入disas phase_1,出来第一关:

1
2
3
4
5
6
7
8
9
Dump of assembler code for function phase_1:
0x0000000000400ee0 <+0>: sub rsp,0x8//开辟0x8的空间
0x0000000000400ee4 <+4>: mov esi,0x402400//将0x402400存到esi中,里面可能会有字符串
0x0000000000400ee9 <+9>: call 0x401338 <strings_not_equal>//这个函数可能是对比函数
0x0000000000400eee <+14>: test eax,eax//对比
0x0000000000400ef0 <+16>: je 0x400ef7 <phase_1+23>//如果eax=0,则进入phase2;否则爆炸
0x0000000000400ef2 <+18>: call 0x40143a <explode_bomb>
0x0000000000400ef7 <+23>: add rsp,0x8//返回0x8大小的内存
0x0000000000400efb <+27>: ret

image-20220303172619689

用ida看的话更清楚,就是一个对比函数:

image-20220303172745254

image-20220303172937753

拿下!

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
Dump of assembler code for function phase_2:
0x0000000000400efc <+0>: push rbp
0x0000000000400efd <+1>: push rbx
0x0000000000400efe <+2>: sub rsp,0x28//开辟0x28空间
0x0000000000400f02 <+6>: mov rsi,rsp
0x0000000000400f05 <+9>: call 0x40145c <read_six_numbers>//输入6个数
0x0000000000400f0a <+14>: cmp DWORD PTR [rsp],0x1//与1对比
0x0000000000400f0e <+18>: je 0x400f30 <phase_2+52>
0x0000000000400f10 <+20>: call 0x40143a <explode_bomb>
0x0000000000400f15 <+25>: jmp 0x400f30 <phase_2+52>//跳转到phase3
0x0000000000400f17 <+27>: mov eax,DWORD PTR [rbx-0x4]
0x0000000000400f1a <+30>: add eax,eax//eax += eax
0x0000000000400f1c <+32>: cmp DWORD PTR [rbx],eax
0x0000000000400f1e <+34>: je 0x400f25 <phase_2+41>
0x0000000000400f20 <+36>: call 0x40143a <explode_bomb>
0x0000000000400f25 <+41>: add rbx,0x4//rbx+4这个地址在循环
0x0000000000400f29 <+45>: cmp rbx,rbp//对比rbx。rbp
0x0000000000400f2c <+48>: jne 0x400f17 <phase_2+27>//进入循环
0x0000000000400f2e <+50>: jmp 0x400f3c <phase_2+64>
0x0000000000400f30 <+52>: lea rbx,[rsp+0x4]
0x0000000000400f35 <+57>: lea rbp,[rsp+0x18]
0x0000000000400f3a <+62>: jmp 0x400f17 <phase_2+27>
0x0000000000400f3c <+64>: add rsp,0x28
0x0000000000400f40 <+68>: pop rbx
0x0000000000400f41 <+69>: pop rbp
0x0000000000400f42 <+70>: ret
End of assembler dump.

那么很清楚了,我们这个循环做的操作就是让eax*2,那么找到第一个值就行了,我们用ida反编译

image-20220303181512313

所以6个数是1,2,4,8,16,32

image-20220303181600058

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
Dump of assembler code for function phase_3:
0x0000000000400f43 <+0>: sub rsp,0x18//开辟0x18空间
0x0000000000400f47 <+4>: lea rcx,[rsp+0xc]//将[rsp+0xc]的值存在rcx寄存器
0x0000000000400f4c <+9>: lea rdx,[rsp+0x8]
0x0000000000400f51 <+14>: mov esi,0x4025cf//esi寄存器的值为0x4025cf
0x0000000000400f56 <+19>: mov eax,0x0
0x0000000000400f5b <+24>: call 0x400bf0 <__isoc99_sscanf@plt>//scanf
0x0000000000400f60 <+29>: cmp eax,0x1
0x0000000000400f63 <+32>: jg 0x400f6a <phase_3+39>
0x0000000000400f65 <+34>: call 0x40143a <explode_bomb>
0x0000000000400f6a <+39>: cmp DWORD PTR [rsp+0x8],0x7
0x0000000000400f6f <+44>: ja 0x400fad <phase_3+106>
0x0000000000400f71 <+46>: mov eax,DWORD PTR [rsp+0x8]
0x0000000000400f75 <+50>: jmp QWORD PTR [rax*8+0x402470]
0x0000000000400f7c <+57>: mov eax,0xcf
0x0000000000400f81 <+62>: jmp 0x400fbe <phase_3+123>
0x0000000000400f83 <+64>: mov eax,0x2c3
0x0000000000400f88 <+69>: jmp 0x400fbe <phase_3+123>
0x0000000000400f8a <+71>: mov eax,0x100
0x0000000000400f8f <+76>: jmp 0x400fbe <phase_3+123>
0x0000000000400f91 <+78>: mov eax,0x185
0x0000000000400f96 <+83>: jmp 0x400fbe <phase_3+123>
0x0000000000400f98 <+85>: mov eax,0xce
0x0000000000400f9d <+90>: jmp 0x400fbe <phase_3+123>
0x0000000000400f9f <+92>: mov eax,0x2aa
0x0000000000400fa4 <+97>: jmp 0x400fbe <phase_3+123>
0x0000000000400fa6 <+99>: mov eax,0x147
0x0000000000400fab <+104>: jmp 0x400fbe <phase_3+123>
0x0000000000400fad <+106>: call 0x40143a <explode_bomb>
0x0000000000400fb2 <+111>: mov eax,0x0
0x0000000000400fb7 <+116>: jmp 0x400fbe <phase_3+123>
0x0000000000400fb9 <+118>: mov eax,0x137
0x0000000000400fbe <+123>: cmp eax,DWORD PTR [rsp+0xc]
0x0000000000400fc2 <+127>: je 0x400fc9 <phase_3+134>
0x0000000000400fc4 <+129>: call 0x40143a <explode_bomb>
0x0000000000400fc9 <+134>: add rsp,0x18
0x0000000000400fcd <+138>: ret
End of assembler dump.

我认为这个不太好看出来,下面是关键

1
2
0x0000000000400f6a <+39>:    cmp    DWORD PTR [rsp+0x8],0x7
0x0000000000400f6f <+44>: ja 0x400fad <phase_3+106>

ja是大于则跳转,跳转就爆炸了,所以不能大于7,给了我们许多选择,我们选0-7都行,第二个数就对应switch上的另一个值,用ida更好看出!

image-20220303185344874

我选2,就必须对应707。

image-20220303185414142

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Dump of assembler code for function phase_4:
0x000000000040100c <+0>: sub rsp,0x18//开辟空间
0x0000000000401010 <+4>: lea rcx,[rsp+0xc]
0x0000000000401015 <+9>: lea rdx,[rsp+0x8]
0x000000000040101a <+14>: mov esi,0x4025cf
0x000000000040101f <+19>: mov eax,0x0
0x0000000000401024 <+24>: call 0x400bf0 <__isoc99_sscanf@plt>//输入两个值
0x0000000000401029 <+29>: cmp eax,0x2
0x000000000040102c <+32>: jne 0x401035 <phase_4+41>
0x000000000040102e <+34>: cmp DWORD PTR [rsp+0x8],0xe
0x0000000000401033 <+39>: jbe 0x40103a <phase_4+46>
0x0000000000401035 <+41>: call 0x40143a <explode_bomb>
0x000000000040103a <+46>: mov edx,0xe
0x000000000040103f <+51>: mov esi,0x0
0x0000000000401044 <+56>: mov edi,DWORD PTR [rsp+0x8]
0x0000000000401048 <+60>: call 0x400fce <func4>
0x000000000040104d <+65>: test eax,eax
0x000000000040104f <+67>: jne 0x401058 <phase_4+76>
0x0000000000401051 <+69>: cmp DWORD PTR [rsp+0xc],0x0
0x0000000000401056 <+74>: je 0x40105d <phase_4+81>
0x0000000000401058 <+76>: call 0x40143a <explode_bomb>
0x000000000040105d <+81>: add rsp,0x18
0x0000000000401061 <+85>: ret
End of assembler dump.

jbe小于等于则跳转,所以eax要≤ 14,第一个参数要≤ 14

接下来第二个参数要看func4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Dump of assembler code for function func4:
0x0000000000400fce <+0>: sub rsp,0x8
0x0000000000400fd2 <+4>: mov eax,edx
0x0000000000400fd4 <+6>: sub eax,esi
0x0000000000400fd6 <+8>: mov ecx,eax
0x0000000000400fd8 <+10>: shr ecx,0x1f
0x0000000000400fdb <+13>: add eax,ecx
0x0000000000400fdd <+15>: sar eax,1
0x0000000000400fdf <+17>: lea ecx,[rax+rsi*1]
0x0000000000400fe2 <+20>: cmp ecx,edi
0x0000000000400fe4 <+22>: jle 0x400ff2 <func4+36>
0x0000000000400fe6 <+24>: lea edx,[rcx-0x1]
0x0000000000400fe9 <+27>: call 0x400fce <func4>
0x0000000000400fee <+32>: add eax,eax
0x0000000000400ff0 <+34>: jmp 0x401007 <func4+57>
0x0000000000400ff2 <+36>: mov eax,0x0
0x0000000000400ff7 <+41>: cmp ecx,edi
0x0000000000400ff9 <+43>: jge 0x401007 <func4+57>
0x0000000000400ffb <+45>: lea esi,[rcx+0x1]
0x0000000000400ffe <+48>: call 0x400fce <func4>
0x0000000000401003 <+53>: lea eax,[rax+rax*1+0x1]
0x0000000000401007 <+57>: add rsp,0x8
0x000000000040100b <+61>: ret
End of assembler dump.

func4()函数的返回值(保存在寄存器eax中), 如果eax不是0的话, 则会跳转到引爆炸弹的地方. 因此函数func4()返回值eax必须是0

image-20220303194719642

image-20220303194725447

很明显,在我们选择第二个参数时,我们如果让第二个参数=0,那么这些问题顺利解决,因为在func4函数中没有v3==0这个选项,当a1=7,a2=0时非常完美的做到了上述一切。

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
Dump of assembler code for function phase_5:
0x0000000000401062 <+0>: push rbx
0x0000000000401063 <+1>: sub rsp,0x20
0x0000000000401067 <+5>: mov rbx,rdi
0x000000000040106a <+8>: mov rax,QWORD PTR fs:0x28
0x0000000000401073 <+17>: mov QWORD PTR [rsp+0x18],rax
0x0000000000401078 <+22>: xor eax,eax
0x000000000040107a <+24>: call 0x40131b <string_length>
0x000000000040107f <+29>: cmp eax,0x6//flag长度为6
0x0000000000401082 <+32>: je 0x4010d2 <phase_5+112>
0x0000000000401084 <+34>: call 0x40143a <explode_bomb>
0x0000000000401089 <+39>: jmp 0x4010d2 <phase_5+112>
0x000000000040108b <+41>: movzx ecx,BYTE PTR [rbx+rax*1]
0x000000000040108f <+45>: mov BYTE PTR [rsp],cl
0x0000000000401092 <+48>: mov rdx,QWORD PTR [rsp]
0x0000000000401096 <+52>: and edx,0xf
0x0000000000401099 <+55>: movzx edx,BYTE PTR [rdx+0x4024b0]
0x00000000004010a0 <+62>: mov BYTE PTR [rsp+rax*1+0x10],dl
0x00000000004010a4 <+66>: add rax,0x1
0x00000000004010a8 <+70>: cmp rax,0x6
0x00000000004010ac <+74>: jne 0x40108b <phase_5+41>
0x00000000004010ae <+76>: mov BYTE PTR [rsp+0x16],0x0
0x00000000004010b3 <+81>: mov esi,0x40245e
0x00000000004010b8 <+86>: lea rdi,[rsp+0x10]
0x00000000004010bd <+91>: call 0x401338 <strings_not_equal>
0x00000000004010c2 <+96>: test eax,eax
0x00000000004010c4 <+98>: je 0x4010d9 <phase_5+119>
0x00000000004010c6 <+100>: call 0x40143a <explode_bomb>
0x00000000004010cb <+105>: nop DWORD PTR [rax+rax*1+0x0]
0x00000000004010d0 <+110>: jmp 0x4010d9 <phase_5+119>
0x00000000004010d2 <+112>: mov eax,0x0
0x00000000004010d7 <+117>: jmp 0x40108b <phase_5+41>
0x00000000004010d9 <+119>: mov rax,QWORD PTR [rsp+0x18]
0x00000000004010de <+124>: xor rax,QWORD PTR fs:0x28
0x00000000004010e7 <+133>: je 0x4010ee <phase_5+140>
0x00000000004010e9 <+135>: call 0x400b30 <__stack_chk_fail@plt>
0x00000000004010ee <+140>: add rsp,0x20
0x00000000004010f2 <+144>: pop rbx
0x00000000004010f3 <+145>: ret
End of assembler dump.

属实不想看汇编了,直接ida搞了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
unsigned __int64 __fastcall phase_5(__int64 a1)
{
__int64 i; // rax
char v3[8]; // [rsp+10h] [rbp-18h] BYREF
unsigned __int64 v4; // [rsp+18h] [rbp-10h]

v4 = __readfsqword(0x28u);
if ( (unsigned int)string_length(a1) != 6 )
explode_bomb();
for ( i = 0LL; i != 6; ++i )
v3[i] = array_3449[*(_BYTE *)(a1 + i) & 0xF];
v3[6] = 0;
if ( (unsigned int)strings_not_equal(v3, "flyers") )
explode_bomb();
return __readfsqword(0x28u) ^ v4;
}

也就爆破一下就行了

1
2
3
4
5
6
7
8
9
10
11
flag = ""
a = "maduiersnfotvbyl"
b = "flyers"
for i in range(6):
for j in range(65,127):
c = ord(a[(j) & 0xf])
if c == ord(b[i]):
flag += chr(j)
break
print(flag)
#IONEFG

成功!最后一关!

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
Dump of assembler code for function phase_6:
0x00000000004010f4 <+0>: push r14
0x00000000004010f6 <+2>: push r13
0x00000000004010f8 <+4>: push r12
0x00000000004010fa <+6>: push rbp
0x00000000004010fb <+7>: push rbx
0x00000000004010fc <+8>: sub rsp,0x50
0x0000000000401100 <+12>: mov r13,rsp
0x0000000000401103 <+15>: mov rsi,rsp
0x0000000000401106 <+18>: call 0x40145c <read_six_numbers>//读入6个数字
0x000000000040110b <+23>: mov r14,rsp
0x000000000040110e <+26>: mov r12d,0x0
0x0000000000401114 <+32>: mov rbp,r13//rsp赋值给rbp
0x0000000000401117 <+35>: mov eax,DWORD PTR [r13+0x0]//取第一个参数
0x000000000040111b <+39>: sub eax,0x1//参数1-1
0x000000000040111e <+42>: cmp eax,0x5//参数1-1 =< 5,所以参数一小于6
0x0000000000401121 <+45>: jbe 0x401128 <phase_6+52>
0x0000000000401123 <+47>: call 0x40143a <explode_bomb>
0x0000000000401128 <+52>: add r12d,0x1//r12控制循环次数
0x000000000040112c <+56>: cmp r12d,0x6
0x0000000000401130 <+60>: je 0x401153 <phase_6+95>
0x0000000000401132 <+62>: mov ebx,r12d
0x0000000000401135 <+65>: movsxd rax,ebx
0x0000000000401138 <+68>: mov eax,DWORD PTR [rsp+rax*4]//这个循环是使后面的参数不能等于参数1
0x000000000040113b <+71>: cmp DWORD PTR [rbp+0x0],eax
0x000000000040113e <+74>: jne 0x401145 <phase_6+81>
0x0000000000401140 <+76>: call 0x40143a <explode_bomb>
0x0000000000401145 <+81>: add ebx,0x1//又是循环
0x0000000000401148 <+84>: cmp ebx,0x5
0x000000000040114b <+87>: jle 0x401135 <phase_6+65>
0x000000000040114d <+89>: add r13,0x4//参数2
0x0000000000401151 <+93>: jmp 0x401114 <phase_6+32>
0x0000000000401153 <+95>: lea rsi,[rsp+0x18]//这个是'\0'
0x0000000000401158 <+100>: mov rax,r14
0x000000000040115b <+103>: mov ecx,0x7//ecx永远是7
0x0000000000401160 <+108>: mov edx,ecx
0x0000000000401162 <+110>: sub edx,DWORD PTR [rax]//7-当前参数
0x0000000000401164 <+112>: mov DWORD PTR [rax],edx
0x0000000000401166 <+114>: add rax,0x4//地址+4,即下一个参数
0x000000000040116a <+118>: cmp rax,rsi
0x000000000040116d <+121>: jne 0x401160 <phase_6+108>
0x000000000040116f <+123>: mov esi,0x0
0x0000000000401174 <+128>: jmp 0x401197 <phase_6+163>
0x0000000000401176 <+130>: mov rdx,QWORD PTR [rdx+0x8]//rdx是node1
0x000000000040117a <+134>: add eax,0x1//内层循环
0x000000000040117d <+137>: cmp eax,ecx
0x000000000040117f <+139>: jne 0x401176 <phase_6+130>
0x0000000000401181 <+141>: jmp 0x401188 <phase_6+148>
0x0000000000401183 <+143>: mov edx,0x6032d0//链表处
0x0000000000401188 <+148>: mov QWORD PTR [rsp+rsi*2+0x20],rdx
0x000000000040118d <+153>: add rsi,0x4//每次加4的进行循环到0x18循环结束
0x0000000000401191 <+157>: cmp rsi,0x18
0x0000000000401195 <+161>: je 0x4011ab <phase_6+183>
0x0000000000401197 <+163>: mov ecx,DWORD PTR [rsp+rsi*1]
0x000000000040119a <+166>: cmp ecx,0x1
0x000000000040119d <+169>: jle 0x401183 <phase_6+143>
0x000000000040119f <+171>: mov eax,0x1
0x00000000004011a4 <+176>: mov edx,0x6032d0
0x00000000004011a9 <+181>: jmp 0x401176 <phase_6+130>
0x00000000004011ab <+183>: mov rbx,QWORD PTR [rsp+0x20]//指针数组存在rsp中
0x00000000004011b0 <+188>: lea rax,[rsp+0x28]
0x00000000004011b5 <+193>: lea rsi,[rsp+0x50]
0x00000000004011ba <+198>: mov rcx,rbx
0x00000000004011bd <+201>: mov rdx,QWORD PTR [rax]
0x00000000004011c0 <+204>: mov QWORD PTR [rcx+0x8],rdx
0x00000000004011c4 <+208>: add rax,0x8
0x00000000004011c8 <+212>: cmp rax,rsi
0x00000000004011cb <+215>: je 0x4011d2 <phase_6+222>
0x00000000004011cd <+217>: mov rcx,rdx
0x00000000004011d0 <+220>: jmp 0x4011bd <phase_6+201>
0x00000000004011d2 <+222>: mov QWORD PTR [rdx+0x8],0x0
0x00000000004011da <+230>: mov ebp,0x5
0x00000000004011df <+235>: mov rax,QWORD PTR [rbx+0x8]
0x00000000004011e3 <+239>: mov eax,DWORD PTR [rax]
0x00000000004011e5 <+241>: cmp DWORD PTR [rbx],eax
0x00000000004011e7 <+243>: jge 0x4011ee <phase_6+250>//参数1>参数2
0x00000000004011e9 <+245>: call 0x40143a <explode_bomb>
0x00000000004011ee <+250>: mov rbx,QWORD PTR [rbx+0x8]
0x00000000004011f2 <+254>: sub ebp,0x1
0x00000000004011f5 <+257>: jne 0x4011df <phase_6+235>
0x00000000004011f7 <+259>: add rsp,0x50
0x00000000004011fb <+263>: pop rbx
0x00000000004011fc <+264>: pop rbp
0x00000000004011fd <+265>: pop r12
0x00000000004011ff <+267>: pop r13
0x0000000000401201 <+269>: pop r14
0x0000000000401203 <+271>: ret
End of assembler dump.

在read_six_numbers函数中我们看出用rsp开辟了0x18空间,所以输入数在rsp中

image-20220303205629062

我们发现这个就是对链表进行升序排序:{14C,1,A8,2,39C,3,2B3,4,1DD,5,1BB,6}

所以答案是;4 3 2 1 6 5

image-20220303212529967

起飞!!!这个比datalab好玩多了

CSAPP-7-END

链接

链接时将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可以被加载到内存并执行。链接可以执行于编译时,也可以执行与加载时,甚至可以执行于运行时。在现代系统中,链接是由链接器程序自动执行。

链接可以是软件开发中分离编译

7.1、编译器驱动程序

main.c执行过程:先通过c预处理器,成为ascii码编写的main.i程序,接下来由c编译器将其编为ascii汇编语言文件main.s,然后汇编器将其变成可重定位目标文件main.o,如果需要链接,最后运行链接器ld,将必要文件链接,成为可执行文件,在shell里运行需要调用loader即加载器。

7.2、静态链接

链接器的两大任务:

符号解析。目标文件定义和引用符号,每个符号对应于1个函数,一个全局变量或者一个静态变量,其目的就是为了将每个符号引用正好和一个符号定义关联起来。

重定位。编译器和汇编器生成从0开始的代码和数据节。链接器通过把每个符号定位于一个内存位置关联起来,从而重定位这些节,再修改符号引用,使得他们指向这个内存位置。

7.3、目标文件

三种文件:

可重定位目标文件:含二进制代码和数据,其形式能于其他可重定位目标文件合并起来。

可执行文件:包含二进制和数据,其形式可以直接复制到内存中并执行

共享目标文件:一种特殊的可重定位目标文件,可在加载或者运行时被动态的加载进内存并链接

目标文件就是以文件形式存放再磁盘中的目标模块,而目标模块时一个字节序列

7.4、可重定位目标文件

image-20220317175712426

image-20220317175850287

image-20220317175859399

7.5、符号和符号表

每个重定位的目标模块都存在一个符号表,其包括m定义和引用符号的消息.在链接器的上下文,存在三种符号

由m定义并能被其他模块引用的全局符号.全局链接器符号对应于非静态的c函数和全局变量

由其他模块定义并被m引用的全局符号.这些符号叫外部符号,对应其他模块中定义的非静态c函数和全局变量

只被模块m定义和引用的局部符号,他们对应于带static的c函数和全局变量.这些符号全局可见,但不可引用

本地链接器符号和本地程序变量不同

.symtab中的符号表不包括对应于本地非静态程序变量的任何符号,这些符号是在栈中管理的,也就是局部变量

static的变量在.data或者.bss中为其分配空间

image-20220317185459019

name是字符串表的字节偏移,指向符号以null结尾的字符串名字.value是符号地址,size是目标大小,type通常是数据或函数,blinging表明是全局还是本地。

每个符号都被分配到某个节,由section字段表示。

image-20220317191156258

7.6、符号解析

链接器解析符号引用的方法是将每个引用与它输入的可重定位目标文件的符号表中的一个确定的符号定义关联起来。

对于全局符号解析采用假设法,如果不是就终止。

重载:对于一些方法在源代码中有相同的名字,却有不同参数列表,c++和java使用重载函数.,是因为编译器将每一个唯一的方法和参数列表组合编码成一个,对链接器来说是唯一的名字,这就是重载,相反的过程叫恢复。

7.6.1、链接器如何解析多重定义的全局变量

多个模块定义同名的全局符号:

首先分为强和弱,函数和已初始化的变量是强符号,未初始化的全局变量是弱符号。

有三个规则,不允许有多个同名的强符号,如果有一个强符号与多个弱符号同名,选择强符号,如果有多个弱符号同名,任选一个。

7.6.2、与静态库链接

所有编译系统提供机制:将所有相关的目标模块打包成为一个单独的文件,成为静态库,可作为链接库的输入。这样的操作减少内存的使用或者减少操作每个函数的重复性,直接调用库函数就解决问题了。

7.6.3、链接器如何使用静态库来解析引用

在linux链接器及逆行符号解析阶段时,链接器从左到右扫描命令行出现顺序的可重定位目标文件和存档文件。在这当中链接器维护一个可重定位目标文件的集合E(被认为是可执行文件),一个违背解析符号的集合U(被引用但未被定义的符号),以及一个在前面输入文件已定义的符号集合D。

对于命令行上的输入文件,如果是目标文件f,链接器把f添加到E,修改U和D来反映f中的符号定义和引用,并继续下一个输入文件。

如果是存档文件,那么链接器久长时匹配U中未解析的符号和有存档文件成员定义的符号,对于其中成员m,定义一个符号解析U中的一个引用,将m加入E,修改U和D来反映m中的符号定义和引用。当U和D都不变,不再在E中包含的成员,都被丢弃,输入下个文件。

如果扫描后U非空,直接输出错误,否则U会和重定位E中的目标文件,构建输出的可执行文件、

7.7、重定位

链接器完成符号解析后,就把代码中的每个符号引用和正好一个符号定义关联起来,此时,链接器直到目标module中代码节和data节大小,就可以重定位了:

1.重定位和符号定义。链接器将相同类型的节合并成同一类型的聚合节,比如.data节合成一个.data节,这就成为了可执行文件的.data节,然后链接器将运行时内存地址付给新的聚合节,赋给输入模块定义的每个节以及符号,完成时,程序每条指令和全局变量都有唯一的运行时内存地址

2.重定位节的符号引用。链接器修改代码节和数据节中对每个符号的引用,使得她们指向正确的运行时地址,这一步依赖于可重定位目标模块中成为重定位条目的数据结构

7.7.1、重定位条目

重定位条目会告诉链接器在将目标文件合并成可执行文件时如何修改这个引用,代码重定位条目存放在.rel.text中,已初始化的放在.rel.data

image-20220330144554826

7.7.2、重定位符号引用

重定位算法:

image-20220330150855839

汇编器会为每一个引用产生一个重定位条目,在引用后面的一行

image-20220330151839295

1.重定位PC相对引用

image-20220330152051016

sum正好处于第6行,而且是0xf位,在内存中运行时的地址=基址+偏移=0x4004d0 + 0xf

这个等式,其中0x5就是第6行有5字节,执行完是0x5字节

image-20220330195229301

2.重定位绝对引用

image-20220330195407058

image-20220330195411404

7.8、可执行目标文件

image-20220330161638664

.init节定义了小函数,会被藏东西的,程序初始化代码会调用它,因为可执行文件是完全链接的,已经重定位,所以不需要.rel节

可执行文件的连续的片(chunk)被映射到连续的内存段,程序头部表描述映射关系

image-20220330161932306

第2行的大小0x69c,包含ELF头和程序头部表,init,text,rodata节

3,4行存储.data节和.bss节

7.9、加载可执行目标文件

我们用加载器来加载可执行文件,运行时存在内存映像,从0x400000开始,后面是数据段,运行时堆在数据段后,通过调用malloc库向上增长,用户栈总是从最大合法用户地址2的48次幂-1开始,想较小内存地址增长。栈上区域从地址2d的48次幂开始,是为内核kernel中的代码和数据进行保留的,内核就是操作系统驻留在内存的部分

image-20220330164410397

7.10、动态链接共享库

共享库是致力于解决静态库缺陷的一个现代产物,运行加载时可以加载到任意模块,并和一个在内存中的程序链接起来,可以加载到任何内存地址,并和内存中的程序连接起来,这个过程称为动态链接,是由动态链接器执行的。共享库也叫做共享目标,在linux中用.so文件,微软使用的共享库成为dll

image-20220330182320641

image-20220330182504346

7.11、从应用程序中加载和链接共享库

image-20220330184616086

image-20220330184631787

7.12、位置无关代码

共享库是为了节约内存资源而诞生的,如果多个进程共用一个库,那么再每个内存的位置,甚至大小都不同,那么就应该使用:位置无关代码PIC,可以加载无需重定位的代码叫做PIC,这个东西可以把库加载到内存任何位置且不用修改链接器。

1、PIC数据引用

无论我们在内存加载什么模块,数据段和代码段的距离一直不变,即,代码段任何指令与数据段的变量之间的距离在运行时都是一个常量,与二者的绝对内存位置是无关的。PIC在数据段的开始处创建一个表,即全局偏移量表GOT。在GOT中,每个被这个目标module引用的全局数据目标都有一个8字节的条目。编译器还为GOT中的条目生成重定位记录,加载时动态链接器重定位每个条目并使其包含正确的绝对地址

image-20220330190117921

2、PIC函数调用

程序调用一个共享库中的函数,该函数可以存在于内存中任何地址,这就很折磨了,但通过延迟绑定,我们将过程地址的绑定推迟到第一次调用该过程时。

延迟绑定是通过GOT和过程链接表PLT,这两个数据结构完成的、GOT属于数据段,PLT属于代码段

PLT:是个数组,每个条目是16字节代码,PLT【0】很特殊,器跳转到动态链接器中,每个库函数都有自己的条目

GOT:是个数组,每个条目是8字节代码,GOT[0]和GOT[1]是加载时的函数,其余的会与PLT一一对应

image-20220330191054571

image-20220330192218540

image-20220330192224264

7.13、库打桩机制

简单来说就是欺骗系统调用的包装函数,插入自己的函数进去,想拿到什么值都可以。

异常控制流

异常控制流指的是:现代系统通过使控制流繁盛突变来对这些情况做出反应,这些突变叫做异常控制流(ECF)。异常控制流发生在计算机的每个层次上,在硬件层上会发生,在操作系统层上,内核通过上下文切换进行进程的切换,在应用层中,一个进程可以发送信号到另一个进程

8.1、异常

异常是异常控制流的一种形式,一部分由硬件实现,一部分由操作系统实现。

当处理器检测到由事件发生时,它会通过一张叫做异常表的跳转表,进行间接的调用,到专门处理此类事件的操作系统子程序,即异常处理程序,处理完成,出现三种情况:

1.控制返回原指令

2.返回给原指令,没异常就执行下一条指令

3.终止被中断的程序

8.1.1、异常处理

系统中每种异常都有一个唯一的非负整数的异常号

image-20220407161312042

image-20220407161502198

8.1.2、异常的类别

image-20220407161528243

1.中断

中断是异步,硬件中断的异常处理程序通常称为中断处理程序,

中断处理将控制返回给应用程序的下一条指令。

2.陷阱和系统调用

陷阱是有意的异常,是执行一条指令的结果。返回下一条指令。其最重要的功能是在用户程序和内核之间提供一个像过程一样的接口,叫做系统调用。

读取文件,创建新的进程,加载新的程序,结束程序都要像内核请求

3.故障

故障由错误引起,当发生故障时,交给故障处理程序。它会返回引起故障的指令,重新执行

4.终止

终止是不可恢复的致命错误造成的结果,通常是硬件错误。直接终止应用程序

8.1.3、linux/x86-64的异常

image-20220407164830759

对于linux的系统调用,每个应用想要请求内核服务时,都有唯一一个整数号对应于一个内核中的跳转表的偏移量,c语言用syscall函数来调用系统调用,但实际上对于大多数系统调用,c语言采用包装函数,包装函数将参数打包在一起,以适当系统调用使指令陷入内核。

系统调用和包装函数统称为系统级函数。在linux的系统调用通常使用寄存器不通过栈传递。

%rax为系统调用号,剩下rdi,rsi,rdx,r10,r8,r9当参数,rax还返回返回值,-4095到-1的负数返回值表示出错

image-20220407165613175

8.2、进程

异常是允许操纵系统内核提供进程概念的基本构造块。

在一个执行中程序的实例就是进程,系统的每个程序都运行在某个进程的上下文中。

上下文是由程序正确运行所需的状态组成的。这个状态包括放在内存中的程序的代码和数据,它的栈,通用目的寄存器的内容,程序技术器,环境变量以及打开文件描述符号的集合。

8.2.1、逻辑控制流

不多解释,已经很清楚

image-20220407171051825

8.2.2、并发流

一个逻辑流的执行在时间上与另一个流重叠,这个就是字面意思,并发运行就是两个程序运行有时间上的交错。

8.2.3、私有地址空间

在一个程序中,进程为其提供自己的私有地址空间,这个空间是不能被别的进程进行r or w。

8.2.4用户模式和内核模式

为了使操作系统内核提供一个无懈可击的进程抽象,处理器必须提供一种机制,限制一个应用可以执行的指令以及它可以访问的地址空间范围

处理器通常使用某个控制寄存器中的一个模式位来提供这种功能,该寄存器在该进程中有特权。当设置了模式位,进程就运行在内核模式中,即超级用户模式。

用户模式改变为内核模式唯一方法就是通过中断,故障或者陷入系统调用这种异常。

linux中存在/proc文件系统,可允许用户访问内核数据结构的内容。

8.2.5、上下文切换

操作系统内核使用上下文切换的较高层形式的异常控制流来实现多任务。在进程执行的时候,内核可以决定抢占当前进程,这就叫调度,由内核中的调度器代码完成。

8.3、进程控制

8.3.1、获取进程ID

每个进程都有自己的PID。

getpid函数返回调用进程的PID。

getppid函数返回它的父进程PID。

8.3.2、创建和终止进程

进程总是有三种状态,

1.运行:要么在cpu上执行,要么就在等待内核的调度

2.停止:进程执行要么被挂起,且不会调度。当收到sigstop,sigtstp,sigttn或者sigttou时,进程就停止,并且停止直到收到sigcont信号,然后运行

3.终止:进程停止,进程停止有三种原因:收到信号,return从主函数,exit

父进程通过调用fork函数创建新子进程,子进程几乎与父进程相同,子进程得到与父进程用户级虚拟地址空间相同的副本,当父进程调用fork时,子进程可以读写父进程中打开的任何文件。父子进程最大区别是PID不同

fork函数被调用一次,却返回两次,一次在调用父进程中,一次是在新创建的子进程中,父进程中,返回子进程的PID。子进程中返回0,通过返回值我们能直到程序是在父进程中进行还是子进程中执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t pid;
int x = 1;
pid = Fork();
if (pid == 0){
printf("child: x = %d\n",++x);
exit(0);
}
printf("parent: x = %d\n",--x);
exit(0);
}

在linux下运行,发现先返回parent是0,再返回child是2,那么以下就是几个特性了:

1.调用1次,返回了两次

2.并发执行:先返回父进程再返回子进程,但实际上来说并不一定,在另一台机器上就可能不是这样的情况

3.相同但是独立的地址空间:子进程和父进程的地址空间以及值什么的都相同,我们发现x的值并无变化,所以再两个进程中是独立的过程,不互相影响

4.共享文件:输出都在屏幕上

image-20220407190742632

8.3.3、回收子进程

image-20220407190946484

如果父进程终止了,内核会安排init进程成为其父进程。init的PID为1,其不会终止时所有进程的祖先。一个进程可以通过waitpid函数来等待其子进程终止或停止。

1
pid_t waitpid(pid_t pid, int *statusp, int options)

1.pid = -1 ,等待的集合就是父进程的所有子进程

pid>0,单独子进程,进程ID为pid

2.修改默认行为

image-20220407194955709

1
2
pid_t wait (int *statusp)
wait(&s) 完全等价于 waitpid(-1, &s, 0)

回收顺序时这台电脑的特殊属性,不确定

8.3.4、进程休眠

1
unsigned int sleep(unsigned int second)

sleep让一个进程挂起一段时间

1
int pause(void

让调用函数休眠,征集到该进程接收到一个信号

8.3.5、加载并运行程序

1
int execv(const char *filename, const char *argv[],const char *envp[])

该函数加载运行可执行文件filename,且带参数argv和环境变量列表envp,找不到filename就返回其调用程序,这个函数调用一次从不返回。

8.4、信号

Linux信号属于软件形式的异常,一个信号就是一个小消息,其通知进程系统种发生了某件类型的事件,如下图:

image-20220409213205635

低层的硬件异常是由内核异常处理程序处理的

8.4.1、信号术语

传送一个信号到目的进程由两个步骤组成:

发送信号:内核通过更新目的进程上下文的状态来发送一个信号给目的进程,或者一个进程调用kill函数,显示的要求内核发信号给目的进程。

接收信号:当目的进程被内核强迫以某种方式对信号的发送做出反应时,就接受了信号

一个发出但没接收到的信号叫做待处理信号,一种类型的待处理信号在一个进程中最多只有一个,其余的都被丢弃。当然还可以通过阻塞这种方式选择性接受信号。

在内核中有一个集合,这个集合有所有信号,一旦接收到信号,这个信号就会从集合中被剔除。

8.4.2、发送信号

发送信号的机制基于进程组这个概念

1.进程组

每个进程属于一个进程组,进程组是由一个正整数进程组ID来标志的。

1
pid_t getpgrp(void);//返回当前进程的id

默认的,一个子进程和其父进程同属于一个进程组

1
int setpgid(pid_t pid, pid_t pgid);//若成功返回0,不成功返回-1,该函数可以改变自己和其他进程的进程组

pid的进程改为pidg,若pid为0,使用当前进程PID,弱pgid为0,用pid的PID为进程组ID,如果进程15213是调用进程,再把两个参数设为0,会创建新的进程组,其ID是15213,并把这个进程加到新进程组中。

2.用/bin/kill程序来发送信号

image-20220409214918203

image-20220409215023731

4.调用kill函数发送信号

1
int kill(pid_t pid, int sig);

若pid大于0,发送信号号码给sig给pid,若等于0发送给进程组每个进程,小于0,发送绝对值的pid到每个进程。

5.alarm函数发送信号

1
unsigned int alarm(unsigned int secs);//返回前一次闹钟秒数,若未设闹钟则为0

该函数安排内核在secs秒后发送SIGALARM信号给调用进程

8.4.3、接收信号

当内核模式变成用户模式时,进程检查未被阻塞的待处理信号的集合,若不为空,该进程接收某个信号,每个信号都有一个预定义默认行为:

进程终止,进程终止并转储内存,进程挂起直到被SIGCONT信号重启,进程忽略该信号

image-20220409220108931

8.4.4、阻塞和解除阻塞信号

隐式阻塞机制。内核默认阻塞任何当前处理程序正在处理信号类型的待处理的信号。

显式阻塞机制。调用函数,来明确阻塞信号

image-20220410205254755

8.4.5、编写信号处理程序

1.安全的信号处理

信号处理程序回合主程序和其他信号处理程序并发运行,要注意以下事项:

image-20220410205657029

输出的唯一安全方法是write,还有一些专门开发函数:

image-20220410205814914

image-20220410210008538

2.正常信号处理

未处理的信号是不排队的,直接被丢弃了。

3.可移植的信号处理

signal函数语义不同,在一些unix系统上,如信号k被捕获后必须将信号k恢复成默认值,所以每次运行后都要调用signal函数,显式的重新设置自己

系统调用可以中断,read write accept这些系统调用会阻塞进程一段进程一段时间,称为慢速系统调用

image-20220412135816648

8.4.6、同步流避免并发错误

看不懂了

8.4.7、显式地等待信号

不懂。

8.5、非本地跳转

c语言提供一种用户级的异常控制流形式,称为非本地跳转,他将控制直接从一个函数转移到另一个当前正在执行的函数,通过setjmp,longjmp函数来提供。

1
2
3
#include<setjmp.h>
int set jmp(jmp_buf, env);
int sigsetjmp(sigjmp_buf env, int savesigs)

env保持调用环境,这个函数返回值为0,但不能赋值给变量

1
2
3
#include<setjmp.h>
void longjmp(jmp_buf env, int retval);
void siglongjmp(sigjmp_buf env, int retval);

8.6、操作进程的工具

Base64编码详解:

这么几个月了,最近做了好多题,也有好多很隐蔽的base64,所以有必要深刻的了解一下base64的编码原理了。

一、base64编码规则:

第一步,将待转换的字符串每三个字节分为一组,每个字节占8bit,那么共有24个二进制位。
第二步,将上面的24个二进制位每6个一组,共分为4组。
第三步,在每组前面添加两个0,每组由6个变为8个二进制位,总共32个二进制位,即四个字节。
第四步,根据Base64编码对照表(见下图)获得对应的值。

就是先转换成二进制,分6分切开,再在前面补两个0,变成9位,算索引,找表即可。

第一步:“M”、“a”、”n”对应的ASCII码值分别为77,97,110,对应的二进制值是01001101、01100001、01101110。如图第二三行所示,由此组成一个24位的二进制字符串。
第二步:如图红色框,将24位每6位二进制位一组分成四组。
第三步:在上面每一组前面补两个0,扩展成32个二进制位,此时变为四个字节:00010011、00010110、00000101、00101110。分别对应的值(Base64编码索引)为:19、22、5、46。
第四步:用上面的值在Base64编码表中进行查找,分别对应:T、W、F、u。因此“Man”Base64编码之后就变为:TWFu。

那么有时候会出现“==”是什么情况呢?

二、base64的补位

当只有一个字符时,不足24位,那么后面就需要补0,不存在的位就需要” = “来取代。

上图很好的表示了补位。

三、base58,base32,base16

base64是切成6份,base32是切成5份,同理base16切成4份。

base58编码方式显然是不一样的,采用辗转相除:

如要将1234转换为58进制;

第一步:1234除于58,商21,余数为16,查表得H

第二步:21除于58,商0,余数为21,查表得N

所以得到base58编码为:NH

四、代码表示

base64的C语言的代码有很明显的特征,我们只需要找到“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”字符串即可,有时候又会变表,那么我们给出一个python变表脚本:

1
2
3
4
5
6
7
8
9
10
11
12
import base64
t1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
t2='nopqrstuvwxyzabcdefghijklm0123456789ABCDEFGHIJKL+/MNOPQRSTUVWXYZ'
data="OBufaa21Td86rWS8Wob8iGhZYocbr5vxZfcCoWv3"
result = ''
flag=""
for ch in data:
result += t1[t2.index(ch)]
result = bytearray(base64.b64decode(result+"=="))
for i in range(len(result)):
flag+=chr(result[i])
print(flag)

RSA详细介绍:

在极客的时候做了好几道RSA的题,现在来详细介绍一下。

RSA是一种非对称加密。

一、生成密钥过程

首先选择两个不相等的质数,分别为p和q,然后算出pq为n,n就是密钥长度。计算欧拉函数,如果n是质数,则 φ(n)=n-1,所以φ(3233) = φ(61x53) = φ(61)φ(53)=60x52=3120。接下来选择一个整数e,且e与φ(n)互质。然后计算模反元素,所谓“模反元素”就是指有一个整数d,可以使得ed除以φ(n)的余数为1,公式表示:ed*≡1(*m**odφ*(n)),即*edkφ(n)=1,所以公钥是(n,e)**,私钥*(n,d)**,则公钥可以发布,私钥自己留着。

二、反解密钥过程

直接给出脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
from gmpy2 import*
from libnum import*
from Crypto.Util.number import long_to_bytes
import gmpy2
n=103461035900816914121390101299049044413950405173712170434161686539878160984549
c=0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
e=65537
p=366669102002966856876605669837014229419
q=282164587459512124844245113950593348271
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=pow(c,int(d),n)
print(n2s(flag))

AES详细介绍:

是一种常见的对称加密方式:加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。AES加密由明文,密钥,加密函数,密文,AES解密函数组成。加密函数是将明文和密钥作为参数传进函数中的,

一、加密

AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。

假设这里使用128位的密钥,加密10轮

设P位明文,我们知道明文是16个字节,我们将这16个字节搞成4×4的矩阵,矩阵的排列顺序为从上到下、从左至右。再将明文矩阵换成对应ascii码成为状态矩阵.

密钥的加密是不一样的

128位密钥也是用字节为单位的矩阵表示,矩阵的每一列被称为1个32位比特字。通过密钥编排函数该密钥矩阵被扩展成一个44个字组成的序列W[0],W[1], … ,W[43],该序列的前4个元素W[0],W[1],W[2],W[3]是原始密钥,用于加密运算中的初始密钥加(下面介绍);后面40个字分为10组,每组4个字(128比特)分别用于10轮加密运算中的轮密钥加,如下图所示:

AES加密分为4个步骤:字节代换、行位移、列混合和轮密钥加

1、字节代换

AES字节代换是一个查表的操作。AES定义了一个S盒和逆S盒。

S盒是一个16×16的表格,我们怎么进行查取呢,一个字节是8位,我们取高4位作为行值,低4位作为列值,按照表格进行查询,然后替换。

2、行移位

行移位是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,如下图所示:

3、列混合

列混合的操作是通过矩阵相乘实现,但乘法实际上是异或

4、轮密钥加

使用P和密钥进行异或,以列位单位,对应位置异或,对应下标相等异或。

二、密钥扩展

我们知道密钥总共存在44列,前4列是我们给出的16位密钥分成的4列,那么后面40列每4列是经过一轮AES函数所搞出来的

这个44矩阵的每一列的4个字节组成一个字,矩阵4列的4个字依次命名为W[0]、W[1]、W[2]和W[3],它们构成一个以字为单位的数组W。例如,设密钥K为”abcdefghijklmnop”,则K0 = ‘a’,K1 = ‘b’, K2 = ‘c’,K3 = ‘d’,W[0] = “abcd”。
接着,对W数组扩充40个新列,构成总共44列的扩展密钥数组。新列以如下的递归方式产生:
1.如果i不是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁W[i-1]
2.如果i是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁T(W[i-1])
其中,T是一个有点复杂的函数。
函数T由3部分组成:字循环、字节代换和轮常量异或,这3部分的作用分别如下。
a.字循环:将1个字中的4个字节循环左移1个字节。即将输入字[b0, b1, b2, b3]变换成[b1,b2,b3,b0]。
b.字节代换:对字循环的结果使用S盒进行字节代换。
c.轮常量异或:将前两步的结果同轮常量Rcon[j]进行异或,其中j表示轮数。
轮常量Rcon[j]是一个字,其值见下表。

下面举个例子:
设初始的128位密钥为:
3C A1 0B 21 57 F0 19 16 90 2E 13 80 AC C1 07 BD
那么4个初始值为:
W[0] = 3C A1 0B 21
W[1] = 57 F0 19 16
W[2] = 90 2E 13 80
W[3] = AC C1 07 BD
下面求扩展的第1轮的子密钥(W[4],W[5],W[6],W[7])。
由于4是4的倍数,所以:
W[4] = W[0] ⨁ T(W[3])
T(W[3])的计算步骤如下:

循环地将W[3]的元素移位:AC C1 07 BD变成C1 07 BD AC;
将 C1 07 BD AC 作为S盒的输入,输出为78 C5 7A 91;
将78 C5 7A 91与第一轮轮常量Rcon[1]进行异或运算,将得到79 C5 7A 91,因此,T(W[3])=79 C5 7A 91,故
W[4] = 3C A1 0B 21 ⨁ 79 C5 7A 91 = 45 64 71 B0
其余的3个子密钥段的计算如下:
W[5] = W[1] ⨁ W[4] = 57 F0 19 16 ⨁ 45 64 71 B0 = 12 94 68 A6
W[6] = W[2] ⨁ W[5] =90 2E 13 80 ⨁ 12 94 68 A6 = 82 BA 7B 26
W[7] = W[3] ⨁ W[6] = AC C1 07 BD ⨁ 82 BA 7B 26 = 2E 7B 7C 9B
所以,第一轮的密钥为 45 64 71 B0 12 94 68 A6 82 BA 7B 26 2E 7B 7C 9B。

三、解密

1、字节代换

查逆S盒

2、行移位

行移位的逆变换是将状态矩阵中的每一行执行相反的移位操作,例如AES-128中,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节。

3、列混合

左乘的为逆变换矩阵,逆变换矩阵与变换矩阵乘积为单位矩阵

4、轮密钥加

轮密钥加的逆运算同正向的轮密钥加运算完全一致

normal14-17

normal14

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
int64 __fastcall main(int a1, char **a2, char **a3)
{
char v4[16]; // [rsp+0h] [rbp-4A0h] BYREF
char v5[16]; // [rsp+10h] [rbp-490h] BYREF
char v6[16]; // [rsp+20h] [rbp-480h] BYREF
char v7[16]; // [rsp+30h] [rbp-470h] BYREF
char v8[112]; // [rsp+40h] [rbp-460h] BYREF
char v9[1000]; // [rsp+B0h] [rbp-3F0h] BYREF
unsigned __int64 v10; // [rsp+498h] [rbp-8h]

v10 = __readfsqword(0x28u);
puts("[sign in]");
printf("[input your flag]: ");
__isoc99_scanf("%99s", v8);
sub_96A(v8, (__int64)v9);
__gmpz_init_set_str((__int64)v7, (__int64)"ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
__gmpz_init_set_str((__int64)v6, (__int64)v9, 16LL);
__gmpz_init_set_str(
(__int64)v4,
(__int64)"103461035900816914121390101299049044413950405173712170434161686539878160984549",
10LL);
__gmpz_init_set_str((__int64)v5, (__int64)"65537", 10LL);
__gmpz_powm((__int64)v6, (__int64)v6, (__int64)v5, (__int64)v4);
if ( (unsigned int)__gmpz_cmp((__int64)v6, (__int64)v7) )
puts("GG!");
else
puts("TTTTTTTTTTql!");
return 0LL;
}

这个题我想查看函数发现没东西,那么证明这个函数是c中自带的,但是这个我感觉好熟悉。看到65537,多半是RSA,当时极客大挑战做过几道,就直接给脚本了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from gmpy2 import*
from libnum import*
from Crypto.Util.number import long_to_bytes
import gmpy2
n=103461035900816914121390101299049044413950405173712170434161686539878160984549
c=0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
e=65537
p=366669102002966856876605669837014229419
q=282164587459512124844245113950593348271
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=pow(c,int(d),n)
print(n2s(flag))
#b'suctf{Pwn_@_hundred_years}'

我们将n分为两个质因数,则剩下的就是c,由此可以求flag

normal16

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
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
DWORD v3; // eax
DWORD v4; // eax
char Str[260]; // [esp+4Ch] [ebp-310h] BYREF
int v7; // [esp+150h] [ebp-20Ch]
char String1[260]; // [esp+154h] [ebp-208h] BYREF
char Destination[260]; // [esp+258h] [ebp-104h] BYREF

memset(Destination, 0, sizeof(Destination));
memset(String1, 0, sizeof(String1));
v7 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", Destination);
if ( strlen(Destination) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
v7 = atoi(Destination); //将Destination转成int类型说明Destination只能是数字,如果有字母,return 0
if ( v7 < 100000 )
ExitProcess(0);
strcat(Destination, "@DBApp"); //六位数字后连接字符串
v3 = strlen(Destination);
sub_40100A((BYTE *)Destination, v3, String1); //第一个函数
if ( !_strcmpi(String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
{
printf("continue...\n\n");
printf("pls input the first passwd(2): ");
memset(Str, 0, sizeof(Str));
scanf("%s", Str);
if ( strlen(Str) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
strcat(Str, Destination); //password2加上password1
memset(String1, 0, sizeof(String1));
v4 = strlen(Str);
sub_401019((BYTE *)Str, v4, String1);
if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", String1) )
{
if ( !(unsigned __int8)sub_40100F(Str) )
{
printf("Error!!\n");
ExitProcess(0);
}
printf("bye ~~\n");
}
}
return 0;
}

这道题只看主函数应该是很好理解的 。

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
int __cdecl sub_401230(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
DWORD i; // [esp+4Ch] [ebp-28h]
CHAR String2[4]; // [esp+50h] [ebp-24h] BYREF
BYTE v6[20]; // [esp+54h] [ebp-20h] BYREF
DWORD pdwDataLen; // [esp+68h] [ebp-Ch] BYREF
HCRYPTHASH phHash; // [esp+6Ch] [ebp-8h] BYREF
HCRYPTPROV phProv; // [esp+70h] [ebp-4h] BYREF

if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
return 0;
if ( CryptCreateHash(phProv, 0x8004u, 0, 0, &phHash) )
{
if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
{
CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0);
*lpString1 = 0;
for ( i = 0; i < pdwDataLen; ++i )
{
wsprintfA(String2, "%02X", v6[i]);
lstrcatA(lpString1, String2);
}
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 1;
}
else
{
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 0;
}
}
else
{
CryptReleaseContext(phProv, 0);
return 0;
}
}

这个里面全是api函数,根据参数来确定是哪种hash加密。0x8004u对应sha1加密,我学习了一下脚本的写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib
password1 = ""
arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
for i1 in arr:
for i2 in arr:
for i3 in arr:
for i4 in arr:
for i5 in arr:
for i6 in arr:
password1 = i1 + i2 + i3 + i4 + i5 + i6 + "@DBApp"
if(hashlib.sha1(password1.encode("utf-8")).hexdigest().upper() =="6E32D0943418C2C33385BC35A1470250DD8923A9"):
print(password1)
break
#hash引入hashlib库,用hashlib.sha1(a.encode("utf-8"))来编码,要指名编码的格式,不然会报错,hexdigest函数是转换成16进制,upper是将小写转换成大写。
#password1=123321@DBApp

从参数来看第二个函数:

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
int __cdecl sub_401040(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
DWORD i; // [esp+4Ch] [ebp-24h]
CHAR String2[4]; // [esp+50h] [ebp-20h] BYREF
BYTE v6[16]; // [esp+54h] [ebp-1Ch] BYREF
DWORD pdwDataLen; // [esp+64h] [ebp-Ch] BYREF
HCRYPTHASH phHash; // [esp+68h] [ebp-8h] BYREF
HCRYPTPROV phProv; // [esp+6Ch] [ebp-4h] BYREF

if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
return 0;
if ( CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash) )
{
if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
{
CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0);
*lpString1 = 0;
for ( i = 0; i < pdwDataLen; ++i )
{
wsprintfA(String2, "%02X", v6[i]);
lstrcatA(lpString1, String2);
}
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 1;
}
else
{
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 0;
}
}
else
{
CryptReleaseContext(phProv, 0);
return 0;
}
}

参数为:0x8003u是个md5函数,但md5爆破的话是很慢的。所以我们找到最后对比时的函数:

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
char __cdecl sub_4014D0(LPCSTR lpString)
{
LPCVOID lpBuffer; // [esp+50h] [ebp-1Ch]
DWORD NumberOfBytesWritten; // [esp+58h] [ebp-14h] BYREF
DWORD nNumberOfBytesToWrite; // [esp+5Ch] [ebp-10h]
HGLOBAL hResData; // [esp+60h] [ebp-Ch]
HRSRC hResInfo; // [esp+64h] [ebp-8h]
HANDLE hFile; // [esp+68h] [ebp-4h]

hFile = 0;
hResData = 0;
nNumberOfBytesToWrite = 0;
NumberOfBytesWritten = 0;
hResInfo = FindResourceA(0, (LPCSTR)0x65, "AAA");
if ( !hResInfo )
return 0;
nNumberOfBytesToWrite = SizeofResource(0, hResInfo);
hResData = LoadResource(0, hResInfo);
if ( !hResData )
return 0;
lpBuffer = LockResource(hResData);
sub_401005(lpString, (int)lpBuffer, nNumberOfBytesToWrite);
hFile = CreateFileA("dbapp.rtf", 0x10000000u, 0, 0, 2u, 0x80u, 0);
if ( hFile == (HANDLE)-1 )
return 0;
if ( !WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0) )
return 0;
CloseHandle(hFile);
return 1;
}

查阅了一下:FindResourceA:确定指定模块中指定类型和名称的资源的位置。

RTF格式:{\rtf1\ansiHello!\parThis is some {\b bold} text.\par}

我们分析一下,首先用ResourceHacker软件查找名为“AAA”的资源并取出数据,接着进入sub_401005,取出的数据跟

输入的密码2+输入的密码1+“@DBApp”进行了异或,最后生成了.rtf文件,最后的flag应该就在.rtf文件里。

那么如何求密码2呢,我们只需要找到rtf文件将其文件头和AAA前6位异或就行了

1
2
3
4
5
6
7
8
9
rtf="{\\rtf1"
AAA=[0x05,0x7D,0x41,0x15,0x26,0x01]
password2=""
for i in range(6):
password2 += chr(AAA[i] ^ ord(rtf[i]))
print(password2)
#~!3a@0


我们运行程序输入密码,回出现一个文件里面存有flag

Flag{N0_M0re_Free_Bugs}

normal17

刚开始没法反编译,

我们找到这里,是栈帧不平衡导致的,将pop处的改为0x0,即可。修改的原则是,只需在出现负数的那个地方的上一行,按alt+k,调整成跟这个数一摸一样的值就可以了。

我们找到main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
HANDLE Thread; // [esp+D0h] [ebp-14h]
HANDLE hObject; // [esp+DCh] [ebp-8h]

sub_4110FF();
::hObject = CreateMutexW(0, 0, 0);
j_strcpy(Destination, &Source);
hObject = CreateThread(0, 0, StartAddress, 0, 0, 0);
Thread = CreateThread(0, 0, sub_41119F, 0, 0, 0);
CloseHandle(hObject);
CloseHandle(Thread);
while ( dword_418008 != -1 )
;
sub_411190();
CloseHandle(::hObject);
return 0;
}

稍微能看懂一点,hObject一般代表句柄,CreateThread代表着创建线程,看来这个题创建了两个线程.

  1. 进程
    进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

  2. 线程
    线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

一个正在运行的软件(如迅雷)就是一个进程,一个进程可以同时运行多个任务( 迅雷软件可以同时下载多个文件,每个下载任务就是一个线程), 可以简单的认为进程是线程的集合。

  • 对于单核CPU而言:多线程就是一个CPU在来回的切换,在交替执行。
  • 对于多核CPU而言:多线程就是同时有多条执行路径在同时(并行)执行,每个核执行一个线程,多个核就有可能是一块同时执行的。

第一个线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
char *__cdecl sub_411940(int a1, int a2)
{
char *result; // eax
char v3; // [esp+D3h] [ebp-5h]

v3 = *(_BYTE *)(a2 + a1);
if ( (v3 < 'a' || v3 > 122) && (v3 < 65 || v3 > 90) )
exit(0);
if ( v3 < 97 || v3 > 122 )
{
result = off_418000[0];
*(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 38];
}
else
{
result = off_418000[0];
*(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 96];
}
return result;
}

这个线程的很清楚,就是加加减减。

第二个线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
void __stdcall __noreturn sub_411B10(int a1)
{
while ( 1 )
{
WaitForSingleObject(hObject, 0xFFFFFFFF);
if ( dword_418008 > -1 )
{
Sleep(0x64u);
--dword_418008;
}
ReleaseMutex(hObject);
}
}

CreateThread API 会创建新线程,这个题是一个典型的双线程问题.CreateMutex 创建一个互斥体,用于防止多线程中出现资源争用,即多个线程同时读写同一个资源的情况,所创建的互斥体的句柄会存到全局变量 hObject 中,WaitForSingleObject 等待互斥体的使用权空闲出来,并获取使用权,然后再访问和其他线程共享的资源,访问完后,用 ReleaseMutex 释放使用权,给其他线程使用的机会。那么这两个线程共享的数据是什么呢,看参数我们就知道是dword_418008。

这两个线程一前一后创建,理论上是 StartAddress 先获得使用权,后来的 sub_41119F 进入等待状态,前者执行一次循环后释放使用权,与此同时后者等待结束、获得使用权,进入循环,循环完后释放使用权,前者又获得使用权,如此循环往复。

所以就相当于我给出的字符串是第一位照抄,第二位进行线程一的变化。经过线程后与Source对比

1
2
3
4
5
6
7
8
9
10
int sub_411880()
{
int i; // [esp+D0h] [ebp-8h]
for ( i = 0; i < 29; ++i )
{
if ( Source[i] != off_418004[i] )
exit(0);
}
return printf("\nflag{%s}\n\n", Destination);
}

给出脚本:

1
2
3
4
5
6
7
8
9
10
11
12
data1="TOiZiZtOrYaToUwPnToBsOaOapsyS"
data2="QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"
flag=""
for i in range(len(data1)):
if i%2==0:
flag+=data1[i]
else:
if ord(data1[i])>ord('a') and ord(data1[i])<ord('z'):
flag+=chr(data2.find(data1[i])+38)
else:
flag+=chr(data2.find(data1[i])+96)
print(flag)

最后这个E是什么都行,因为dword_418008只有29位!

得到ThisisthreadofwindowshahaIsES

normal1

共有三道逆向,先做第一道:

看着挺简单的,就是异或,然后比较字符串,但一看见sub_A84这个函数,我就觉得不太对劲。

点开后,果真如我所想,不会那么简单。

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
_BYTE *__fastcall sub_A84(__int64 a1, _BYTE *a2)
{
_BYTE *result; // rax
char v4; // [rsp+19h] [rbp-7h]
unsigned __int8 v5; // [rsp+1Ah] [rbp-6h]
unsigned __int8 i; // [rsp+1Bh] [rbp-5h]
int v7; // [rsp+1Ch] [rbp-4h]

v4 = 0;
v5 = 0;
v7 = 0;
while ( *(_BYTE *)(v7 + a1) )
{
*a2++ = sub_7FA((unsigned __int8)(((int)*(unsigned __int8 *)(v7 + a1) >> (v5 + 2)) | v4));
v5 = (v5 + 2) & 7;
v4 = 0;
for ( i = 0; i < v5; ++i )
v4 |= ((1 << i) & *(unsigned __int8 *)(v7 + a1)) << (6 - v5);
if ( v5 <= 5u )
++v7;
}
result = a2;
*a2 = 0;
return result;
}

我在仔细一瞧,还有个sub_7EA这个函数

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
194
195
196
197
198
199
200
201
202
203
204
int64 __fastcall sub_7FA(char a1)
{
__int64 result; // rax

switch ( a1 )
{
case 0:
result = 110LL;
break;
case 1:
result = 111LL;
break;
case 2:
result = 112LL;
break;
case 3:
result = 113LL;
break;
case 4:
result = 114LL;
break;
case 5:
result = 115LL;
break;
case 6:
result = 116LL;
break;
case 7:
result = 117LL;
break;
case 8:
result = 118LL;
break;
case 9:
result = 119LL;
break;
case 10:
result = 120LL;
break;
case 11:
result = 121LL;
break;
case 12:
result = 122LL; //以上可一起表示
break;
case 13:
result = 97LL;
break;
case 14:
result = 98LL;
break;
case 15:
result = 99LL;
break;
case 16:
result = 100LL;
break;
case 17:
result = 101LL;
break;
case 18:
result = 102LL;
break;
case 19:
result = 103LL;
break;
case 20:
result = 104LL;
break;
case 21:
result = 105LL;
break;
case 22:
result = 106LL;
break;
case 23:
result = 107LL;
break;
case 24:
result = 108LL;
break;
case 25:
result = 109LL; //可一起表示
break;
case 26:
result = 48LL;
break;
case 27:
result = 49LL;
break;
case 28:
result = 50LL;
break;
case 29:
result = 51LL;
break;
case 30:
result = 52LL;
break;
case 31:
result = 53LL;
break;
case 32:
result = 54LL;
break;
case 33:
result = 55LL;
break;
case 34:
result = 56LL;
break;
case 35:
result = 57LL;
break;
case 36:
result = 65LL;
break;
case 37:
result = 66LL;
break;
case 38:
result = 67LL;
break;
case 39:
result = 68LL;
break;
case 40:
result = 69LL;
break;
case 41:
result = 70LL;
break;
case 42:
result = 71LL;
break;
case 43:
result = 72LL;
break;
case 44:
result = 73LL;
break;
case 45:
result = 74LL;
break;
case 46:
result = 75LL;
break;
case 47:
result = 76LL; //可一起表示
break;
case 48:
result = 43LL; //单独表示
break;
case 49:
result = 47LL; //单独表示
break;
case 50:
result = 77LL;
break;
case 51:
result = 78LL;
break;
case 52:
result = 79LL;
break;
case 53:
result = 80LL;
break;
case 54:
result = 81LL;
break;
case 55:
result = 82LL;
break;
case 56:
result = 83LL;
break;
case 57:
result = 84LL;
break;
case 58:
result = 85LL;
break;
case 59:
result = 86LL;
break;
case 60:
result = 87LL;
break;
case 61:
result = 88LL;
break;
case 62:
result = 89LL;
break;
case 63:
result = 90LL; //一起表示
break;
default:
result = 63LL; //单独表示
break;
}
return result;
}

很明显是一个转换字符的操作,可用python写脚本。我们返回sub_A84函数,深刻了解一下原理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
v4 = 0;
v5 = 0;
v7 = 0;
while ( *(_BYTE *)(v7 + a1) )
{
*a2++ = sub_7FA((unsigned __int8)(((int)*(unsigned __int8 *)(v7 + a1) >> (v5 + 2)) | v4)); //将a1数组右移(v5+2),即舍去(v5+2)项,再进入sub_7EAh
v5 = (v5 + 2) & 7; //用动态调试测出值
v4 = 0;
for ( i = 0; i < v5; ++i )
v4 |= ((1 << i) & *(unsigned __int8 *)(v7 + a1)) << (6 - v5); //左移
if ( v5 <= 5u )
++v7;
}
result = a2;
*a2 = 0;
return result;

a1是一个数组,对应每个循环过后,如果v5<=5,v7++,那么我们先观察v5,v5进行取余操作,又进行循环,对v4进行进一步操作。这个时候,我们是可以算出v5可以取:0,2,4,6(当v5=6时)就要进行下一轮操作。看第二行的操作是什么,a2是数组,该操作是将a1数组中的值右移(v5+2)个操作数,再与v4进行 “|” 运算。v4的值是什么,我们通过动态调试发现v4的值是与上一轮循环时a1数组的值保持一致的,所以我们要进行三轮这个操作,而这三轮操作是对于四个数组进行的。由于太菜,还是用c++写吧:

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
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int sub_A84(int a1)
{
if(a1>=110&&a1<=122)
return a1-110+0;
if(a1>=97&&a1<=109)
return a1-97+13;
if(a1>=48&&a1<=57)
return a1-48+26;
if(a1>=65&&a1<=76)
return a1-65+36;
if(a1==43)
return 48;
if(a1==47)
return 49;
if(a1>=77&&a1<=90)
return a1-77+50;
if(a1==63)
return 64;
}
int main()
{
int j=0,a4=0;
char s2[]="OBufaa21Td86rWS8Wob8iGhZYocbr5vxZfcCoWv3";
int len = strlen(s2);
char data[100];
for(int i=0;i<len;i=i+4)
{
data[j+0]=((sub_A84(s2[i+0])&0xff)<<2)|((sub_A84(s2[i+1])>>4));
data[j+1]=((sub_A84(s2[i+1])&0xff)<<4)|((sub_A84(s2[i+2])>>2));
data[j+2]=((sub_A84(s2[i+2])&0xff)<<6)|((sub_A84(s2[i+3])>>0));
j+=3;
}
for(int i=0;i<30;i++)
{
if((i&1)!=0)
data[i]^=0x60;
else
data[i]^=0x91;
printf("%c",data[i]);
}
return 0;
}

得到:C1CTF{th1s_Bas364_is_qcjlCwgS}

这是base64?有些疑惑,下一篇好好研究一下base64,有些忘了。。。

我稍微看了一下base64,发现这个代码就是base64源码。。。还是我太不熟悉了:

给出base64脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import base64
t1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
t2='nopqrstuvwxyzabcdefghijklm0123456789ABCDEFGHIJKL+/MNOPQRSTUVWXYZ'
data='OBufaa21Td86rWS8Wob8iGhZYocbr5vxZfcCoWv3'
result = ''
flag=""
for ch in data:
result += t1[t2.index(ch)]
result = bytearray(base64.b64decode(result+"=="))
for i in range(len(result)):
if((i&1)!=0):
flag +=chr(result[i]^0x60)
else:
flag +=chr(result[i]^0x91)

print(flag)

base64诚然不欺我!

normal2

这个题有些难度,找了一下wp参考了一下,原来是aes加密,记得在二面也有一道aes题没做出来,看来要仔细学一下了。

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned __int8 *v3; // rdi
__int64 v4; // rsi
char *v5; // rbx
__int64 v6; // rdx
__int64 v7; // r8
CHAR String1[192]; // [rsp+20h] [rbp-118h] BYREF
__int64 Buffer[8]; // [rsp+E0h] [rbp-58h] BYREF

memset(Buffer, 0, sizeof(Buffer));
sub_7FF619B814F0("Please enter flag:", argv, envp);
gets_s((char *)Buffer, 0x40ui64);
sub_7FF619B81000(String1);
sub_7FF619B812A0((unsigned __int8 *)Buffer, (__int64)String1);
memset(String1, 0, 0x64ui64);
v3 = (unsigned __int8 *)Buffer;
v4 = 32i64;
v5 = String1;
do
{
sub_7FF619B81550(v5, "%.2x", *v3);
v5 += 2;
++v3;
--v4;
}
while ( v4 );
if ( lstrcmpA(String1, "934d8706bed74cd6eea683c7be86b2eb32616562363039383965386433333531") )
exit(0);
sub_7FF619B814F0("successful!\nplease entry any key exit...", v6, v7);
fgetchar();
return 0;
}

这个题有三个比较重要的地方sub_7FF619B81000函数和sub_7FF619B812A0函数和do-while循环中的函数。

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
char __fastcall sub_7FF619B81000(_BYTE *a1)
{
_BYTE *v1; // r9
char v2; // r11
unsigned int v3; // er10
unsigned __int64 v4; // r14
__int64 v5; // r8
unsigned __int8 v6; // bl
unsigned __int8 v7; // di
unsigned __int8 v8; // si
unsigned __int8 v9; // bp
__int64 v10; // rdx
char v11; // bl
__int64 v12; // rax
__int64 v13; // r8
char result; // al

v1 = a1 + 18;
*a1 = byte_7FF619B9DA40;
v2 = 4;
a1[1] = byte_7FF619B9DA41;
v3 = 16;
v4 = 4i64;
a1[2] = byte_7FF619B9DA42;
a1[3] = byte_7FF619B9DA43;
a1[4] = byte_7FF619B9DA44;
a1[5] = byte_7FF619B9DA45;
a1[6] = byte_7FF619B9DA46;
a1[7] = byte_7FF619B9DA47;
a1[8] = byte_7FF619B9DA48;
a1[9] = byte_7FF619B9DA49;
a1[10] = byte_7FF619B9DA4A;
a1[11] = byte_7FF619B9DA4B;
a1[12] = byte_7FF619B9DA4C;
a1[13] = byte_7FF619B9DA4D;
a1[14] = byte_7FF619B9DA4E;
a1[15] = byte_7FF619B9DA4F;
do
{
v5 = v3 - 4;
v6 = a1[v5];
v7 = a1[(unsigned int)(v5 + 1)];
v8 = a1[(unsigned int)(v5 + 2)];
v9 = a1[(unsigned int)(v5 + 3)];
if ( (v2 & 3) == 0 )
{
v10 = v6;
v11 = byte_7FF619B9AC50[v7];
v7 = byte_7FF619B9AC50[v8];
v12 = v9;
v9 = byte_7FF619B9AC50[v10];
v8 = byte_7FF619B9AC50[v12];
v6 = byte_7FF619B9AC50[(v4 >> 2) + 512] ^ v11;
}
v13 = v3 - 16;
++v2;
++v4;
*(v1 - 2) = v6 ^ a1[v13];
v3 += 4;
*(v1 - 1) = v7 ^ a1[(unsigned int)(v13 + 1)];
*v1 = v8 ^ a1[(unsigned int)(v13 + 2)];
result = v9 ^ a1[(unsigned int)(v13 + 3)];
v1[1] = result;
v1 += 4;
}
while ( v3 < 0xB0 );
return result;
}

在第一个函数是aes的一部分对密钥进行处理,我们可以找到这16位key{0x1b,0x2e,0x35,0x46,0x58,0x6e,0x72,0x86,0x9b,0xa7,0xb5,0xc8,0xd9,0xef,0xff,0xc}

__

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
int64 __fastcall sub_7FF619B812A0(unsigned __int8 *a1, __int64 a2)
{
unsigned __int8 *v2; // rbx
__int64 v3; // rsi
unsigned __int8 *v4; // r8
__int64 v5; // r9
__int64 v6; // rcx
__int64 v7; // rdi
__int64 v8; // rbp
unsigned __int8 *v9; // r8
__int64 v10; // r9
unsigned __int8 *v11; // rcx
__int64 v12; // rdx
__int64 v13; // rax
unsigned __int8 v14; // cl
unsigned __int8 v15; // al
unsigned __int8 v16; // cl
unsigned __int8 v17; // al
unsigned __int8 v18; // cl
unsigned __int8 v19; // al
unsigned __int8 v20; // cl
unsigned __int8 v21; // al
unsigned __int8 *v22; // rax
__int64 v23; // r8
__int64 v24; // rdx
unsigned __int8 *v25; // r8
__int64 v26; // r9
unsigned __int8 *v27; // rcx
__int64 v28; // rdx
__int64 v29; // rax
__int64 v30; // rdx
unsigned __int8 v31; // cl
unsigned __int8 v32; // al
unsigned __int8 v33; // cl
unsigned __int8 v34; // al
unsigned __int8 v35; // cl
unsigned __int8 v36; // al
unsigned __int8 v37; // cl
__int64 v38; // rcx
__int64 result; // rax

v2 = a1;
v3 = a2 - (_QWORD)a1;
v4 = a1;
v5 = 4i64;
do
{
v6 = 4i64;
do
{
*v4 ^= v4[v3];
++v4;
--v6;
}
while ( v6 );
--v5;
}
while ( v5 );
v7 = v3 + 16;
v8 = 9i64;
do
{
v9 = v2;
v10 = 4i64;
do
{
v11 = v9;
v12 = 4i64;
do
{
v13 = *v11;
v11 += 4;
*(v11 - 4) = byte_7FF619B9AC50[v13];
--v12;
}
while ( v12 );
++v9;
--v10;
}
while ( v10 );
v14 = v2[1];
v2[1] = v2[5];
v2[5] = v2[9];
v2[9] = v2[13];
v15 = v2[10];
v2[13] = v14;
v16 = v2[2];
v2[2] = v15;
v17 = v2[14];
v2[10] = v16;
v18 = v2[6];
v2[6] = v17;
v19 = v2[15];
v2[14] = v18;
v20 = v2[3];
v2[3] = v19;
v2[15] = v2[11];
v21 = v2[7];
v2[7] = v20;
v2[11] = v21;
sub_7FF619B811B0(v2, 0i64, v9);
v22 = v2;
v23 = 4i64;
do
{
v24 = 4i64;
do
{
*v22 ^= v22[v7];
++v22;
--v24;
}
while ( v24 );
--v23;
}
while ( v23 );
v7 += 16i64;
--v8;
}
while ( v8 );
v25 = v2;
v26 = 4i64;
do
{
v27 = v25;
v28 = 4i64;
do
{
v29 = *v27;
v27 += 4;
*(v27 - 4) = byte_7FF619B9AC50[v29];
--v28;
}
while ( v28 );
++v25;
--v26;
}
while ( v26 );
v30 = 4i64;
v31 = v2[1];
v2[1] = v2[5];
v2[5] = v2[9];
v2[9] = v2[13];
v32 = v2[10];
v2[13] = v31;
v33 = v2[2];
v2[2] = v32;
v34 = v2[14];
v2[10] = v33;
v35 = v2[6];
v2[6] = v34;
v36 = v2[15];
v2[14] = v35;
v37 = v2[3];
v2[3] = v36;
v2[15] = v2[11];
v2[11] = v2[7];
v2[7] = v37;
do
{
v38 = 4i64;
do
{
result = v2[v3 + 160];
*v2++ ^= result;
--v38;
}
while ( v38 );
--v30;
}
while ( v30 );
return result;
}

第二个函数是对前16位进行了加密,但后16位并没有变化

1
2
3
4
5
6
7
8
9
10
11
12
13
int sub_7FF619B81550(char *Buffer, char *Format, ...)
{
_QWORD *v4; // rax
int result; // eax
va_list va; // [rsp+60h] [rbp+18h] BYREF

va_start(va, Format);
v4 = (_QWORD *)sub_7FF619B814E0();
result = _stdio_common_vsprintf(*v4 | 1i64, Buffer, 0xFFFFFFFFFFFFFFFFui64, Format, 0i64, va);
if ( result < 0 )
return -1;
return result;
}

do-while函数是将每一个字符的16进制拆成了两位,如0x28就变成0x2和0x8,这样的函数第一次见,我觉得下次还会再见到的

那么我们可以直接根据比较数据的后32位 ’32616562363039383965386433333531‘每两位一组写出flag的后16为 ’2aeb60989e8d3351‘

那么前16位就要写脚本了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
L1=[0x1b,0x2e,0x35,0x46,0x58,0x6e,0x72,0x86,0x9b,0xa7,0xb5,0xc8,0xd9,0xef,0xff,0xc]

for i in range(len(L1)):

L1[i] = chr( L1[i])

key = ''. join( L1)

aes = AES.new(key, AES.MODE_ECB)

L2=[0x93,0x4d,0x87,0x06,0xbe,0xd7,0x4c,0xd6,0xee,0xa6,0x83,0xc7,0xbe,0x86,0xb2,0xeb]

for i in range(len(L2)):

L2[i] = chr( L2[i])

cipher = ''. join( L2)

plain = aes.decrypt( cipher)

print plain

上面是python2的脚本,近期学业繁忙,待我到暑假,把基础打牢,近些天就把逆向基础看一下,等csapp到了我就两本一起来看,反正无论如何寒假时把写脚本这个打牢!

normal3

这道题实际上就是要找到递归算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
__int64 __fastcall main(int a1, char **a2, char **a3)
{
puts("Input flag:");
__isoc99_scanf("%64s", &a);
b = 0;
fun2(0LL);
if ( !strcmp(&s1, "bcec8d7dcda25d91ed3e0b720cbb6cf202b09fedbc3e017774273ef5d5581794") )
{
memset(&s1, 0, 0x80uLL);
b = 0;
fun(0LL);
if ( !strcmp(&s1, "7d8dcdcaed592e1dcb07e02c36bcb2f0bf9e0bdcb0e13777237e25fd48515974") )
printf("TQL! TQL! flag: nctf{%s}\n", &a);
else
puts("Emmmm.....");
return 0LL;
}
else
{
puts("GG!");
return 0LL;
}
}

我们跟进fun和fun2函数,发现这就是个算法,二者是很像的,所以想到一个好主意,我们只要随便输一个字符串,然后观察进入这个函数后改字符串位置变化,就可以倒推找到原码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int64 __fastcall fun2(int a1)
{
int v1; // eax
__int64 result; // rax

if ( a1 <= 63 )
{
v1 = b++;
*(&s1 + v1) = a[a1];
fun2((unsigned int)(2 * a1 + 1));
return fun2((unsigned int)(2 * (a1 + 1)));
}
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int64 __fastcall fun(int a1)
{
int v1; // eax
__int64 result; // rax

if ( a1 <= 63 )
{
fun((unsigned int)(2 * a1 + 1));
v1 = b++;
*(&s1 + v1) = a[a1];
return fun((unsigned int)(2 * (a1 + 1)));
}
return result;
}


我们动态调试一下,输入下面的信息:

1
2
3
4
abcdefghijklmnop
qrstuvwsyzABCDEF
GHIJKLMNOPQRSTUV
WXYZ0123456789+=

经过fun2函数得到下面的字符串。

1
2
3
4
abdhpF=GqHIirJKs
LMejtNOuPQkvRSwT
UcflsVWyXYmzZ0A1
2gnB34C56oD78E9+

我们的fun2变过后的字符串:

1
2
3
4
bcec8d7dcda25d91
ed3e0b720cbb6cf2
02b09fedbc3e0177
74273ef5d5581794

则我们原来的字符串:

1
2
3
4
bc2e3b4c2eb03258
c5102bf9de77f57d
ddad9edb70c6c20f
ebc01773e5d81947

​ 这样就得到了flag

nctf{bc2e3b4c2eb03258c5102bf9de77f57dddad9edb70c6c20febc01773e5d81947}

其实,想一下,如果是逆算法的话,也不过是把位置顺序逆出来,其实跟我这样是没有差别的。

normal4

本题不是算法题,题目很容易看懂

对了这个题还得upx脱壳一下,比较简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // kr00_4
char Buffer[40]; // [esp+4h] [ebp-2Ch] BYREF

memset(Buffer, 0, sizeof(Buffer));
printf("Welcome The System\nPlease Input Key:");
gets_s(Buffer, 0x28u);
v3 = strlen(Buffer);
if ( (unsigned int)(v3 - 35) <= 2 )
{
if ( sub_401090((int)Buffer, v3) == 1 )
printf("Well Done!\n");
else
printf("Your Wrong!\n");
}
return 0;
}

在这里面能看出我们的flag长度小于37,那么最重要的函数就是sub_401090函数,进入:

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
int __fastcall sub_401090(int a1, int a2)
{
int v4; // edx
char v5; // al
int v6; // esi
int v7; // edi
char v8; // al
int v9; // eax
char v10; // cl
int v11; // eax
int v12; // ecx

if ( a2 != 35 ) // 长度为35
return -1;
v4 = 0;
while ( 1 )
{
v5 = *(_BYTE *)(v4 + a1);
v6 = (v5 >> 4) % 16;
v7 = ((16 * v5) >> 4) % 16;
v8 = byte_402150[2 * v4];
if ( v8 < 48 || v8 > 57 )
v9 = v8 - 87;
else
v9 = v8 - 48;
v10 = byte_402151[2 * v4];
v11 = 16 * v9;
if ( v10 < 48 || v10 > 57 )
v12 = v10 - 87;
else
v12 = v10 - 48;
if ( (unsigned __int8)byte_4021A0[16 * v6 + v7] != ((v11 + v12) ^ 0x19) )
break;
if ( ++v4 >= 35 )
return 1;
}
return -1;
}

byte_402150数组,byte_402151数组,byte_4021A0数组是我们的重点,这个题我觉得比较好的地方就是进入byte_402150数组时,发现就一个数,那么怎么找到这个数组他的地址时00402150,我们转到16进制去看:

1
2
3
4
5
00402150  32 61 34 39 66 36 39 63  33 38 33 39 35 63 64 65  2a49f69c38395cde
00402160 39 36 64 36 64 65 39 36 64 36 66 34 65 30 32 35 96d6de96d6f4e025
00402170 34 38 34 39 35 34 64 36 31 39 35 34 34 38 64 65 484954d6195448de
00402180 66 36 65 32 64 61 64 36 37 37 38 36 65 32 31 64 f6e2dad67786e21d
00402190 35 61 64 61 65 36 00 00 00 00 00 00 00 00 00 00 5adae6..........

我们发现原来byte_402150数组就是比byte_402151数组多了一个2,我们给出一个爆破脚本,话说好久没写爆破脚本了,上一次是在二面的第三题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
byte_402150 = '2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6'
byte_402151 = 'a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6'
data2=[0x63, 0x7C, 0x77, 0x7B, 0x0F2, 0x6B, 0x6F, 0x0C5, 0x30, 0x1, 0x67, 0x2B, 0x0FE,
0x0D7, 0x0AB, 0x76, 0x0CA, 0x82, 0x0C9, 0x7D, 0x0FA, 0x59, 0x47, 0x0F0, 0x0AD, 0x0D4, 0x0A2, 0x0AF, 0x9C, 0x0A4, 0x72, 0x0C0, 0x0B7, 0x0FD, 0x93, 0x26, 0x36, 0x3F, 0x0F7, 0x0CC, 0x34, 0x0A5, 0x0E5, 0x0F1, 0x71, 0x0D8, 0x31, 0x15, 0x4, 0x0C7, 0x23, 0x0C3, 0x18, 0x96, 0x5,0x9A, 0x7, 0x12, 0x80, 0x0E2, 0x0EB, 0x27, 0x0B2, 0x75, 0x9, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0x0A0, 0x52, 0x3B, 0x0D6, 0x0B3, 0x29, 0x0E3, 0x2F, 0x84, 0x53, 0x0D1, 0x0, 0x0ED, 0x20, 0x0FC, 0x0B1, 0x5B, 0x6A, 0x0CB, 0x0BE, 0x39, 0x4A, 0x4C, 0x58, 0x0CF, 0x0D0, 0x0EF, 0x0AA, 0x0FB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0x0F9, 0x2, 0x7F, 0x50, 0x3C, 0x9F, 0x0A8, 0x51, 0x0A3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0x0F5, 0x0BC, 0x0B6, 0x0DA, 0x21, 0x10, 0x0FF, 0x0F3, 0x0D2, 0x0CD, 0x0C, 0x13, 0x0EC, 0x5F, 0x97, 0x44, 0x17, 0x0C4, 0x0A7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0x0DC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0x0EE, 0x0B8, 0x14, 0x0DE, 0x5E, 0x0B, 0x0DB, 0x0E0, 0x32, 0x3A, 0x0A, 0x49, 0x6, 0x24, 0x5C, 0x0C2, 0x0D3, 0x0AC, 0x62, 0x91, 0x95, 0x0E4, 0x79, 0x0E7, 0x0C8, 0x37, 0x6D, 0x8D, 0x0D5, 0x4E, 0x0A9, 0x6C, 0x56, 0x0F4, 0x0EA, 0x65, 0x7A, 0x0AE, 0x8, 0x0BA, 0x78, 0x25, 0x2E, 0x1C, 0x0A6, 0x0B4, 0x0C6, 0x0E8, 0x0DD, 0x74, 0x1F, 0x4B, 0x0BD, 0x8B, 0x8A, 0x70, 0x3E, 0x0B5, 0x66, 0x48, 0x3, 0x0F6, 0x0E, 0x61, 0x35, 0x57, 0x0B9, 0x86, 0x0C1, 0x1D, 0x9E, 0x0E1, 0x0F8, 0x98, 0x11, 0x69, 0x0D9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0x0E9, 0x0CE, 0x55, 0x28, 0x0DF, 0x8C, 0x0A1, 0x89, 0x0D, 0x0BF, 0x0E6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0x0B0, 0x54, 0x0BB, 0x16]
flag=""
for i in range(35): //i相当于v4
v8=ord(byte_402150[2*i])
if v8<48 or v8>57:
v9=v8-87
else:
v9=v8-48
v10=ord(byte_402151[2*i])
v11=16*v9
if v10<48 or v10>57:
v12=v10-87
else:
v12=v10-48
for j in range(16,127): //j相当于v5
v6=(j>>4)%16
v7=((16*j)>>4)%16
if data2[16*v6+v7]==((v11+v12)^0x19):
flag+=chr(j)
print(flag)

得到flag{Th1s_1s_Simple_Rep1ac3_Enc0d3}

normal5

这是一类叫VM类型的题,第一次见,先写一下vm类型的题是什么意思。

vm逆向
首先这里的虚拟机往往不是商业的vmp之类的保护软件,而是出题人实现的小型虚拟机,题目本身一般也没有实现某些复杂的功能。

基本原理
这里的虚拟机当然并不是指VMWare或者VirtualBox之类的虚拟机,而是指的意思是一种解释执行系统或者模拟器(Emulator)。
逆向中的虚拟机保护是一种基于虚拟机的代码保护技术。它将基于x86汇编系统中的可执行代码转换为字节码指令系统的代码,来达到不被轻易逆向和篡改的目的。简单点说就是将程序的代码转换自定义的操作码(opcode),然后在程序执行时再通过解释这些操作码,选择对应的函数执行,从而实现程序原有的功能。

总之vm类型的题一般是将指令变为作者想要的形式,找到特征,执行相应特征。

vm包括三个系统

vm_start:

虚拟机的入口函数,对虚拟机环境进行初始化

vm_dispatcher:

调度器,解释opcode,并选择对应的handle函数执行,当handle执行完后会跳回这里,形成一个循环。

opcode :

程序可执行代码转换成的操作码

__

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int64 __fastcall main(int a1, char **a2, char **a3)
{
char v4; // [rsp+Bh] [rbp-5h]
int i; // [rsp+Ch] [rbp-4h]

puts("[WxyVM 0.0.1]");
puts("input your flag:");
scanf("%s", &byte_604B80);
v4 = 1;
sub_4005B6();
if ( strlen(&byte_604B80) != 24 )
v4 = 0;
for ( i = 0; i <= 23; ++i )
{
if ( *(&byte_604B80 + i) != dword_601060[i] )
v4 = 0;
}
if ( v4 )
puts("correct");
else
puts("wrong");
return 0LL;
}

从主函数可以判断出该字符长度为24,判断完后又和dword_601060进行了字符串比较

sub_4005B6这个函数内容:

__

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
int64 sub_4005B6()
{
__int64 result; // rax
int i; // [rsp+0h] [rbp-10h]
char v2; // [rsp+8h] [rbp-8h]
int v3; // [rsp+Ch] [rbp-4h]

for ( i = 0; i <= 14999; i += 3 )
{
v2 = byte_6010C0[i + 2];
v3 = byte_6010C0[i + 1];
result = (unsigned int)byte_6010C0[i];
switch ( byte_6010C0[i] )
{
case 1:
result = byte_6010C0[i + 1];
*(&byte_604B80 + v3) += v2;
break;
case 2:
result = byte_6010C0[i + 1];
*(&byte_604B80 + v3) -= v2;
break;
case 3:
result = byte_6010C0[i + 1];
*(&byte_604B80 + v3) ^= v2;
break;
case 4:
result = byte_6010C0[i + 1];
*(&byte_604B80 + v3) *= v2;
break;
case 5:
result = byte_6010C0[i + 1];
*(&byte_604B80 + v3) ^= *(&byte_604B80 + byte_6010C0[i + 2]);
break;
default:
continue;
}
}
return result;
}

这就是一个最基础也是最常见的vm模型,分为三个一组,其中第一个是我们所说的选择的操作方式,无非就五种操作,通过v3来计算值。我看许多wp是用idapython写的,但ida7.6好像改了,好多api都不对。。。哭了,只能用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
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
dword_601060 = [0xC4, 0x34, 0x22, 0xb1, 0xd3, 0x11, 0x97, 0x07, 0xdb, 0x37, 0xc4, 0x06, 0x1d, 0xfc,
0x5b, 0xed, 0x98, 0xdf, 0x94, 0xd8, 0xb3, 0x84, 0xcc, 0x08]
b = [
0x01, 0x10, 0x25, 0x03, 0x0D, 0x0A, 0x02, 0x0B, 0x28, 0x02,
0x14, 0x3F, 0x01, 0x17, 0x3C, 0x01, 0x00, 0x69, 0x01, 0x12,
0x3F, 0x02, 0x0E, 0x77, 0x03, 0x15, 0x53, 0x02, 0x0E, 0x7D,
0x03, 0x05, 0x0A, 0x02, 0x04, 0x55, 0x02, 0x15, 0x33, 0x02,
0x15, 0x05, 0x01, 0x05, 0x2F, 0x03, 0x07, 0x43, 0x01, 0x11,
0x39, 0x03, 0x0D, 0x27, 0x01, 0x05, 0x1E, 0x03, 0x04, 0x3C,
0x01, 0x13, 0x1E, 0x03, 0x01, 0x78, 0x01, 0x00, 0x20, 0x02,
0x0F, 0x53, 0x03, 0x14, 0x2B, 0x03, 0x14, 0x28, 0x03, 0x0A,
0x19, 0x03, 0x12, 0x60, 0x01, 0x05, 0x7E, 0x03, 0x0F, 0x20,
0x01, 0x0F, 0x58, 0x02, 0x11, 0x51, 0x01, 0x0B, 0x24, 0x01,
0x17, 0x79, 0x01, 0x0E, 0x4A, 0x03, 0x10, 0x67, 0x02, 0x16,
0x5C, 0x03, 0x09, 0x6D, 0x01, 0x17, 0x30, 0x02, 0x0A, 0x2C,
0x03, 0x07, 0x3F, 0x03, 0x07, 0x43, 0x01, 0x04, 0x04, 0x02,
0x00, 0x0F, 0x01, 0x00, 0x1F, 0x01, 0x00, 0x59, 0x03, 0x0B,
0x6B, 0x01, 0x16, 0x11, 0x03, 0x03, 0x38, 0x01, 0x12, 0x41,
0x01, 0x02, 0x66, 0x02, 0x0F, 0x1A, 0x03, 0x08, 0x14, 0x03,
0x0A, 0x2A, 0x01, 0x01, 0x15, 0x01, 0x0B, 0x0A, 0x01, 0x01,
0x36, 0x01, 0x05, 0x66, 0x01, 0x08, 0x14, 0x01, 0x0B, 0x7A,
0x03, 0x0D, 0x7D, 0x02, 0x13, 0x52, 0x03, 0x0D, 0x0E, 0x03,
0x10, 0x3E, 0x03, 0x06, 0x30, 0x02, 0x01, 0x6B, 0x02, 0x04,
0x77, 0x01, 0x01, 0x12, 0x02, 0x09, 0x38, 0x03, 0x07, 0x74,
0x02, 0x0A, 0x2C, 0x02, 0x05, 0x46, 0x01, 0x12, 0x1E, 0x03,
0x04, 0x10, 0x02, 0x01, 0x6A, 0x02, 0x03, 0x5C, 0x03, 0x09,
0x11, 0x03, 0x07, 0x26, 0x02, 0x01, 0x3E, 0x02, 0x0D, 0x42,
0x02, 0x16, 0x35, 0x02, 0x09, 0x33, 0x01, 0x04, 0x00, 0x03,
0x07, 0x3C, 0x03, 0x0C, 0x5B, 0x01, 0x0D, 0x0F, 0x02, 0x16,
0x34, 0x02, 0x01, 0x61, 0x01, 0x08, 0x38, 0x03, 0x05, 0x37,
0x03, 0x0E, 0x64, 0x03, 0x0F, 0x72, 0x03, 0x0D, 0x08, 0x01,
0x0F, 0x2B, 0x03, 0x04, 0x79, 0x02, 0x12, 0x62, 0x03, 0x17,
0x57, 0x01, 0x16, 0x55, 0x02, 0x05, 0x19, 0x03, 0x07, 0x23,
0x01, 0x06, 0x62, 0x02, 0x0D, 0x54, 0x03, 0x11, 0x4D, 0x01,
0x10, 0x4E, 0x01, 0x0A, 0x53, 0x01, 0x0C, 0x6A, 0x02, 0x10,
0x42, 0x03, 0x05, 0x08, 0x02, 0x0D, 0x75, 0x03, 0x01, 0x34,
0x01, 0x09, 0x1F, 0x01, 0x16, 0x23, 0x01, 0x11, 0x5E, 0x02,
0x0A, 0x39, 0x03, 0x16, 0x15, 0x01, 0x02, 0x7C, 0x03, 0x04,
0x51, 0x01, 0x0F, 0x1B, 0x01, 0x17, 0x5C, 0x02, 0x09, 0x3C,
0x01, 0x12, 0x0B, 0x02, 0x0E, 0x2E, 0x03, 0x06, 0x68, 0x03,
0x0C, 0x48, 0x01, 0x07, 0x02, 0x03, 0x0A, 0x2E, 0x03, 0x0C,
0x4D, 0x02, 0x14, 0x6F, 0x03, 0x04, 0x0F, 0x03, 0x07, 0x5A,
0x01, 0x02, 0x45, 0x01, 0x03, 0x63, 0x02, 0x01, 0x33, 0x03,
0x01, 0x31, 0x01, 0x10, 0x60, 0x02, 0x08, 0x30, 0x02, 0x07,
0x2A, 0x03, 0x16, 0x66, 0x01, 0x09, 0x2C, 0x02, 0x16, 0x16,
0x01, 0x0D, 0x04, 0x01, 0x0E, 0x5F, 0x03, 0x0D, 0x47, 0x03,
0x0C, 0x39, 0x01, 0x0E, 0x68, 0x03, 0x0B, 0x36, 0x02, 0x16,
0x10, 0x01, 0x10, 0x07, 0x03, 0x17, 0x0C, 0x02, 0x14, 0x33,
0x03, 0x0E, 0x0B, 0x02, 0x14, 0x39, 0x02, 0x0D, 0x6E, 0x03,
0x16, 0x37, 0x03, 0x0C, 0x5D, 0x03, 0x12, 0x6D, 0x02, 0x06,
0x66, 0x02, 0x0A, 0x40, 0x03, 0x12, 0x05, 0x02, 0x0F, 0x7A,
0x03, 0x03, 0x2A, 0x01, 0x06, 0x1B, 0x01, 0x04, 0x33, 0x03,
0x13, 0x4D, 0x01, 0x14, 0x44, 0x02, 0x09, 0x10, 0x02, 0x0A,
0x12, 0x01, 0x04, 0x0B, 0x01, 0x08, 0x5E, 0x02, 0x17, 0x77,
0x02, 0x10, 0x3F, 0x01, 0x11, 0x4B, 0x02, 0x0C, 0x47, 0x03,
0x11, 0x16, 0x02, 0x14, 0x51, 0x01, 0x14, 0x01, 0x03, 0x13,
0x67, 0x01, 0x0F, 0x73, 0x02, 0x0E, 0x7B, 0x01, 0x01, 0x0D,
0x01, 0x13, 0x13, 0x02, 0x01, 0x0B, 0x02, 0x15, 0x2A, 0x03,
0x01, 0x1E, 0x01, 0x0E, 0x6F, 0x02, 0x05, 0x26, 0x03, 0x0C,
0x38, 0x01, 0x11, 0x7E, 0x02, 0x02, 0x01, 0x03, 0x10, 0x2E,
0x01, 0x05, 0x05, 0x02, 0x12, 0x66, 0x02, 0x0B, 0x6E, 0x03,
0x0F, 0x40, 0x02, 0x00, 0x68, 0x01, 0x0B, 0x41, 0x02, 0x04,
0x74, 0x03, 0x04, 0x5B, 0x03, 0x10, 0x29, 0x01, 0x0F, 0x37,
0x03, 0x10, 0x61, 0x02, 0x11, 0x7A, 0x01, 0x09, 0x55, 0x02,
0x11, 0x7E, 0x01, 0x12, 0x12, 0x02, 0x00, 0x2F, 0x02, 0x0A,
0x0C, 0x02, 0x17, 0x58, 0x02, 0x0C, 0x19, 0x02, 0x0B, 0x2C,
0x01, 0x09, 0x31, 0x02, 0x07, 0x6E, 0x02, 0x0B, 0x0E, 0x02,
0x16, 0x37, 0x02, 0x02, 0x20, 0x01, 0x10, 0x2E, 0x02, 0x0F,
0x70, 0x01, 0x02, 0x45, 0x03, 0x12, 0x11, 0x03, 0x0A, 0x6B,
0x01, 0x0E, 0x66, 0x01, 0x14, 0x1B, 0x03, 0x00, 0x54, 0x03,
0x11, 0x41, 0x01, 0x13, 0x4D, 0x01, 0x08, 0x2B, 0x02, 0x04,
0x09, 0x02, 0x17, 0x46, 0x03, 0x01, 0x0F, 0x02, 0x17, 0x04,
0x01, 0x15, 0x14, 0x01, 0x17, 0x56, 0x02, 0x15, 0x56, 0x03,
0x17, 0x31, 0x02, 0x12, 0x76, 0x01, 0x16, 0x47, 0x02, 0x06,
0x7F, 0x01, 0x0A, 0x2D, 0x01, 0x17, 0x1E, 0x03, 0x15, 0x58,
0x01, 0x01, 0x69, 0x02, 0x05, 0x28, 0x03, 0x0A, 0x69, 0x01,
0x17, 0x2F, 0x02, 0x0A, 0x63, 0x02, 0x0D, 0x29, 0x03, 0x16,
0x4E, 0x01, 0x05, 0x37, 0x03, 0x06, 0x58, 0x03, 0x03, 0x55,
0x02, 0x0C, 0x15, 0x02, 0x0A, 0x54, 0x01, 0x12, 0x24, 0x01,
0x0D, 0x75, 0x01, 0x08, 0x45, 0x03, 0x0C, 0x68, 0x02, 0x03,
0x6C, 0x03, 0x14, 0x12, 0x02, 0x11, 0x35, 0x01, 0x02, 0x0B,
0x02, 0x00, 0x7A, 0x01, 0x02, 0x74, 0x01, 0x03, 0x62, 0x01,
0x00, 0x6A, 0x02, 0x0B, 0x41, 0x02, 0x0B, 0x29, 0x03, 0x05,
0x2D, 0x01, 0x0C, 0x54, 0x03, 0x01, 0x5C, 0x02, 0x0D, 0x1B,
0x03, 0x05, 0x16, 0x02, 0x0B, 0x74, 0x02, 0x04, 0x19, 0x03,
0x02, 0x42, 0x03, 0x10, 0x72, 0x01, 0x0F, 0x04, 0x02, 0x06,
0x63, 0x03, 0x10, 0x0E, 0x03, 0x03, 0x77, 0x02, 0x0B, 0x4C,
0x02, 0x0E, 0x16, 0x01, 0x0F, 0x20, 0x02, 0x08, 0x06, 0x01,
0x0F, 0x16, 0x01, 0x0B, 0x36, 0x03, 0x0F, 0x37, 0x03, 0x07,
0x19, 0x02, 0x09, 0x69, 0x02, 0x00, 0x44, 0x02, 0x07, 0x2C,
0x02, 0x0D, 0x43, 0x02, 0x08, 0x52, 0x02, 0x11, 0x38, 0x02,
0x04, 0x2B, 0x01, 0x01, 0x79, 0x01, 0x12, 0x5A, 0x03, 0x03,
0x31, 0x03, 0x13, 0x4D, 0x02, 0x05, 0x54, 0x01, 0x02, 0x17,
0x03, 0x03, 0x55, 0x03, 0x10, 0x6E, 0x01, 0x0E, 0x7E, 0x03,
0x07, 0x1D, 0x01, 0x03, 0x20, 0x03, 0x14, 0x31, 0x01, 0x15,
0x30, 0x03, 0x11, 0x03, 0x02, 0x11, 0x71, 0x03, 0x0F, 0x73,
0x03, 0x01, 0x54, 0x02, 0x0E, 0x62, 0x01, 0x01, 0x3C, 0x01,
0x04, 0x13, 0x02, 0x09, 0x6D, 0x01, 0x0C, 0x2A, 0x03, 0x0B,
0x2B, 0x02, 0x02, 0x05, 0x03, 0x08, 0x2F, 0x03, 0x10, 0x7F,
0x01, 0x10, 0x70, 0x01, 0x16, 0x4E, 0x03, 0x16, 0x29, 0x02,
0x16, 0x31, 0x01, 0x07, 0x2F, 0x01, 0x14, 0x64, 0x02, 0x09,
0x65, 0x01, 0x02, 0x3C, 0x01, 0x0B, 0x1F, 0x03, 0x0E, 0x32,
0x03, 0x15, 0x7F, 0x01, 0x0F, 0x3D, 0x03, 0x01, 0x08, 0x02,
0x08, 0x66, 0x03, 0x06, 0x63, 0x02, 0x03, 0x12, 0x03, 0x17,
0x03, 0x03, 0x15, 0x75, 0x03, 0x0B, 0x44, 0x01, 0x07, 0x4A,
0x01, 0x12, 0x5C, 0x01, 0x12, 0x5A, 0x01, 0x06, 0x59, 0x03,
0x00, 0x21, 0x01, 0x15, 0x6C, 0x03, 0x02, 0x3D, 0x02, 0x0D,
0x2C, 0x02, 0x08, 0x64, 0x03, 0x03, 0x79, 0x03, 0x17, 0x68,
0x03, 0x00, 0x60, 0x02, 0x07, 0x6A, 0x03, 0x0E, 0x5A, 0x01,
0x05, 0x16, 0x02, 0x11, 0x7E, 0x03, 0x04, 0x09, 0x02, 0x10,
0x36, 0x02, 0x14, 0x46, 0x02, 0x04, 0x04, 0x01, 0x06, 0x6A,
0x03, 0x00, 0x24, 0x02, 0x10, 0x6F, 0x03, 0x02, 0x2E, 0x01,
0x08, 0x5F, 0x02, 0x08, 0x38, 0x02, 0x13, 0x16, 0x03, 0x04,
0x03, 0x02, 0x08, 0x47, 0x01, 0x11, 0x0A, 0x02, 0x00, 0x0A,
0x01, 0x0D, 0x3D, 0x01, 0x10, 0x6B, 0x03, 0x14, 0x45, 0x03,
0x07, 0x25, 0x01, 0x0F, 0x11, 0x01, 0x00, 0x2D, 0x03, 0x00,
0x72, 0x03, 0x00, 0x51, 0x01, 0x07, 0x01, 0x03, 0x05, 0x32,
0x02, 0x04, 0x39, 0x01, 0x04, 0x3F, 0x02, 0x07, 0x43, 0x03,
0x10, 0x38, 0x02, 0x07, 0x0B, 0x03, 0x14, 0x2C, 0x03, 0x08,
0x67, 0x02, 0x02, 0x0A, 0x02, 0x01, 0x79, 0x01, 0x0B, 0x4B,
0x03, 0x0F, 0x6A, 0x02, 0x09, 0x12, 0x03, 0x08, 0x4A, 0x01,
0x04, 0x6D, 0x02, 0x05, 0x10, 0x03, 0x0C, 0x6B, 0x01, 0x10,
0x6D, 0x02, 0x17, 0x24, 0x02, 0x10, 0x7D, 0x01, 0x0B, 0x2C,
0x03, 0x13, 0x61, 0x03, 0x0A, 0x61, 0x01, 0x14, 0x47, 0x03,
0x16, 0x71, 0x02, 0x0D, 0x04, 0x01, 0x00, 0x1C, 0x02, 0x00,
0x16, 0x03, 0x0C, 0x2F, 0x03, 0x0D, 0x2A, 0x03, 0x0B, 0x4B,
0x01, 0x11, 0x5B, 0x02, 0x11, 0x27, 0x01, 0x05, 0x18, 0x01,
0x12, 0x78, 0x03, 0x0E, 0x2F, 0x02, 0x12, 0x24, 0x03, 0x10,
0x7E, 0x03, 0x0E, 0x69, 0x02, 0x08, 0x73, 0x01, 0x12, 0x22,
0x02, 0x14, 0x65, 0x02, 0x04, 0x59, 0x01, 0x08, 0x46, 0x03,
0x0E, 0x0F, 0x03, 0x0E, 0x65, 0x01, 0x15, 0x5F, 0x01, 0x13,
0x1C, 0x02, 0x04, 0x59, 0x01, 0x14, 0x54, 0x01, 0x11, 0x27,
0x03, 0x03, 0x03, 0x02, 0x15, 0x52, 0x01, 0x0D, 0x00, 0x02,
0x00, 0x79, 0x01, 0x0B, 0x7F, 0x01, 0x05, 0x2F, 0x01, 0x07,
0x27, 0x02, 0x0C, 0x53, 0x02, 0x16, 0x2C, 0x02, 0x0C, 0x3C,
0x01, 0x05, 0x30, 0x02, 0x05, 0x08, 0x01, 0x10, 0x6A, 0x01,
0x0E, 0x1B, 0x01, 0x07, 0x70, 0x03, 0x10, 0x3D, 0x02, 0x16,
0x7E, 0x01, 0x0C, 0x15, 0x03, 0x16, 0x72, 0x02, 0x07, 0x75,
0x02, 0x0D, 0x4A, 0x03, 0x11, 0x50, 0x02, 0x14, 0x6C, 0x01,
0x11, 0x09, 0x01, 0x12, 0x5A, 0x03, 0x06, 0x37, 0x03, 0x11,
0x61, 0x01, 0x16, 0x26, 0x02, 0x13, 0x29, 0x01, 0x01, 0x6B,
0x03, 0x17, 0x61, 0x01, 0x14, 0x54, 0x03, 0x17, 0x53, 0x01,
0x05, 0x55, 0x03, 0x03, 0x4B, 0x03, 0x15, 0x56, 0x01, 0x06,
0x2B, 0x01, 0x0F, 0x0E, 0x02, 0x0A, 0x59, 0x03, 0x09, 0x2A,
0x02, 0x04, 0x66, 0x01, 0x16, 0x47, 0x01, 0x03, 0x36, 0x01,
0x03, 0x0B, 0x02, 0x15, 0x4A, 0x02, 0x06, 0x1B, 0x01, 0x06,
0x0D, 0x01, 0x08, 0x04, 0x03, 0x04, 0x74, 0x03, 0x0F, 0x4E,
0x01, 0x00, 0x20, 0x01, 0x04, 0x2D, 0x02, 0x0B, 0x52, 0x02,
0x0B, 0x6B, 0x03, 0x0D, 0x0E, 0x02, 0x03, 0x24, 0x02, 0x08,
0x43, 0x02, 0x16, 0x35, 0x03, 0x16, 0x7F, 0x03, 0x04, 0x5E,
0x01, 0x09, 0x7E, 0x03, 0x0A, 0x3B, 0x01, 0x12, 0x5B, 0x01,
0x14, 0x0D, 0x03, 0x14, 0x25, 0x02, 0x02, 0x62, 0x02, 0x13,
0x0C, 0x03, 0x17, 0x74, 0x01, 0x0F, 0x11, 0x01, 0x10, 0x5D,
0x02, 0x0B, 0x43, 0x02, 0x0E, 0x3C, 0x01, 0x0F, 0x68, 0x01,
0x0C, 0x76, 0x02, 0x17, 0x7A, 0x01, 0x02, 0x09, 0x02, 0x03,
0x78, 0x03, 0x08, 0x12, 0x03, 0x05, 0x76, 0x01, 0x0B, 0x72,
0x02, 0x08, 0x0E, 0x03, 0x0C, 0x26, 0x02, 0x13, 0x63, 0x03,
0x15, 0x63, 0x02, 0x03, 0x3C, 0x01, 0x17, 0x0D, 0x03, 0x0B,
0x01, 0x03, 0x10, 0x0F, 0x02, 0x03, 0x40, 0x03, 0x0D, 0x45,
0x02, 0x0B, 0x68, 0x03, 0x0E, 0x25, 0x03, 0x0C, 0x7F, 0x02,
0x09, 0x62, 0x03, 0x01, 0x35, 0x01, 0x10, 0x0D, 0x03, 0x03,
0x42, 0x03, 0x01, 0x6A, 0x01, 0x14, 0x38, 0x02, 0x0E, 0x26,
0x03, 0x11, 0x1B, 0x03, 0x15, 0x3F, 0x03, 0x01, 0x34, 0x02,
0x12, 0x28, 0x03, 0x0E, 0x03, 0x02, 0x11, 0x3A, 0x01, 0x05,
0x36, 0x03, 0x03, 0x4D, 0x03, 0x0E, 0x3B, 0x01, 0x12, 0x1E,
0x02, 0x0E, 0x39, 0x01, 0x12, 0x6D, 0x02, 0x16, 0x52, 0x01,
0x0A, 0x63, 0x02, 0x00, 0x30, 0x02, 0x14, 0x7C, 0x02, 0x17,
0x06, 0x03, 0x07, 0x36, 0x02, 0x02, 0x47, 0x03, 0x00, 0x5B,
0x03, 0x11, 0x58, 0x01, 0x05, 0x5A, 0x02, 0x0A, 0x38, 0x03,
0x04, 0x2A, 0x01, 0x01, 0x56, 0x03, 0x0F, 0x7A, 0x02, 0x15,
0x63, 0x03, 0x0E, 0x7C, 0x02, 0x09, 0x0E, 0x02, 0x13, 0x25,
0x03, 0x0D, 0x32, 0x02, 0x00, 0x11, 0x03, 0x00, 0x05, 0x01,
0x0B, 0x47, 0x02, 0x0F, 0x70, 0x02, 0x09, 0x75, 0x01, 0x02,
0x69, 0x03, 0x0C, 0x49, 0x03, 0x09, 0x09, 0x01, 0x0A, 0x43,
0x01, 0x17, 0x1F, 0x01, 0x0A, 0x6A, 0x01, 0x12, 0x28, 0x03,
0x01, 0x36, 0x01, 0x08, 0x72, 0x02, 0x10, 0x1D, 0x03, 0x0B,
0x09, 0x01, 0x0D, 0x01, 0x01, 0x0B, 0x72, 0x02, 0x03, 0x5A,
0x03, 0x08, 0x29, 0x02, 0x0A, 0x50, 0x02, 0x17, 0x2B, 0x02,
0x11, 0x05, 0x02, 0x08, 0x55, 0x02, 0x0C, 0x40, 0x02, 0x03,
0x0C, 0x02, 0x02, 0x16, 0x01, 0x0B, 0x0A, 0x03, 0x00, 0x16,
0x02, 0x15, 0x11, 0x03, 0x03, 0x5F, 0x03, 0x08, 0x5D, 0x03,
0x13, 0x4E, 0x03, 0x08, 0x4D, 0x03, 0x10, 0x24, 0x01, 0x11,
0x59, 0x02, 0x0A, 0x66, 0x02, 0x02, 0x25, 0x02, 0x17, 0x7C,
0x02, 0x09, 0x5B, 0x01, 0x03, 0x54, 0x03, 0x15, 0x0B, 0x02,
0x13, 0x71, 0x03, 0x0A, 0x72, 0x01, 0x0A, 0x6B, 0x01, 0x0E,
0x37, 0x01, 0x0B, 0x12, 0x02, 0x15, 0x3F, 0x03, 0x0D, 0x76,
0x01, 0x13, 0x1B, 0x01, 0x0E, 0x6F, 0x02, 0x0E, 0x14, 0x02,
0x0C, 0x2B, 0x01, 0x06, 0x28, 0x03, 0x13, 0x4B, 0x03, 0x10,
0x4B, 0x03, 0x0D, 0x21, 0x02, 0x0D, 0x3B, 0x03, 0x0D, 0x1E,
0x02, 0x00, 0x42, 0x01, 0x01, 0x67, 0x02, 0x0A, 0x1F, 0x02,
0x13, 0x54, 0x01, 0x01, 0x0E, 0x03, 0x15, 0x66, 0x03, 0x0B,
0x24, 0x03, 0x07, 0x38, 0x03, 0x03, 0x64, 0x01, 0x06, 0x78,
0x03, 0x09, 0x3E, 0x03, 0x05, 0x2E, 0x03, 0x0D, 0x17, 0x03,
0x04, 0x4D, 0x01, 0x14, 0x5F, 0x02, 0x16, 0x6B, 0x03, 0x10,
0x25, 0x03, 0x0C, 0x5A, 0x03, 0x15, 0x29, 0x02, 0x0A, 0x13,
0x03, 0x08, 0x4C, 0x03, 0x05, 0x3C, 0x03, 0x00, 0x5F, 0x03,
0x09, 0x3A, 0x03, 0x01, 0x32, 0x03, 0x0F, 0x0A, 0x02, 0x06,
0x6A, 0x03, 0x06, 0x01, 0x03, 0x0A, 0x5B, 0x01, 0x16, 0x06,
0x03, 0x14, 0x62, 0x02, 0x0F, 0x21, 0x02, 0x03, 0x7E, 0x01,
0x06, 0x0B, 0x02, 0x17, 0x78, 0x03, 0x01, 0x30, 0x03, 0x08,
0x6B, 0x02, 0x12, 0x06, 0x02, 0x0B, 0x4C, 0x02, 0x07, 0x77,
0x02, 0x08, 0x4A, 0x03, 0x13, 0x24, 0x02, 0x09, 0x2A, 0x02,
0x14, 0x77, 0x01, 0x0B, 0x0F, 0x01, 0x0F, 0x6F, 0x02, 0x0E,
0x22, 0x03, 0x04, 0x64, 0x02, 0x0A, 0x53, 0x01, 0x15, 0x6D,
0x01, 0x06, 0x07, 0x01, 0x0F, 0x45, 0x01, 0x0B, 0x33, 0x03,
0x17, 0x4C, 0x02, 0x0C, 0x49, 0x01, 0x04, 0x74, 0x02, 0x05,
0x13, 0x03, 0x12, 0x5E, 0x02, 0x08, 0x47, 0x01, 0x16, 0x05,
0x02, 0x0D, 0x3C, 0x01, 0x01, 0x45, 0x03, 0x17, 0x4B, 0x02,
0x03, 0x43, 0x03, 0x0D, 0x62, 0x01, 0x0F, 0x65, 0x02, 0x12,
0x3A, 0x02, 0x16, 0x01, 0x02, 0x16, 0x6F, 0x03, 0x08, 0x48,
0x01, 0x08, 0x2C, 0x01, 0x08, 0x1B, 0x03, 0x10, 0x30, 0x01,
0x0E, 0x38, 0x02, 0x0D, 0x08, 0x01, 0x14, 0x2B, 0x02, 0x0A,
0x27, 0x01, 0x13, 0x06, 0x01, 0x07, 0x24, 0x01, 0x00, 0x68,
0x03, 0x16, 0x17, 0x03, 0x0A, 0x5A, 0x01, 0x0D, 0x3C, 0x03,
0x0D, 0x3C, 0x02, 0x01, 0x57, 0x03, 0x0C, 0x2A, 0x01, 0x05,
0x2F, 0x02, 0x00, 0x0C, 0x01, 0x15, 0x44, 0x01, 0x04, 0x49,
0x02, 0x0C, 0x01, 0x02, 0x0B, 0x1A, 0x03, 0x13, 0x0B, 0x03,
0x01, 0x70, 0x01, 0x0C, 0x68, 0x01, 0x0A, 0x7C, 0x02, 0x16,
0x49, 0x03, 0x0A, 0x5F, 0x01, 0x14, 0x5A, 0x01, 0x00, 0x29,
0x01, 0x02, 0x0E, 0x02, 0x02, 0x0E, 0x02, 0x04, 0x7C, 0x01,
0x04, 0x3D, 0x01, 0x12, 0x3B, 0x02, 0x11, 0x65, 0x03, 0x0A,
0x59, 0x01, 0x08, 0x22, 0x02, 0x09, 0x6B, 0x02, 0x00, 0x59,
0x01, 0x09, 0x2B, 0x01, 0x10, 0x5D, 0x02, 0x05, 0x43, 0x02,
0x0E, 0x5B, 0x01, 0x15, 0x58, 0x01, 0x04, 0x52, 0x01, 0x02,
0x19, 0x01, 0x10, 0x02, 0x02, 0x14, 0x1D, 0x03, 0x10, 0x18,
0x02, 0x03, 0x23, 0x01, 0x01, 0x0B, 0x02, 0x0A, 0x28, 0x02,
0x14, 0x7E, 0x03, 0x12, 0x07, 0x02, 0x15, 0x37, 0x01, 0x0F,
0x47, 0x03, 0x07, 0x58, 0x03, 0x14, 0x59, 0x02, 0x11, 0x14,
0x01, 0x17, 0x3B, 0x01, 0x07, 0x71, 0x01, 0x06, 0x56, 0x03,
0x02, 0x4A, 0x01, 0x04, 0x04, 0x03, 0x10, 0x0D, 0x03, 0x15,
0x4F, 0x03, 0x06, 0x6F, 0x02, 0x06, 0x61, 0x03, 0x07, 0x20,
0x02, 0x0D, 0x0A, 0x01, 0x02, 0x5E, 0x02, 0x02, 0x14, 0x01,
0x01, 0x4A, 0x01, 0x05, 0x58, 0x02, 0x10, 0x59, 0x01, 0x0C,
0x34, 0x03, 0x10, 0x4F, 0x02, 0x15, 0x61, 0x01, 0x11, 0x23,
0x03, 0x08, 0x39, 0x02, 0x0E, 0x3E, 0x01, 0x11, 0x2F, 0x01,
0x06, 0x61, 0x01, 0x0B, 0x3A, 0x01, 0x02, 0x27, 0x01, 0x04,
0x5D, 0x02, 0x17, 0x13, 0x03, 0x05, 0x0C, 0x02, 0x16, 0x2B,
0x03, 0x02, 0x14, 0x02, 0x12, 0x1F, 0x03, 0x14, 0x18, 0x01,
0x08, 0x63, 0x01, 0x0D, 0x16, 0x01, 0x03, 0x1F, 0x03, 0x0D,
0x0A, 0x01, 0x15, 0x03, 0x01, 0x00, 0x0F, 0x02, 0x12, 0x3B,
0x01, 0x14, 0x18, 0x01, 0x14, 0x65, 0x02, 0x05, 0x13, 0x01,
0x0D, 0x74, 0x01, 0x00, 0x67, 0x02, 0x11, 0x55, 0x03, 0x05,
0x68, 0x01, 0x11, 0x05, 0x02, 0x07, 0x2E, 0x01, 0x10, 0x6E,
0x01, 0x04, 0x45, 0x03, 0x17, 0x01, 0x03, 0x0D, 0x4B, 0x01,
0x10, 0x6D, 0x03, 0x00, 0x26, 0x01, 0x14, 0x51, 0x03, 0x01,
0x1D, 0x03, 0x09, 0x5F, 0x01, 0x00, 0x68, 0x01, 0x0E, 0x7D,
0x01, 0x0E, 0x18, 0x02, 0x13, 0x3D, 0x03, 0x0F, 0x03, 0x02,
0x13, 0x21, 0x03, 0x16, 0x46, 0x03, 0x04, 0x3D, 0x03, 0x0B,
0x37, 0x03, 0x06, 0x54, 0x01, 0x09, 0x48, 0x01, 0x10, 0x66,
0x02, 0x00, 0x5C, 0x03, 0x12, 0x68, 0x01, 0x0F, 0x58, 0x02,
0x08, 0x2F, 0x02, 0x0C, 0x1D, 0x03, 0x13, 0x54, 0x02, 0x07,
0x78, 0x03, 0x13, 0x4D, 0x01, 0x0B, 0x14, 0x02, 0x16, 0x2A,
0x02, 0x0A, 0x27, 0x01, 0x16, 0x42, 0x01, 0x01, 0x28, 0x02,
0x07, 0x69, 0x02, 0x01, 0x33, 0x03, 0x0F, 0x50, 0x01, 0x17,
0x19, 0x01, 0x0C, 0x3B, 0x03, 0x12, 0x03, 0x03, 0x13, 0x51,
0x01, 0x0A, 0x47, 0x03, 0x15, 0x10, 0x03, 0x05, 0x56, 0x01,
0x0C, 0x7C, 0x01, 0x09, 0x35, 0x02, 0x0E, 0x7A, 0x03, 0x0E,
0x79, 0x01, 0x11, 0x73, 0x01, 0x0A, 0x43, 0x03, 0x08, 0x41,
0x03, 0x02, 0x2B, 0x02, 0x09, 0x31, 0x03, 0x0C, 0x36, 0x03,
0x00, 0x6A, 0x02, 0x12, 0x47, 0x03, 0x00, 0x51, 0x01, 0x04,
0x36, 0x03, 0x06, 0x71, 0x02, 0x05, 0x2A, 0x03, 0x0D, 0x1A,
0x01, 0x05, 0x49, 0x03, 0x00, 0x1A, 0x02, 0x04, 0x5C, 0x03,
0x09, 0x72, 0x01, 0x11, 0x1C, 0x02, 0x0F, 0x37, 0x01, 0x0A,
0x41, 0x02, 0x06, 0x6E, 0x03, 0x14, 0x77, 0x01, 0x13, 0x35,
0x03, 0x0C, 0x6C, 0x03, 0x12, 0x21, 0x01, 0x0B, 0x6B, 0x01,
0x15, 0x4E, 0x02, 0x15, 0x6E, 0x01, 0x14, 0x0A, 0x02, 0x0B,
0x65, 0x03, 0x16, 0x78, 0x02, 0x0E, 0x2C, 0x02, 0x16, 0x43,
0x03, 0x14, 0x4B, 0x03, 0x0C, 0x7A, 0x01, 0x16, 0x10, 0x03,
0x01, 0x45, 0x02, 0x0F, 0x67, 0x03, 0x16, 0x59, 0x01, 0x08,
0x1E, 0x01, 0x10, 0x76, 0x02, 0x12, 0x00, 0x03, 0x17, 0x6A,
0x02, 0x10, 0x39, 0x03, 0x0B, 0x51, 0x02, 0x17, 0x2F, 0x03,
0x04, 0x26, 0x02, 0x17, 0x4B, 0x02, 0x0D, 0x31, 0x01, 0x11,
0x43, 0x01, 0x05, 0x09, 0x01, 0x14, 0x79, 0x03, 0x0F, 0x01,
0x02, 0x0C, 0x22, 0x03, 0x0A, 0x0F, 0x02, 0x05, 0x2E, 0x03,
0x03, 0x72, 0x02, 0x07, 0x20, 0x03, 0x16, 0x18, 0x02, 0x0A,
0x40, 0x03, 0x04, 0x2C, 0x03, 0x03, 0x7F, 0x03, 0x0F, 0x4E,
0x03, 0x08, 0x63, 0x02, 0x12, 0x2D, 0x01, 0x02, 0x50, 0x02,
0x00, 0x59, 0x03, 0x13, 0x0C, 0x02, 0x00, 0x5A, 0x02, 0x0E,
0x78, 0x03, 0x12, 0x27, 0x01, 0x10, 0x28, 0x03, 0x05, 0x68,
0x02, 0x12, 0x1D, 0x01, 0x04, 0x2B, 0x01, 0x10, 0x2B, 0x02,
0x02, 0x7A, 0x03, 0x13, 0x76, 0x03, 0x06, 0x68, 0x03, 0x0C,
0x35, 0x03, 0x10, 0x6C, 0x03, 0x0A, 0x7F, 0x02, 0x05, 0x47,
0x01, 0x10, 0x77, 0x02, 0x13, 0x34, 0x01, 0x05, 0x67, 0x01,
0x15, 0x1E, 0x01, 0x0C, 0x60, 0x03, 0x02, 0x1A, 0x02, 0x01,
0x15, 0x03, 0x13, 0x64, 0x03, 0x08, 0x28, 0x01, 0x0B, 0x58,
0x02, 0x08, 0x59, 0x01, 0x13, 0x39, 0x01, 0x0D, 0x27, 0x01,
0x05, 0x60, 0x01, 0x17, 0x15, 0x01, 0x13, 0x19, 0x02, 0x11,
0x2C, 0x01, 0x02, 0x3D, 0x03, 0x07, 0x20, 0x03, 0x15, 0x4C,
0x02, 0x0B, 0x26, 0x02, 0x00, 0x20, 0x03, 0x02, 0x44, 0x03,
0x0D, 0x18, 0x02, 0x11, 0x51, 0x03, 0x12, 0x34, 0x01, 0x17,
0x68, 0x03, 0x04, 0x11, 0x03, 0x01, 0x73, 0x03, 0x0D, 0x6A,
0x01, 0x0C, 0x1E, 0x02, 0x08, 0x0A, 0x01, 0x02, 0x31, 0x01,
0x13, 0x62, 0x03, 0x0F, 0x0A, 0x02, 0x17, 0x23, 0x02, 0x0C,
0x25, 0x02, 0x13, 0x32, 0x03, 0x0E, 0x2B, 0x01, 0x17, 0x48,
0x03, 0x11, 0x73, 0x01, 0x12, 0x04, 0x01, 0x03, 0x31, 0x02,
0x10, 0x33, 0x01, 0x17, 0x1A, 0x03, 0x0C, 0x11, 0x03, 0x05,
0x18, 0x02, 0x09, 0x44, 0x02, 0x05, 0x3B, 0x01, 0x04, 0x52,
0x02, 0x16, 0x48, 0x03, 0x0F, 0x06, 0x02, 0x0A, 0x0C, 0x01,
0x09, 0x1D, 0x03, 0x06, 0x7F, 0x01, 0x15, 0x0D, 0x02, 0x17,
0x26, 0x02, 0x10, 0x7B, 0x02, 0x15, 0x11, 0x02, 0x10, 0x5E,
0x01, 0x08, 0x06, 0x03, 0x03, 0x3F, 0x03, 0x05, 0x4B, 0x03,
0x0B, 0x7A, 0x01, 0x0D, 0x2C, 0x01, 0x02, 0x49, 0x02, 0x04,
0x4A, 0x02, 0x15, 0x39, 0x01, 0x06, 0x46, 0x03, 0x00, 0x15,
0x01, 0x15, 0x57, 0x03, 0x0C, 0x2C, 0x02, 0x07, 0x22, 0x01,
0x17, 0x55, 0x01, 0x0A, 0x44, 0x01, 0x13, 0x54, 0x03, 0x11,
0x5B, 0x01, 0x01, 0x1E, 0x01, 0x13, 0x11, 0x01, 0x0C, 0x4B,
0x01, 0x08, 0x6B, 0x01, 0x10, 0x0F, 0x02, 0x00, 0x79, 0x01,
0x08, 0x4F, 0x02, 0x15, 0x43, 0x02, 0x13, 0x20, 0x01, 0x15,
0x7F, 0x02, 0x05, 0x7E, 0x03, 0x11, 0x37, 0x03, 0x13, 0x3C,
0x03, 0x11, 0x1B, 0x02, 0x14, 0x28, 0x02, 0x17, 0x06, 0x03,
0x09, 0x77, 0x03, 0x01, 0x19, 0x02, 0x02, 0x10, 0x03, 0x11,
0x3B, 0x01, 0x15, 0x49, 0x02, 0x10, 0x68, 0x01, 0x17, 0x36,
0x03, 0x11, 0x08, 0x03, 0x0A, 0x27, 0x03, 0x07, 0x7F, 0x03,
0x0B, 0x03, 0x02, 0x0D, 0x6B, 0x01, 0x10, 0x44, 0x03, 0x0F,
0x3E, 0x03, 0x0D, 0x63, 0x01, 0x13, 0x28, 0x02, 0x0C, 0x0D,
0x02, 0x05, 0x7B, 0x03, 0x0C, 0x67, 0x01, 0x0D, 0x7E, 0x01,
0x0B, 0x35, 0x02, 0x08, 0x58, 0x01, 0x15, 0x00, 0x01, 0x01,
0x1C, 0x02, 0x04, 0x57, 0x03, 0x0E, 0x44, 0x03, 0x13, 0x4C,
0x01, 0x14, 0x30, 0x03, 0x12, 0x36, 0x02, 0x07, 0x3C, 0x01,
0x0D, 0x51, 0x02, 0x00, 0x32, 0x02, 0x01, 0x4B, 0x01, 0x16,
0x0F, 0x01, 0x05, 0x5D, 0x01, 0x12, 0x00, 0x02, 0x16, 0x3A,
0x02, 0x17, 0x6D, 0x01, 0x15, 0x0A, 0x03, 0x03, 0x2B, 0x02,
0x05, 0x7B, 0x03, 0x09, 0x6D, 0x03, 0x10, 0x7E, 0x03, 0x03,
0x4B, 0x01, 0x0B, 0x76, 0x03, 0x16, 0x79, 0x02, 0x08, 0x49,
0x03, 0x12, 0x57, 0x03, 0x0F, 0x05, 0x01, 0x0D, 0x1F, 0x01,
0x13, 0x10, 0x02, 0x0A, 0x07, 0x02, 0x17, 0x05, 0x02, 0x06,
0x6B, 0x02, 0x0A, 0x10, 0x02, 0x0D, 0x03, 0x02, 0x14, 0x5A,
0x02, 0x04, 0x3C, 0x02, 0x14, 0x21, 0x03, 0x09, 0x75, 0x01,
0x08, 0x03, 0x03, 0x0F, 0x31, 0x02, 0x06, 0x5F, 0x02, 0x10,
0x63, 0x01, 0x0E, 0x62, 0x02, 0x11, 0x6B, 0x02, 0x08, 0x70,
0x03, 0x07, 0x02, 0x03, 0x17, 0x52, 0x01, 0x04, 0x31, 0x03,
0x14, 0x1C, 0x03, 0x00, 0x53, 0x02, 0x05, 0x74, 0x02, 0x00,
0x6A, 0x02, 0x15, 0x21, 0x03, 0x0A, 0x76, 0x01, 0x00, 0x03,
0x01, 0x0A, 0x1E, 0x03, 0x10, 0x0F, 0x02, 0x15, 0x11, 0x03,
0x10, 0x3B, 0x02, 0x06, 0x18, 0x03, 0x0D, 0x21, 0x03, 0x03,
0x21, 0x03, 0x14, 0x50, 0x03, 0x01, 0x34, 0x02, 0x13, 0x2A,
0x03, 0x11, 0x06, 0x03, 0x0E, 0x2C, 0x02, 0x0B, 0x2E, 0x01,
0x09, 0x68, 0x03, 0x0D, 0x63, 0x01, 0x09, 0x59, 0x02, 0x15,
0x23, 0x03, 0x05, 0x64, 0x02, 0x09, 0x66, 0x02, 0x17, 0x5B,
0x02, 0x14, 0x65, 0x02, 0x07, 0x07, 0x03, 0x00, 0x57, 0x01,
0x13, 0x3F, 0x03, 0x0B, 0x01, 0x02, 0x04, 0x79, 0x03, 0x0A,
0x63, 0x03, 0x03, 0x65, 0x02, 0x03, 0x5D, 0x03, 0x0B, 0x43,
0x03, 0x0D, 0x06, 0x02, 0x03, 0x6F, 0x03, 0x0A, 0x5A, 0x01,
0x01, 0x6B, 0x01, 0x10, 0x45, 0x01, 0x0D, 0x1C, 0x02, 0x01,
0x45, 0x03, 0x04, 0x10, 0x01, 0x03, 0x56, 0x02, 0x01, 0x1D,
0x02, 0x16, 0x41, 0x01, 0x15, 0x6E, 0x01, 0x0E, 0x1F, 0x03,
0x10, 0x4D, 0x02, 0x0D, 0x19, 0x01, 0x0D, 0x43, 0x03, 0x0A,
0x7F, 0x03, 0x14, 0x26, 0x01, 0x0B, 0x5F, 0x01, 0x06, 0x7A,
0x03, 0x17, 0x27, 0x03, 0x17, 0x62, 0x01, 0x00, 0x3F, 0x02,
0x00, 0x75, 0x03, 0x10, 0x27, 0x02, 0x10, 0x16, 0x01, 0x0D,
0x54, 0x01, 0x17, 0x71, 0x02, 0x0C, 0x0E, 0x01, 0x13, 0x09,
0x01, 0x05, 0x49, 0x03, 0x15, 0x3D, 0x02, 0x0F, 0x51, 0x02,
0x02, 0x40, 0x02, 0x15, 0x65, 0x01, 0x0F, 0x3D, 0x02, 0x0D,
0x5B, 0x03, 0x13, 0x31, 0x02, 0x15, 0x1C, 0x02, 0x15, 0x50,
0x01, 0x04, 0x7E, 0x03, 0x11, 0x05, 0x03, 0x05, 0x1B, 0x01,
0x06, 0x5C, 0x02, 0x15, 0x5C, 0x02, 0x12, 0x79, 0x01, 0x04,
0x6D, 0x03, 0x0F, 0x5D, 0x03, 0x08, 0x01, 0x02, 0x05, 0x76,
0x03, 0x0E, 0x5E, 0x01, 0x0A, 0x74, 0x03, 0x07, 0x42, 0x01,
0x16, 0x37, 0x02, 0x03, 0x28, 0x03, 0x11, 0x30, 0x01, 0x13,
0x1F, 0x02, 0x0A, 0x4B, 0x03, 0x0F, 0x56, 0x03, 0x0B, 0x0D,
0x02, 0x11, 0x6B, 0x03, 0x05, 0x10, 0x03, 0x02, 0x24, 0x02,
0x10, 0x3B, 0x03, 0x00, 0x39, 0x03, 0x03, 0x70, 0x02, 0x0D,
0x08, 0x03, 0x15, 0x32, 0x02, 0x17, 0x1B, 0x02, 0x01, 0x47,
0x01, 0x01, 0x53, 0x02, 0x17, 0x30, 0x02, 0x03, 0x5C, 0x03,
0x0A, 0x50, 0x01, 0x0B, 0x23, 0x03, 0x0D, 0x44, 0x03, 0x14,
0x00, 0x01, 0x17, 0x20, 0x03, 0x0B, 0x5C, 0x03, 0x0F, 0x01,
0x03, 0x03, 0x1C, 0x03, 0x07, 0x47, 0x03, 0x00, 0x5C, 0x02,
0x0F, 0x76, 0x03, 0x16, 0x2D, 0x02, 0x14, 0x39, 0x03, 0x07,
0x74, 0x02, 0x15, 0x55, 0x02, 0x0D, 0x03, 0x02, 0x0A, 0x1C,
0x02, 0x00, 0x27, 0x01, 0x0A, 0x19, 0x02, 0x0C, 0x49, 0x01,
0x09, 0x06, 0x02, 0x08, 0x2F, 0x03, 0x14, 0x5F, 0x02, 0x11,
0x59, 0x02, 0x17, 0x1E, 0x02, 0x13, 0x04, 0x02, 0x12, 0x27,
0x03, 0x16, 0x4D, 0x01, 0x07, 0x07, 0x02, 0x07, 0x4D, 0x01,
0x08, 0x2D, 0x03, 0x0F, 0x75, 0x01, 0x00, 0x3E, 0x02, 0x07,
0x70, 0x01, 0x06, 0x1B, 0x02, 0x0A, 0x17, 0x03, 0x15, 0x04,
0x03, 0x05, 0x5A, 0x03, 0x00, 0x37, 0x02, 0x14, 0x1B, 0x02,
0x04, 0x1F, 0x01, 0x0C, 0x5A, 0x03, 0x17, 0x4F, 0x02, 0x02,
0x3C, 0x03, 0x0E, 0x50, 0x01, 0x0B, 0x18, 0x01, 0x0A, 0x3E,
0x01, 0x0B, 0x62, 0x01, 0x00, 0x37, 0x01, 0x0D, 0x7E, 0x03,
0x0B, 0x61, 0x03, 0x02, 0x2B, 0x03, 0x03, 0x59, 0x03, 0x01,
0x61, 0x02, 0x04, 0x44, 0x03, 0x12, 0x17, 0x02, 0x10, 0x1A,
0x01, 0x02, 0x48, 0x03, 0x08, 0x0D, 0x03, 0x0B, 0x73, 0x02,
0x00, 0x73, 0x03, 0x05, 0x51, 0x01, 0x10, 0x0D, 0x01, 0x0B,
0x18, 0x01, 0x00, 0x2B, 0x01, 0x0E, 0x3D, 0x01, 0x14, 0x01,
0x03, 0x14, 0x3D, 0x03, 0x10, 0x56, 0x02, 0x02, 0x3C, 0x03,
0x0E, 0x31, 0x01, 0x0E, 0x42, 0x02, 0x08, 0x16, 0x03, 0x13,
0x2B, 0x03, 0x07, 0x60, 0x01, 0x01, 0x05, 0x02, 0x05, 0x0E,
0x01, 0x06, 0x48, 0x01, 0x0E, 0x67, 0x02, 0x0F, 0x59, 0x02,
0x07, 0x12, 0x03, 0x10, 0x68, 0x02, 0x13, 0x69, 0x03, 0x0F,
0x40, 0x03, 0x16, 0x22, 0x02, 0x17, 0x4D, 0x03, 0x03, 0x0D,
0x01, 0x0D, 0x6B, 0x03, 0x10, 0x78, 0x01, 0x02, 0x6D, 0x03,
0x17, 0x4D, 0x02, 0x16, 0x78, 0x02, 0x0D, 0x54, 0x03, 0x05,
0x1C, 0x03, 0x11, 0x76, 0x02, 0x06, 0x0B, 0x01, 0x0F, 0x6A,
0x03, 0x04, 0x7E, 0x02, 0x0F, 0x3A, 0x01, 0x00, 0x23, 0x03,
0x00, 0x64, 0x02, 0x12, 0x78, 0x03, 0x0F, 0x60, 0x03, 0x0F,
0x1A, 0x03, 0x16, 0x36, 0x01, 0x02, 0x76, 0x02, 0x0F, 0x27,
0x03, 0x0C, 0x18, 0x01, 0x0D, 0x04, 0x03, 0x17, 0x43, 0x02,
0x13, 0x2F, 0x01, 0x06, 0x3E, 0x02, 0x00, 0x43, 0x01, 0x0F,
0x7D, 0x03, 0x0F, 0x45, 0x03, 0x03, 0x11, 0x02, 0x01, 0x5F,
0x03, 0x01, 0x4F, 0x03, 0x09, 0x67, 0x01, 0x17, 0x08, 0x03,
0x00, 0x1B, 0x03, 0x02, 0x27, 0x03, 0x17, 0x1B, 0x03, 0x01,
0x26, 0x03, 0x15, 0x35, 0x02, 0x0D, 0x0E, 0x03, 0x17, 0x4C,
0x03, 0x04, 0x56, 0x01, 0x04, 0x42, 0x02, 0x11, 0x0C, 0x01,
0x13, 0x46, 0x03, 0x13, 0x1B, 0x01, 0x08, 0x58, 0x02, 0x10,
0x3C, 0x02, 0x04, 0x21, 0x02, 0x0C, 0x14, 0x02, 0x10, 0x22,
0x02, 0x14, 0x1A, 0x01, 0x06, 0x45, 0x02, 0x10, 0x3C, 0x03,
0x0A, 0x1B, 0x03, 0x04, 0x4B, 0x02, 0x17, 0x59, 0x01, 0x02,
0x5A, 0x01, 0x09, 0x08, 0x01, 0x01, 0x2A, 0x02, 0x03, 0x03,
0x02, 0x0E, 0x3D, 0x01, 0x11, 0x41, 0x02, 0x09, 0x39, 0x03,
0x0F, 0x03, 0x01, 0x16, 0x23, 0x01, 0x0A, 0x28, 0x03, 0x05,
0x68, 0x03, 0x0F, 0x70, 0x02, 0x03, 0x63, 0x03, 0x08, 0x59,
0x01, 0x03, 0x1C, 0x01, 0x07, 0x78, 0x03, 0x09, 0x2D, 0x02,
0x0E, 0x1A, 0x03, 0x03, 0x46, 0x02, 0x0C, 0x21, 0x02, 0x09,
0x09, 0x03, 0x0E, 0x7B, 0x03, 0x0E, 0x72, 0x03, 0x17, 0x58,
0x02, 0x11, 0x44, 0x02, 0x13, 0x5F, 0x03, 0x00, 0x7B, 0x03,
0x0F, 0x3E, 0x02, 0x06, 0x1C, 0x01, 0x0A, 0x2F, 0x01, 0x0A,
0x13, 0x02, 0x07, 0x5A, 0x02, 0x0B, 0x72, 0x02, 0x11, 0x75,
0x01, 0x07, 0x76, 0x02, 0x0F, 0x20, 0x03, 0x0E, 0x5F, 0x02,
0x0F, 0x0F, 0x03, 0x0B, 0x1A, 0x01, 0x08, 0x22, 0x03, 0x05,
0x4B, 0x02, 0x02, 0x1D, 0x03, 0x09, 0x73, 0x03, 0x09, 0x52,
0x02, 0x09, 0x16, 0x01, 0x12, 0x3D, 0x01, 0x0B, 0x45, 0x03,
0x12, 0x03, 0x03, 0x0D, 0x0C, 0x02, 0x09, 0x66, 0x03, 0x0D,
0x73, 0x02, 0x14, 0x30, 0x02, 0x0C, 0x37, 0x03, 0x01, 0x64,
0x02, 0x12, 0x52, 0x01, 0x14, 0x6E, 0x01, 0x00, 0x15, 0x03,
0x13, 0x12, 0x03, 0x12, 0x0E, 0x02, 0x10, 0x79, 0x01, 0x0D,
0x75, 0x03, 0x09, 0x4B, 0x01, 0x16, 0x4D, 0x02, 0x0A, 0x03,
0x02, 0x03, 0x2B, 0x02, 0x16, 0x52, 0x01, 0x05, 0x00, 0x03,
0x09, 0x0C, 0x01, 0x01, 0x4B, 0x03, 0x11, 0x06, 0x01, 0x17,
0x3E, 0x02, 0x14, 0x3B, 0x01, 0x08, 0x43, 0x02, 0x0F, 0x42,
0x03, 0x0F, 0x6E, 0x01, 0x0A, 0x4A, 0x02, 0x17, 0x09, 0x03,
0x12, 0x79, 0x03, 0x12, 0x74, 0x01, 0x12, 0x5D, 0x01, 0x15,
0x3C, 0x03, 0x15, 0x7F, 0x01, 0x0C, 0x16, 0x03, 0x05, 0x79,
0x02, 0x0A, 0x29, 0x02, 0x15, 0x38, 0x02, 0x0F, 0x71, 0x02,
0x0A, 0x63, 0x01, 0x17, 0x1C, 0x01, 0x06, 0x15, 0x02, 0x02,
0x23, 0x02, 0x04, 0x61, 0x03, 0x00, 0x76, 0x01, 0x10, 0x22,
0x03, 0x04, 0x43, 0x02, 0x02, 0x6A, 0x01, 0x15, 0x5E, 0x03,
0x11, 0x20, 0x01, 0x0B, 0x58, 0x03, 0x14, 0x31, 0x01, 0x10,
0x4C, 0x03, 0x0E, 0x76, 0x02, 0x0F, 0x35, 0x01, 0x13, 0x06,
0x02, 0x11, 0x32, 0x03, 0x04, 0x74, 0x02, 0x0C, 0x74, 0x01,
0x08, 0x7C, 0x03, 0x05, 0x6A, 0x01, 0x08, 0x5B, 0x03, 0x05,
0x4D, 0x03, 0x01, 0x24, 0x01, 0x11, 0x07, 0x02, 0x11, 0x00,
0x03, 0x01, 0x7B, 0x02, 0x01, 0x2C, 0x01, 0x02, 0x17, 0x01,
0x13, 0x5E, 0x02, 0x14, 0x5F, 0x02, 0x06, 0x20, 0x01, 0x08,
0x69, 0x02, 0x09, 0x4C, 0x02, 0x07, 0x20, 0x03, 0x11, 0x73,
0x02, 0x02, 0x6E, 0x02, 0x17, 0x1C, 0x01, 0x13, 0x7C, 0x01,
0x01, 0x13, 0x02, 0x10, 0x6F, 0x01, 0x14, 0x0C, 0x01, 0x07,
0x57, 0x01, 0x01, 0x0C, 0x01, 0x0E, 0x03, 0x02, 0x0A, 0x22,
0x02, 0x0E, 0x39, 0x01, 0x0E, 0x29, 0x01, 0x06, 0x0A, 0x01,
0x0B, 0x43, 0x02, 0x0B, 0x65, 0x03, 0x0B, 0x1F, 0x02, 0x0B,
0x44, 0x02, 0x01, 0x7F, 0x03, 0x0B, 0x60, 0x02, 0x12, 0x22,
0x01, 0x09, 0x76, 0x03, 0x0B, 0x3C, 0x03, 0x0E, 0x77, 0x01,
0x05, 0x6E, 0x01, 0x11, 0x2F, 0x01, 0x08, 0x5C, 0x03, 0x00,
0x1B, 0x02, 0x0B, 0x0E, 0x01, 0x0C, 0x0F, 0x02, 0x0D, 0x56,
0x02, 0x15, 0x7C, 0x02, 0x0D, 0x13, 0x03, 0x13, 0x54, 0x01,
0x05, 0x51, 0x03, 0x01, 0x3C, 0x02, 0x16, 0x75, 0x01, 0x16,
0x6D, 0x01, 0x15, 0x12, 0x03, 0x0F, 0x14, 0x01, 0x0E, 0x69,
0x03, 0x04, 0x31, 0x03, 0x09, 0x62, 0x01, 0x0B, 0x6D, 0x02,
0x11, 0x22, 0x02, 0x14, 0x10, 0x02, 0x0D, 0x60, 0x01, 0x12,
0x1F, 0x03, 0x09, 0x6B, 0x02, 0x10, 0x3C, 0x02, 0x12, 0x1B,
0x01, 0x06, 0x33, 0x02, 0x03, 0x3A, 0x02, 0x01, 0x2C, 0x02,
0x15, 0x3C, 0x01, 0x06, 0x6F, 0x03, 0x17, 0x10, 0x01, 0x03,
0x71, 0x01, 0x04, 0x3B, 0x03, 0x15, 0x74, 0x01, 0x16, 0x62,
0x03, 0x02, 0x74, 0x01, 0x10, 0x54, 0x01, 0x12, 0x13, 0x02,
0x0C, 0x3E, 0x01, 0x15, 0x6C, 0x02, 0x0C, 0x10, 0x02, 0x01,
0x6D, 0x03, 0x05, 0x2C, 0x02, 0x16, 0x66, 0x02, 0x13, 0x7F,
0x01, 0x0C, 0x5C, 0x01, 0x09, 0x54, 0x01, 0x06, 0x22, 0x03,
0x13, 0x55, 0x02, 0x09, 0x4A, 0x01, 0x0D, 0x5E, 0x03, 0x12,
0x59, 0x01, 0x05, 0x00, 0x02, 0x0B, 0x3A, 0x01, 0x0F, 0x3D,
0x02, 0x10, 0x44, 0x01, 0x0E, 0x65, 0x01, 0x08, 0x73, 0x01,
0x05, 0x55, 0x01, 0x05, 0x17, 0x01, 0x14, 0x6E, 0x01, 0x08,
0x17, 0x03, 0x17, 0x3D, 0x01, 0x04, 0x39, 0x02, 0x02, 0x79,
0x03, 0x10, 0x18, 0x02, 0x0F, 0x1D, 0x01, 0x02, 0x26, 0x03,
0x14, 0x11, 0x02, 0x0B, 0x31, 0x03, 0x09, 0x34, 0x02, 0x01,
0x61, 0x03, 0x0F, 0x13, 0x03, 0x08, 0x69, 0x01, 0x0E, 0x45,
0x01, 0x0F, 0x1E, 0x03, 0x0D, 0x37, 0x03, 0x0D, 0x42, 0x02,
0x17, 0x1F, 0x01, 0x01, 0x00, 0x01, 0x17, 0x1D, 0x03, 0x0A,
0x3D, 0x02, 0x06, 0x68, 0x02, 0x13, 0x43, 0x03, 0x13, 0x57,
0x02, 0x05, 0x7D, 0x03, 0x05, 0x33, 0x01, 0x0C, 0x53, 0x01,
0x0A, 0x64, 0x03, 0x05, 0x0E, 0x02, 0x03, 0x7E, 0x03, 0x00,
0x4D, 0x02, 0x06, 0x40, 0x01, 0x13, 0x04, 0x03, 0x11, 0x7A,
0x02, 0x0D, 0x38, 0x03, 0x0E, 0x38, 0x03, 0x15, 0x63, 0x02,
0x0B, 0x58, 0x02, 0x08, 0x09, 0x01, 0x02, 0x0A, 0x03, 0x0B,
0x11, 0x02, 0x07, 0x78, 0x02, 0x05, 0x3B, 0x03, 0x0B, 0x63,
0x03, 0x11, 0x51, 0x01, 0x15, 0x4F, 0x03, 0x00, 0x3B, 0x01,
0x0E, 0x4C, 0x01, 0x17, 0x49, 0x01, 0x05, 0x5A, 0x02, 0x05,
0x27, 0x03, 0x00, 0x08, 0x01, 0x02, 0x0B, 0x03, 0x13, 0x52,
0x03, 0x11, 0x7D, 0x01, 0x16, 0x0F, 0x03, 0x0C, 0x37, 0x03,
0x0A, 0x76, 0x02, 0x16, 0x7C, 0x01, 0x0C, 0x30, 0x02, 0x11,
0x16, 0x02, 0x06, 0x60, 0x01, 0x09, 0x6F, 0x03, 0x11, 0x66,
0x01, 0x02, 0x0E, 0x01, 0x15, 0x53, 0x03, 0x11, 0x0A, 0x02,
0x16, 0x53, 0x01, 0x00, 0x49, 0x02, 0x14, 0x28, 0x01, 0x0B,
0x77, 0x01, 0x0E, 0x37, 0x01, 0x17, 0x2C, 0x03, 0x07, 0x08,
0x02, 0x0E, 0x0D, 0x03, 0x15, 0x62, 0x02, 0x07, 0x20, 0x02,
0x0F, 0x59, 0x01, 0x0F, 0x09, 0x01, 0x0D, 0x6E, 0x02, 0x0D,
0x4D, 0x02, 0x0C, 0x21, 0x02, 0x0C, 0x28, 0x03, 0x14, 0x1D,
0x01, 0x07, 0x01, 0x01, 0x07, 0x4C, 0x01, 0x07, 0x24, 0x03,
0x03, 0x61, 0x03, 0x0E, 0x68, 0x03, 0x02, 0x0B, 0x02, 0x01,
0x2F, 0x03, 0x07, 0x14, 0x02, 0x05, 0x08, 0x03, 0x15, 0x6A,
0x02, 0x11, 0x20, 0x03, 0x0A, 0x19, 0x01, 0x08, 0x32, 0x02,
0x0B, 0x37, 0x01, 0x08, 0x4A, 0x03, 0x08, 0x7D, 0x03, 0x02,
0x41, 0x02, 0x02, 0x09, 0x03, 0x11, 0x4E, 0x02, 0x0D, 0x2C,
0x01, 0x06, 0x35, 0x03, 0x16, 0x67, 0x02, 0x11, 0x3C, 0x03,
0x13, 0x71, 0x03, 0x10, 0x5F, 0x02, 0x07, 0x20, 0x01, 0x02,
0x6A, 0x01, 0x0A, 0x3D, 0x02, 0x16, 0x10, 0x02, 0x0C, 0x30,
0x02, 0x0E, 0x76, 0x02, 0x14, 0x7A, 0x01, 0x0B, 0x49, 0x02,
0x09, 0x5E, 0x03, 0x09, 0x4D, 0x02, 0x17, 0x4E, 0x02, 0x02,
0x64, 0x01, 0x14, 0x53, 0x01, 0x05, 0x29, 0x02, 0x05, 0x0D,
0x01, 0x07, 0x49, 0x03, 0x03, 0x51, 0x02, 0x00, 0x5D, 0x02,
0x17, 0x3B, 0x03, 0x17, 0x66, 0x01, 0x03, 0x36, 0x01, 0x14,
0x1D, 0x03, 0x12, 0x64, 0x01, 0x13, 0x3E, 0x02, 0x09, 0x40,
0x01, 0x12, 0x3F, 0x02, 0x0A, 0x15, 0x03, 0x12, 0x76, 0x02,
0x04, 0x6F, 0x03, 0x03, 0x1C, 0x02, 0x0F, 0x06, 0x01, 0x00,
0x7F, 0x01, 0x0B, 0x34, 0x01, 0x04, 0x5B, 0x01, 0x10, 0x28,
0x02, 0x12, 0x7F, 0x03, 0x13, 0x79, 0x01, 0x14, 0x2E, 0x03,
0x03, 0x79, 0x01, 0x07, 0x15, 0x02, 0x05, 0x04, 0x02, 0x0E,
0x3C, 0x01, 0x0D, 0x71, 0x03, 0x02, 0x07, 0x03, 0x14, 0x53,
0x02, 0x07, 0x6B, 0x02, 0x11, 0x1A, 0x03, 0x02, 0x43, 0x03,
0x02, 0x40, 0x03, 0x15, 0x57, 0x02, 0x15, 0x1D, 0x01, 0x09,
0x0B, 0x02, 0x08, 0x5C, 0x03, 0x0E, 0x6A, 0x03, 0x06, 0x4B,
0x02, 0x12, 0x66, 0x01, 0x10, 0x22, 0x01, 0x11, 0x0A, 0x02,
0x0A, 0x4B, 0x03, 0x14, 0x44, 0x02, 0x09, 0x27, 0x01, 0x08,
0x65, 0x02, 0x13, 0x18, 0x02, 0x06, 0x67, 0x03, 0x0E, 0x4A,
0x03, 0x01, 0x7F, 0x02, 0x05, 0x56, 0x02, 0x03, 0x5B, 0x01,
0x02, 0x40, 0x03, 0x03, 0x0E, 0x01, 0x14, 0x78, 0x02, 0x05,
0x05, 0x02, 0x04, 0x1A, 0x01, 0x0F, 0x44, 0x01, 0x06, 0x3F,
0x01, 0x0F, 0x79, 0x02, 0x0A, 0x63, 0x01, 0x08, 0x5C, 0x01,
0x11, 0x60, 0x03, 0x0E, 0x1F, 0x01, 0x0B, 0x06, 0x02, 0x0B,
0x11, 0x02, 0x09, 0x72, 0x02, 0x0F, 0x53, 0x01, 0x04, 0x52,
0x01, 0x10, 0x31, 0x03, 0x0A, 0x1B, 0x02, 0x0D, 0x1B, 0x02,
0x03, 0x79, 0x03, 0x0C, 0x25, 0x03, 0x17, 0x29, 0x03, 0x0D,
0x61, 0x02, 0x08, 0x2E, 0x02, 0x0A, 0x7F, 0x03, 0x17, 0x5D,
0x01, 0x03, 0x34, 0x02, 0x02, 0x59, 0x03, 0x0A, 0x5F, 0x01,
0x00, 0x44, 0x03, 0x02, 0x27, 0x03, 0x09, 0x48, 0x01, 0x00,
0x2F, 0x03, 0x16, 0x0E, 0x02, 0x03, 0x66, 0x03, 0x0F, 0x0B,
0x02, 0x17, 0x73, 0x02, 0x10, 0x30, 0x01, 0x0E, 0x4E, 0x01,
0x13, 0x4C, 0x02, 0x06, 0x2B, 0x03, 0x0A, 0x4F, 0x02, 0x03,
0x21, 0x03, 0x12, 0x35, 0x02, 0x00, 0x2E, 0x01, 0x03, 0x2C,
0x01, 0x15, 0x72, 0x02, 0x08, 0x55, 0x02, 0x14, 0x04, 0x01,
0x16, 0x04, 0x01, 0x07, 0x17, 0x02, 0x10, 0x42, 0x02, 0x0A,
0x73, 0x02, 0x0D, 0x36, 0x03, 0x12, 0x2A, 0x02, 0x01, 0x49,
0x01, 0x13, 0x06, 0x03, 0x11, 0x13, 0x03, 0x01, 0x55, 0x03,
0x09, 0x4A, 0x01, 0x09, 0x2B, 0x02, 0x05, 0x4B, 0x03, 0x0F,
0x07, 0x03, 0x0F, 0x73, 0x01, 0x09, 0x47, 0x01, 0x00, 0x42,
0x03, 0x11, 0x11, 0x02, 0x17, 0x51, 0x02, 0x16, 0x24, 0x02,
0x0B, 0x40, 0x01, 0x14, 0x6B, 0x02, 0x05, 0x3C, 0x01, 0x02,
0x60, 0x03, 0x01, 0x2D, 0x03, 0x09, 0x3F, 0x03, 0x17, 0x32,
0x01, 0x07, 0x73, 0x03, 0x0A, 0x12, 0x01, 0x01, 0x41, 0x01,
0x01, 0x4F, 0x01, 0x0C, 0x3A, 0x03, 0x16, 0x22, 0x02, 0x05,
0x6C, 0x02, 0x02, 0x6F, 0x03, 0x0A, 0x5F, 0x02, 0x0A, 0x37,
0x02, 0x03, 0x40, 0x02, 0x0C, 0x1A, 0x02, 0x0D, 0x5B, 0x03,
0x03, 0x4B, 0x02, 0x01, 0x15, 0x03, 0x17, 0x4D, 0x01, 0x07,
0x09, 0x01, 0x11, 0x42, 0x03, 0x11, 0x0B, 0x02, 0x15, 0x2D,
0x01, 0x01, 0x4F, 0x03, 0x03, 0x25, 0x03, 0x05, 0x71, 0x02,
0x0C, 0x1E, 0x02, 0x0F, 0x4E, 0x02, 0x0C, 0x76, 0x03, 0x02,
0x24, 0x03, 0x09, 0x41, 0x03, 0x08, 0x34, 0x02, 0x0A, 0x58,
0x01, 0x11, 0x02, 0x02, 0x0B, 0x6E, 0x01, 0x07, 0x77, 0x01,
0x01, 0x58, 0x03, 0x15, 0x12, 0x02, 0x12, 0x55, 0x01, 0x0A,
0x44, 0x01, 0x17, 0x44, 0x03, 0x03, 0x71, 0x01, 0x0C, 0x6F,
0x03, 0x03, 0x33, 0x01, 0x07, 0x67, 0x02, 0x06, 0x70, 0x02,
0x05, 0x47, 0x01, 0x12, 0x0F, 0x01, 0x13, 0x12, 0x03, 0x0D,
0x16, 0x03, 0x0E, 0x7A, 0x01, 0x11, 0x0C, 0x01, 0x02, 0x59,
0x01, 0x01, 0x39, 0x03, 0x13, 0x61, 0x03, 0x08, 0x07, 0x02,
0x13, 0x45, 0x03, 0x09, 0x47, 0x02, 0x03, 0x15, 0x03, 0x0D,
0x19, 0x02, 0x0E, 0x2C, 0x01, 0x03, 0x12, 0x03, 0x09, 0x16,
0x03, 0x09, 0x6F, 0x02, 0x14, 0x3A, 0x02, 0x10, 0x63, 0x03,
0x07, 0x51, 0x02, 0x17, 0x7E, 0x03, 0x11, 0x57, 0x02, 0x02,
0x50, 0x03, 0x02, 0x28, 0x03, 0x10, 0x68, 0x03, 0x03, 0x02,
0x02, 0x0C, 0x66, 0x03, 0x14, 0x22, 0x01, 0x12, 0x4D, 0x01,
0x0A, 0x62, 0x01, 0x14, 0x69, 0x03, 0x03, 0x7B, 0x02, 0x02,
0x23, 0x03, 0x0D, 0x73, 0x02, 0x15, 0x2B, 0x01, 0x0C, 0x3F,
0x03, 0x14, 0x68, 0x02, 0x14, 0x19, 0x03, 0x12, 0x72, 0x01,
0x13, 0x15, 0x03, 0x0B, 0x38, 0x02, 0x09, 0x32, 0x01, 0x11,
0x1C, 0x02, 0x08, 0x2C, 0x03, 0x17, 0x5A, 0x02, 0x09, 0x4E,
0x03, 0x06, 0x16, 0x02, 0x10, 0x68, 0x03, 0x05, 0x28, 0x03,
0x0B, 0x74, 0x02, 0x15, 0x4A, 0x01, 0x14, 0x16, 0x02, 0x14,
0x2F, 0x02, 0x06, 0x61, 0x01, 0x09, 0x45, 0x03, 0x05, 0x2B,
0x01, 0x02, 0x76, 0x02, 0x11, 0x78, 0x02, 0x0D, 0x08, 0x03,
0x10, 0x3F, 0x03, 0x02, 0x01, 0x03, 0x0B, 0x2E, 0x01, 0x12,
0x66, 0x02, 0x01, 0x50, 0x02, 0x08, 0x6B, 0x01, 0x01, 0x1C,
0x02, 0x15, 0x31, 0x03, 0x09, 0x0A, 0x01, 0x09, 0x22, 0x01,
0x10, 0x2C, 0x03, 0x14, 0x4A, 0x01, 0x11, 0x5D, 0x02, 0x17,
0x4F, 0x01, 0x12, 0x05, 0x03, 0x0A, 0x14, 0x03, 0x02, 0x22,
0x01, 0x16, 0x4E, 0x02, 0x12, 0x65, 0x03, 0x06, 0x48, 0x03,
0x06, 0x14, 0x01, 0x0F, 0x6D, 0x01, 0x0F, 0x08, 0x01, 0x16,
0x0E, 0x03, 0x10, 0x07, 0x01, 0x12, 0x75, 0x02, 0x14, 0x03,
0x01, 0x10, 0x39, 0x02, 0x01, 0x42, 0x02, 0x0A, 0x6F, 0x02,
0x0B, 0x1E, 0x03, 0x00, 0x3B, 0x01, 0x10, 0x2A, 0x01, 0x15,
0x1E, 0x03, 0x0F, 0x71, 0x03, 0x15, 0x52, 0x01, 0x14, 0x07,
0x02, 0x0A, 0x3D, 0x02, 0x06, 0x61, 0x02, 0x06, 0x21, 0x03,
0x06, 0x79, 0x03, 0x0A, 0x29, 0x01, 0x07, 0x52, 0x02, 0x09,
0x43, 0x01, 0x11, 0x5E, 0x03, 0x0F, 0x19, 0x03, 0x13, 0x60,
0x02, 0x03, 0x67, 0x02, 0x00, 0x15, 0x02, 0x06, 0x0B, 0x01,
0x0E, 0x05, 0x03, 0x15, 0x61, 0x01, 0x01, 0x21, 0x01, 0x13,
0x23, 0x01, 0x05, 0x18, 0x03, 0x00, 0x3C, 0x03, 0x03, 0x77,
0x01, 0x0A, 0x35, 0x02, 0x16, 0x6D, 0x03, 0x10, 0x0E, 0x02,
0x03, 0x32, 0x02, 0x04, 0x62, 0x03, 0x09, 0x1F, 0x03, 0x16,
0x7D, 0x01, 0x10, 0x74, 0x01, 0x01, 0x5D, 0x03, 0x0D, 0x62,
0x01, 0x0A, 0x30, 0x02, 0x0C, 0x3C, 0x01, 0x17, 0x7A, 0x02,
0x02, 0x4F, 0x02, 0x0A, 0x25, 0x01, 0x00, 0x4F, 0x02, 0x09,
0x27, 0x02, 0x10, 0x5C, 0x02, 0x09, 0x54, 0x03, 0x03, 0x62,
0x01, 0x15, 0x30, 0x02, 0x0C, 0x74, 0x02, 0x01, 0x11, 0x02,
0x14, 0x6E, 0x02, 0x06, 0x39, 0x03, 0x08, 0x63, 0x03, 0x03,
0x41, 0x02, 0x00, 0x78, 0x02, 0x06, 0x0D, 0x03, 0x15, 0x00,
0x01, 0x0F, 0x0F, 0x01, 0x01, 0x44, 0x03, 0x0E, 0x41, 0x03,
0x06, 0x1B, 0x02, 0x10, 0x5E, 0x01, 0x14, 0x29, 0x02, 0x14,
0x2B, 0x02, 0x11, 0x16, 0x03, 0x0D, 0x6E, 0x02, 0x10, 0x0C,
0x02, 0x0F, 0x0D, 0x01, 0x0E, 0x36, 0x03, 0x15, 0x19, 0x03,
0x00, 0x28, 0x01, 0x04, 0x02, 0x02, 0x16, 0x35, 0x02, 0x05,
0x30, 0x02, 0x05, 0x0E, 0x02, 0x04, 0x30, 0x01, 0x04, 0x00,
0x03, 0x04, 0x5D, 0x01, 0x02, 0x72, 0x02, 0x0A, 0x0C, 0x03,
0x06, 0x0E, 0x03, 0x06, 0x57, 0x02, 0x03, 0x0A, 0x02, 0x01,
0x43, 0x02, 0x12, 0x20, 0x02, 0x10, 0x5F, 0x02, 0x10, 0x7F,
0x02, 0x0A, 0x05, 0x03, 0x07, 0x5A, 0x01, 0x0D, 0x0A, 0x01,
0x14, 0x73, 0x03, 0x00, 0x24, 0x01, 0x14, 0x11, 0x01, 0x06,
0x63, 0x02, 0x11, 0x43, 0x02, 0x14, 0x4A, 0x02, 0x0E, 0x5C,
0x03, 0x16, 0x05, 0x02, 0x0C, 0x06, 0x03, 0x10, 0x0D, 0x03,
0x17, 0x35, 0x03, 0x10, 0x05, 0x01, 0x08, 0x2B, 0x01, 0x0C,
0x47, 0x03, 0x06, 0x24, 0x03, 0x05, 0x2E, 0x02, 0x02, 0x6B,
0x02, 0x0A, 0x2C, 0x01, 0x03, 0x6D, 0x02, 0x10, 0x7B, 0x03,
0x04, 0x75, 0x01, 0x02, 0x5B, 0x01, 0x14, 0x68, 0x01, 0x0B,
0x40, 0x01, 0x08, 0x5C, 0x01, 0x14, 0x54, 0x02, 0x0C, 0x03,
0x02, 0x0E, 0x75, 0x03, 0x02, 0x2D, 0x03, 0x04, 0x11, 0x03,
0x0F, 0x70, 0x03, 0x0F, 0x02, 0x03, 0x02, 0x16, 0x02, 0x09,
0x20, 0x03, 0x16, 0x74, 0x01, 0x08, 0x2E, 0x02, 0x0E, 0x55,
0x03, 0x03, 0x3B, 0x01, 0x04, 0x55, 0x03, 0x06, 0x0C, 0x01,
0x16, 0x41, 0x03, 0x15, 0x31, 0x01, 0x11, 0x70, 0x01, 0x0D,
0x47, 0x01, 0x00, 0x0A, 0x02, 0x0F, 0x79, 0x03, 0x16, 0x59,
0x01, 0x16, 0x76, 0x03, 0x08, 0x5D, 0x03, 0x02, 0x65, 0x03,
0x03, 0x3E, 0x01, 0x05, 0x52, 0x01, 0x07, 0x08, 0x01, 0x0F,
0x18, 0x03, 0x0B, 0x65, 0x01, 0x16, 0x2E, 0x01, 0x03, 0x76,
0x01, 0x0F, 0x10, 0x02, 0x10, 0x59, 0x03, 0x02, 0x77, 0x01,
0x0C, 0x33, 0x01, 0x0B, 0x70, 0x01, 0x0D, 0x5B, 0x03, 0x12,
0x6D, 0x02, 0x04, 0x49, 0x03, 0x03, 0x4B, 0x03, 0x0A, 0x0D,
0x02, 0x01, 0x23, 0x01, 0x17, 0x77, 0x03, 0x0B, 0x1C, 0x02,
0x01, 0x11, 0x01, 0x0D, 0x46, 0x02, 0x03, 0x4F, 0x03, 0x07,
0x07, 0x01, 0x09, 0x17, 0x01, 0x14, 0x12, 0x03, 0x04, 0x0F,
0x02, 0x08, 0x6B, 0x01, 0x12, 0x0F, 0x01, 0x0B, 0x73, 0x03,
0x06, 0x32, 0x02, 0x0F, 0x04, 0x01, 0x02, 0x39, 0x02, 0x12,
0x6E, 0x01, 0x0A, 0x5F, 0x02, 0x03, 0x06, 0x02, 0x17, 0x5B,
0x03, 0x0F, 0x4B, 0x02, 0x08, 0x5D, 0x03, 0x02, 0x5E, 0x02,
0x0B, 0x15, 0x02, 0x14, 0x60, 0x02, 0x0C, 0x2E, 0x02, 0x09,
0x28, 0x03, 0x01, 0x0C, 0x01, 0x0D, 0x54, 0x01, 0x00, 0x11,
0x02, 0x0E, 0x59, 0x03, 0x15, 0x74, 0x03, 0x0E, 0x0F, 0x02,
0x0B, 0x29, 0x03, 0x05, 0x36, 0x03, 0x14, 0x79, 0x01, 0x01,
0x24, 0x02, 0x0E, 0x5F, 0x01, 0x11, 0x05, 0x02, 0x0F, 0x21,
0x03, 0x03, 0x11, 0x01, 0x17, 0x60, 0x01, 0x12, 0x5F, 0x01,
0x11, 0x4C, 0x03, 0x17, 0x2E, 0x03, 0x01, 0x0F, 0x03, 0x0E,
0x16, 0x03, 0x06, 0x4A, 0x03, 0x0A, 0x37, 0x02, 0x0C, 0x79,
0x03, 0x05, 0x5C, 0x02, 0x17, 0x55, 0x03, 0x0C, 0x68, 0x03,
0x08, 0x37, 0x01, 0x17, 0x37, 0x01, 0x16, 0x30, 0x02, 0x17,
0x58, 0x02, 0x0B, 0x78, 0x03, 0x0B, 0x2A, 0x02, 0x03, 0x27,
0x02, 0x0D, 0x38, 0x02, 0x07, 0x50, 0x02, 0x0A, 0x75, 0x02,
0x11, 0x6E, 0x01, 0x08, 0x4C, 0x03, 0x14, 0x14, 0x03, 0x14,
0x28, 0x03, 0x03, 0x75, 0x01, 0x17, 0x12, 0x03, 0x09, 0x43,
0x02, 0x17, 0x2D, 0x01, 0x10, 0x27, 0x02, 0x00, 0x2E, 0x02,
0x0C, 0x59, 0x02, 0x0D, 0x55, 0x01, 0x04, 0x7F, 0x03, 0x04,
0x26, 0x03, 0x01, 0x10, 0x02, 0x00, 0x0F, 0x03, 0x0C, 0x4C,
0x03, 0x00, 0x57, 0x01, 0x0F, 0x1D, 0x01, 0x10, 0x39, 0x03,
0x05, 0x7D, 0x02, 0x16, 0x0D, 0x02, 0x09, 0x7B, 0x02, 0x08,
0x55, 0x03, 0x01, 0x0B, 0x02, 0x08, 0x42, 0x03, 0x06, 0x2E,
0x03, 0x06, 0x6E, 0x03, 0x17, 0x7B, 0x01, 0x10, 0x10, 0x02,
0x04, 0x03, 0x02, 0x12, 0x0E, 0x03, 0x0A, 0x06, 0x02, 0x15,
0x16, 0x03, 0x11, 0x2C, 0x02, 0x14, 0x00, 0x02, 0x16, 0x21,
0x03, 0x12, 0x32, 0x01, 0x03, 0x3E, 0x02, 0x03, 0x50, 0x03,
0x10, 0x79, 0x01, 0x09, 0x75, 0x03, 0x04, 0x61, 0x03, 0x14,
0x24, 0x01, 0x0B, 0x3B, 0x01, 0x15, 0x5E, 0x01, 0x02, 0x5B,
0x01, 0x08, 0x46, 0x01, 0x12, 0x71, 0x01, 0x0E, 0x1A, 0x03,
0x02, 0x0B, 0x03, 0x12, 0x5E, 0x01, 0x06, 0x5F, 0x01, 0x07,
0x20, 0x02, 0x0C, 0x2A, 0x01, 0x16, 0x70, 0x03, 0x13, 0x4E,
0x03, 0x10, 0x4B, 0x03, 0x12, 0x73, 0x01, 0x0F, 0x0D, 0x02,
0x12, 0x71, 0x03, 0x11, 0x32, 0x01, 0x0C, 0x58, 0x01, 0x05,
0x78, 0x02, 0x0E, 0x35, 0x01, 0x10, 0x43, 0x03, 0x11, 0x62,
0x03, 0x08, 0x68, 0x03, 0x17, 0x1A, 0x03, 0x06, 0x6B, 0x01,
0x11, 0x52, 0x01, 0x03, 0x2E, 0x03, 0x08, 0x6F, 0x02, 0x04,
0x6C, 0x03, 0x06, 0x4D, 0x01, 0x08, 0x44, 0x01, 0x06, 0x34,
0x02, 0x0E, 0x6D, 0x02, 0x15, 0x40, 0x02, 0x04, 0x01, 0x02,
0x03, 0x3A, 0x01, 0x08, 0x3A, 0x02, 0x0C, 0x33, 0x01, 0x02,
0x43, 0x01, 0x12, 0x0A, 0x02, 0x06, 0x46, 0x03, 0x08, 0x08,
0x02, 0x17, 0x37, 0x03, 0x0A, 0x71, 0x01, 0x0C, 0x4C, 0x01,
0x11, 0x38, 0x03, 0x0E, 0x76, 0x01, 0x0D, 0x48, 0x01, 0x13,
0x17, 0x01, 0x17, 0x21, 0x01, 0x11, 0x42, 0x02, 0x07, 0x78,
0x02, 0x05, 0x3C, 0x01, 0x0A, 0x5A, 0x01, 0x0B, 0x0A, 0x01,
0x09, 0x01, 0x03, 0x14, 0x16, 0x02, 0x11, 0x6A, 0x02, 0x0B,
0x7B, 0x03, 0x14, 0x16, 0x01, 0x01, 0x16, 0x02, 0x12, 0x00,
0x01, 0x00, 0x45, 0x02, 0x17, 0x58, 0x02, 0x0C, 0x21, 0x02,
0x11, 0x12, 0x03, 0x01, 0x5A, 0x03, 0x04, 0x54, 0x02, 0x08,
0x43, 0x02, 0x15, 0x6B, 0x01, 0x0B, 0x1A, 0x03, 0x13, 0x58,
0x02, 0x10, 0x2E, 0x02, 0x14, 0x07, 0x03, 0x07, 0x61, 0x02,
0x12, 0x7C, 0x02, 0x00, 0x09, 0x01, 0x11, 0x41, 0x01, 0x17,
0x5E, 0x03, 0x11, 0x49, 0x01, 0x16, 0x12, 0x03, 0x11, 0x7F,
0x02, 0x06, 0x23, 0x01, 0x08, 0x08, 0x02, 0x16, 0x58, 0x02,
0x08, 0x5A, 0x01, 0x09, 0x4D, 0x01, 0x13, 0x44, 0x03, 0x01,
0x67, 0x01, 0x06, 0x29, 0x03, 0x09, 0x10, 0x01, 0x0B, 0x7B,
0x01, 0x07, 0x0E, 0x02, 0x14, 0x5E, 0x02, 0x08, 0x36, 0x03,
0x15, 0x39, 0x02, 0x0D, 0x39, 0x01, 0x0C, 0x7E, 0x01, 0x0F,
0x1F, 0x03, 0x09, 0x5B, 0x01, 0x11, 0x74, 0x03, 0x01, 0x18,
0x02, 0x02, 0x01, 0x02, 0x06, 0x02, 0x03, 0x0D, 0x02, 0x03,
0x11, 0x14, 0x02, 0x03, 0x7D, 0x02, 0x0F, 0x59, 0x01, 0x05,
0x57, 0x01, 0x0F, 0x05, 0x03, 0x08, 0x30, 0x01, 0x07, 0x2E,
0x01, 0x00, 0x70, 0x03, 0x14, 0x0C, 0x02, 0x07, 0x38, 0x02,
0x03, 0x7B, 0x02, 0x03, 0x03, 0x01, 0x05, 0x37, 0x03, 0x0B,
0x2C, 0x01, 0x16, 0x6B, 0x01, 0x04, 0x30, 0x01, 0x13, 0x77,
0x03, 0x06, 0x22, 0x02, 0x00, 0x43, 0x02, 0x11, 0x2F, 0x01,
0x02, 0x64, 0x03, 0x09, 0x30, 0x03, 0x09, 0x43, 0x02, 0x05,
0x13, 0x01, 0x07, 0x19, 0x02, 0x01, 0x0A, 0x02, 0x16, 0x3D,
0x02, 0x0E, 0x04, 0x01, 0x0C, 0x34, 0x02, 0x17, 0x67, 0x01,
0x14, 0x3B, 0x02, 0x04, 0x45, 0x02, 0x0A, 0x48, 0x01, 0x01,
0x6A, 0x02, 0x0C, 0x1F, 0x02, 0x06, 0x7C, 0x01, 0x0B, 0x00,
0x01, 0x17, 0x7B, 0x03, 0x07, 0x17, 0x01, 0x11, 0x02, 0x03,
0x03, 0x23, 0x03, 0x01, 0x2C, 0x01, 0x0F, 0x16, 0x01, 0x05,
0x6A, 0x03, 0x04, 0x65, 0x03, 0x08, 0x63, 0x03, 0x03, 0x7F,
0x01, 0x08, 0x76, 0x02, 0x15, 0x04, 0x01, 0x0B, 0x67, 0x01,
0x0C, 0x47, 0x01, 0x16, 0x4E, 0x01, 0x0F, 0x64, 0x03, 0x17,
0x4C, 0x03, 0x13, 0x40, 0x01, 0x0D, 0x2E, 0x01, 0x0D, 0x29,
0x01, 0x05, 0x4D, 0x02, 0x0E, 0x20, 0x02, 0x04, 0x48, 0x02,
0x17, 0x48, 0x02, 0x09, 0x55, 0x01, 0x09, 0x67, 0x01, 0x08,
0x0D, 0x02, 0x13, 0x08, 0x03, 0x0E, 0x44, 0x03, 0x17, 0x32,
0x02, 0x0A, 0x3B, 0x03, 0x02, 0x54, 0x02, 0x0E, 0x7B, 0x02,
0x02, 0x3E, 0x01, 0x13, 0x04, 0x03, 0x00, 0x68, 0x02, 0x05,
0x68, 0x01, 0x05, 0x26, 0x03, 0x0F, 0x6D, 0x01, 0x0F, 0x03,
0x01, 0x07, 0x03, 0x02, 0x15, 0x6D, 0x01, 0x11, 0x75, 0x01,
0x03, 0x3B, 0x02, 0x09, 0x0A, 0x03, 0x0F, 0x61, 0x02, 0x10,
0x47, 0x01, 0x04, 0x22, 0x03, 0x0F, 0x01, 0x01, 0x12, 0x55,
0x03, 0x0F, 0x4D, 0x03, 0x02, 0x59, 0x03, 0x07, 0x2F, 0x02,
0x16, 0x35, 0x01, 0x0D, 0x13, 0x02, 0x12, 0x65, 0x01, 0x11,
0x6B, 0x03, 0x06, 0x76, 0x02, 0x05, 0x7C, 0x03, 0x15, 0x0E,
0x01, 0x0D, 0x4D, 0x03, 0x00, 0x12, 0x02, 0x09, 0x2E, 0x01,
0x12, 0x7D, 0x02, 0x06, 0x3F, 0x03, 0x15, 0x51, 0x03, 0x05,
0x0A, 0x03, 0x13, 0x32, 0x03, 0x06, 0x07, 0x01, 0x0B, 0x6D,
0x01, 0x13, 0x5D, 0x01, 0x02, 0x65, 0x02, 0x0F, 0x3B, 0x02,
0x0A, 0x14, 0x01, 0x0B, 0x02, 0x01, 0x16, 0x03, 0x03, 0x17,
0x48, 0x02, 0x0C, 0x40, 0x01, 0x14, 0x5C, 0x02, 0x17, 0x47,
0x03, 0x08, 0x15, 0x02, 0x0C, 0x3B, 0x03, 0x0C, 0x3D, 0x01,
0x05, 0x2E, 0x01, 0x15, 0x76, 0x02, 0x11, 0x6B, 0x01, 0x04,
0x7A, 0x03, 0x08, 0x61, 0x02, 0x14, 0x20, 0x03, 0x10, 0x08,
0x01, 0x0F, 0x19, 0x02, 0x07, 0x78, 0x02, 0x00, 0x5C, 0x01,
0x16, 0x07, 0x01, 0x16, 0x7E, 0x03, 0x05, 0x46, 0x02, 0x01,
0x10, 0x02, 0x01, 0x22, 0x03, 0x05, 0x7D, 0x03, 0x0B, 0x36,
0x01, 0x11, 0x54, 0x03, 0x12, 0x70, 0x01, 0x06, 0x19, 0x03,
0x0C, 0x56, 0x01, 0x07, 0x00, 0x01, 0x03, 0x15, 0x02, 0x02,
0x66, 0x01, 0x07, 0x6D, 0x02, 0x02, 0x62, 0x02, 0x04, 0x13,
0x02, 0x08, 0x76, 0x01, 0x11, 0x1F, 0x02, 0x06, 0x4A, 0x03,
0x0C, 0x25, 0x03, 0x16, 0x6A, 0x01, 0x16, 0x7B, 0x01, 0x16,
0x65, 0x03, 0x01, 0x05, 0x03, 0x03, 0x35, 0x03, 0x06, 0x46,
0x01, 0x05, 0x25, 0x02, 0x0E, 0x4D, 0x01, 0x0A, 0x6E, 0x02,
0x0F, 0x69, 0x01, 0x01, 0x20, 0x02, 0x0A, 0x62, 0x01, 0x15,
0x24, 0x03, 0x15, 0x1F, 0x03, 0x0D, 0x75, 0x01, 0x10, 0x4B,
0x02, 0x10, 0x1D, 0x02, 0x10, 0x20, 0x02, 0x13, 0x72, 0x01,
0x09, 0x25, 0x01, 0x05, 0x77, 0x03, 0x00, 0x77, 0x03, 0x08,
0x57, 0x01, 0x06, 0x39, 0x01, 0x09, 0x4B, 0x03, 0x0E, 0x2F,
0x02, 0x13, 0x60, 0x02, 0x09, 0x09, 0x03, 0x15, 0x1C, 0x03,
0x07, 0x03, 0x03, 0x01, 0x7C, 0x03, 0x04, 0x62, 0x03, 0x03,
0x4C, 0x03, 0x0E, 0x12, 0x03, 0x0C, 0x4B, 0x03, 0x0F, 0x4F,
0x02, 0x17, 0x4A, 0x01, 0x11, 0x1E, 0x01, 0x00, 0x7C, 0x03,
0x03, 0x12, 0x03, 0x02, 0x53, 0x03, 0x01, 0x6E, 0x02, 0x00,
0x1C, 0x03, 0x09, 0x13, 0x02, 0x03, 0x41, 0x01, 0x11, 0x12,
0x02, 0x0D, 0x55, 0x01, 0x13, 0x28, 0x01, 0x04, 0x20, 0x03,
0x14, 0x11, 0x02, 0x01, 0x05, 0x03, 0x04, 0x27, 0x03, 0x16,
0x50, 0x02, 0x14, 0x0C, 0x02, 0x0F, 0x32, 0x02, 0x16, 0x78,
0x03, 0x14, 0x22, 0x02, 0x0A, 0x50, 0x03, 0x13, 0x64, 0x02,
0x16, 0x52, 0x02, 0x01, 0x7A, 0x02, 0x04, 0x24, 0x01, 0x06,
0x71, 0x01, 0x0C, 0x75, 0x02, 0x17, 0x1B, 0x03, 0x0D, 0x5C,
0x01, 0x10, 0x6E, 0x02, 0x15, 0x36, 0x01, 0x0F, 0x55, 0x03,
0x13, 0x23, 0x03, 0x17, 0x79, 0x03, 0x13, 0x17, 0x03, 0x0D,
0x54, 0x01, 0x0A, 0x72, 0x02, 0x15, 0x01, 0x01, 0x15, 0x4C,
0x02, 0x03, 0x5C, 0x03, 0x0E, 0x30, 0x02, 0x0D, 0x30, 0x03,
0x0B, 0x47, 0x01, 0x17, 0x0F, 0x02, 0x0D, 0x5D, 0x02, 0x12,
0x38, 0x02, 0x0A, 0x11, 0x01, 0x00, 0x7A, 0x01, 0x00, 0x5A,
0x02, 0x06, 0x1E, 0x03, 0x0A, 0x1E, 0x02, 0x00, 0x70, 0x03,
0x0A, 0x55, 0x01, 0x00, 0x7F, 0x01, 0x0D, 0x70, 0x02, 0x11,
0x6A, 0x02, 0x12, 0x7C, 0x01, 0x08, 0x46, 0x01, 0x0B, 0x0E,
0x03, 0x08, 0x4F, 0x02, 0x14, 0x73, 0x03, 0x14, 0x36, 0x01,
0x0A, 0x7B, 0x02, 0x00, 0x79, 0x03, 0x09, 0x4F, 0x01, 0x11,
0x21, 0x03, 0x01, 0x34, 0x02, 0x11, 0x78, 0x03, 0x15, 0x01,
0x03, 0x08, 0x2A, 0x02, 0x07, 0x70, 0x02, 0x02, 0x56, 0x01,
0x01, 0x3E, 0x02, 0x02, 0x77, 0x01, 0x08, 0x75, 0x01, 0x05,
0x07, 0x02, 0x07, 0x18, 0x03, 0x09, 0x3B, 0x03, 0x12, 0x34,
0x01, 0x0B, 0x3D, 0x03, 0x0F, 0x3D, 0x03, 0x17, 0x11, 0x01,
0x0E, 0x5E, 0x01, 0x0D, 0x68, 0x02, 0x0B, 0x25, 0x03, 0x07,
0x1B, 0x02, 0x0A, 0x52, 0x03, 0x0F, 0x03, 0x03, 0x08, 0x61,
0x01, 0x16, 0x2E, 0x03, 0x0E, 0x05, 0x01, 0x08, 0x12, 0x02,
0x03, 0x59, 0x03, 0x0D, 0x63, 0x02, 0x08, 0x14, 0x02, 0x07,
0x60, 0x02, 0x06, 0x45, 0x03, 0x05, 0x17, 0x03, 0x0C, 0x63,
0x03, 0x0B, 0x66, 0x02, 0x06, 0x2F, 0x01, 0x0D, 0x0E, 0x02,
0x00, 0x08, 0x01, 0x0C, 0x3C, 0x03, 0x07, 0x33, 0x03, 0x11,
0x14, 0x02, 0x14, 0x51, 0x03, 0x17, 0x26, 0x01, 0x0B, 0x79,
0x01, 0x03, 0x09, 0x02, 0x00, 0x75, 0x01, 0x11, 0x07, 0x01,
0x00, 0x6F, 0x02, 0x16, 0x7F, 0x03, 0x17, 0x49, 0x03, 0x11,
0x42, 0x03, 0x17, 0x57, 0x01, 0x10, 0x60, 0x02, 0x01, 0x66,
0x01, 0x17, 0x53, 0x03, 0x00, 0x0D, 0x01, 0x0A, 0x17, 0x03,
0x0D, 0x44, 0x02, 0x0C, 0x24, 0x01, 0x14, 0x4A, 0x02, 0x10,
0x71, 0x03, 0x00, 0x15, 0x01, 0x0C, 0x46, 0x03, 0x0C, 0x73,
0x03, 0x12, 0x51, 0x03, 0x06, 0x52, 0x03, 0x12, 0x2A, 0x03,
0x17, 0x32, 0x01, 0x0E, 0x19, 0x01, 0x0C, 0x56, 0x03, 0x13,
0x0C, 0x03, 0x0F, 0x5D, 0x01, 0x08, 0x2E, 0x02, 0x00, 0x56,
0x02, 0x0A, 0x01, 0x02, 0x14, 0x1F, 0x03, 0x05, 0x22, 0x01,
0x14, 0x08, 0x02, 0x17, 0x24, 0x02, 0x00, 0x0A, 0x01, 0x10,
0x3B, 0x02, 0x05, 0x0C, 0x02, 0x13, 0x4A, 0x02, 0x17, 0x6E,
0x01, 0x0B, 0x21, 0x01, 0x16, 0x1F, 0x03, 0x0D, 0x2C, 0x01,
0x0D, 0x5C, 0x03, 0x11, 0x27, 0x03, 0x12, 0x35, 0x02, 0x01,
0x60, 0x03, 0x0B, 0x0F, 0x03, 0x15, 0x7D, 0x03, 0x09, 0x5C,
0x03, 0x01, 0x74, 0x03, 0x06, 0x77, 0x01, 0x08, 0x26, 0x03,
0x0F, 0x05, 0x02, 0x00, 0x0B, 0x03, 0x12, 0x2B, 0x01, 0x15,
0x65, 0x01, 0x08, 0x01, 0x01, 0x03, 0x7F, 0x01, 0x04, 0x42,
0x02, 0x07, 0x56, 0x03, 0x16, 0x3C, 0x03, 0x05, 0x20, 0x02,
0x15, 0x51, 0x02, 0x05, 0x11, 0x02, 0x0C, 0x07, 0x03, 0x05,
0x79, 0x03, 0x02, 0x25, 0x02, 0x17, 0x66, 0x03, 0x16, 0x7E,
0x02, 0x13, 0x0B, 0x01, 0x12, 0x7F, 0x02, 0x13, 0x51, 0x02,
0x0B, 0x3A, 0x01, 0x12, 0x39, 0x01, 0x0B, 0x56, 0x02, 0x0E,
0x2A, 0x01, 0x08, 0x09, 0x01, 0x0A, 0x26, 0x01, 0x06, 0x1D,
0x03, 0x08, 0x5B, 0x02, 0x0E, 0x6A, 0x02, 0x04, 0x20, 0x01,
0x04, 0x09, 0x02, 0x10, 0x4C, 0x03, 0x11, 0x29, 0x03, 0x07,
0x6D, 0x01, 0x07, 0x52, 0x01, 0x10, 0x1D, 0x02, 0x02, 0x56,
0x01, 0x01, 0x1E, 0x03, 0x12, 0x33, 0x02, 0x09, 0x54, 0x02,
0x01, 0x19, 0x01, 0x03, 0x7B, 0x03, 0x09, 0x43, 0x01, 0x17,
0x39, 0x03, 0x16, 0x45, 0x02, 0x13, 0x63, 0x01, 0x06, 0x19,
0x03, 0x06, 0x1D, 0x02, 0x08, 0x56, 0x02, 0x0B, 0x25, 0x01,
0x05, 0x5C, 0x02, 0x02, 0x7E, 0x01, 0x0F, 0x7D, 0x02, 0x16,
0x11, 0x03, 0x11, 0x1A, 0x01, 0x05, 0x19, 0x03, 0x0F, 0x6E,
0x03, 0x15, 0x47, 0x03, 0x15, 0x05, 0x01, 0x08, 0x45, 0x03,
0x03, 0x69, 0x02, 0x17, 0x41, 0x01, 0x08, 0x4A, 0x01, 0x08,
0x20, 0x02, 0x12, 0x5F, 0x01, 0x17, 0x79, 0x01, 0x17, 0x65,
0x03, 0x01, 0x38, 0x01, 0x0B, 0x00, 0x01, 0x15, 0x51, 0x01,
0x03, 0x27, 0x02, 0x12, 0x62, 0x01, 0x06, 0x04, 0x01, 0x0C,
0x00, 0x01, 0x04, 0x2A, 0x02, 0x0A, 0x2A, 0x03, 0x0F, 0x7D,
0x03, 0x0D, 0x00, 0x01, 0x10, 0x10, 0x03, 0x0F, 0x3A, 0x03,
0x16, 0x65, 0x03, 0x06, 0x17, 0x01, 0x04, 0x7F, 0x01, 0x0A,
0x6D, 0x01, 0x12, 0x38, 0x01, 0x09, 0x67, 0x03, 0x01, 0x36,
0x02, 0x10, 0x25, 0x02, 0x0A, 0x25, 0x01, 0x06, 0x69, 0x03,
0x08, 0x27, 0x01, 0x0B, 0x78, 0x02, 0x05, 0x56, 0x01, 0x03,
0x13, 0x03, 0x04, 0x2A, 0x02, 0x12, 0x53, 0x02, 0x01, 0x36,
0x03, 0x09, 0x37, 0x02, 0x08, 0x2F, 0x02, 0x08, 0x15, 0x02,
0x16, 0x5F, 0x02, 0x07, 0x29, 0x03, 0x14, 0x0F, 0x01, 0x11,
0x2C, 0x02, 0x0C, 0x60, 0x03, 0x06, 0x3E, 0x01, 0x07, 0x14,
0x01, 0x07, 0x54, 0x02, 0x07, 0x21, 0x02, 0x08, 0x28, 0x02,
0x0A, 0x36, 0x02, 0x05, 0x00, 0x02, 0x17, 0x16, 0x02, 0x01,
0x1E, 0x03, 0x01, 0x2A, 0x01, 0x03, 0x09, 0x03, 0x02, 0x00,
0x03, 0x15, 0x5B, 0x02, 0x09, 0x40, 0x02, 0x09, 0x6E, 0x01,
0x01, 0x75, 0x03, 0x03, 0x79, 0x01, 0x00, 0x11, 0x03, 0x0C,
0x47, 0x03, 0x01, 0x37, 0x01, 0x11, 0x05, 0x02, 0x15, 0x4F,
0x01, 0x05, 0x3A, 0x01, 0x0D, 0x52, 0x01, 0x0C, 0x36, 0x02,
0x13, 0x2D, 0x03, 0x11, 0x65, 0x02, 0x0B, 0x11, 0x03, 0x11,
0x58, 0x03, 0x07, 0x3D, 0x02, 0x12, 0x27, 0x03, 0x06, 0x53,
0x01, 0x17, 0x5E, 0x01, 0x0D, 0x7D, 0x03, 0x16, 0x1C, 0x03,
0x11, 0x16, 0x01, 0x08, 0x52, 0x01, 0x15, 0x58, 0x03, 0x0A,
0x08, 0x01, 0x11, 0x3F, 0x01, 0x0B, 0x26, 0x02, 0x03, 0x6C,
0x01, 0x04, 0x75, 0x03, 0x13, 0x34, 0x01, 0x16, 0x13, 0x02,
0x0B, 0x33, 0x01, 0x00, 0x56, 0x03, 0x12, 0x0C, 0x02, 0x14,
0x55, 0x01, 0x0A, 0x72, 0x01, 0x07, 0x4D, 0x01, 0x16, 0x50,
0x03, 0x06, 0x76, 0x02, 0x09, 0x28, 0x02, 0x00, 0x07, 0x01,
0x16, 0x3E, 0x02, 0x0F, 0x4A, 0x01, 0x03, 0x1D, 0x02, 0x0A,
0x63, 0x03, 0x05, 0x3A, 0x01, 0x04, 0x1A, 0x02, 0x02, 0x03,
0x03, 0x05, 0x45, 0x02, 0x12, 0x41, 0x01, 0x09, 0x66, 0x03,
0x01, 0x4C, 0x02, 0x10, 0x65, 0x03, 0x01, 0x6F, 0x01, 0x15,
0x61, 0x02, 0x03, 0x0F, 0x01, 0x08, 0x66, 0x02, 0x0E, 0x5C,
0x02, 0x08, 0x45, 0x02, 0x0C, 0x6A, 0x01, 0x03, 0x4F, 0x03,
0x03, 0x6B, 0x02, 0x04, 0x74, 0x02, 0x05, 0x70, 0x02, 0x11,
0x68, 0x02, 0x0A, 0x6B, 0x01, 0x0C, 0x32, 0x03, 0x11, 0x13,
0x01, 0x10, 0x4F, 0x01, 0x0F, 0x55, 0x03, 0x0A, 0x54, 0x01,
0x11, 0x66, 0x01, 0x17, 0x3F, 0x02, 0x03, 0x71, 0x01, 0x08,
0x1C, 0x03, 0x11, 0x7D, 0x02, 0x0B, 0x1B, 0x01, 0x06, 0x23,
0x02, 0x01, 0x35, 0x01, 0x03, 0x3B, 0x03, 0x01, 0x0A, 0x03,
0x0F, 0x10, 0x01, 0x0D, 0x50, 0x02, 0x15, 0x44, 0x01, 0x07,
0x42, 0x03, 0x00, 0x26, 0x01, 0x0C, 0x6B, 0x01, 0x05, 0x60,
0x01, 0x0B, 0x15, 0x02, 0x0F, 0x61, 0x01, 0x17, 0x67, 0x03,
0x0B, 0x3B, 0x03, 0x11, 0x3E, 0x03, 0x00, 0x10, 0x01, 0x07,
0x3E, 0x03, 0x07, 0x40, 0x01, 0x04, 0x05, 0x02, 0x11, 0x3B,
0x01, 0x0E, 0x02, 0x02, 0x15, 0x27, 0x02, 0x0C, 0x68, 0x03,
0x09, 0x54, 0x01, 0x04, 0x3D, 0x03, 0x09, 0x48, 0x03, 0x03,
0x50, 0x02, 0x13, 0x27, 0x03, 0x15, 0x6D, 0x02, 0x02, 0x1F,
0x01, 0x17, 0x62, 0x02, 0x07, 0x5B, 0x01, 0x12, 0x71, 0x03,
0x15, 0x6B, 0x01, 0x0B, 0x73, 0x03, 0x04, 0x49, 0x01, 0x0A,
0x1A, 0x02, 0x17, 0x10, 0x02, 0x0E, 0x3C, 0x01, 0x02, 0x24,
0x01, 0x0C, 0x0C, 0x02, 0x04, 0x19, 0x03, 0x04, 0x20, 0x02,
0x12, 0x6D, 0x02, 0x0D, 0x36, 0x02, 0x09, 0x36, 0x03, 0x11,
0x4E, 0x01, 0x03, 0x3C, 0x03, 0x0E, 0x0E, 0x02, 0x01, 0x37,
0x01, 0x05, 0x72, 0x01, 0x15, 0x6D, 0x01, 0x08, 0x08, 0x01,
0x14, 0x67, 0x03, 0x02, 0x5C, 0x03, 0x17, 0x7C, 0x02, 0x07,
0x0A, 0x01, 0x14, 0x15, 0x02, 0x11, 0x5D, 0x02, 0x13, 0x19,
0x02, 0x0E, 0x09, 0x02, 0x16, 0x4E, 0x03, 0x10, 0x09, 0x03,
0x12, 0x50, 0x01, 0x0E, 0x67, 0x03, 0x13, 0x56, 0x01, 0x0F,
0x01, 0x03, 0x15, 0x31, 0x02, 0x0B, 0x64, 0x02, 0x17, 0x0A,
0x01, 0x01, 0x70, 0x02, 0x10, 0x2C, 0x02, 0x0E, 0x43, 0x03,
0x01, 0x79, 0x01, 0x13, 0x6B, 0x02, 0x17, 0x43, 0x01, 0x14,
0x2F, 0x03, 0x0D, 0x30, 0x03, 0x03, 0x57, 0x01, 0x0F, 0x64,
0x01, 0x0D, 0x0F, 0x03, 0x17, 0x1E, 0x03, 0x15, 0x7F, 0x01,
0x10, 0x02, 0x02, 0x06, 0x3C, 0x01, 0x09, 0x10, 0x03, 0x06,
0x42, 0x02, 0x0A, 0x0B, 0x02, 0x0F, 0x66, 0x02, 0x07, 0x44,
0x03, 0x01, 0x70, 0x02, 0x11, 0x58, 0x01, 0x06, 0x1F, 0x02,
0x11, 0x31, 0x03, 0x0A, 0x25, 0x02, 0x0C, 0x04, 0x02, 0x04,
0x23, 0x02, 0x05, 0x1D, 0x02, 0x04, 0x2C, 0x01, 0x0D, 0x5F,
0x01, 0x03, 0x5F, 0x03, 0x0E, 0x13, 0x03, 0x14, 0x63, 0x03,
0x0F, 0x07, 0x03, 0x05, 0x43, 0x03, 0x15, 0x35, 0x03, 0x17,
0x72, 0x03, 0x05, 0x6E, 0x03, 0x02, 0x77, 0x02, 0x16, 0x7D,
0x01, 0x0E, 0x51, 0x03, 0x08, 0x40, 0x02, 0x17, 0x5E, 0x03,
0x04, 0x6B, 0x02, 0x0F, 0x7D, 0x03, 0x0A, 0x30, 0x01, 0x03,
0x76, 0x02, 0x15, 0x51, 0x02, 0x06, 0x77, 0x02, 0x17, 0x19,
0x02, 0x05, 0x23, 0x02, 0x04, 0x23, 0x02, 0x15, 0x57, 0x03,
0x03, 0x30, 0x02, 0x03, 0x5E, 0x03, 0x10, 0x2C, 0x01, 0x10,
0x38, 0x02, 0x11, 0x2D, 0x01, 0x04, 0x77, 0x02, 0x08, 0x57,
0x03, 0x0D, 0x27, 0x03, 0x00, 0x38, 0x03, 0x06, 0x32, 0x02,
0x12, 0x0D, 0x02, 0x10, 0x30, 0x02, 0x17, 0x09, 0x01, 0x0D,
0x23, 0x03, 0x02, 0x59, 0x01, 0x17, 0x73, 0x02, 0x05, 0x27,
0x03, 0x16, 0x3D, 0x02, 0x02, 0x1F, 0x02, 0x16, 0x3D, 0x03,
0x16, 0x14, 0x03, 0x14, 0x64, 0x01, 0x11, 0x4E, 0x02, 0x0A,
0x09, 0x01, 0x07, 0x2E, 0x01, 0x08, 0x25, 0x02, 0x0B, 0x0A,
0x03, 0x0E, 0x61, 0x02, 0x08, 0x69, 0x03, 0x06, 0x2C, 0x02,
0x16, 0x69, 0x03, 0x16, 0x1C, 0x01, 0x0A, 0x56, 0x01, 0x16,
0x72, 0x03, 0x07, 0x6F, 0x03, 0x10, 0x19, 0x01, 0x07, 0x0F,
0x02, 0x14, 0x29, 0x02, 0x17, 0x48, 0x03, 0x12, 0x54, 0x03,
0x01, 0x2C, 0x02, 0x17, 0x0F, 0x03, 0x02, 0x44, 0x02, 0x07,
0x6A, 0x03, 0x15, 0x2B, 0x01, 0x06, 0x3D, 0x03, 0x0B, 0x50,
0x03, 0x14, 0x60, 0x02, 0x04, 0x57, 0x01, 0x11, 0x77, 0x03,
0x02, 0x2F, 0x01, 0x01, 0x07, 0x03, 0x13, 0x5B, 0x03, 0x17,
0x28, 0x01, 0x16, 0x22, 0x01, 0x17, 0x58, 0x01, 0x13, 0x14,
0x02, 0x14, 0x44, 0x02, 0x17, 0x1D, 0x03, 0x15, 0x05, 0x03,
0x14, 0x0E, 0x01, 0x17, 0x10, 0x01, 0x00, 0x16, 0x03, 0x07,
0x7B, 0x01, 0x0F, 0x03, 0x02, 0x0D, 0x6A, 0x03, 0x0A, 0x72,
0x03, 0x09, 0x3E, 0x03, 0x10, 0x7E, 0x01, 0x15, 0x78, 0x02,
0x01, 0x36, 0x02, 0x12, 0x17, 0x01, 0x07, 0x38, 0x03, 0x03,
0x62, 0x02, 0x0C, 0x2A, 0x01, 0x15, 0x4B, 0x02, 0x0B, 0x15,
0x01, 0x13, 0x4D, 0x02, 0x12, 0x72, 0x03, 0x03, 0x38, 0x03,
0x08, 0x12, 0x02, 0x0A, 0x3C, 0x02, 0x13, 0x44, 0x01, 0x08,
0x78, 0x03, 0x05, 0x27, 0x02, 0x03, 0x62, 0x02, 0x07, 0x5D,
0x02, 0x0B, 0x08, 0x02, 0x0B, 0x16, 0x02, 0x10, 0x03, 0x03,
0x08, 0x22, 0x03, 0x16, 0x1A, 0x02, 0x05, 0x4A, 0x03, 0x03,
0x28, 0x03, 0x15, 0x3F, 0x03, 0x01, 0x3B, 0x03, 0x09, 0x6F,
0x02, 0x0F, 0x1F, 0x01, 0x0B, 0x4B, 0x01, 0x16, 0x48, 0x02,
0x0A, 0x2B, 0x03, 0x0A, 0x01, 0x03, 0x0E, 0x2C, 0x03, 0x03,
0x2B, 0x01, 0x13, 0x2D, 0x03, 0x08, 0x30, 0x02, 0x13, 0x26,
0x01, 0x06, 0x48, 0x03, 0x0C, 0x0B, 0x03, 0x14, 0x13, 0x03,
0x14, 0x51, 0x03, 0x17, 0x5B, 0x02, 0x11, 0x1C, 0x01, 0x04,
0x34, 0x02, 0x09, 0x5E, 0x02, 0x0B, 0x0C, 0x03, 0x15, 0x1B,
0x02, 0x07, 0x32, 0x01, 0x0F, 0x25, 0x01, 0x04, 0x46, 0x03,
0x15, 0x4C, 0x03, 0x10, 0x70, 0x01, 0x08, 0x34, 0x01, 0x04,
0x2E, 0x02, 0x06, 0x3B, 0x03, 0x0A, 0x63, 0x01, 0x15, 0x08,
0x02, 0x05, 0x56, 0x03, 0x04, 0x1A, 0x03, 0x09, 0x69, 0x01,
0x02, 0x4B, 0x02, 0x16, 0x0F, 0x03, 0x10, 0x57, 0x03, 0x08,
0x12, 0x02, 0x03, 0x1D, 0x01, 0x0E, 0x7F, 0x02, 0x13, 0x55,
0x01, 0x11, 0x71, 0x03, 0x0C, 0x55, 0x02, 0x17, 0x7F, 0x01,
0x0C, 0x22, 0x03, 0x14, 0x5A, 0x01, 0x05, 0x19, 0x01, 0x02,
0x0F, 0x02, 0x12, 0x0E, 0x03, 0x03, 0x52, 0x02, 0x05, 0x16,
0x02, 0x11, 0x58, 0x01, 0x0E, 0x28, 0x01, 0x10, 0x16, 0x02,
0x0F, 0x55, 0x02, 0x0C, 0x0A, 0x03, 0x15, 0x0E, 0x02, 0x16,
0x64, 0x01, 0x0B, 0x20, 0x01, 0x06, 0x4A, 0x01, 0x04, 0x3C,
0x02, 0x06, 0x10, 0x03, 0x02, 0x3B, 0x01, 0x0C, 0x77, 0x02,
0x03, 0x06, 0x03, 0x17, 0x4F, 0x01, 0x02, 0x11, 0x02, 0x0E,
0x26, 0x01, 0x09, 0x43, 0x01, 0x01, 0x05, 0x01, 0x0A, 0x0C,
0x01, 0x10, 0x05, 0x03, 0x03, 0x07, 0x03, 0x13, 0x3C, 0x03,
0x01, 0x24, 0x03, 0x11, 0x0E, 0x02, 0x14, 0x27, 0x01, 0x06,
0x1B, 0x01, 0x0F, 0x6D, 0x03, 0x07, 0x67, 0x03, 0x07, 0x5C,
0x03, 0x03, 0x4E, 0x01, 0x0D, 0x11, 0x03, 0x0F, 0x5F, 0x03,
0x14, 0x4B, 0x02, 0x17, 0x32, 0x03, 0x00, 0x1A, 0x01, 0x02,
0x53, 0x03, 0x0E, 0x7B, 0x01, 0x15, 0x1C, 0x02, 0x08, 0x42,
0x01, 0x0B, 0x62, 0x01, 0x15, 0x33, 0x01, 0x16, 0x66, 0x02,
0x00, 0x54, 0x01, 0x11, 0x5E, 0x02, 0x16, 0x45, 0x03, 0x10,
0x5B, 0x02, 0x17, 0x33, 0x03, 0x01, 0x0E, 0x01, 0x08, 0x1A,
0x02, 0x05, 0x1C, 0x01, 0x11, 0x26, 0x03, 0x0F, 0x55, 0x01,
0x08, 0x04, 0x03, 0x0E, 0x13, 0x03, 0x02, 0x15, 0x01, 0x11,
0x6D, 0x01, 0x17, 0x27, 0x01, 0x0A, 0x1A, 0x02, 0x0A, 0x4F,
0x02, 0x02, 0x25, 0x02, 0x0B, 0x3C, 0x02, 0x07, 0x1F, 0x02,
0x07, 0x7C, 0x02, 0x08, 0x78, 0x03, 0x0E, 0x22, 0x03, 0x11,
0x07, 0x02, 0x15, 0x29, 0x03, 0x04, 0x05, 0x02, 0x15, 0x40,
0x01, 0x04, 0x4D, 0x02, 0x0A, 0x00, 0x02, 0x00, 0x07, 0x03,
0x05, 0x2E, 0x02, 0x08, 0x0E, 0x02, 0x11, 0x4A, 0x03, 0x16,
0x7E, 0x02, 0x02, 0x62, 0x03, 0x15, 0x55, 0x02, 0x13, 0x10,
0x02, 0x00, 0x3E, 0x02, 0x02, 0x7A, 0x03, 0x14, 0x66, 0x01,
0x10, 0x18, 0x01, 0x05, 0x68, 0x01, 0x02, 0x04, 0x02, 0x07,
0x5D, 0x03, 0x06, 0x6E, 0x03, 0x0C, 0x76, 0x02, 0x14, 0x7B,
0x02, 0x09, 0x4A, 0x01, 0x11, 0x58, 0x02, 0x03, 0x09, 0x03,
0x00, 0x5B, 0x02, 0x17, 0x54, 0x01, 0x05, 0x5A, 0x02, 0x09,
0x19, 0x01, 0x06, 0x57, 0x01, 0x15, 0x76, 0x02, 0x17, 0x52,
0x03, 0x11, 0x7C, 0x03, 0x06, 0x1E, 0x02, 0x17, 0x42, 0x02,
0x09, 0x55, 0x01, 0x14, 0x69, 0x01, 0x0E, 0x64, 0x03, 0x13,
0x1E, 0x03, 0x0C, 0x7B, 0x02, 0x01, 0x70, 0x03, 0x05, 0x20,
0x02, 0x13, 0x4C, 0x03, 0x01, 0x09, 0x03, 0x05, 0x27, 0x01,
0x0D, 0x3E, 0x03, 0x02, 0x40, 0x01, 0x02, 0x16, 0x02, 0x08,
0x7E, 0x02, 0x01, 0x2F, 0x02, 0x12, 0x73, 0x03, 0x08, 0x75,
0x02, 0x09, 0x4E, 0x03, 0x0C, 0x2A, 0x01, 0x11, 0x22, 0x01,
0x05, 0x5D, 0x03, 0x0B, 0x1F, 0x01, 0x13, 0x63, 0x01, 0x0E,
0x5B, 0x01, 0x0C, 0x55, 0x02, 0x03, 0x72, 0x02, 0x0A, 0x27,
0x02, 0x0E, 0x31, 0x01, 0x08, 0x45, 0x01, 0x13, 0x7C, 0x03,
0x17, 0x04, 0x01, 0x14, 0x49, 0x02, 0x08, 0x11, 0x03, 0x07,
0x01, 0x03, 0x01, 0x25, 0x03, 0x11, 0x70, 0x03, 0x08, 0x08,
0x03, 0x11, 0x6C, 0x01, 0x03, 0x39, 0x01, 0x0A, 0x68, 0x01,
0x0C, 0x3E, 0x02, 0x0A, 0x47, 0x02, 0x0F, 0x08, 0x02, 0x03,
0x38, 0x02, 0x07, 0x67, 0x02, 0x15, 0x49, 0x03, 0x11, 0x7B,
0x02, 0x0A, 0x0A, 0x02, 0x06, 0x4E, 0x01, 0x0B, 0x11, 0x01,
0x15, 0x04, 0x02, 0x11, 0x6F, 0x01, 0x07, 0x3E, 0x02, 0x12,
0x18, 0x01, 0x00, 0x6D, 0x02, 0x14, 0x7A, 0x03, 0x09, 0x06,
0x02, 0x17, 0x70, 0x01, 0x0F, 0x4D, 0x02, 0x02, 0x08, 0x02,
0x0D, 0x69, 0x02, 0x01, 0x3D, 0x01, 0x0A, 0x0F, 0x01, 0x09,
0x6F, 0x01, 0x17, 0x23, 0x03, 0x0E, 0x75, 0x03, 0x06, 0x5A,
0x01, 0x15, 0x09, 0x02, 0x14, 0x40, 0x02, 0x03, 0x4A, 0x03,
0x11, 0x09, 0x03, 0x03, 0x7A, 0x03, 0x00, 0x02, 0x02, 0x07,
0x68, 0x03, 0x17, 0x32, 0x01, 0x04, 0x3C, 0x01, 0x0F, 0x35,
0x03, 0x0E, 0x4D, 0x03, 0x0C, 0x05, 0x03, 0x06, 0x52, 0x03,
0x08, 0x76, 0x01, 0x10, 0x56, 0x02, 0x0B, 0x22, 0x02, 0x0B,
0x69, 0x01, 0x0E, 0x00, 0x02, 0x04, 0x4E, 0x01, 0x14, 0x11,
0x02, 0x03, 0x18, 0x02, 0x0D, 0x40, 0x02, 0x16, 0x53, 0x01,
0x11, 0x00, 0x02, 0x0E, 0x71, 0x01, 0x17, 0x1D, 0x02, 0x0E,
0x11, 0x03, 0x01, 0x38, 0x03, 0x07, 0x6F, 0x01, 0x07, 0x1E,
0x02, 0x10, 0x38, 0x01, 0x11, 0x67, 0x01, 0x13, 0x0C, 0x01,
0x01, 0x47, 0x02, 0x17, 0x7C, 0x01, 0x0C, 0x2D, 0x01, 0x06,
0x17, 0x03, 0x00, 0x56, 0x01, 0x0A, 0x60, 0x02, 0x14, 0x64,
0x03, 0x0C, 0x55, 0x03, 0x0A, 0x0E, 0x02, 0x11, 0x19, 0x03,
0x08, 0x03, 0x02, 0x17, 0x5F, 0x02, 0x13, 0x12, 0x03, 0x04,
0x16, 0x02, 0x0C, 0x0C, 0x02, 0x05, 0x52, 0x01, 0x15, 0x78,
0x01, 0x13, 0x34, 0x03, 0x09, 0x0F, 0x03, 0x0A, 0x72, 0x02,
0x10, 0x60, 0x01, 0x13, 0x2F, 0x02, 0x02, 0x01, 0x01, 0x04,
0x15, 0x02, 0x0D, 0x44, 0x03, 0x10, 0x19, 0x03, 0x05, 0x1F,
0x01, 0x00, 0x4E, 0x02, 0x05, 0x2B, 0x02, 0x09, 0x61, 0x02,
0x16, 0x07, 0x03, 0x09, 0x0C, 0x01, 0x17, 0x64, 0x01, 0x0E,
0x35, 0x03, 0x09, 0x63, 0x02, 0x17, 0x48, 0x01, 0x15, 0x7A,
0x01, 0x0B, 0x7F, 0x01, 0x0B, 0x66, 0x03, 0x0A, 0x0F, 0x02,
0x0E, 0x46, 0x02, 0x08, 0x31, 0x03, 0x0F, 0x6F, 0x01, 0x14,
0x1B, 0x03, 0x09, 0x69, 0x01, 0x07, 0x37, 0x02, 0x09, 0x02,
0x02, 0x04, 0x5E, 0x01, 0x05, 0x3C, 0x02, 0x0D, 0x2D, 0x03,
0x09, 0x02, 0x02, 0x14, 0x06, 0x03, 0x12, 0x77, 0x02, 0x08,
0x15, 0x01, 0x09, 0x38, 0x03, 0x12, 0x36, 0x02, 0x09, 0x69,
0x01, 0x14, 0x55, 0x02, 0x13, 0x68, 0x03, 0x17, 0x2B, 0x01,
0x0C, 0x23, 0x03, 0x00, 0x12, 0x01, 0x11, 0x1C, 0x03, 0x12,
0x61, 0x03, 0x11, 0x58, 0x02, 0x11, 0x17, 0x02, 0x06, 0x42,
0x02, 0x08, 0x48, 0x01, 0x16, 0x2B, 0x01, 0x0D, 0x07, 0x03,
0x0E, 0x03, 0x03, 0x08, 0x54, 0x03, 0x02, 0x36, 0x03, 0x11,
0x6C, 0x01, 0x16, 0x37, 0x02, 0x10, 0x02, 0x01, 0x12, 0x78,
0x02, 0x11, 0x79, 0x01, 0x08, 0x22, 0x01, 0x15, 0x74, 0x02,
0x0E, 0x78, 0x01, 0x0D, 0x4B, 0x01, 0x08, 0x2D, 0x03, 0x0E,
0x76, 0x01, 0x14, 0x13, 0x01, 0x0C, 0x05, 0x03, 0x16, 0x3B,
0x03, 0x0B, 0x40, 0x02, 0x0B, 0x56, 0x01, 0x07, 0x26, 0x01,
0x0F, 0x5B, 0x03, 0x05, 0x1B, 0x02, 0x0E, 0x7F, 0x01, 0x06,
0x02, 0x03, 0x0B, 0x00, 0x03, 0x17, 0x73, 0x02, 0x09, 0x52,
0x03, 0x09, 0x48, 0x02, 0x0A, 0x4A, 0x03, 0x08, 0x35, 0x03,
0x0E, 0x51, 0x01, 0x15, 0x24, 0x03, 0x08, 0x77, 0x02, 0x07,
0x4A, 0x01, 0x0F, 0x05, 0x03, 0x05, 0x67, 0x02, 0x0F, 0x44,
0x01, 0x0A, 0x07, 0x01, 0x00, 0x10, 0x02, 0x00, 0x08, 0x01,
0x0E, 0x59, 0x01, 0x0E, 0x4E, 0x01, 0x0D, 0x75, 0x03, 0x0D,
0x07, 0x02, 0x0B, 0x79, 0x03, 0x04, 0x5E, 0x03, 0x05, 0x0A,
0x02, 0x0F, 0x07, 0x02, 0x0C, 0x0C, 0x02, 0x04, 0x66, 0x02,
0x03, 0x59, 0x02, 0x15, 0x17, 0x03, 0x02, 0x75, 0x01, 0x05,
0x74, 0x02, 0x0B, 0x27, 0x01, 0x08, 0x0E, 0x01, 0x00, 0x72,
0x02, 0x12, 0x0D, 0x02, 0x03, 0x04, 0x01, 0x06, 0x56, 0x01,
0x0C, 0x30, 0x02, 0x17, 0x36, 0x03, 0x00, 0x6F, 0x03, 0x09,
0x5E, 0x01, 0x02, 0x3A, 0x03, 0x12, 0x19, 0x02, 0x05, 0x01,
0x01, 0x14, 0x6F, 0x02, 0x09, 0x57, 0x02, 0x10, 0x4F, 0x03,
0x07, 0x73, 0x01, 0x14, 0x56, 0x01, 0x0B, 0x5C, 0x03, 0x0A,
0x65, 0x02, 0x11, 0x2D, 0x03, 0x15, 0x3B, 0x02, 0x11, 0x4E,
0x03, 0x08, 0x09, 0x03, 0x15, 0x2F, 0x01, 0x09, 0x48, 0x02,
0x00, 0x01, 0x01, 0x0E, 0x7E, 0x01, 0x04, 0x3A, 0x01, 0x0A,
0x28, 0x01, 0x17, 0x2C, 0x01, 0x14, 0x4C, 0x03, 0x0E, 0x5C,
0x03, 0x02, 0x50, 0x03, 0x00, 0x08, 0x01, 0x0B, 0x17, 0x03,
0x07, 0x44, 0x01, 0x0B, 0x1E, 0x03, 0x13, 0x43, 0x01, 0x10,
0x26, 0x01, 0x17, 0x30, 0x01, 0x0C, 0x43, 0x02, 0x14, 0x14,
0x02, 0x04, 0x55, 0x03, 0x15, 0x07, 0x03, 0x03, 0x46, 0x01,
0x03, 0x50, 0x01, 0x08, 0x3A, 0x02, 0x01, 0x6F, 0x02, 0x01,
0x10, 0x01, 0x13, 0x6B, 0x02, 0x14, 0x1D, 0x03, 0x14, 0x35,
0x03, 0x07, 0x27, 0x03, 0x17, 0x3D, 0x01, 0x05, 0x1E, 0x01,
0x07, 0x06, 0x03, 0x00, 0x60, 0x02, 0x15, 0x24, 0x03, 0x16,
0x7D, 0x03, 0x16, 0x18, 0x03, 0x0C, 0x0A, 0x02, 0x14, 0x7C,
0x02, 0x06, 0x45, 0x01, 0x0D, 0x05, 0x02, 0x0D, 0x4B, 0x03,
0x16, 0x69, 0x03, 0x02, 0x75, 0x03, 0x15, 0x58, 0x01, 0x0F,
0x5F, 0x01, 0x14, 0x68, 0x01, 0x17, 0x47, 0x03, 0x16, 0x25,
0x02, 0x11, 0x2A, 0x01, 0x00, 0x53, 0x03, 0x01, 0x4B, 0x02,
0x05, 0x10, 0x03, 0x01, 0x2C, 0x03, 0x12, 0x1F, 0x02, 0x13,
0x77, 0x03, 0x10, 0x65, 0x02, 0x00, 0x1B, 0x03, 0x12, 0x43,
0x03, 0x09, 0x10, 0x03, 0x16, 0x18, 0x02, 0x0F, 0x1A, 0x01,
0x09, 0x0F, 0x02, 0x13, 0x47, 0x01, 0x0C, 0x69, 0x03, 0x0F,
0x73, 0x03, 0x14, 0x10, 0x02, 0x0B, 0x6E, 0x03, 0x01, 0x40,
0x03, 0x10, 0x57, 0x02, 0x08, 0x54, 0x01, 0x0C, 0x11, 0x03,
0x10, 0x11, 0x01, 0x16, 0x01, 0x03, 0x0D, 0x61, 0x01, 0x03,
0x7F, 0x01, 0x13, 0x7C, 0x03, 0x02, 0x18, 0x01, 0x08, 0x5C,
0x02, 0x0A, 0x28, 0x01, 0x11, 0x28, 0x02, 0x01, 0x1C, 0x03,
0x10, 0x4B, 0x01, 0x0C, 0x04, 0x01, 0x0B, 0x35, 0x01, 0x10,
0x60, 0x03, 0x03, 0x2B, 0x03, 0x00, 0x1A, 0x01, 0x07, 0x78,
0x01, 0x10, 0x57, 0x02, 0x0D, 0x02, 0x01, 0x02, 0x7D, 0x03,
0x13, 0x3C, 0x01, 0x03, 0x51, 0x02, 0x0C, 0x73, 0x03, 0x10,
0x45, 0x01, 0x02, 0x3B, 0x03, 0x07, 0x32, 0x01, 0x0E, 0x09,
0x03, 0x07, 0x6F, 0x03, 0x0F, 0x46, 0x01, 0x0F, 0x47, 0x02,
0x0E, 0x61, 0x03, 0x12, 0x7C, 0x03, 0x0C, 0x0D, 0x03, 0x0D,
0x42, 0x01, 0x01, 0x5C, 0x03, 0x0A, 0x4D, 0x03, 0x16, 0x01,
0x01, 0x06, 0x6E, 0x02, 0x0F, 0x1F, 0x02, 0x13, 0x02, 0x02,
0x0C, 0x47, 0x02, 0x09, 0x33, 0x02, 0x0C, 0x0A, 0x01, 0x11,
0x2C, 0x01, 0x15, 0x08, 0x02, 0x14, 0x6F, 0x03, 0x09, 0x33,
0x03, 0x03, 0x1A, 0x03, 0x01, 0x05, 0x02, 0x04, 0x3C, 0x03,
0x11, 0x0B, 0x03, 0x03, 0x7A, 0x02, 0x12, 0x5E, 0x02, 0x14,
0x5B, 0x02, 0x13, 0x79, 0x03, 0x00, 0x5C, 0x03, 0x05, 0x67,
0x01, 0x17, 0x10, 0x01, 0x00, 0x53, 0x03, 0x0C, 0x3A, 0x01,
0x07, 0x0E, 0x03, 0x11, 0x67, 0x03, 0x03, 0x58, 0x02, 0x11,
0x32, 0x03, 0x0D, 0x28, 0x01, 0x0F, 0x44, 0x03, 0x0A, 0x26,
0x02, 0x00, 0x69, 0x02, 0x0E, 0x47, 0x01, 0x14, 0x5B, 0x03,
0x02, 0x55, 0x03, 0x01, 0x13, 0x01, 0x06, 0x47, 0x03, 0x09,
0x36, 0x02, 0x15, 0x09, 0x01, 0x06, 0x7E, 0x03, 0x04, 0x46,
0x03, 0x17, 0x2C, 0x03, 0x0C, 0x3F, 0x01, 0x04, 0x42, 0x03,
0x03, 0x0F, 0x01, 0x15, 0x1A, 0x03, 0x08, 0x3B, 0x02, 0x03,
0x34, 0x02, 0x15, 0x32, 0x02, 0x0D, 0x0E, 0x01, 0x00, 0x3F,
0x02, 0x0C, 0x32, 0x03, 0x14, 0x7E, 0x01, 0x04, 0x7B, 0x02,
0x12, 0x4C, 0x03, 0x02, 0x5D, 0x02, 0x00, 0x0A, 0x03, 0x0E,
0x09, 0x02, 0x16, 0x07, 0x01, 0x13, 0x61, 0x03, 0x0D, 0x4E,
0x03, 0x07, 0x02, 0x01, 0x17, 0x55, 0x03, 0x0D, 0x36, 0x01,
0x08, 0x5E, 0x01, 0x04, 0x0C, 0x01, 0x0D, 0x2D, 0x01, 0x01,
0x22, 0x03, 0x04, 0x1C, 0x01, 0x02, 0x3C, 0x01, 0x15, 0x60,
0x02, 0x0C, 0x5B, 0x01, 0x0C, 0x0B, 0x03, 0x0F, 0x77, 0x01,
0x11, 0x28, 0x01, 0x06, 0x7F, 0x01, 0x0C, 0x13, 0x03, 0x08,
0x18, 0x01, 0x0C, 0x4D, 0x02, 0x16, 0x05, 0x03, 0x0E, 0x22,
0x02, 0x15, 0x7C, 0x03, 0x08, 0x5C, 0x03, 0x0C, 0x4E, 0x03,
0x10, 0x28, 0x02, 0x11, 0x17, 0x03, 0x05, 0x32, 0x02, 0x0A,
0x44, 0x01, 0x01, 0x5C, 0x02, 0x14, 0x35, 0x01, 0x0D, 0x0A,
0x01, 0x0F, 0x29, 0x02, 0x16, 0x43, 0x01, 0x01, 0x2A, 0x01,
0x09, 0x64, 0x01, 0x0E, 0x41, 0x02, 0x11, 0x67, 0x01, 0x10,
0x73, 0x02, 0x0C, 0x67, 0x02, 0x16, 0x24, 0x01, 0x0B, 0x0D,
0x01, 0x10, 0x00, 0x01, 0x0D, 0x29, 0x03, 0x0C, 0x23, 0x02,
0x0A, 0x36, 0x01, 0x01, 0x7C, 0x02, 0x11, 0x78, 0x02, 0x09,
0x3C, 0x03, 0x0D, 0x04, 0x02, 0x09, 0x21, 0x02, 0x0E, 0x04,
0x02, 0x0A, 0x07, 0x03, 0x13, 0x31, 0x01, 0x01, 0x1F, 0x03,
0x0B, 0x17, 0x01, 0x16, 0x5D, 0x02, 0x00, 0x60, 0x03, 0x0B,
0x36, 0x02, 0x03, 0x01, 0x03, 0x0F, 0x08, 0x03, 0x16, 0x07,
0x02, 0x07, 0x0B, 0x02, 0x14, 0x3E, 0x02, 0x02, 0x0A, 0x02,
0x11, 0x32, 0x03, 0x08, 0x54, 0x03, 0x0A, 0x53, 0x02, 0x14,
0x44, 0x02, 0x11, 0x5F, 0x03, 0x06, 0x0A, 0x03, 0x13, 0x75,
0x03, 0x10, 0x11, 0x02, 0x07, 0x7A, 0x01, 0x02, 0x48, 0x01,
0x02, 0x0C, 0x03, 0x0E, 0x69, 0x02, 0x0C, 0x25, 0x01, 0x05,
0x5E, 0x03, 0x0D, 0x3D, 0x01, 0x0B, 0x4F, 0x01, 0x0F, 0x5B,
0x01, 0x0F, 0x06, 0x01, 0x06, 0x45, 0x03, 0x0D, 0x02, 0x03,
0x0A, 0x67, 0x03, 0x16, 0x2E, 0x01, 0x16, 0x00, 0x03, 0x00,
0x0D, 0x03, 0x17, 0x4E, 0x03, 0x13, 0x17, 0x03, 0x11, 0x3D,
0x01, 0x07, 0x61, 0x03, 0x15, 0x1F, 0x02, 0x11, 0x1E, 0x03,
0x15, 0x32, 0x01, 0x08, 0x1A, 0x03, 0x0A, 0x29, 0x02, 0x0A,
0x76, 0x03, 0x07, 0x2B, 0x03, 0x13, 0x2F, 0x02, 0x09, 0x2E,
0x02, 0x0E, 0x33, 0x01, 0x12, 0x13, 0x03, 0x16, 0x1F, 0x03,
0x05, 0x23, 0x02, 0x13, 0x77, 0x01, 0x17, 0x17, 0x01, 0x13,
0x12, 0x02, 0x03, 0x51, 0x03, 0x00, 0x0F, 0x03, 0x08, 0x4A,
0x03, 0x17, 0x06, 0x03, 0x10, 0x18, 0x01, 0x14, 0x4E, 0x02,
0x08, 0x1F, 0x01, 0x13, 0x23, 0x01, 0x0D, 0x6F, 0x01, 0x14,
0x45, 0x01, 0x0F, 0x23, 0x02, 0x01, 0x5B, 0x02, 0x05, 0x7E,
0x03, 0x07, 0x36, 0x01, 0x08, 0x1B, 0x01, 0x06, 0x45, 0x02,
0x0E, 0x1F, 0x03, 0x03, 0x28, 0x01, 0x0C, 0x7D, 0x02, 0x09,
0x79, 0x01, 0x0D, 0x5E, 0x03, 0x08, 0x4F, 0x01, 0x02, 0x3E,
0x01, 0x07, 0x5F, 0x03, 0x03, 0x67, 0x02, 0x06, 0x56, 0x02,
0x01, 0x17, 0x02, 0x16, 0x60, 0x02, 0x04, 0x44, 0x02, 0x10,
0x40, 0x02, 0x10, 0x66, 0x02, 0x01, 0x61, 0x03, 0x0D, 0x47,
0x02, 0x11, 0x75, 0x03, 0x0E, 0x57, 0x03, 0x12, 0x75, 0x03,
0x17, 0x6E, 0x02, 0x15, 0x2D, 0x03, 0x0A, 0x7A, 0x01, 0x11,
0x02, 0x01, 0x16, 0x31, 0x02, 0x05, 0x34, 0x02, 0x00, 0x35,
0x03, 0x17, 0x3B, 0x02, 0x10, 0x73, 0x02, 0x0B, 0x4A, 0x01,
0x01, 0x2D, 0x03, 0x01, 0x1A, 0x01, 0x11, 0x27, 0x01, 0x13,
0x5C, 0x03, 0x0A, 0x7F, 0x03, 0x15, 0x21, 0x02, 0x00, 0x4E,
0x03, 0x01, 0x2D, 0x03, 0x0C, 0x5B, 0x02, 0x16, 0x33, 0x01,
0x04, 0x4C, 0x03, 0x13, 0x7E, 0x03, 0x15, 0x1B, 0x03, 0x0B,
0x75, 0x02, 0x12, 0x1D, 0x03, 0x0D, 0x63, 0x03, 0x0F, 0x46,
0x01, 0x06, 0x61, 0x02, 0x13, 0x2F, 0x03, 0x08, 0x41, 0x01,
0x13, 0x4D, 0x01, 0x03, 0x5E, 0x03, 0x14, 0x17, 0x02, 0x00,
0x24, 0x01, 0x09, 0x0F, 0x03, 0x0B, 0x04, 0x01, 0x13, 0x66,
0x01, 0x0C, 0x00, 0x02, 0x17, 0x2E, 0x02, 0x09, 0x50, 0x02,
0x09, 0x73, 0x01, 0x0D, 0x57, 0x03, 0x00, 0x20, 0x03, 0x05,
0x1B, 0x01, 0x11, 0x05, 0x01, 0x16, 0x4D, 0x03, 0x07, 0x53,
0x03, 0x0C, 0x7E, 0x01, 0x16, 0x1B, 0x03, 0x0E, 0x66, 0x02,
0x02, 0x18, 0x01, 0x14, 0x66, 0x01, 0x01, 0x16, 0x02, 0x09,
0x38, 0x02, 0x0E, 0x49, 0x01, 0x04, 0x46, 0x01, 0x0F, 0x11,
0x02, 0x0E, 0x67, 0x02, 0x08, 0x2A, 0x01, 0x15, 0x5A, 0x02,
0x03, 0x5B, 0x03, 0x0D, 0x55, 0x02, 0x07, 0x3A, 0x01, 0x07,
0x04, 0x02, 0x00, 0x16, 0x01, 0x04, 0x60, 0x02, 0x0C, 0x0E,
0x01, 0x17, 0x41, 0x03, 0x0F, 0x52, 0x01, 0x0E, 0x67, 0x01,
0x03, 0x0D, 0x03, 0x10, 0x3C, 0x03, 0x00, 0x6B, 0x01, 0x11,
0x4F, 0x03, 0x12, 0x3D, 0x03, 0x05, 0x05, 0x03, 0x04, 0x21,
0x01, 0x0C, 0x62, 0x02, 0x08, 0x64, 0x02, 0x16, 0x62, 0x02,
0x07, 0x42, 0x02, 0x0B, 0x74, 0x01, 0x0B, 0x04, 0x02, 0x13,
0x0A, 0x03, 0x07, 0x39, 0x03, 0x09, 0x1B, 0x03, 0x16, 0x62,
0x01, 0x17, 0x46, 0x02, 0x01, 0x6D, 0x02, 0x09, 0x1F, 0x02,
0x10, 0x65, 0x03, 0x16, 0x21, 0x02, 0x06, 0x6E, 0x02, 0x01,
0x43, 0x02, 0x0B, 0x65, 0x02, 0x12, 0x09, 0x03, 0x05, 0x6E,
0x02, 0x0C, 0x01, 0x01, 0x13, 0x17, 0x03, 0x15, 0x2B, 0x01,
0x0D, 0x18, 0x01, 0x0B, 0x1E, 0x01, 0x16, 0x01, 0x01, 0x0C,
0x1E, 0x03, 0x04, 0x15, 0x02, 0x07, 0x25, 0x02, 0x06, 0x09,
0x02, 0x13, 0x23, 0x01, 0x14, 0x4D, 0x02, 0x16, 0x05, 0x03,
0x0A, 0x38, 0x03, 0x16, 0x14, 0x03, 0x03, 0x78, 0x02, 0x17,
0x28, 0x02, 0x07, 0x76, 0x01, 0x01, 0x24, 0x02, 0x07, 0x06,
0x01, 0x01, 0x7B, 0x03, 0x00, 0x00, 0x02, 0x0A, 0x6E, 0x01,
0x12, 0x66, 0x03, 0x05, 0x53, 0x01, 0x04, 0x2E, 0x02, 0x01,
0x4C, 0x02, 0x04, 0x7D, 0x03, 0x09, 0x69, 0x01, 0x15, 0x1C,
0x02, 0x0D, 0x71, 0x03, 0x11, 0x50, 0x03, 0x0E, 0x34, 0x01,
0x05, 0x7F, 0x02, 0x13, 0x49, 0x01, 0x0D, 0x17, 0x01, 0x12,
0x2A, 0x03, 0x07, 0x13, 0x01, 0x08, 0x4C, 0x02, 0x05, 0x41,
0x03, 0x0D, 0x18, 0x01, 0x12, 0x4C, 0x03, 0x0A, 0x3A, 0x02,
0x06, 0x64, 0x02, 0x0B, 0x6E, 0x01, 0x15, 0x52, 0x03, 0x0A,
0x5B, 0x01, 0x0B, 0x55, 0x03, 0x04, 0x1A, 0x03, 0x0A, 0x54,
0x03, 0x11, 0x03, 0x02, 0x11, 0x5B, 0x03, 0x09, 0x56, 0x03,
0x01, 0x0A, 0x02, 0x10, 0x61, 0x03, 0x00, 0x0D, 0x01, 0x14,
0x2F, 0x02, 0x0D, 0x74, 0x01, 0x17, 0x6A, 0x01, 0x17, 0x7F,
0x01, 0x00, 0x5D, 0x03, 0x01, 0x3C, 0x03, 0x12, 0x25, 0x03,
0x0C, 0x20, 0x02, 0x02, 0x60, 0x03, 0x03, 0x55, 0x01, 0x08,
0x24, 0x02, 0x08, 0x22, 0x03, 0x16, 0x2D, 0x01, 0x03, 0x67,
0x01, 0x08, 0x20, 0x01, 0x12, 0x12, 0x01, 0x16, 0x5F, 0x02,
0x0E, 0x04, 0x01, 0x15, 0x2D, 0x03, 0x09, 0x45, 0x02, 0x03,
0x7A, 0x01, 0x03, 0x35, 0x03, 0x10, 0x07, 0x01, 0x09, 0x7C,
0x01, 0x0F, 0x5E, 0x02, 0x12, 0x1B, 0x02, 0x0B, 0x1C, 0x03,
0x07, 0x60, 0x03, 0x04, 0x6C, 0x03, 0x03, 0x0B, 0x02, 0x09,
0x3A, 0x02, 0x09, 0x04, 0x03, 0x05, 0x51, 0x03, 0x06, 0x72,
0x03, 0x0F, 0x01, 0x01, 0x03, 0x2D, 0x02, 0x00, 0x04, 0x03,
0x00, 0x31, 0x02, 0x06, 0x52, 0x03, 0x01, 0x3D, 0x02, 0x0A,
0x25, 0x02, 0x09, 0x29, 0x02, 0x13, 0x63, 0x03, 0x0E, 0x69,
0x02, 0x10, 0x63, 0x03, 0x14, 0x20, 0x02, 0x05, 0x00, 0x02,
0x16, 0x76, 0x03, 0x0E, 0x75, 0x02, 0x15, 0x01, 0x03, 0x0D,
0x55, 0x02, 0x09, 0x23, 0x01, 0x02, 0x12, 0x03, 0x02, 0x49,
0x01, 0x0B, 0x6B, 0x02, 0x17, 0x11, 0x02, 0x12, 0x43, 0x01,
0x15, 0x24, 0x01, 0x0D, 0x27, 0x01, 0x10, 0x06, 0x01, 0x0E,
0x31, 0x03, 0x17, 0x60, 0x01, 0x03, 0x50, 0x02, 0x0A, 0x3C,
0x02, 0x06, 0x33, 0x02, 0x00, 0x7B, 0x03, 0x09, 0x22, 0x03,
0x04, 0x77, 0x03, 0x0F, 0x57, 0x01, 0x17, 0x5E, 0x02, 0x15,
0x6E, 0x02, 0x0B, 0x0B, 0x03, 0x08, 0x04, 0x03, 0x05, 0x24,
0x03, 0x0B, 0x0E, 0x01, 0x04, 0x61, 0x03, 0x0B, 0x01, 0x01,
0x09, 0x5B, 0x01, 0x0E, 0x40, 0x01, 0x17, 0x15, 0x01, 0x10,
0x6E, 0x01, 0x08, 0x5E, 0x03, 0x08, 0x2B, 0x03, 0x0A, 0x4E,
0x03, 0x07, 0x3D, 0x02, 0x0A, 0x51, 0x03, 0x0C, 0x6A, 0x01,
0x13, 0x5F, 0x02, 0x0B, 0x28, 0x03, 0x12, 0x69, 0x01, 0x14,
0x7C, 0x02, 0x07, 0x1C, 0x01, 0x00, 0x48, 0x03, 0x05, 0x10,
0x01, 0x12, 0x55, 0x01, 0x11, 0x4A, 0x01, 0x17, 0x23, 0x01,
0x02, 0x65, 0x03, 0x10, 0x74, 0x03, 0x0C, 0x42, 0x01, 0x00,
0x49, 0x02, 0x03, 0x16, 0x02, 0x01, 0x12, 0x01, 0x10, 0x3C,
0x03, 0x11, 0x1D, 0x01, 0x01, 0x6F, 0x03, 0x11, 0x00, 0x02,
0x0F, 0x16, 0x03, 0x13, 0x00, 0x03, 0x07, 0x73, 0x01, 0x0A,
0x40, 0x03, 0x07, 0x7C, 0x02, 0x15, 0x41, 0x03, 0x05, 0x35,
0x01, 0x07, 0x6B, 0x01, 0x0B, 0x1F, 0x01, 0x15, 0x11, 0x03,
0x08, 0x4E, 0x01, 0x0F, 0x6F, 0x02, 0x0A, 0x65, 0x03, 0x13,
0x02, 0x01, 0x07, 0x22, 0x02, 0x08, 0x6C, 0x01, 0x0C, 0x13,
0x02, 0x08, 0x17, 0x03, 0x07, 0x1F, 0x01, 0x07, 0x33, 0x01,
0x0D, 0x7A, 0x03, 0x01, 0x12, 0x01, 0x16, 0x61, 0x01, 0x0D,
0x38, 0x02, 0x13, 0x27, 0x03, 0x0D, 0x13, 0x01, 0x04, 0x07,
0x01, 0x14, 0x67, 0x03, 0x13, 0x08, 0x03, 0x0D, 0x04, 0x01,
0x00, 0x4C, 0x02, 0x0C, 0x36, 0x01, 0x16, 0x49, 0x02, 0x12,
0x51, 0x03, 0x08, 0x6C, 0x01, 0x00, 0x73, 0x03, 0x00, 0x47,
0x03, 0x15, 0x40, 0x01, 0x01, 0x59, 0x01, 0x11, 0x7B, 0x02,
0x0E, 0x76, 0x03, 0x04, 0x6A, 0x03, 0x0D, 0x5B, 0x01, 0x0B,
0x30, 0x01, 0x03, 0x6D, 0x03, 0x13, 0x7B, 0x01, 0x17, 0x71,
0x02, 0x16, 0x41, 0x03, 0x15, 0x5D, 0x01, 0x08, 0x12, 0x02,
0x0A, 0x41, 0x01, 0x17, 0x1B, 0x01, 0x0C, 0x41, 0x03, 0x00,
0x33, 0x02, 0x10, 0x4E, 0x01, 0x01, 0x38, 0x02, 0x17, 0x66,
0x01, 0x11, 0x5F, 0x03, 0x0E, 0x49, 0x01, 0x10, 0x4B, 0x01,
0x15, 0x67, 0x02, 0x0B, 0x3A, 0x01, 0x15, 0x01, 0x02, 0x14,
0x5D, 0x03, 0x05, 0x01, 0x02, 0x0D, 0x44, 0x02, 0x09, 0x03,
0x01, 0x0D, 0x59, 0x03, 0x10, 0x45, 0x01, 0x07, 0x16, 0x03,
0x02, 0x4A, 0x03, 0x0A, 0x11, 0x03, 0x11, 0x07, 0x01, 0x06,
0x5D, 0x02, 0x00, 0x7F, 0x03, 0x03, 0x5D, 0x03, 0x03, 0x33,
0x02, 0x08, 0x6C, 0x03, 0x09, 0x60, 0x02, 0x0E, 0x6C, 0x01,
0x14, 0x0B, 0x02, 0x02, 0x0A, 0x01, 0x11, 0x24, 0x02, 0x08,
0x30, 0x03, 0x01, 0x6F, 0x02, 0x00, 0x0B, 0x01, 0x07, 0x13,
0x02, 0x03, 0x5D, 0x03, 0x08, 0x46, 0x01, 0x15, 0x3A, 0x01,
0x13, 0x16, 0x02, 0x00, 0x4B, 0x03, 0x11, 0x7F, 0x01, 0x0D,
0x3B, 0x02, 0x16, 0x61, 0x03, 0x05, 0x7F, 0x03, 0x00, 0x02,
0x01, 0x02, 0x2F, 0x01, 0x0C, 0x04, 0x01, 0x09, 0x7F, 0x03,
0x0C, 0x44, 0x03, 0x10, 0x0C, 0x02, 0x0E, 0x3C, 0x02, 0x17,
0x49, 0x03, 0x16, 0x59, 0x01, 0x01, 0x2C, 0x02, 0x0F, 0x53,
0x01, 0x12, 0x5E, 0x03, 0x11, 0x06, 0x02, 0x0F, 0x15, 0x01,
0x08, 0x76, 0x02, 0x0C, 0x70, 0x01, 0x06, 0x2F, 0x01, 0x05,
0x3C, 0x03, 0x04, 0x04, 0x03, 0x05, 0x3B, 0x01, 0x0E, 0x3C,
0x01, 0x07, 0x04, 0x03, 0x01, 0x2E, 0x02, 0x0A, 0x1C, 0x02,
0x0A, 0x2F, 0x02, 0x03, 0x6B, 0x03, 0x0E, 0x5C, 0x01, 0x17,
0x01, 0x02, 0x13, 0x71, 0x01, 0x00, 0x69, 0x03, 0x02, 0x59,
0x02, 0x04, 0x46, 0x01, 0x17, 0x6A, 0x01, 0x02, 0x3B, 0x02,
0x0F, 0x12, 0x03, 0x06, 0x40, 0x01, 0x03, 0x56, 0x02, 0x01,
0x3C, 0x02, 0x00, 0x23, 0x02, 0x0B, 0x33, 0x01, 0x12, 0x5F,
0x01, 0x15, 0x43, 0x02, 0x06, 0x4B, 0x01, 0x16, 0x69, 0x02,
0x14, 0x12, 0x01, 0x11, 0x05, 0x01, 0x0B, 0x5E, 0x02, 0x17,
0x4A, 0x02, 0x17, 0x21, 0x02, 0x0C, 0x60, 0x01, 0x05, 0x54,
0x03, 0x0D, 0x1A, 0x01, 0x0C, 0x19, 0x03, 0x0C, 0x7C, 0x02,
0x01, 0x61, 0x03, 0x06, 0x41, 0x01, 0x05, 0x7F, 0x03, 0x08,
0x71, 0x03, 0x0B, 0x27, 0x03, 0x15, 0x55, 0x03, 0x01, 0x33,
0x02, 0x0E, 0x4D, 0x01, 0x06, 0x3E, 0x02, 0x0B, 0x72, 0x03,
0x12, 0x35, 0x01, 0x03, 0x69, 0x03, 0x12, 0x07, 0x03, 0x13,
0x7A, 0x02, 0x08, 0x1E, 0x01, 0x11, 0x12, 0x03, 0x17, 0x63,
0x03, 0x10, 0x38, 0x03, 0x13, 0x70, 0x02, 0x0A, 0x5E, 0x02,
0x06, 0x38, 0x01, 0x00, 0x47, 0x01, 0x0A, 0x73, 0x03, 0x01,
0x21, 0x01, 0x09, 0x0B, 0x01, 0x04, 0x7F, 0x03, 0x14, 0x72,
0x03, 0x06, 0x73, 0x03, 0x0D, 0x2A, 0x03, 0x16, 0x17, 0x02,
0x13, 0x2A, 0x01, 0x05, 0x65, 0x03, 0x0D, 0x41, 0x02, 0x05,
0x64, 0x01, 0x11, 0x52, 0x01, 0x0E, 0x45, 0x01, 0x07, 0x5A,
0x02, 0x06, 0x78, 0x02, 0x0C, 0x30, 0x03, 0x14, 0x77, 0x02,
0x14, 0x7F, 0x02, 0x12, 0x16, 0x02, 0x09, 0x1E, 0x01, 0x15,
0x61, 0x02, 0x09, 0x53, 0x02, 0x15, 0x7C, 0x02, 0x17, 0x1E,
0x03, 0x0A, 0x63, 0x01, 0x0B, 0x1B, 0x02, 0x07, 0x31, 0x01,
0x0C, 0x09, 0x03, 0x10, 0x1A, 0x01, 0x04, 0x45, 0x02, 0x11,
0x7C, 0x01, 0x13, 0x45, 0x02, 0x10, 0x67, 0x01, 0x11, 0x16,
0x01, 0x14, 0x35, 0x02, 0x0B, 0x4B, 0x01, 0x0D, 0x2C, 0x03,
0x07, 0x7C, 0x02, 0x0C, 0x58, 0x03, 0x14, 0x09, 0x03, 0x07,
0x7B, 0x01, 0x0A, 0x12, 0x03, 0x0F, 0x3B, 0x01, 0x11, 0x29,
0x01, 0x0B, 0x29, 0x02, 0x06, 0x0D, 0x02, 0x0D, 0x7E, 0x02,
0x0C, 0x60, 0x01, 0x12, 0x52, 0x01, 0x0D, 0x04, 0x01, 0x09,
0x28, 0x01, 0x14, 0x7D, 0x03, 0x0A, 0x43, 0x01, 0x17, 0x63,
0x01, 0x11, 0x19, 0x02, 0x12, 0x4D, 0x02, 0x08, 0x59, 0x01,
0x0E, 0x25, 0x01, 0x03, 0x53, 0x03, 0x05, 0x51, 0x02, 0x02,
0x1D, 0x01, 0x0C, 0x3E, 0x03, 0x13, 0x24, 0x03, 0x08, 0x28,
0x02, 0x13, 0x64, 0x02, 0x0A, 0x34, 0x03, 0x0E, 0x13, 0x01,
0x0C, 0x73, 0x03, 0x0B, 0x10, 0x02, 0x0F, 0x51, 0x02, 0x10,
0x49, 0x02, 0x03, 0x14, 0x03, 0x16, 0x20, 0x03, 0x15, 0x1B,
0x02, 0x16, 0x06, 0x02, 0x08, 0x0B, 0x02, 0x05, 0x4D, 0x01,
0x0D, 0x10, 0x01, 0x0D, 0x54, 0x02, 0x11, 0x18, 0x02, 0x15,
0x0A, 0x01, 0x11, 0x47, 0x01, 0x02, 0x27, 0x01, 0x0B, 0x48,
0x02, 0x15, 0x22, 0x01, 0x10, 0x7A, 0x01, 0x0E, 0x0E, 0x01,
0x0A, 0x10, 0x01, 0x13, 0x2C, 0x02, 0x0A, 0x11, 0x01, 0x0A,
0x2A, 0x03, 0x01, 0x7E, 0x01, 0x0E, 0x35, 0x02, 0x17, 0x2A,
0x02, 0x16, 0x08, 0x02, 0x09, 0x1A, 0x02, 0x03, 0x33, 0x02,
0x05, 0x51, 0x03, 0x0A, 0x06, 0x02, 0x0B, 0x7C, 0x01, 0x0C,
0x46, 0x02, 0x10, 0x3F, 0x01, 0x06, 0x63, 0x01, 0x02, 0x63,
0x01, 0x0B, 0x5A, 0x03, 0x0A, 0x11, 0x02, 0x0E, 0x0A, 0x01,
0x0B, 0x31, 0x03, 0x03, 0x27, 0x03, 0x03, 0x21, 0x02, 0x0E,
0x3B, 0x03, 0x14, 0x0A, 0x03, 0x08, 0x77, 0x03, 0x17, 0x28,
0x01, 0x15, 0x7A, 0x03, 0x0B, 0x4E, 0x03, 0x0B, 0x51, 0x02,
0x14, 0x61, 0x02, 0x0E, 0x39, 0x03, 0x0B, 0x66, 0x03, 0x00,
0x56, 0x01, 0x15, 0x1B, 0x02, 0x13, 0x41, 0x03, 0x0B, 0x7C,
0x01, 0x13, 0x3E, 0x02, 0x12, 0x04, 0x03, 0x13, 0x72, 0x02,
0x02, 0x27, 0x01, 0x04, 0x78, 0x01, 0x0C, 0x54, 0x03, 0x13,
0x02, 0x01, 0x09, 0x74, 0x01, 0x01, 0x10, 0x03, 0x00, 0x6F,
0x03, 0x05, 0x26, 0x02, 0x05, 0x02, 0x01, 0x02, 0x10, 0x02,
0x17, 0x3C, 0x02, 0x12, 0x24, 0x01, 0x10, 0x37, 0x01, 0x02,
0x03, 0x03, 0x13, 0x11, 0x03, 0x16, 0x1D, 0x01, 0x16, 0x5E,
0x01, 0x14, 0x0E, 0x02, 0x00, 0x53, 0x01, 0x11, 0x01, 0x01,
0x00, 0x41, 0x01, 0x06, 0x23, 0x03, 0x03, 0x68, 0x03, 0x05,
0x21, 0x01, 0x02, 0x28, 0x02, 0x0A, 0x43, 0x01, 0x0A, 0x5E,
0x01, 0x04, 0x11, 0x01, 0x06, 0x03, 0x01, 0x04, 0x0D, 0x03,
0x0A, 0x54, 0x02, 0x01, 0x5A, 0x02, 0x07, 0x6F, 0x01, 0x0B,
0x34, 0x03, 0x12, 0x68, 0x02, 0x13, 0x0C, 0x03, 0x00, 0x6D,
0x01, 0x12, 0x7E, 0x03, 0x06, 0x44, 0x03, 0x10, 0x25, 0x01,
0x0A, 0x42, 0x02, 0x09, 0x60, 0x03, 0x01, 0x76, 0x03, 0x05,
0x53, 0x03, 0x0A, 0x3B, 0x02, 0x03, 0x75, 0x03, 0x01, 0x3B,
0x01, 0x01, 0x62, 0x02, 0x06, 0x6F, 0x03, 0x07, 0x10, 0x03,
0x02, 0x04, 0x03, 0x11, 0x5B, 0x01, 0x08, 0x5A, 0x01, 0x16,
0x5C, 0x02, 0x0B, 0x1C, 0x02, 0x04, 0x2B, 0x02, 0x02, 0x53,
0x03, 0x11, 0x25, 0x01, 0x11, 0x08, 0x03, 0x05, 0x6F, 0x03,
0x12, 0x36, 0x03, 0x10, 0x68, 0x02, 0x09, 0x15, 0x03, 0x17,
0x33, 0x03, 0x16, 0x59, 0x02, 0x08, 0x44, 0x02, 0x12, 0x33,
0x01, 0x15, 0x26, 0x02, 0x16, 0x68, 0x03, 0x05, 0x3F, 0x03,
0x05, 0x49, 0x03, 0x02, 0x00, 0x02, 0x11, 0x08, 0x02, 0x11,
0x5E, 0x03, 0x06, 0x7F, 0x03, 0x12, 0x4D, 0x01, 0x14, 0x77,
0x03, 0x0B, 0x56, 0x02, 0x14, 0x35, 0x02, 0x0D, 0x39, 0x02,
0x09, 0x18, 0x03, 0x16, 0x03, 0x01, 0x0B, 0x4D, 0x03, 0x07,
0x0F, 0x01, 0x09, 0x3F, 0x03, 0x15, 0x5E, 0x03, 0x04, 0x67,
0x01, 0x06, 0x11, 0x03, 0x01, 0x77, 0x01, 0x04, 0x1B, 0x02,
0x02, 0x5E, 0x03, 0x14, 0x1C, 0x02, 0x13, 0x1D, 0x03, 0x12,
0x78, 0x01, 0x03, 0x1A, 0x03, 0x10, 0x03, 0x02, 0x05, 0x6D,
0x01, 0x16, 0x4E, 0x02, 0x15, 0x31, 0x02, 0x0A, 0x2B, 0x01,
0x0E, 0x4A, 0x03, 0x11, 0x3D, 0x01, 0x06, 0x2D, 0x02, 0x17,
0x26, 0x02, 0x06, 0x1E, 0x02, 0x13, 0x5B, 0x02, 0x00, 0x54,
0x01, 0x00, 0x7C, 0x02, 0x0D, 0x5D, 0x02, 0x05, 0x3F, 0x01,
0x08, 0x01, 0x03, 0x11, 0x3A, 0x01, 0x13, 0x70, 0x03, 0x12,
0x78, 0x02, 0x0C, 0x50, 0x01, 0x10, 0x6C, 0x01, 0x07, 0x1E,
0x01, 0x03, 0x4D, 0x02, 0x15, 0x18, 0x02, 0x0A, 0x4A, 0x02,
0x15, 0x3F, 0x01, 0x16, 0x20, 0x03, 0x01, 0x41, 0x02, 0x06,
0x2E, 0x02, 0x12, 0x64, 0x02, 0x0D, 0x64, 0x02, 0x16, 0x18,
0x02, 0x0B, 0x2C, 0x03, 0x08, 0x4A, 0x02, 0x04, 0x17, 0x03,
0x10, 0x60, 0x01, 0x14, 0x31, 0x02, 0x0B, 0x3E, 0x01, 0x00,
0x52, 0x03, 0x0C, 0x2B, 0x01, 0x0D, 0x15, 0x02, 0x01, 0x2B,
0x02, 0x17, 0x73, 0x01, 0x14, 0x74, 0x03, 0x10, 0x20, 0x03,
0x15, 0x5F, 0x02, 0x11, 0x59, 0x02, 0x16, 0x01, 0x03, 0x0F,
0x5B, 0x02, 0x04, 0x3F, 0x01, 0x0B, 0x2B, 0x02, 0x0A, 0x1A,
0x03, 0x01, 0x23, 0x03, 0x10, 0x64, 0x03, 0x0A, 0x17, 0x03,
0x17, 0x46, 0x01, 0x03, 0x27, 0x02, 0x12, 0x25, 0x02, 0x11,
0x3A, 0x03, 0x17, 0x0A, 0x03, 0x14, 0x21, 0x01, 0x17, 0x5F,
0x03, 0x0D, 0x56, 0x02, 0x10, 0x77, 0x01, 0x15, 0x5B, 0x03,
0x03, 0x10, 0x01, 0x0B, 0x11, 0x01, 0x0D, 0x2C, 0x02, 0x11,
0x3A, 0x01, 0x0D, 0x5B, 0x03, 0x10, 0x40, 0x03, 0x16, 0x24,
0x03, 0x10, 0x28, 0x03, 0x17, 0x05, 0x02, 0x08, 0x46, 0x01,
0x14, 0x2B, 0x03, 0x0A, 0x0A, 0x01, 0x0E, 0x1A, 0x03, 0x0B,
0x69, 0x03, 0x15, 0x2D, 0x03, 0x0B, 0x3B, 0x01, 0x08, 0x17,
0x03, 0x0A, 0x58, 0x01, 0x00, 0x60, 0x01, 0x0F, 0x0E, 0x02,
0x02, 0x62, 0x02, 0x0E, 0x02, 0x02, 0x0C, 0x09, 0x01, 0x04,
0x53, 0x03, 0x07, 0x1B, 0x02, 0x10, 0x01, 0x03, 0x03, 0x67,
0x02, 0x04, 0x26, 0x02, 0x07, 0x75, 0x03, 0x17, 0x02, 0x02,
0x0F, 0x1D, 0x02, 0x00, 0x18, 0x01, 0x0A, 0x0B, 0x02, 0x0B,
0x0D, 0x01, 0x17, 0x04, 0x01, 0x0B, 0x1F, 0x02, 0x13, 0x2F,
0x02, 0x01, 0x42, 0x02, 0x14, 0x4C, 0x03, 0x0A, 0x1A, 0x03,
0x0D, 0x2B, 0x01, 0x12, 0x0F, 0x01, 0x04, 0x25, 0x02, 0x09,
0x3C, 0x02, 0x14, 0x1B, 0x02, 0x0F, 0x2C, 0x01, 0x11, 0x05,
0x02, 0x05, 0x49, 0x01, 0x06, 0x4B, 0x03, 0x0F, 0x0F, 0x01,
0x02, 0x0C, 0x03, 0x07, 0x7F, 0x03, 0x12, 0x42, 0x01, 0x01,
0x7F, 0x01, 0x05, 0x53, 0x01, 0x04, 0x5A, 0x03, 0x17, 0x58,
0x02, 0x04, 0x01, 0x01, 0x16, 0x31, 0x03, 0x0B, 0x53, 0x01,
0x11, 0x58, 0x02, 0x17, 0x37, 0x02, 0x0D, 0x24, 0x01, 0x00,
0x31, 0x03, 0x15, 0x49, 0x01, 0x0F, 0x31, 0x02, 0x0F, 0x65,
0x03, 0x03, 0x72, 0x01, 0x11, 0x5D, 0x03, 0x10, 0x17, 0x02,
0x05, 0x22, 0x03, 0x03, 0x22, 0x02, 0x05, 0x32, 0x01, 0x09,
0x72, 0x03, 0x00, 0x7B, 0x03, 0x0E, 0x5F, 0x01, 0x11, 0x46,
0x01, 0x07, 0x42, 0x03, 0x03, 0x43, 0x03, 0x16, 0x7F, 0x01,
0x15, 0x45, 0x01, 0x05, 0x3F, 0x01, 0x03, 0x5A, 0x01, 0x0D,
0x1A, 0x03, 0x11, 0x75, 0x01, 0x00, 0x11, 0x03, 0x16, 0x6E,
0x02, 0x17, 0x73, 0x01, 0x15, 0x55, 0x03, 0x0E, 0x19, 0x01,
0x15, 0x2C, 0x02, 0x11, 0x6B, 0x01, 0x01, 0x04, 0x03, 0x04,
0x78, 0x02, 0x0C, 0x5E, 0x02, 0x07, 0x76, 0x01, 0x13, 0x51,
0x02, 0x15, 0x33, 0x02, 0x11, 0x53, 0x01, 0x17, 0x7A, 0x01,
0x12, 0x3D, 0x03, 0x12, 0x61, 0x01, 0x09, 0x4A, 0x03, 0x14,
0x1C, 0x01, 0x15, 0x04, 0x01, 0x14, 0x11, 0x01, 0x14, 0x7B,
0x02, 0x14, 0x71, 0x03, 0x16, 0x6A, 0x01, 0x03, 0x42, 0x03,
0x0C, 0x03, 0x03, 0x10, 0x48, 0x02, 0x0D, 0x68, 0x02, 0x00,
0x5E, 0x03, 0x15, 0x4D, 0x02, 0x06, 0x7D, 0x01, 0x05, 0x2C,
0x01, 0x07, 0x4E, 0x02, 0x0D, 0x29, 0x03, 0x17, 0x77, 0x02,
0x0F, 0x15, 0x03, 0x17, 0x66, 0x02, 0x09, 0x45, 0x02, 0x0E,
0x68, 0x01, 0x13, 0x56, 0x02, 0x16, 0x73, 0x02, 0x0E, 0x6D,
0x01, 0x0E, 0x39, 0x01, 0x04, 0x76, 0x02, 0x07, 0x52, 0x03,
0x12, 0x30, 0x02, 0x0E, 0x50, 0x03, 0x06, 0x12, 0x02, 0x0F,
0x50, 0x03, 0x10, 0x40, 0x02, 0x10, 0x2F, 0x03, 0x07, 0x74,
0x02, 0x11, 0x50, 0x01, 0x0D, 0x7F, 0x02, 0x13, 0x1C, 0x01,
0x0B, 0x26, 0x02, 0x00, 0x11, 0x03, 0x0F, 0x72, 0x03, 0x01,
0x5A, 0x01, 0x16, 0x36, 0x01, 0x10, 0x37, 0x03, 0x08, 0x22,
0x03, 0x0C, 0x50, 0x02, 0x04, 0x5D, 0x02, 0x0B, 0x08, 0x01,
0x0C, 0x50, 0x03, 0x0A, 0x6A, 0x01, 0x17, 0x34, 0x01, 0x0C,
0x71, 0x02, 0x06, 0x1F, 0x01, 0x08, 0x22, 0x02, 0x05, 0x43,
0x02, 0x05, 0x68, 0x03, 0x05, 0x26, 0x03, 0x02, 0x57, 0x01,
0x11, 0x7C, 0x03, 0x0B, 0x64, 0x01, 0x15, 0x2D, 0x01, 0x06,
0x59, 0x03, 0x13, 0x24, 0x03, 0x02, 0x49, 0x03, 0x04, 0x70,
0x01, 0x13, 0x2F, 0x01, 0x12, 0x72, 0x01, 0x08, 0x0E, 0x02,
0x0D, 0x3B, 0x01, 0x03, 0x2F, 0x01, 0x11, 0x69, 0x01, 0x08,
0x49, 0x02, 0x01, 0x36, 0x02, 0x11, 0x51, 0x03, 0x0B, 0x01,
0x03, 0x10, 0x49, 0x01, 0x11, 0x5D, 0x02, 0x12, 0x72, 0x03,
0x10, 0x6C, 0x03, 0x05, 0x00, 0x01, 0x04, 0x4A, 0x01, 0x14,
0x20, 0x02, 0x05, 0x26, 0x01, 0x01, 0x01, 0x02, 0x09, 0x75,
0x02, 0x01, 0x0C, 0x01, 0x0F, 0x64, 0x01, 0x17, 0x36, 0x03,
0x02, 0x2D, 0x03, 0x00, 0x61, 0x03, 0x07, 0x64, 0x02, 0x12,
0x2E, 0x02, 0x12, 0x29, 0x01, 0x05, 0x7D, 0x01, 0x02, 0x32,
0x01, 0x10, 0x2C, 0x02, 0x08, 0x4B, 0x03, 0x0C, 0x74, 0x03,
0x06, 0x33, 0x02, 0x05, 0x1B, 0x01, 0x0C, 0x22, 0x03, 0x16,
0x6C, 0x03, 0x01, 0x6B, 0x03, 0x02, 0x03, 0x01, 0x02, 0x43,
0x02, 0x05, 0x5B, 0x03, 0x17, 0x15, 0x02, 0x15, 0x3B, 0x02,
0x12, 0x0A, 0x01, 0x05, 0x01, 0x02, 0x14, 0x25, 0x02, 0x02,
0x11, 0x03, 0x05, 0x4C, 0x02, 0x0D, 0x2F, 0x02, 0x0B, 0x3A,
0x03, 0x12, 0x1E, 0x01, 0x01, 0x5D, 0x01, 0x14, 0x38, 0x03,
0x09, 0x47, 0x03, 0x0B, 0x6C, 0x03, 0x0A, 0x04, 0x03, 0x0C,
0x21, 0x01, 0x16, 0x0B, 0x03, 0x0E, 0x23, 0x03, 0x10, 0x0A,
0x01, 0x0A, 0x24, 0x01, 0x01, 0x42, 0x03, 0x10, 0x33, 0x03,
0x08, 0x50, 0x03, 0x01, 0x22, 0x02, 0x04, 0x16, 0x02, 0x08,
0x29, 0x01, 0x03, 0x20, 0x03, 0x04, 0x1A, 0x01, 0x0C, 0x2E,
0x03, 0x0C, 0x2A, 0x02, 0x15, 0x0D, 0x02, 0x0D, 0x47, 0x01,
0x0F, 0x49, 0x01, 0x05, 0x5D, 0x03, 0x16, 0x41, 0x02, 0x09,
0x1F, 0x01, 0x11, 0x00, 0x03, 0x08, 0x51, 0x02, 0x12, 0x14,
0x02, 0x12, 0x06, 0x03, 0x05, 0x7F, 0x03, 0x0D, 0x5A, 0x03,
0x0B, 0x61, 0x02, 0x01, 0x78, 0x02, 0x13, 0x1A, 0x02, 0x11,
0x01, 0x01, 0x0E, 0x11, 0x02, 0x0A, 0x01, 0x01, 0x05, 0x7E,
0x02, 0x16, 0x1C, 0x02, 0x10, 0x21, 0x02, 0x11, 0x30, 0x03,
0x08, 0x75, 0x03, 0x0C, 0x15, 0x03, 0x13, 0x1B, 0x03, 0x16,
0x43, 0x01, 0x08, 0x66, 0x03, 0x17, 0x43, 0x03, 0x0D, 0x46,
0x01, 0x00, 0x02, 0x01, 0x02, 0x12, 0x01, 0x15, 0x14, 0x03,
0x0B, 0x63, 0x03, 0x11, 0x08, 0x02, 0x16, 0x40, 0x03, 0x02,
0x62, 0x02, 0x02, 0x0F, 0x03, 0x0B, 0x13, 0x01, 0x09, 0x69,
0x01, 0x03, 0x3A, 0x02, 0x0E, 0x43, 0x03, 0x09, 0x29, 0x02,
0x00, 0x15, 0x02, 0x08, 0x5F, 0x02, 0x00, 0x06, 0x02, 0x03,
0x69, 0x01, 0x08, 0x13, 0x03, 0x13, 0x75, 0x03, 0x02, 0x58,
0x03, 0x04, 0x7D, 0x01, 0x07, 0x2E, 0x03, 0x00, 0x3A, 0x01,
0x16, 0x4C, 0x02, 0x01, 0x42, 0x03, 0x12, 0x65, 0x01, 0x13,
0x78, 0x02, 0x08, 0x7A, 0x03, 0x0C, 0x7A, 0x01, 0x01, 0x40,
0x02, 0x0B, 0x41, 0x01, 0x16, 0x10, 0x01, 0x17, 0x1A, 0x01,
0x08, 0x6D, 0x03, 0x0F, 0x74, 0x03, 0x09, 0x00, 0x01, 0x00,
0x1F, 0x03, 0x13, 0x30, 0x03, 0x04, 0x6A, 0x01, 0x06, 0x30,
0x02, 0x10, 0x56, 0x03, 0x0B, 0x76, 0x02, 0x16, 0x1D, 0x02,
0x0F, 0x28, 0x02, 0x08, 0x25, 0x03, 0x07, 0x40, 0x01, 0x13,
0x7D, 0x03, 0x10, 0x6B, 0x01, 0x17, 0x34, 0x03, 0x04, 0x02,
0x01, 0x00, 0x77, 0x03, 0x01, 0x51, 0x01, 0x08, 0x19, 0x03,
0x0E, 0x38, 0x02, 0x11, 0x31, 0x03, 0x0F, 0x2B, 0x02, 0x11,
0x1A, 0x01, 0x0E, 0x49, 0x01, 0x10, 0x72, 0x01, 0x0C, 0x70,
0x01, 0x0D, 0x25, 0x03, 0x12, 0x15, 0x01, 0x02, 0x01, 0x03,
0x0B, 0x74, 0x03, 0x12, 0x65, 0x02, 0x01, 0x61, 0x03, 0x07,
0x62, 0x01, 0x13, 0x39, 0x03, 0x16, 0x5D, 0x03, 0x13, 0x50,
0x03, 0x0B, 0x3D, 0x01, 0x09, 0x07, 0x02, 0x03, 0x31, 0x01,
0x0B, 0x38, 0x01, 0x0B, 0x3E, 0x03, 0x05, 0x1A, 0x03, 0x03,
0x40, 0x03, 0x12, 0x28, 0x03, 0x09, 0x1E, 0x03, 0x01, 0x65,
0x02, 0x04, 0x17, 0x01, 0x10, 0x29, 0x01, 0x0B, 0x77, 0x03,
0x14, 0x3F, 0x01, 0x01, 0x65, 0x02, 0x13, 0x67, 0x02, 0x04,
0x30, 0x02, 0x13, 0x00, 0x01, 0x00, 0x1A, 0x03, 0x03, 0x5E,
0x03, 0x15, 0x56, 0x02, 0x09, 0x0F, 0x02, 0x0B, 0x74, 0x01,
0x0E, 0x6C, 0x01, 0x03, 0x7C, 0x02, 0x0B, 0x3B, 0x02, 0x0A,
0x3A, 0x02, 0x12, 0x4B, 0x03, 0x13, 0x72, 0x01, 0x16, 0x26,
0x02, 0x03, 0x35, 0x03, 0x02, 0x2A, 0x01, 0x01, 0x55, 0x01,
0x0A, 0x3F, 0x01, 0x14, 0x55, 0x02, 0x12, 0x10, 0x02, 0x06,
0x15, 0x02, 0x09, 0x40, 0x03, 0x07, 0x61, 0x03, 0x09, 0x3B,
0x01, 0x0C, 0x38, 0x01, 0x03, 0x37, 0x03, 0x0B, 0x1A, 0x02,
0x12, 0x09, 0x03, 0x11, 0x4C, 0x03, 0x07, 0x70, 0x01, 0x11,
0x14, 0x03, 0x07, 0x75, 0x01, 0x02, 0x1A, 0x01, 0x00, 0x5D,
0x02, 0x09, 0x2A, 0x03, 0x09, 0x74, 0x03, 0x05, 0x69, 0x02,
0x0A, 0x35, 0x03, 0x05, 0x32, 0x01, 0x17, 0x58, 0x02, 0x00,
0x6A, 0x03, 0x14, 0x58, 0x01, 0x0D, 0x7C, 0x01, 0x14, 0x34,
0x03, 0x13, 0x67, 0x03, 0x12, 0x67, 0x03, 0x07, 0x31, 0x02,
0x15, 0x21, 0x02, 0x0B, 0x49, 0x02, 0x10, 0x25, 0x01, 0x0D,
0x14, 0x01, 0x13, 0x25, 0x01, 0x06, 0x20, 0x03, 0x10, 0x3C,
0x02, 0x0B, 0x5A, 0x02, 0x07, 0x52, 0x01, 0x07, 0x06, 0x03,
0x02, 0x70, 0x01, 0x16, 0x04, 0x03, 0x0B, 0x52, 0x02, 0x01,
0x2B, 0x01, 0x04, 0x16, 0x01, 0x06, 0x7F, 0x01, 0x00, 0x0B,
0x02, 0x15, 0x59, 0x02, 0x06, 0x03, 0x02, 0x06, 0x3F, 0x02,
0x08, 0x34, 0x03, 0x05, 0x56, 0x02, 0x12, 0x04, 0x02, 0x15,
0x73, 0x01, 0x06, 0x1A, 0x03, 0x0D, 0x7E, 0x03, 0x0D, 0x3B,
0x02, 0x03, 0x40, 0x01, 0x00, 0x6B, 0x02, 0x15, 0x7F, 0x03,
0x09, 0x08, 0x01, 0x17, 0x5C, 0x03, 0x09, 0x22, 0x03, 0x13,
0x05, 0x02, 0x16, 0x0F, 0x01, 0x0B, 0x5C, 0x03, 0x01, 0x76,
0x01, 0x04, 0x5D, 0x02, 0x05, 0x64, 0x01, 0x01, 0x4A, 0x01,
0x05, 0x33, 0x01, 0x01, 0x08, 0x02, 0x04, 0x2B, 0x02, 0x0E,
0x1D, 0x03, 0x07, 0x38, 0x02, 0x10, 0x46, 0x03, 0x09, 0x07,
0x02, 0x08, 0x4A, 0x02, 0x06, 0x43, 0x03, 0x01, 0x45, 0x02,
0x07, 0x7A, 0x02, 0x0E, 0x78, 0x02, 0x06, 0x56, 0x01, 0x07,
0x4F, 0x02, 0x03, 0x57, 0x02, 0x11, 0x49, 0x02, 0x00, 0x18,
0x03, 0x0A, 0x17, 0x02, 0x08, 0x08, 0x01, 0x17, 0x3D, 0x03,
0x09, 0x19, 0x01, 0x17, 0x35, 0x01, 0x05, 0x1C, 0x03, 0x0B,
0x16, 0x03, 0x0F, 0x43, 0x03, 0x08, 0x10, 0x03, 0x11, 0x14,
0x03, 0x00, 0x2E, 0x01, 0x02, 0x11, 0x02, 0x06, 0x68, 0x01,
0x0E, 0x2E, 0x01, 0x0A, 0x18, 0x01, 0x09, 0x36, 0x02, 0x16,
0x60, 0x02, 0x0A, 0x3A, 0x02, 0x10, 0x29, 0x02, 0x12, 0x50,
0x02, 0x17, 0x5B, 0x02, 0x12, 0x3E, 0x01, 0x0D, 0x58, 0x02,
0x14, 0x67, 0x03, 0x0F, 0x24, 0x01, 0x14, 0x50, 0x01, 0x12,
0x70, 0x03, 0x0C, 0x0D, 0x03, 0x14, 0x49, 0x01, 0x09, 0x16]

# print(len(b))

num = 15000
for i in range(5000):
num -= 3
v0 = b[num]
v1 = b[num+1]
v3 = b[num+2]
if v0 == 0x01:
dword_601060[v1] -= v3
elif v0 == 0x02:
dword_601060[v1] += v3
elif v0 == 0x03:
dword_601060[v1] ^= v3
elif v0 == 0x04:
dword_601060[v1] = dword_601060[v1]/v3
elif v0 == 0x05:
dword_601060[v1] ^= dword_601060[v3]
else:
continue

flag = ''
for i in range(24):
flag += chr(dword_601060[i] % 128) #char类型每4位取最低位

print(flag)

得到flag:nctf{Embr4ce_Vm_j0in_R3}

normal6

这是一道安卓题,老样子先进jeb中查看一下

找到重要的so文件,我们将文件解压一下,在lib文件夹中找到so文件拖入ida32,

又回到了熟悉的问题,如何找到关键函数,我们搜索字符串

两处双击进入

很明显,不在这,我们定位到1号字符串

在1号字符串处点X跳转在F5反编译。

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
Word16 sub_1233(Word16 x, Word16 y)
{
int v2; // r2
int v3; // r5
int v4; // r4
char *v5; // r6
signed int v6; // r4
unsigned __int8 *v7; // r0
unsigned __int8 *v8; // r5
size_t v9; // r0
signed int v10; // r2
_BYTE *v11; // r3
int v12; // t1
const char *v13; // r2
int v14; // r3
int v15; // t1
int v16; // t1

v3 = x;
v4 = v2;
v5 = (char *)(*(int (__fastcall **)(Word16, int, _DWORD))(*(_DWORD *)x + 736))(x, v2, 0); //就是输入
v6 = (*(int (__fastcall **)(int, int))(*(_DWORD *)v3 + 684))(v3, v4); //输入的大小
v7 = (unsigned __int8 *)malloc(v6);
v8 = v7;
if ( v6 <= 0 )
{
v7[v6] = 0;
LOBYTE(v7) = 1;
}
else
{
v9 = strlen(asc_4028) + 47;
v10 = v6;
v11 = v8;
do
{
v12 = *v5++; //v12就是答案
--v10;
*v11++ = asc_4028[v9 - v12] ^ 0x5F; //1号字符串=二号字符串[v9-v12]^0x5F
}
while ( v10 );
v8[v6] = 0;
v13 = "vrt~rzey{vvyt{v";
LOBYTE(v7) = 1;
do //下面的do-while循环与寻找v13与哪个值有关
{
v15 = *v8++;
v14 = v15;
v16 = *(unsigned __int8 *)v13++;
if ( v16 != v14 )
LOBYTE(v7) = 0;
--v6;
}
while ( v6 );
}
LOWORD(v7) = (unsigned __int8)v7;
return (__int16)v7;
}

乍一看条理非常不清晰,但仔细分析一下就出来了。asc_4028是存2号字符串的 “!:#”,0x24,”%&()+-“ , vrt~rzey{vvyt{v是一号字符串,我们先跟踪一下v13是什么,是字符串。还是v16,又因为v16与v14对比了,所以还是v14,还是v15,那么就是v8,v8又等于v11。那么v9是什么v9 = strlen(asc_4028) + 47,所以v9=57,v12是什么?v12代表v5这个数组,v5又与x有关,那么我们有理由怀疑v5是我们要找的字符串,那么我们现在的目标是找v12是多少。好了,已经全部清楚了

给出脚本:

1
2
3
4
5
6
7
8
9
data1="vrt~rzey{vvyt{v"
data2="!:#"+chr(0x24)+"%&()+-"
flag=""
for i in range(15):
for j in range(10):
if ord(data1[i]) ^ 0x5F == ord(data2[j]):
flag += chr(57-j)
print(flag)
#201905846224162

normal7

又是一道安卓逆向,用jeb打开,发现jeb过期了,下了个jeb-patch补了一下。

发现字符串,很像是base64变表,又找到:

用base64试一下,

1
2
3
4
5
6
7
8
9
10
import base64
t1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
t2='αβγδεζηθικλμνξοπρσ89+/さしすせそたちτυφχψω012345てとゐなにぬねの67つっはひふへほゑま;;;'
data="すひ6ねτ3/7しはξ2すつιのν92φτひ/なしひξねたさ+ψιρ;;"
result = ''
flag=""
for ch in data:
result += t1[t2.index(ch)]
result = bytearray(base64.b64decode(result+"=="))
print(result)

成功了bytearray(b’clover_Sec2019_wel_come!!\x0f<’)

这里有几点要注意,在jeb得反编译中不可copy,只能在strings中来copy。

而且变表是不全的,所以要进行一下补充“ ; ; ;”

normal8

z3求解器的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int64 __fastcall main(int a1, char **a2, char **a3)
{
char s[56]; // [rsp+0h] [rbp-40h] BYREF
unsigned __int64 v5; // [rsp+38h] [rbp-8h]

v5 = __readfsqword(0x28u);
memset(s, 0, 0x30uLL);
puts("You are a good Reverser!");
puts(off_602250);
puts("wakalimasu.Give me your starlight!");
fgets(s, 47, stdin);
if ( (unsigned __int8)sub_40094C(s) )
puts("you are top star!");
else
puts("non-non dayo~");
return 0LL;
}

off_602250里是一张图片,我也没看出来是啥东西,好像是个鹿。

我们真正重要的是sub_40094C这个函数,我们进入

__

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
int64 __fastcall sub_40094C(const char *a1)
{
unsigned __int8 v2; // [rsp+13h] [rbp-2Dh]
int i; // [rsp+14h] [rbp-2Ch]
int j; // [rsp+18h] [rbp-28h]
int v5; // [rsp+1Ch] [rbp-24h]
_DWORD *ptr; // [rsp+20h] [rbp-20h]
_DWORD *v7; // [rsp+28h] [rbp-18h]
_DWORD *v8; // [rsp+30h] [rbp-10h]
_DWORD *v9; // [rsp+38h] [rbp-8h]

v2 = 1;
v5 = strlen(a1);
if ( v5 > 37 )
return 0LL;
ptr = (_DWORD *)sub_400736(36LL);
v7 = (_DWORD *)sub_400736(36LL);
for ( i = 0; i < v5; ++i )
{
ptr[i] = a1[i] >> 4;
v7[i] = a1[i] & 0xF;
}
v8 = (_DWORD *)sub_40078E((__int64)ptr, (__int64)&data3, 6);
v9 = (_DWORD *)sub_400892(v7, &data3, 6LL);
for ( j = 0; j <= 35; ++j )
{
if ( v8[j] != data1[j] || v9[j] != data2[j] ) //不满足就返回0
v2 = 0;
}
free(ptr);
free(v7);
free(v8);
free(v9);
return v2;
}

free这个函数,毫无作用,不用管,sub_400736这个函数是开辟空间的,没有用。我们一定要满足上面的判断式,如果不满足返回0,那么就寄了,我们可以提取出data1和data2的数组,那么变化后的v8和v9就知道了,而且我们知道flag长度36 . 我们再倒推,总共有两个函数,sub_40078E对ptr变化,sub_400892对v7变换,我们再看上面,ptr是由flag右移4位得到,v7是由flag&15得到的。那我们只用逆其中一个算法就行了。

先看sub_40078E函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
_DWORD *__fastcall sub_40078E(__int64 a1, __int64 a2, int a3)
{
int i; // [rsp+2Ch] [rbp-14h]
int j; // [rsp+30h] [rbp-10h]
int k; // [rsp+34h] [rbp-Ch]
_DWORD *v8; // [rsp+38h] [rbp-8h]

v8 = sub_400736(a3);
for ( i = 0; i < a3; ++i )
{
for ( j = 0; j < a3; ++j )
{
for ( k = 0; k < a3; ++k )
v8[a3 * i + j] += *(_DWORD *)(4LL * (a3 * i + k) + a1) * *(_DWORD *)(4LL * (a3 * k + j) + a2);
}
}
return v8;
}

再看sub_400892函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
_DWORD *__fastcall sub_400892(__int64 a1, __int64 a2, int a3)
{
int i; // [rsp+20h] [rbp-10h]
int j; // [rsp+24h] [rbp-Ch]
_DWORD *v7; // [rsp+28h] [rbp-8h]

v7 = sub_400736(a3);
for ( i = 0; i < a3; ++i )
{
for ( j = 0; j < a3; ++j )
v7[a3 * i + j] = *(_DWORD *)(4LL * (a3 * i + j) + a1) + *(_DWORD *)(4LL * (a3 * i + j) + a2);
}
return v7;
}

这两个嵌套了三层循环,实在有些不好逆,那我们只能采用z3库来解决问题了。

介绍一下z3库的大致解题思路:

1
from z3 import*                 #引入z3
1
s=Solver()                      #创建求解器
1
flag=[Int('flag%d'%i) for i in range(64)]                      #int类型
1
flag = [BitVec("flag%d" % i, 8) for i in range(36)]            #按位运算,每一位有8字节大小空间
1
s.add()                        #约束条件
1
2
3
4
5
6
7
8
9
if s.check() == sat:                              #检查机制,如果有解就输出,无解就错误
m = s.model()
res = []
for i in range(36):
res.append(chr(m[flag[i]].as_long()))
s=''.join(res)
print(s)
else:
print(nope)

给出官方中文翻译版:https://arabelatso.github.io/2018/06/14/Z3%20API%20in%20Python/

给出脚本:

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
from z3 import*
data1=[0x0000007A, 0x000000CF, 0x0000008C, 0x00000095, 0x0000008E, 0x000000A8, 0x0000005F, 0x000000C9, 0x0000007A, 0x00000091, 0x00000088, 0x000000A7, 0x00000070, 0x000000C0, 0x0000007F, 0x00000089, 0x00000086, 0x00000093, 0x0000005F, 0x000000CF, 0x0000006E, 0x00000086, 0x00000085, 0x000000AD, 0x00000088, 0x000000D4, 0x000000A0, 0x000000A2, 0x00000098, 0x000000B3, 0x00000079, 0x000000C1, 0x0000007E, 0x0000007E, 0x00000077, 0x00000093]
data2=[0x00000010, 0x00000008, 0x00000008, 0x0000000E, 0x00000006, 0x0000000B, 0x00000005, 0x00000017, 0x00000005, 0x0000000A, 0x0000000C, 0x00000017, 0x0000000E, 0x00000017, 0x00000013, 0x00000007, 0x00000008, 0x0000000A, 0x00000004, 0x0000000D, 0x00000016, 0x00000011, 0x0000000B, 0x00000016, 0x00000006, 0x0000000E, 0x00000002, 0x0000000B, 0x00000012, 0x00000009, 0x00000005, 0x00000008, 0x00000008, 0x0000000A, 0x00000010, 0x0000000D]
data3=[0x00000008, 0x00000001, 0x00000007, 0x00000001, 0x00000001, 0x00000000, 0x00000004, 0x00000008, 0x00000001, 0x00000002, 0x00000003, 0x00000009, 0x00000003, 0x00000008, 0x00000006, 0x00000006, 0x00000004, 0x00000008, 0x00000003, 0x00000005, 0x00000007, 0x00000008, 0x00000008, 0x00000007, 0x00000000, 0x00000009, 0x00000000, 0x00000002, 0x00000003, 0x00000004, 0x00000002, 0x00000003, 0x00000002, 0x00000005, 0x00000004, 0x00000000]
s=Solver()
flag = [BitVec("flag%d" % i, 8) for i in range(36)]
ptr = [(i >> 4) for i in flag] #每一位右移4,很精妙的表达
v7 = [(i & 15) for i in flag]
v8 = [0 for i in range(36)]
v9 = [0 for i in range(36)]
for i in range(len(flag)): #限制在可见字符内
s.add(flag[i] < 127)
s.add(flag[i] > 32)

for i in range(6):
for j in range(6):
for k in range(6):
v8[6*i+j]+=ptr[6*i+k]*data3[6*k+j]

for i in range(6):
for j in range(6):
v9[6*i+j]=v7[6*i+j]+data3[6*i+j]

for i in range(36):
s.add(v8[i]==data1[i]) #两个约束条件
s.add(v9[i]==data2[i])
if s.check() == sat:
m = s.model()
res = []
for i in range(36):
res.append(chr(m[flag[i]].as_long()))
s=''.join(res)
print(s)
else:
print(nope)


#hgame{1_think_Matr1x_is_very_usef5l}

normal9

我认为是由于我使用的是ida7.6所以功能更强大,所以反编译看的还是很清楚的,就是两个数组异或。

normal10

先玩一个掷骰子的游戏,动调一下,一直F8就过了

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // rdx
unsigned int v5; // ebx
__int64 v6; // rdx
__int64 v7; // rax
__int64 v8; // rax
__int64 v9; // rdx
__int64 v10; // rax
__int64 v11; // rax
__int64 v12; // rdx
__int64 v13; // rax
__int64 v14; // rdx
__int64 v15; // rax
__int64 v16; // rax
__int64 v17; // rdx
__int64 v18; // rax
unsigned int v20; // [rsp+8h] [rbp-48h] BYREF
unsigned int v21; // [rsp+Ch] [rbp-44h]
char v22[40]; // [rsp+10h] [rbp-40h] BYREF
unsigned __int64 v23; // [rsp+38h] [rbp-18h]

v23 = __readfsqword(0x28u);
v3 = std::operator<<<std::char_traits<char>>(
&std::cout,
"to continue, you have to guess the value of my dice first!",
envp);
std::ostream::operator<<(v3, (__int64)&std::endl<char,std::char_traits<char>>);
v21 = rolling_dice();
std::operator<<<std::char_traits<char>>(&std::cout, "now the dice have been rolled, guess what it is: ", v4);
std::istream::operator>>(&std::cin, &v20);
v5 = v20;
v7 = std::operator<<<std::char_traits<char>>(&std::cout, "expected: ", v6);
v8 = std::ostream::operator<<(v7, v21);
v10 = std::operator<<<std::char_traits<char>>(v8, ", guess: ", v9);
v11 = std::ostream::operator<<(v10, v5);
std::ostream::operator<<(v11, (__int64)&std::endl<char,std::char_traits<char>>);
if ( v20 != v21 )
{
v13 = std::operator<<<std::char_traits<char>>(&std::cout, "you are bad at guessing dice", v12);
std::ostream::operator<<(v13, (__int64)&std::endl<char,std::char_traits<char>>);
exit(0);
}
std::operator<<<std::char_traits<char>>(
&std::cout,
"wow, you are good at dice-guessing, now give me your flag: ",
v12);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(v22);
std::operator>><char>(&std::cin, v22);
if ( std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length(v22) != 32 )
{
v15 = std::operator<<<std::char_traits<char>>(&std::cout, "assert len(flag) == 32", v14);
std::ostream::operator<<(v15, (__int64)&std::endl<char,std::char_traits<char>>);
exit(0);
}
v16 = std::operator<<<std::char_traits<char>>(&std::cout, "now the math part...", v14);
std::ostream::operator<<(v16, (__int64)&std::endl<char,std::char_traits<char>>);
if ( (unsigned __int8)math_part(v22) )
v18 = std::operator<<<std::char_traits<char>>(
&std::cout,
"wow, you are good at doing math too, you deserve to have the flag, just submit it!",
v17);
else
v18 = std::operator<<<std::char_traits<char>>(&std::cout, "you are bad at doing math", v17);
std::ostream::operator<<(v18, (__int64)&std::endl<char,std::char_traits<char>>);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(v22);
return 0;
}

我们主要看math_part这个部分

__

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
int64 __fastcall math_part(__int64 a1)
{
int v1; // et1
int v2; // edx
int v3; // ecx
int v4; // et1
int v5; // et1
int v6; // et1
int v7; // edx
int v8; // edx
int v9; // et1
int v10; // ecx
int v11; // edx
int v12; // et1
int v13; // edx
int v14; // edx
int v15; // ecx
int v16; // edx
int v17; // et1
int v18; // edx
int v19; // et1
int v20; // ecx
int v21; // edx
int v22; // ecx
int v23; // et1
int v24; // edx
int v25; // edx
int v26; // ecx
int v27; // ecx
int v28; // ecx
int v29; // et1
int v30; // ecx
int v31; // ecx
int v32; // edx
char *v34; // [rsp+18h] [rbp-8h]

v34 = (char *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str(a1);
v1 = 76 * v34[21]
+ 31 * v34[9]
+ 87 * v34[28]
+ 54 * v34[2]
+ 74 * v34[5]
+ 99 * v34[26]
+ 94 * v34[3]
+ 84 * v34[19]
+ 32 * v34[15]
+ 90 * v34[27]
+ 16 * v34[14]
+ 19 * v34[8]
+ 33 * v34[20]
+ 35 * v34[31]
+ 65 * v34[29]
+ 47 * v34[12]
+ 3 * v34[1]
+ 57 * v34[7]
+ 5 * v34[17]
+ 70 * v34[13]
+ 28 * v34[24]
+ 79 * v34[11]
+ 63 * v34[23]
+ 66 * v34[30]
+ 28 * v34[10]
+ v34[4];
if ( 82 * v34[16] + 58 * v34[25] + v1 + 81 * v34[6] + 61 * v34[18] + 31 * v34[22] + 71 * *v34 != 145397 )
return 0LL;
v2 = 55 * v34[6]
+ 38 * v34[9]
+ 39 * v34[18]
+ 73 * v34[24]
+ 86 * v34[13]
+ 18 * v34[11]
+ 40 * v34[21]
+ 40 * v34[26]
+ 54 * v34[14]
+ 81 * v34[10]
+ 71 * v34[27]
+ 20 * v34[8]
+ 16 * v34[28]
+ 65 * v34[30]
+ 87 * v34[3]
+ 14 * v34[16]
+ v34[5]
+ 41 * *v34
+ 58 * v34[15]
+ 73 * v34[2]
+ 46 * v34[23]
+ 7 * v34[19]
+ 89 * v34[17]
+ 65 * v34[25]
+ 43 * v34[7]
+ 6 * v34[20];
if ( v2 + 60 * v34[12] + 40 * v34[31] + 57 * v34[29] + 40 * v34[4] + 30 * v34[1] + 63 * v34[22] != 127517 )
return 0LL;
v3 = 53 * v34[10]
+ 82 * v34[14]
+ 70 * v34[5]
+ 84 * v34[2]
+ 57 * v34[19]
+ 92 * v34[27]
+ 57 * v34[11]
+ 77 * v34[4]
+ 49 * v34[8]
+ 62 * v34[29]
+ 97 * v34[22]
+ 47 * v34[1]
+ 30 * v34[16]
+ 45 * v34[30]
+ 94 * v34[28]
+ 6 * v34[9]
+ 83 * v34[20]
+ 18 * v34[23]
+ 97 * v34[15]
+ 11 * v34[12]
+ 35 * v34[7]
+ 81 * v34[26]
+ 67 * v34[13]
+ 11 * v34[31]
+ 84 * v34[24];
if ( 28 * v34[6] + 17 * v34[21] + 18 * v34[3] + v3 + 63 * v34[25] + 61 * v34[18] != 141411 )
return 0LL;
v4 = 14 * v34[24]
+ 46 * v34[6]
+ 56 * v34[7]
+ 13 * v34[2]
+ 82 * v34[11]
+ 49 * v34[30]
+ 97 * v34[18]
+ 50 * v34[14]
+ 83 * v34[27]
+ 38 * v34[13]
+ 49 * v34[29]
+ 9 * v34[4]
+ 91 * v34[20]
+ 33 * v34[25]
+ 4 * v34[22]
+ 5 * v34[17]
+ 61 * v34[15]
+ 65 * v34[3]
+ 68 * v34[28]
+ 6 * v34[16]
+ (v34[8] << 6)
+ 56 * v34[9]
+ 67 * v34[10]
+ 5 * v34[5]
+ v34[21]
+ 10 * v34[19];
if ( 86 * v34[23] + 52 * v34[1] + v4 + 83 * v34[12] + 37 * v34[26] + 85 * *v34 != 117383 )
return 0LL;
v5 = 9 * v34[28]
+ 63 * v34[5]
+ 20 * v34[4]
+ 96 * v34[8]
+ 39 * v34[11]
+ 91 * v34[1]
+ 40 * v34[9]
+ 85 * v34[14]
+ 62 * v34[16]
+ 95 * v34[19]
+ 34 * v34[22]
+ 67 * v34[31]
+ 51 * v34[27]
+ 45 * v34[26]
+ 92 * v34[15]
+ 91 * v34[21]
+ 85 * v34[13]
+ 12 * v34[7]
+ 26 * v34[23]
+ 56 * v34[30]
+ 82 * v34[18]
+ 72 * v34[17]
+ 54 * v34[6]
+ 17 * v34[12]
+ 84 * v34[29]
+ 17 * *v34;
if ( 53 * v34[3] + 91 * v34[2] + 57 * v34[25] + 66 * v34[20] + v5 + 8 * v34[24] + 63 * v34[10] != 156152 )
return 0LL;
v6 = 88 * v34[9]
+ 48 * v34[4]
+ 83 * v34[13]
+ 66 * v34[7]
+ 60 * v34[30]
+ 57 * v34[6]
+ 85 * v34[17]
+ 71 * v34[28]
+ 98 * v34[24]
+ 83 * v34[10]
+ 12 * v34[1]
+ 72 * v34[31]
+ 12 * v34[22]
+ 80 * v34[20]
+ 15 * v34[19]
+ 81 * v34[21]
+ 87 * *v34
+ 37 * v34[16]
+ 4 * v34[15]
+ 41 * v34[3]
+ 84 * v34[26]
+ 56 * v34[25]
+ 84 * v34[14]
+ 41 * v34[27]
+ 98 * v34[18]
+ 18 * v34[2];
if ( 55 * v34[23] + v6 + 95 * v34[11] + 33 * v34[29] + 66 * v34[8] != 148963 )
return 0LL;
v7 = 57 * v34[21]
+ 63 * v34[12]
+ 4 * v34[14]
+ 59 * v34[31]
+ 15 * v34[23]
+ 12 * v34[25]
+ 58 * v34[5]
+ 40 * v34[4]
+ 26 * v34[30]
+ 8 * v34[15]
+ 25 * v34[6]
+ 97 * v34[10]
+ 12 * v34[28]
+ 74 * v34[26]
+ 65 * v34[8]
+ 93 * v34[27]
+ 18 * v34[22]
+ 84 * v34[2]
+ 7 * v34[1]
+ 22 * v34[18]
+ 9 * v34[17]
+ 89 * v34[19]
+ 72 * v34[13]
+ 47 * v34[20]
+ 7 * v34[29];
if ( 43 * v34[16] + 47 * *v34 + 53 * v34[24] + 75 * v34[11] + v7 + 8 * v34[9] + 24 * v34[7] + 75 * v34[3] != 121517 )
return 0LL;
v8 = 86 * v34[17]
+ 74 * *v34
+ 72 * v34[4]
+ 27 * v34[20]
+ 88 * v34[9]
+ (v34[21] << 6)
+ 52 * v34[15]
+ 4 * v34[19]
+ 8 * v34[1]
+ 16 * v34[13]
+ 54 * v34[25]
+ 8 * v34[29]
+ 52 * v34[23]
+ 14 * v34[10]
+ 88 * v34[18]
+ 33 * v34[8]
+ 99 * v34[27]
+ 65 * v34[14]
+ 66 * v34[5]
+ 36 * v34[6]
+ 58 * v34[16]
+ 63 * v34[22]
+ 93 * v34[3]
+ 96 * v34[11]
+ 26 * v34[26]
+ 65 * v34[12];
if ( 77 * v34[30] + 89 * v34[31] + 55 * v34[7] + v8 + 42 * v34[28] + 14 * v34[2] + 57 * v34[24] != 151446 )
return 0LL;
v9 = 51 * v34[7]
+ 42 * v34[4]
+ 78 * v34[8]
+ 45 * v34[25]
+ 63 * v34[30]
+ 85 * v34[26]
+ 30 * v34[29]
+ 83 * v34[14]
+ 62 * v34[31]
+ 71 * v34[22]
+ 45 * v34[17]
+ (v34[6] << 6)
+ 87 * v34[23]
+ 49 * v34[28]
+ 14 * *v34
+ 4 * v34[21]
+ 63 * v34[5]
+ 53 * v34[13]
+ 19 * v34[19]
+ 44 * v34[16]
+ 5 * v34[3]
+ 74 * v34[15]
+ 19 * v34[18]
+ 89 * v34[11]
+ 11 * v34[20]
+ 34 * v34[12];
if ( 53 * v34[24] + 95 * v34[27] + v9 + 14 * v34[1] + 87 * v34[10] + 63 * v34[9] + 70 * v34[2] != 142830 )
return 0LL;
v10 = 13 * v34[29]
+ 11 * v34[22]
+ 41 * v34[5]
+ 38 * v34[13]
+ 90 * v34[31]
+ 68 * v34[7]
+ 56 * v34[14]
+ 4 * v34[23]
+ 66 * v34[28]
+ 28 * v34[1]
+ 6 * v34[12]
+ 91 * v34[16]
+ 59 * v34[3]
+ 81 * v34[17]
+ 44 * v34[2]
+ 33 * v34[24]
+ 34 * v34[19]
+ 17 * v34[18]
+ 77 * v34[25]
+ 25 * v34[8]
+ 8 * v34[6]
+ 10 * v34[30]
+ 66 * v34[20];
if ( 69 * *v34
+ 67 * v34[9]
+ 57 * v34[15]
+ 77 * v34[10]
+ 67 * v34[26]
+ 94 * v34[11]
+ v10
+ 41 * v34[27]
+ 29 * v34[21] != 122585 )
return 0LL;
v11 = 23 * v34[25]
+ 32 * v34[3]
+ 72 * v34[15]
+ 41 * v34[26]
+ 33 * v34[30]
+ 82 * v34[13]
+ 20 * *v34
+ 7 * v34[12]
+ 25 * v34[29]
+ 39 * v34[21]
+ 57 * v34[14]
+ 14 * v34[16]
+ 24 * v34[24]
+ 37 * v34[22]
+ 71 * v34[10]
+ 65 * v34[23]
+ 46 * v34[8]
+ 40 * v34[19]
+ 77 * v34[27]
+ 80 * v34[18]
+ 88 * v34[6]
+ 20 * v34[31]
+ 83 * v34[11]
+ 73 * v34[1]
+ 8 * v34[5]
+ 15 * v34[20];
if ( 31 * v34[9] + 17 * v34[4] + 6 * v34[28] + v11 + 70 * v34[7] + 24 * v34[17] + 16 * v34[2] != 105293 )
return 0LL;
v12 = 41 * v34[24]
+ 45 * v34[30]
+ 82 * v34[20]
+ 86 * v34[19]
+ 99 * v34[9]
+ 96 * v34[22]
+ 85 * v34[28]
+ 70 * v34[5]
+ 77 * v34[23]
+ 80 * v34[11]
+ 40 * v34[31]
+ 66 * v34[12]
+ 12 * v34[2]
+ 77 * v34[15]
+ 72 * v34[4]
+ 42 * v34[26]
+ 81 * v34[27]
+ 90 * v34[13]
+ 37 * v34[16]
+ 29 * v34[17]
+ 20 * v34[29]
+ 85 * v34[6]
+ 6 * v34[7]
+ 2 * *v34
+ 72 * v34[1]
+ 75 * v34[14];
if ( 25 * v34[21] + 79 * v34[3] + v12 + 40 * v34[25] + 29 * v34[8] + 25 * v34[10] != 151962 )
return 0LL;
v13 = 42 * v34[31]
+ 95 * v34[30]
+ 58 * v34[8]
+ 47 * v34[13]
+ 65 * v34[15]
+ 24 * v34[17]
+ 97 * v34[10]
+ 24 * v34[21]
+ 28 * *v34
+ 77 * v34[5]
+ 97 * v34[6]
+ 24 * v34[26]
+ 32 * v34[12]
+ 5 * v34[25]
+ 55 * v34[28]
+ 9 * v34[23]
+ 85 * v34[4]
+ 6 * v34[9]
+ 61 * v34[19]
+ 12 * v34[3]
+ 76 * v34[7]
+ 36 * v34[27]
+ 77 * v34[24]
+ 24 * v34[29]
+ 67 * v34[14]
+ 19 * v34[16];
if ( 83 * v34[11] + 75 * v34[1] + v13 + 47 * v34[20] + 13 * v34[22] != 125609 )
return 0LL;
v14 = v34[1]
+ 88 * v34[3]
+ 90 * *v34
+ 4 * v34[23]
+ 46 * v34[7]
+ 54 * v34[16]
+ 16 * v34[6]
+ 89 * v34[22]
+ 76 * v34[27]
+ 38 * v34[17]
+ 3 * v34[5]
+ 70 * v34[14]
+ 3 * v34[24]
+ 24 * v34[13]
+ 54 * v34[2]
+ 20 * v34[8]
+ 83 * v34[12]
+ 21 * v34[15]
+ 77 * v34[18]
+ 31 * v34[19]
+ 59 * v34[21]
+ 33 * v34[20]
+ 84 * v34[11]
+ 19 * v34[29]
+ 38 * v34[26]
+ 63 * v34[31];
if ( 30 * v34[25] + 41 * v34[28] + 65 * v34[10] + v14 + 16 * v34[30] + 15 * v34[4] + 39 * v34[9] != 123069 )
return 0LL;
v15 = 27 * v34[18]
+ 48 * v34[4]
+ 13 * v34[20]
+ 44 * v34[10]
+ 70 * v34[12]
+ 44 * v34[17]
+ 22 * v34[23]
+ 55 * v34[14]
+ 73 * v34[26]
+ 55 * v34[8]
+ 58 * v34[11]
+ 31 * v34[30]
+ 78 * v34[29]
+ 19 * v34[25]
+ 52 * v34[31]
+ 27 * v34[21]
+ 38 * v34[27]
+ 40 * v34[28]
+ 35 * v34[1]
+ 48 * v34[22]
+ 71 * v34[15]
+ 24 * v34[6]
+ 89 * v34[16]
+ 37 * v34[3]
+ 78 * v34[2];
if ( 6 * v34[9] + 19 * v34[19] + v15 + 3 * v34[5] + 52 * v34[24] + 40 * v34[7] != 113842 )
return 0LL;
v16 = 31 * v34[12]
+ 35 * v34[10]
+ 54 * v34[20]
+ 26 * v34[29]
+ 29 * v34[3]
+ 2 * v34[23]
+ 46 * *v34
+ 30 * v34[26]
+ 56 * v34[27]
+ 100 * v34[11]
+ 43 * v34[1]
+ 15 * v34[4]
+ 79 * v34[17]
+ 12 * v34[5]
+ 38 * v34[9]
+ 3 * v34[30]
+ 16 * v34[21]
+ 19 * v34[13]
+ 67 * v34[19]
+ 37 * v34[28]
+ v34[7]
+ 73 * v34[16]
+ 85 * v34[6]
+ 17 * v34[14]
+ 90 * v34[22]
+ 15 * v34[2];
if ( 95 * v34[8] + 92 * v34[18] + 84 * v34[31] + v16 + 43 * v34[25] + 96 * v34[24] != 119824 )
return 0LL;
v17 = 92 * v34[20]
+ 43 * v34[23]
+ 16 * v34[19]
+ 92 * v34[5]
+ 49 * v34[26]
+ 44 * v34[2]
+ 26 * v34[29]
+ (v34[25] << 6)
+ 45 * v34[24]
+ 99 * v34[11]
+ 43 * v34[4]
+ 75 * v34[21]
+ 53 * v34[31]
+ 18 * v34[18]
+ 11 * v34[13]
+ 52 * *v34
+ 16 * v34[8]
+ 9 * v34[7]
+ 77 * v34[16]
+ 33 * v34[10]
+ 86 * v34[1]
+ 33 * v34[3]
+ 29 * v34[9]
+ 6 * v34[12]
+ 91 * v34[14]
+ 36 * v34[15];
if ( 36 * v34[22] + 69 * v34[28] + 77 * v34[6] + v17 + 94 * v34[27] + 13 * v34[30] + 89 * v34[17] != 135873 )
return 0LL;
v18 = 68 * v34[2]
+ 83 * v34[10]
+ 47 * v34[5]
+ 85 * v34[13]
+ 22 * v34[8]
+ 92 * v34[27]
+ 75 * v34[28]
+ 43 * v34[3]
+ 29 * v34[22]
+ 92 * *v34
+ 54 * v34[16]
+ 17 * v34[30]
+ 78 * v34[18]
+ 7 * v34[23]
+ 69 * v34[21]
+ 63 * v34[31]
+ 71 * v34[4]
+ 10 * v34[6]
+ 66 * v34[14]
+ 25 * v34[26]
+ 32 * v34[1]
+ 48 * v34[19]
+ 86 * v34[11]
+ 20 * v34[25]
+ 78 * v34[20]
+ 25 * v34[17];
if ( 16 * v34[7] + v34[15] + 82 * v34[9] + 60 * v34[29] + v18 + 76 * v34[12] + 13 * v34[24] != 142509 )
return 0LL;
v19 = 77 * v34[9]
+ 56 * v34[30]
+ 79 * v34[2]
+ 71 * v34[29]
+ 95 * v34[28]
+ 87 * v34[24]
+ 62 * v34[16]
+ 85 * v34[26]
+ 43 * v34[20]
+ 67 * v34[15]
+ 97 * v34[8]
+ 80 * *v34
+ 23 * v34[3]
+ 95 * v34[25]
+ 82 * v34[21]
+ 66 * v34[31]
+ 5 * v34[4]
+ 66 * v34[27]
+ 25 * v34[12]
+ 4 * v34[5]
+ 12 * v34[7]
+ 85 * v34[1]
+ 10 * v34[6]
+ 45 * v34[11]
+ 28 * v34[18]
+ 26 * v34[19];
if ( 88 * v34[22] + 23 * v34[13] + 18 * v34[14] + v19 + 48 * v34[23] + 45 * v34[17] != 148888 )
return 0LL;
v20 = 81 * v34[30]
+ 21 * v34[6]
+ 72 * v34[11]
+ 48 * v34[18]
+ 2 * v34[19]
+ 42 * v34[10]
+ 22 * v34[24]
+ 99 * v34[2]
+ 78 * v34[22]
+ 83 * v34[12]
+ 60 * v34[9]
+ 59 * v34[13]
+ 15 * v34[5]
+ 25 * v34[20]
+ 43 * v34[15]
+ 56 * v34[28]
+ 33 * v34[25]
+ 71 * v34[23]
+ 31 * *v34
+ 95 * v34[3]
+ 73 * v34[17]
+ 86 * v34[14]
+ 15 * v34[21]
+ 61 * v34[7]
+ 12 * v34[29]
+ 95 * v34[26];
if ( 25 * v34[8] + v20 + 13 * v34[1] + 100 * v34[16] + 11 * v34[4] + 79 * v34[27] != 138023 )
return 0LL;
v21 = 53 * v34[27]
+ 52 * v34[29]
+ 70 * v34[22]
+ 35 * v34[30]
+ 50 * v34[16]
+ 59 * v34[8]
+ 75 * v34[10]
+ 55 * v34[20]
+ 23 * *v34
+ 52 * v34[17]
+ 47 * v34[3]
+ 91 * v34[13]
+ 46 * v34[7]
+ 42 * v34[14]
+ 79 * v34[26]
+ 87 * v34[21]
+ 30 * v34[6]
+ 26 * v34[1]
+ 57 * v34[31]
+ 33 * v34[12]
+ 51 * v34[9]
+ 56 * v34[24]
+ 59 * v34[11]
+ 36 * v34[23]
+ 88 * v34[4]
+ 28 * v34[2];
if ( 37 * v34[28] + 62 * v34[25] + 42 * v34[18] + v21 + 44 * v34[15] + 19 * v34[19] + 74 * v34[5] != 142299 )
return 0LL;
v22 = 80 * v34[21]
+ 43 * v34[31]
+ 67 * v34[16]
+ 55 * v34[13]
+ 95 * v34[24]
+ 46 * v34[28]
+ 93 * v34[5]
+ 75 * v34[20]
+ 14 * v34[25]
+ 24 * v34[26]
+ 50 * v34[29]
+ 70 * v34[15]
+ 63 * v34[30]
+ 77 * v34[23]
+ 96 * v34[19]
+ 66 * v34[11]
+ 72 * v34[27]
+ 94 * v34[4]
+ 63 * v34[22]
+ 69 * v34[3]
+ 73 * v34[1]
+ 60 * v34[7]
+ 9 * v34[2]
+ 39 * v34[17]
+ 25 * *v34
+ 49 * v34[14];
if ( v22 + 48 * v34[8] + 86 * v34[9] + 72 * v34[10] + 23 * v34[18] + 21 * v34[6] != 155777 )
return 0LL;
v23 = 27 * v34[11]
+ 40 * v34[8]
+ 53 * v34[15]
+ 40 * v34[18]
+ 56 * v34[3]
+ 2 * v34[2]
+ 32 * v34[4]
+ 90 * v34[1]
+ 54 * v34[16]
+ 20 * v34[9]
+ 86 * v34[17]
+ 82 * v34[31]
+ 43 * v34[25]
+ 43 * v34[13]
+ 86 * v34[21]
+ 17 * *v34
+ (v34[14] << 6)
+ 6 * v34[30]
+ 86 * v34[5]
+ 15 * v34[7]
+ 46 * v34[12]
+ 21 * v34[26]
+ 90 * v34[20]
+ 19 * v34[6]
+ 93 * v34[23]
+ 31 * v34[27];
if ( 25 * v34[24] + 11 * v34[22] + v23 + 62 * v34[29] + 21 * v34[19] + 42 * v34[10] != 117687 )
return 0LL;
v24 = v34[27]
+ 66 * v34[18]
+ 40 * v34[17]
+ 17 * *v34
+ 27 * v34[19]
+ 26 * v34[31]
+ 57 * v34[24]
+ 35 * v34[3]
+ 80 * v34[1]
+ 67 * v34[5]
+ 85 * v34[6]
+ 7 * v34[15]
+ 93 * v34[8]
+ 3 * v34[22]
+ 77 * v34[12]
+ 12 * v34[28]
+ 4 * v34[2]
+ 27 * v34[9]
+ 53 * v34[25]
+ 37 * v34[30]
+ 43 * v34[23]
+ 33 * v34[4]
+ 39 * v34[26]
+ 7 * v34[7]
+ 75 * v34[10]
+ 15 * v34[14];
if ( 89 * v34[21] + 100 * v34[13] + v24 + 45 * v34[20] + 36 * v34[29] + 78 * v34[11] + 31 * v34[16] != 117383 )
return 0LL;
v25 = 71 * v34[16]
+ 4 * v34[1]
+ 77 * v34[31]
+ 83 * v34[2]
+ 11 * v34[30]
+ 53 * v34[19]
+ 85 * v34[12]
+ 67 * v34[13]
+ 39 * v34[8]
+ 45 * v34[24]
+ 84 * v34[22]
+ 99 * v34[14]
+ 38 * v34[3]
+ 29 * v34[4]
+ 90 * v34[9]
+ 61 * v34[18]
+ 40 * v34[7]
+ (v34[17] << 6)
+ 9 * v34[25]
+ 86 * v34[29]
+ 80 * v34[21]
+ 4 * v34[15]
+ 96 * v34[23]
+ 99 * v34[10]
+ 40 * v34[27];
if ( 73 * v34[20] + 16 * v34[26] + 100 * v34[5] + 71 * v34[28] + v25 + 4 * *v34 + 56 * v34[11] != 155741 )
return 0LL;
v26 = 87 * v34[2]
+ 86 * v34[24]
+ 76 * v34[14]
+ 38 * v34[23]
+ 85 * v34[3]
+ 71 * v34[22]
+ 42 * v34[29]
+ 85 * v34[30]
+ 14 * v34[10]
+ 17 * v34[13]
+ 42 * v34[25]
+ 11 * v34[19]
+ 44 * v34[15]
+ 21 * v34[4]
+ 60 * v34[16]
+ 28 * v34[6]
+ 46 * v34[20]
+ 25 * v34[9]
+ 77 * v34[31]
+ 21 * v34[8]
+ 85 * v34[7]
+ 36 * v34[1]
+ 91 * v34[27]
+ 21 * v34[28]
+ 38 * v34[17];
if ( (v34[12] << 6) + 76 * *v34 + 5 * v34[11] + v26 + 3 * v34[26] + 61 * v34[21] + 15 * v34[5] + 32 * v34[18] == 132804
&& (v27 = 36 * v34[1]
+ 60 * v34[3]
+ 84 * v34[11]
+ 19 * v34[26]
+ 76 * v34[27]
+ 86 * v34[16]
+ 92 * v34[8]
+ 96 * v34[14]
+ 60 * v34[21]
+ 23 * v34[4]
+ 60 * v34[12]
+ 50 * v34[23]
+ 78 * v34[22]
+ 45 * v34[9]
+ 42 * v34[18]
+ 10 * v34[2]
+ 60 * v34[20]
+ 24 * v34[24]
+ 77 * v34[7]
+ 41 * v34[6]
+ 29 * v34[13]
+ 33 * v34[5]
+ 2 * v34[15]
+ 33 * v34[29]
+ 39 * v34[31],
95 * v34[30] + 75 * v34[28] + 3 * v34[10] + v27 + 41 * v34[25] + 100 * v34[19] + 9 * v34[17] + 79 * *v34 == 145568)
&& (v28 = 25 * v34[26]
+ 98 * v34[24]
+ 15 * v34[6]
+ 50 * v34[18]
+ 88 * v34[20]
+ 74 * v34[11]
+ 83 * v34[1]
+ 86 * v34[21]
+ 52 * v34[7]
+ 39 * v34[10]
+ 40 * v34[13]
+ 82 * v34[28]
+ 37 * v34[3]
+ 45 * *v34
+ 18 * v34[25]
+ 2 * v34[29]
+ 6 * v34[12]
+ 78 * v34[31]
+ 37 * v34[2]
+ 57 * v34[23]
+ 3 * v34[4]
+ 59 * v34[8]
+ 73 * v34[15]
+ v34[22]
+ 18 * v34[9]
+ 35 * v34[14],
68 * v34[5] + 98 * v34[27] + 98 * v34[16] + 10 * v34[19] + v28 + 20 * v34[17] + 54 * v34[30] == 130175)
&& (v29 = 68 * v34[23]
+ 60 * v34[18]
+ 93 * v34[20]
+ 100 * v34[11]
+ 98 * v34[14]
+ 32 * v34[3]
+ 15 * v34[21]
+ 79 * *v34
+ 6 * v34[24]
+ 62 * v34[26]
+ 96 * v34[6]
+ 68 * v34[22]
+ 9 * v34[7]
+ 88 * v34[5]
+ 18 * v34[27]
+ 70 * v34[9]
+ 96 * v34[25]
+ 89 * v34[4]
+ 14 * v34[31]
+ 83 * v34[17]
+ 19 * v34[15]
+ 44 * v34[1]
+ 96 * v34[8]
+ 87 * v34[16]
+ 48 * v34[2]
+ 95 * v34[13],
60 * v34[10] + 50 * v34[12] + 30 * v34[29] + 90 * v34[19] + v29 + 73 * v34[28] + 92 * v34[30] == 171986)
&& (v30 = 86 * v34[9]
+ 20 * v34[7]
+ 29 * v34[16]
+ 31 * v34[14]
+ 83 * v34[26]
+ 11 * v34[4]
+ 29 * v34[19]
+ 82 * v34[13]
+ 84 * v34[10]
+ 70 * v34[1]
+ 52 * v34[12]
+ 40 * v34[6]
+ 91 * v34[8]
+ 6 * v34[17]
+ 77 * v34[28]
+ 56 * v34[5]
+ 86 * v34[23]
+ 63 * v34[31]
+ 26 * v34[27]
+ 19 * v34[22]
+ 50 * v34[3]
+ 15 * v34[15]
+ 67 * v34[2]
+ 37 * v34[24]
+ 84 * v34[18],
53 * v34[30] + 87 * v34[25] + 23 * v34[29] + 80 * v34[20] + v30 + 81 * v34[21] + 93 * *v34 == 151676)
&& (v31 = 12 * v34[11]
+ 82 * v34[24]
+ 100 * v34[8]
+ 29 * v34[26]
+ 97 * v34[12]
+ 32 * v34[6]
+ 26 * v34[27]
+ 46 * v34[19]
+ 8 * (v34[25] + 9 * *v34 + 2 * v34[17])
+ 63 * v34[10]
+ 39 * v34[29]
+ 81 * v34[15]
+ 51 * v34[13]
+ 31 * v34[30]
+ 49 * v34[4]
+ 3 * v34[22]
+ 26 * v34[28]
+ 15 * v34[20]
+ 89 * v34[2]
+ 5 * v34[31]
+ 47 * v34[18]
+ 19 * v34[23]
+ 98 * v34[9],
29 * v34[3] + 93 * v34[5] + 67 * v34[21] + v31 + 15 * v34[16] + 49 * v34[1] == 128223)
&& (v32 = 84 * v34[25]
+ 91 * v34[10]
+ 67 * v34[22]
+ 77 * v34[15]
+ 23 * v34[26]
+ 38 * v34[4]
+ 3 * v34[31]
+ 76 * v34[13]
+ 50 * *v34
+ 74 * v34[11]
+ 45 * v34[28]
+ 58 * v34[29]
+ 39 * v34[5]
+ 95 * v34[9]
+ 26 * v34[16]
+ 23 * v34[8]
+ 28 * v34[24]
+ 89 * v34[1]
+ 88 * v34[18]
+ 3 * v34[3]
+ 59 * v34[20]
+ 80 * v34[23]
+ 49 * v34[17]
+ 56 * v34[21]
+ 32 * v34[27]
+ 24 * v34[2],
13 * v34[14] + 73 * v34[19] + 99 * v34[7] + 76 * v34[12] + v32 + 77 * v34[30] + 18 * v34[6] == 138403) )
{
return 1LL;
}
else
{
return 0LL;
}
}

很显然是一个z3约束器的使用。

太简单了这个题

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
from z3 import *
x = Solver()
flag = [Int('flag%d'%i) for i in range(32)]
for i in range(32):
x.add(flag[i] > 23)
x.add(flag[i] < 127)
for i in range(6):
x.add(flag[i] == ord("hgame{"[i]))
x.add(flag[31] == ord("}"))
x.add((82 * flag[16] + 58 * flag[25] + 76 * flag[21] + 31 * flag[9]+ 87 * flag[28]+ 54 * flag[2]+ 74 * flag[5]+ 99 * flag[26]+ 94 * flag[3]+ 84 * flag[19]+ 32 * flag[15]+ 90 * flag[27]+ 16 * flag[14]+ 19 * flag[8]+ 33 * flag[20]+ 35 * flag[31]+ 65 * flag[29]+ 47 * flag[12]+ 3 * flag[1]+ 57 * flag[7]+ 5 * flag[17]+ 70 * flag[13]+ 28 * flag[24]+ 79 * flag[11]+ 63 * flag[23]+ 66 * flag[30]+ 28 * flag[10]+ flag[4] + 81 * flag[6] + 61 * flag[18] + 31 * flag[22] + 71 * flag[0]) == 0x237F5)
x.add((55 * flag[6]+ 38 * flag[9]+ 39 * flag[18]+ 73 * flag[24]+ 86 * flag[13]+ 18 * flag[11]+ 40 * flag[21]+ 40 * flag[26]+ 54 * flag[14]+ 81 * flag[10]+ 71 * flag[27]+ 20 * flag[8]+ 16 * flag[28]+ 65 * flag[30]+ 87 * flag[3]+ 14 * flag[16]+ flag[5]+ 41 * flag[0]+ 58 * flag[15]+ 73 * flag[2]+ 46 * flag[23]+ 7 * flag[19]+ 89 * flag[17]+ 65 * flag[25]+ 43 * flag[7]+ 6 * flag[20] + 60 * flag[12] + 40 * flag[31] + 57 * flag[29] + 40 * flag[4] + 30 * flag[1] + 63 * flag[22]) == 0x1F21D)
x.add((28 * flag[6] + 17 * flag[21] + 18 * flag[3] + 53 * flag[10]+ 82 * flag[14]+ 70 * flag[5]+ 84 * flag[2]+ 57 * flag[19]+ 92 * flag[27]+ 57 * flag[11]+ 77 * flag[4]+ 49 * flag[8]+ 62 * flag[29]+ 97 * flag[22]+ 47 * flag[1]+ 30 * flag[16]+ 45 * flag[30]+ 94 * flag[28]+ 6 * flag[9]+ 83 * flag[20]+ 18 * flag[23]+ 97 * flag[15]+ 11 * flag[12]+ 35 * flag[7]+ 81 * flag[26]+ 67 * flag[13]+ 11 * flag[31]+ 84 * flag[24] + 63 * flag[25] + 61 * flag[18]) == 0x22863)
x.add((86 * flag[23] + 52 * flag[1] + 14 * flag[24]+ 46 * flag[6]+ 56 * flag[7]+ 13 * flag[2]+ 82 * flag[11]+ 49 * flag[30]+ 97 * flag[18]+ 50 * flag[14]+ 83 * flag[27]+ 38 * flag[13]+ 49 * flag[29]+ 9 * flag[4]+ 91 * flag[20]+ 33 * flag[25]+ 4 * flag[22]+ 5 * flag[17]+ 61 * flag[15]+ 65 * flag[3]+ 68 * flag[28]+ 6 * flag[16]+ (flag[8] * 64)+ 56 * flag[9]+ 67 * flag[10]+ 5 * flag[5]+ flag[21]+ 10 * flag[19] + 83 * flag[12] + 37 * flag[26] + 85 * flag[0]) == 0x1CA87)
x.add( 53 * flag[3] + 91 * flag[2] + 57 * flag[25] + 66 * flag[20] + 9 * flag[28]+ 63 * flag[5]+ 20 * flag[4]+ 96 * flag[8]+ 39 * flag[11]+ 91 * flag[1]+ 40 * flag[9]+ 85 * flag[14]+ 62 * flag[16]+ 95 * flag[19]+ 34 * flag[22]+ 67 * flag[31]+ 51 * flag[27]+ 45 * flag[26]+ 92 * flag[15]+ 91 * flag[21]+ 85 * flag[13]+ 12 * flag[7]+ 26 * flag[23]+ 56 * flag[30]+ 82 * flag[18]+ 72 * flag[17]+ 54 * flag[6]+ 17 * flag[12]+ 84 * flag[29]+ 17 * flag[0] + 8 * flag[24] + 63 * flag[10] == 0x261F8 )
x.add( 55 * flag[23] + 88 * flag[9]+ 48 * flag[4]+ 83 * flag[13]+ 66 * flag[7]+ 60 * flag[30]+ 57 * flag[6]+ 85 * flag[17]+ 71 * flag[28]+ 98 * flag[24]+ 83 * flag[10]+ 12 * flag[1]+ 72 * flag[31]+ 12 * flag[22]+ 80 * flag[20]+ 15 * flag[19]+ 81 * flag[21]+ 87 * flag[0]+ 37 * flag[16]+ 4 * flag[15]+ 41 * flag[3]+ 84 * flag[26]+ 56 * flag[25]+ 84 * flag[14]+ 41 * flag[27]+ 98 * flag[18]+ 18 * flag[2] + 95 * flag[11] + 33 * flag[29] + 66 * flag[8] == 0x245E3 )
x.add( 43 * flag[16] + 47 * flag[0] + 53 * flag[24] + 75 * flag[11] + 57 * flag[21]+ 63 * flag[12]+ 4 * flag[14]+ 59 * flag[31]+ 15 * flag[23]+ 12 * flag[25]+ 58 * flag[5]+ 40 * flag[4]+ 26 * flag[30]+ 8 * flag[15]+ 25 * flag[6]+ 97 * flag[10]+ 12 * flag[28]+ 74 * flag[26]+ 65 * flag[8]+ 93 * flag[27]+ 18 * flag[22]+ 84 * flag[2]+ 7 * flag[1]+ 22 * flag[18]+ 9 * flag[17]+ 89 * flag[19]+ 72 * flag[13]+ 47 * flag[20]+ 7 * flag[29] + 8 * flag[9] + 24 * flag[7] + 75 * flag[3] == 121517 )
x.add( 77 * flag[30] + 89 * flag[31] + 55 * flag[7] + 86 * flag[17]+ 74 * flag[0]+ 72 * flag[4]+ 27 * flag[20]+ 88 * flag[9]+ (flag[21] * 64)+ 52 * flag[15]+ 4 * flag[19]+ 8 * flag[1]+ 16 * flag[13]+ 54 * flag[25]+ 8 * flag[29]+ 52 * flag[23]+ 14 * flag[10]+ 88 * flag[18]+ 33 * flag[8]+ 99 * flag[27]+ 65 * flag[14]+ 66 * flag[5]+ 36 * flag[6]+ 58 * flag[16]+ 63 * flag[22]+ 93 * flag[3]+ 96 * flag[11]+ 26 * flag[26]+ 65 * flag[12] + 42 * flag[28] + 14 * flag[2] + 57 * flag[24] == 0x24F96 )
x.add( 53 * flag[24] + 95 * flag[27] + 51 * flag[7]+ 42 * flag[4]+ 78 * flag[8]+ 45 * flag[25]+ 63 * flag[30]+ 85 * flag[26]+ 30 * flag[29]+ 83 * flag[14]+ 62 * flag[31]+ 71 * flag[22]+ 45 * flag[17]+ (flag[6] * 64)+ 87 * flag[23]+ 49 * flag[28]+ 14 * flag[0]+ 4 * flag[21]+ 63 * flag[5]+ 53 * flag[13]+ 19 * flag[19]+ 44 * flag[16]+ 5 * flag[3]+ 74 * flag[15]+ 19 * flag[18]+ 89 * flag[11]+ 11 * flag[20]+ 34 * flag[12] + 14 * flag[1] + 87 * flag[10] + 63 * flag[9] + 70 * flag[2] == 142830 )
x.add( 69 * flag[0]+ 67 * flag[9]+ 57 * flag[15]+ 77 * flag[10]+ 67 * flag[26]+ 94 * flag[11]+ 13 * flag[29]+ 11 * flag[22]+ 41 * flag[5]+ 38 * flag[13]+ 90 * flag[31]+ 68 * flag[7]+ 56 * flag[14]+ 4 * flag[23]+ 66 * flag[28]+ 28 * flag[1]+ 6 * flag[12]+ 91 * flag[16]+ 59 * flag[3]+ 81 * flag[17]+ 44 * flag[2]+ 33 * flag[24]+ 34 * flag[19]+ 17 * flag[18]+ 77 * flag[25]+ 25 * flag[8]+ 8 * flag[6]+ 10 * flag[30]+ 66 * flag[20]+ 41 * flag[27]+ 29 * flag[21] == 0x1DED9 )
x.add( 31 * flag[9] + 17 * flag[4] + 6 * flag[28] + 23 * flag[25]+ 32 * flag[3]+ 72 * flag[15]+ 41 * flag[26]+ 33 * flag[30]+ 82 * flag[13]+ 20 * flag[0]+ 7 * flag[12]+ 25 * flag[29]+ 39 * flag[21]+ 57 * flag[14]+ 14 * flag[16]+ 24 * flag[24]+ 37 * flag[22]+ 71 * flag[10]+ 65 * flag[23]+ 46 * flag[8]+ 40 * flag[19]+ 77 * flag[27]+ 80 * flag[18]+ 88 * flag[6]+ 20 * flag[31]+ 83 * flag[11]+ 73 * flag[1]+ 8 * flag[5]+ 15 * flag[20] + 70 * flag[7] + 24 * flag[17] + 16 * flag[2] == 0x19B4D )
x.add( 25 * flag[21] + 79 * flag[3] + 41 * flag[24]+ 45 * flag[30]+ 82 * flag[20]+ 86 * flag[19]+ 99 * flag[9]+ 96 * flag[22]+ 85 * flag[28]+ 70 * flag[5]+ 77 * flag[23]+ 80 * flag[11]+ 40 * flag[31]+ 66 * flag[12]+ 12 * flag[2]+ 77 * flag[15]+ 72 * flag[4]+ 42 * flag[26]+ 81 * flag[27]+ 90 * flag[13]+ 37 * flag[16]+ 29 * flag[17]+ 20 * flag[29]+ 85 * flag[6]+ 6 * flag[7]+ 2 * flag[0]+ 72 * flag[1]+ 75 * flag[14] + 40 * flag[25] + 29 * flag[8] + 25 * flag[10] == 0x2519A )
x.add( 83 * flag[11] + 75 * flag[1] + 42 * flag[31]+ 95 * flag[30]+ 58 * flag[8]+ 47 * flag[13]+ 65 * flag[15]+ 24 * flag[17]+ 97 * flag[10]+ 24 * flag[21]+ 28 * flag[0]+ 77 * flag[5]+ 97 * flag[6]+ 24 * flag[26]+ 32 * flag[12]+ 5 * flag[25]+ 55 * flag[28]+ 9 * flag[23]+ 85 * flag[4]+ 6 * flag[9]+ 61 * flag[19]+ 12 * flag[3]+ 76 * flag[7]+ 36 * flag[27]+ 77 * flag[24]+ 24 * flag[29]+ 67 * flag[14]+ 19 * flag[16] + 47 * flag[20] + 13 * flag[22] == 125609 )
x.add( 30 * flag[25] + 41 * flag[28] + 65 * flag[10] + flag[1]+ 88 * flag[3]+ 90 * flag[0]+ 4 * flag[23]+ 46 * flag[7]+ 54 * flag[16]+ 16 * flag[6]+ 89 * flag[22]+ 76 * flag[27]+ 38 * flag[17]+ 3 * flag[5]+ 70 * flag[14]+ 3 * flag[24]+ 24 * flag[13]+ 54 * flag[2]+ 20 * flag[8]+ 83 * flag[12]+ 21 * flag[15]+ 77 * flag[18]+ 31 * flag[19]+ 59 * flag[21]+ 33 * flag[20]+ 84 * flag[11]+ 19 * flag[29]+ 38 * flag[26]+ 63 * flag[31] + 16 * flag[30] + 15 * flag[4] + 39 * flag[9] == 123069 )
x.add( 6 * flag[9] + 19 * flag[19] + 27 * flag[18]+ 48 * flag[4]+ 13 * flag[20]+ 44 * flag[10]+ 70 * flag[12]+ 44 * flag[17]+ 22 * flag[23]+ 55 * flag[14]+ 73 * flag[26]+ 55 * flag[8]+ 58 * flag[11]+ 31 * flag[30]+ 78 * flag[29]+ 19 * flag[25]+ 52 * flag[31]+ 27 * flag[21]+ 38 * flag[27]+ 40 * flag[28]+ 35 * flag[1]+ 48 * flag[22]+ 71 * flag[15]+ 24 * flag[6]+ 89 * flag[16]+ 37 * flag[3]+ 78 * flag[2] + 3 * flag[5] + 52 * flag[24] + 40 * flag[7] == 113842 )
x.add( 95 * flag[8] + 92 * flag[18] + 84 * flag[31] + 31 * flag[12]+ 35 * flag[10]+ 54 * flag[20]+ 26 * flag[29]+ 29 * flag[3]+ 2 * flag[23]+ 46 * flag[0]+ 30 * flag[26]+ 56 * flag[27]+ 100 * flag[11]+ 43 * flag[1]+ 15 * flag[4]+ 79 * flag[17]+ 12 * flag[5]+ 38 * flag[9]+ 3 * flag[30]+ 16 * flag[21]+ 19 * flag[13]+ 67 * flag[19]+ 37 * flag[28]+ flag[7]+ 73 * flag[16]+ 85 * flag[6]+ 17 * flag[14]+ 90 * flag[22]+ 15 * flag[2] + 43 * flag[25] + 96 * flag[24] == 119824 )
x.add( 36 * flag[22] + 69 * flag[28] + 77 * flag[6] + 92 * flag[20]+ 43 * flag[23]+ 16 * flag[19]+ 92 * flag[5]+ 49 * flag[26]+ 44 * flag[2]+ 26 * flag[29]+ (flag[25] * 64)+ 45 * flag[24]+ 99 * flag[11]+ 43 * flag[4]+ 75 * flag[21]+ 53 * flag[31]+ 18 * flag[18]+ 11 * flag[13]+ 52 * flag[0]+ 16 * flag[8]+ 9 * flag[7]+ 77 * flag[16]+ 33 * flag[10]+ 86 * flag[1]+ 33 * flag[3]+ 29 * flag[9]+ 6 * flag[12]+ 91 * flag[14]+ 36 * flag[15] + 94 * flag[27] + 13 * flag[30] + 89 * flag[17] == 135873 )
x.add( 16 * flag[7] + flag[15] + 82 * flag[9] + 60 * flag[29] + 68 * flag[2]+ 83 * flag[10]+ 47 * flag[5]+ 85 * flag[13]+ 22 * flag[8]+ 92 * flag[27]+ 75 * flag[28]+ 43 * flag[3]+ 29 * flag[22]+ 92 * flag[0]+ 54 * flag[16]+ 17 * flag[30]+ 78 * flag[18]+ 7 * flag[23]+ 69 * flag[21]+ 63 * flag[31]+ 71 * flag[4]+ 10 * flag[6]+ 66 * flag[14]+ 25 * flag[26]+ 32 * flag[1]+ 48 * flag[19]+ 86 * flag[11]+ 20 * flag[25]+ 78 * flag[20]+ 25 * flag[17] + 76 * flag[12] + 13 * flag[24] == 142509 )
x.add( 88 * flag[22] + 23 * flag[13] + 18 * flag[14] + 77 * flag[9]+ 56 * flag[30]+ 79 * flag[2]+ 71 * flag[29]+ 95 * flag[28]+ 87 * flag[24]+ 62 * flag[16]+ 85 * flag[26]+ 43 * flag[20]+ 67 * flag[15]+ 97 * flag[8]+ 80 * flag[0]+ 23 * flag[3]+ 95 * flag[25]+ 82 * flag[21]+ 66 * flag[31]+ 5 * flag[4]+ 66 * flag[27]+ 25 * flag[12]+ 4 * flag[5]+ 12 * flag[7]+ 85 * flag[1]+ 10 * flag[6]+ 45 * flag[11]+ 28 * flag[18]+ 26 * flag[19] + 48 * flag[23] + 45 * flag[17] == 148888 )
x.add( 25 * flag[8] + 81 * flag[30]+ 21 * flag[6]+ 72 * flag[11]+ 48 * flag[18]+ 2 * flag[19]+ 42 * flag[10]+ 22 * flag[24]+ 99 * flag[2]+ 78 * flag[22]+ 83 * flag[12]+ 60 * flag[9]+ 59 * flag[13]+ 15 * flag[5]+ 25 * flag[20]+ 43 * flag[15]+ 56 * flag[28]+ 33 * flag[25]+ 71 * flag[23]+ 31 * flag[0]+ 95 * flag[3]+ 73 * flag[17]+ 86 * flag[14]+ 15 * flag[21]+ 61 * flag[7]+ 12 * flag[29]+ 95 * flag[26] + 13 * flag[1] + 100 * flag[16] + 11 * flag[4] + 79 * flag[27] == 138023 )
x.add( 37 * flag[28] + 62 * flag[25] + 42 * flag[18] + 53 * flag[27]+ 52 * flag[29]+ 70 * flag[22]+ 35 * flag[30]+ 50 * flag[16]+ 59 * flag[8]+ 75 * flag[10]+ 55 * flag[20]+ 23 * flag[0]+ 52 * flag[17]+ 47 * flag[3]+ 91 * flag[13]+ 46 * flag[7]+ 42 * flag[14]+ 79 * flag[26]+ 87 * flag[21]+ 30 * flag[6]+ 26 * flag[1]+ 57 * flag[31]+ 33 * flag[12]+ 51 * flag[9]+ 56 * flag[24]+ 59 * flag[11]+ 36 * flag[23]+ 88 * flag[4]+ 28 * flag[2] + 44 * flag[15] + 19 * flag[19] + 74 * flag[5] == 142299 )
x.add( 80 * flag[21]+ 43 * flag[31]+ 67 * flag[16]+ 55 * flag[13]+ 95 * flag[24]+ 46 * flag[28]+ 93 * flag[5]+ 75 * flag[20]+ 14 * flag[25]+ 24 * flag[26]+ 50 * flag[29]+ 70 * flag[15]+ 63 * flag[30]+ 77 * flag[23]+ 96 * flag[19]+ 66 * flag[11]+ 72 * flag[27]+ 94 * flag[4]+ 63 * flag[22]+ 69 * flag[3]+ 73 * flag[1]+ 60 * flag[7]+ 9 * flag[2]+ 39 * flag[17]+ 25 * flag[0]+ 49 * flag[14] + 48 * flag[8] + 86 * flag[9] + 72 * flag[10] + 23 * flag[18] + 21 * flag[6] == 155777 )
x.add( 25 * flag[24] + 11 * flag[22] + 27 * flag[11]+ 40 * flag[8]+ 53 * flag[15]+ 40 * flag[18]+ 56 * flag[3]+ 2 * flag[2]+ 32 * flag[4]+ 90 * flag[1]+ 54 * flag[16]+ 20 * flag[9]+ 86 * flag[17]+ 82 * flag[31]+ 43 * flag[25]+ 43 * flag[13]+ 86 * flag[21]+ 17 * flag[0]+ (flag[14] * 64)+ 6 * flag[30]+ 86 * flag[5]+ 15 * flag[7]+ 46 * flag[12]+ 21 * flag[26]+ 90 * flag[20]+ 19 * flag[6]+ 93 * flag[23]+ 31 * flag[27] + 62 * flag[29] + 21 * flag[19] + 42 * flag[10] == 117687 )
x.add( 89 * flag[21] + 100 * flag[13] + flag[27]+ 66 * flag[18]+ 40 * flag[17]+ 17 * flag[0]+ 27 * flag[19]+ 26 * flag[31]+ 57 * flag[24]+ 35 * flag[3]+ 80 * flag[1]+ 67 * flag[5]+ 85 * flag[6]+ 7 * flag[15]+ 93 * flag[8]+ 3 * flag[22]+ 77 * flag[12]+ 12 * flag[28]+ 4 * flag[2]+ 27 * flag[9]+ 53 * flag[25]+ 37 * flag[30]+ 43 * flag[23]+ 33 * flag[4]+ 39 * flag[26]+ 7 * flag[7]+ 75 * flag[10]+ 15 * flag[14] + 45 * flag[20] + 36 * flag[29] + 78 * flag[11] + 31 * flag[16] == 117383 )
x.add( 73 * flag[20] + 16 * flag[26] + 100 * flag[5] + 71 * flag[28] + 71 * flag[16]+ 4 * flag[1]+ 77 * flag[31]+ 83 * flag[2]+ 11 * flag[30]+ 53 * flag[19]+ 85 * flag[12]+ 67 * flag[13]+ 39 * flag[8]+ 45 * flag[24]+ 84 * flag[22]+ 99 * flag[14]+ 38 * flag[3]+ 29 * flag[4]+ 90 * flag[9]+ 61 * flag[18]+ 40 * flag[7]+ (flag[17] * 64)+ 9 * flag[25]+ 86 * flag[29]+ 80 * flag[21]+ 4 * flag[15]+ 96 * flag[23]+ 99 * flag[10]+ 40 * flag[27] + 4 * flag[0] + 56 * flag[11] == 155741)
x.add((flag[12] * 64) + 76 * flag[0] + 5 * flag[11] + 87 * flag[2]+ 86 * flag[24]+ 76 * flag[14]+ 38 * flag[23]+ 85 * flag[3]+ 71 * flag[22]+ 42 * flag[29]+ 85 * flag[30]+ 14 * flag[10]+ 17 * flag[13]+ 42 * flag[25]+ 11 * flag[19]+ 44 * flag[15]+ 21 * flag[4]+ 60 * flag[16]+ 28 * flag[6]+ 46 * flag[20]+ 25 * flag[9]+ 77 * flag[31]+ 21 * flag[8]+ 85 * flag[7]+ 36 * flag[1]+ 91 * flag[27]+ 21 * flag[28]+ 38 * flag[17] + 3 * flag[26] + 61 * flag[21] + 15 * flag[5] + 32 * flag[18] == 132804)
x.add(95 * flag[30] + 75 * flag[28] + 3 * flag[10] + 36 * flag[1]+ 60 * flag[3]+ 84 * flag[11]+ 19 * flag[26]+ 76 * flag[27]+ 86 * flag[16]+ 92 * flag[8]+ 96 * flag[14]+ 60 * flag[21]+ 23 * flag[4]+ 60 * flag[12]+ 50 * flag[23]+ 78 * flag[22]+ 45 * flag[9]+ 42 * flag[18]+ 10 * flag[2]+ 60 * flag[20]+ 24 * flag[24]+ 77 * flag[7]+ 41 * flag[6]+ 29 * flag[13]+ 33 * flag[5]+ 2 * flag[15]+ 33 * flag[29]+ 39 * flag[31] + 41 * flag[25] + 100 * flag[19] + 9 * flag[17] + 79 * flag[0] == 145568)
x.add(68 * flag[5] + 98 * flag[27] + 98 * flag[16] + 10 * flag[19] + 25 * flag[26]+ 98 * flag[24]+ 15 * flag[6]+ 50 * flag[18]+ 88 * flag[20]+ 74 * flag[11]+ 83 * flag[1]+ 86 * flag[21]+ 52 * flag[7]+ 39 * flag[10]+ 40 * flag[13]+ 82 * flag[28]+ 37 * flag[3]+ 45 * flag[0]+ 18 * flag[25]+ 2 * flag[29]+ 6 * flag[12]+ 78 * flag[31]+ 37 * flag[2]+ 57 * flag[23]+ 3 * flag[4]+ 59 * flag[8]+ 73 * flag[15]+ flag[22]+ 18 * flag[9]+ 35 * flag[14] + 20 * flag[17] + 54 * flag[30] == 130175)
x.add(60 * flag[10] + 50 * flag[12] + 30 * flag[29] + 90 * flag[19] + 68 * flag[23]+ 60 * flag[18]+ 93 * flag[20]+ 100 * flag[11]+ 98 * flag[14]+ 32 * flag[3]+ 15 * flag[21]+ 79 * flag[0]+ 6 * flag[24]+ 62 * flag[26]+ 96 * flag[6]+ 68 * flag[22]+ 9 * flag[7]+ 88 * flag[5]+ 18 * flag[27]+ 70 * flag[9]+ 96 * flag[25]+ 89 * flag[4]+ 14 * flag[31]+ 83 * flag[17]+ 19 * flag[15]+ 44 * flag[1]+ 96 * flag[8]+ 87 * flag[16]+ 48 * flag[2]+ 95 * flag[13] + 73 * flag[28] + 92 * flag[30] == 171986)
x.add(53 * flag[30] + 87 * flag[25] + 23 * flag[29] + 80 * flag[20] + 86 * flag[9]+ 20 * flag[7]+ 29 * flag[16]+ 31 * flag[14]+ 83 * flag[26]+ 11 * flag[4]+ 29 * flag[19]+ 82 * flag[13]+ 84 * flag[10]+ 70 * flag[1]+ 52 * flag[12]+ 40 * flag[6]+ 91 * flag[8]+ 6 * flag[17]+ 77 * flag[28]+ 56 * flag[5]+ 86 * flag[23]+ 63 * flag[31]+ 26 * flag[27]+ 19 * flag[22]+ 50 * flag[3]+ 15 * flag[15]+ 67 * flag[2]+ 37 * flag[24]+ 84 * flag[18] + 81 * flag[21] + 93 * flag[0] == 151676)
x.add(29 * flag[3] + 93 * flag[5] + 67 * flag[21] + 12 * flag[11]+ 82 * flag[24]+ 100 * flag[8]+ 29 * flag[26]+ 97 * flag[12]+ 32 * flag[6]+ 26 * flag[27]+ 46 * flag[19]+ 8 * (flag[25] + 9 * flag[0] + 2 * flag[17])+ 63 * flag[10]+ 39 * flag[29]+ 81 * flag[15]+ 51 * flag[13]+ 31 * flag[30]+ 49 * flag[4]+ 3 * flag[22]+ 26 * flag[28]+ 15 * flag[20]+ 89 * flag[2]+ 5 * flag[31]+ 47 * flag[18]+ 19 * flag[23]+ 98 * flag[9] + 15 * flag[16] + 49 * flag[1] == 128223)
x.add(13 * flag[14] + 73 * flag[19] + 99 * flag[7] + 76 * flag[12] + 84 * flag[25]+ 91 * flag[10]+ 67 * flag[22]+ 77 * flag[15]+ 23 * flag[26]+ 38 * flag[4]+ 3 * flag[31]+ 76 * flag[13]+ 50 * flag[0]+ 74 * flag[11]+ 45 * flag[28]+ 58 * flag[29]+ 39 * flag[5]+ 95 * flag[9]+ 26 * flag[16]+ 23 * flag[8]+ 28 * flag[24]+ 89 * flag[1]+ 88 * flag[18]+ 3 * flag[3]+ 59 * flag[20]+ 80 * flag[23]+ 49 * flag[17]+ 56 * flag[21]+ 32 * flag[27]+ 24 * flag[2] + 77 * flag[30] + 18 * flag[6] == 138403)
if x.check() == sat: #检查机制,如果有解就输出,无解就错误
m = x.model()
res = []
for i in range(32):
res.append(chr(m[flag[i]].as_long()))
x=''.join(res)
print(x)
else:
print("nope")

其中有几个很麻烦的点需要改动比如*其实是 * ,而<< 6要改成64,这样就出来flag了,太麻烦了只能说。

1
hgame{H4ppY#n3w@Y3AR%fr0M-oDiDi}

normal11

只能说这题看的我,真不会。去看wp了,竟然不是逆我们通常认知的函数

这竟然只是个障眼法,这个是没法逆向的,我们要找到

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
unsigned __int64 sub_400976()
{
int v0; // eax
FILE *stream; // [rsp+0h] [rbp-1080h]
FILE *v3; // [rsp+8h] [rbp-1078h]
char modes[16]; // [rsp+10h] [rbp-1070h] BYREF
char v5[16]; // [rsp+20h] [rbp-1060h] BYREF
char name[16]; // [rsp+30h] [rbp-1050h] BYREF
char path[16]; // [rsp+40h] [rbp-1040h] BYREF
char command[32]; // [rsp+50h] [rbp-1030h] BYREF
char buf[4104]; // [rsp+70h] [rbp-1010h] BYREF
unsigned __int64 v10; // [rsp+1078h] [rbp-8h]

v10 = __readfsqword(0x28u);
strcpy(modes, "rb");
strcpy(name, "./.real.so");
strcpy(v5, "wb+");
strcpy(command, "LD_PRELOAD=./.real.so ./real");
strcpy(path, "/proc/self/exe");
if ( access(name, 0) )
{
readlink(path, buf, 0x1000uLL);
stream = fopen(buf, modes);
fseek(stream, -12936LL, 2);
v3 = fopen(name, v5);
while ( !feof(stream) )
{
v0 = fgetc(stream);
fputc(v0, v3);
}
fclose(stream);
fclose(v3);
system(command);
exit(0);
}
return __readfsqword(0x28u) ^ v10;
}


这个函数的意思从源码读出倒数12936位来作为文件我们可以算出文件起始位置是291F,那么我们只需要用winhex将其分离出来

分离的方法是选中2920位到最末尾,然后右键编辑-剪贴板数据-粘贴至新文件,就可以了记住文件名为.elf

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
unsigned __int64 puts()
{
int i; // [rsp+Ch] [rbp-1014h]
char buf[4104]; // [rsp+10h] [rbp-1010h] BYREF
unsigned __int64 v3; // [rsp+1018h] [rbp-8h]

v3 = __readfsqword(0x28u);
if ( aaaaa )
{
printf("Please input your flag:");
putchar(10);
j_encrypt();
exit(0);
}
memset(buf, 0, 0x1000uLL);
getcwd(buf, 0x1000uLL);
strcat(buf, "/.real.so");
unlink(buf);
printf("Hello!");
putchar(10);
mprotect(0LL, 0x1000uLL, 7);
for ( i = 0; i <= 309; ++i ) //这是SMC自解密,是一种反调试
*((_BYTE *)&encrypt + i + 20) ^= i;
aaaaa = 1;
return __readfsqword(0x28u) ^ v3;
}

我们采用idc来编写脚本进行自解密:

1
2
3
4
5
6
7
8
9
10
#include <idc.idc>
static main()
{
auto addr = 0xAF0; //这里填入要解密字节串的起始地址
auto i = 0;
for(i=0;addr+i<0xB90;i++) //循环结束的条件为字节串的结束地址
{
PatchByte(addr+i+20,Byte(addr+i+20)^i); //异或的数字根据情况修改
}
}

接下来就有汇编错误了,我不会了,先等一下其他师傅写的wp吧!

来填坑喽!!!uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

1
2
for ( i = 0; i <= 309; ++i )                       //这是SMC自解密,是一种反调试
*((_BYTE *)&encrypt + i + 20) ^= i;

一般的smc加密都是这样的一个循环,我们点进加密函数

image-20220328193253471

发现这个函数开头地址是0xAF0,接下来是一个循环长度为0x135,循环的内容一般都是异或一个数,这个是先家20再异或i

1
2
3
4
5
6
7
8
9
10
#include <idc.idc>
static main()
{
auto addr = 0xAF0; //这里填入要解密字节串的起始地址
auto i = 0;
for(i=0;addr+i<0xC25;i++) //循环结束的条件为字节串的结束地址,0xc25 = 0xAF0 + 0X135
{
PatchByte(addr+i+20,Byte(addr+i+20)^i); //异或的数字根据情况修改
}
}

这个才是标准的smc解码,然后就还原了函数,发现中间有个垃圾插入值,nop掉,再在函数名处点u,再点p,出现函数

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
unsigned __int64 encrypt()
{
unsigned int v0; // eax
unsigned int v1; // eax
char s1[128]; // [rsp+10h] [rbp-190h] BYREF
char v4[128]; // [rsp+90h] [rbp-110h] BYREF
char s2[136]; // [rsp+110h] [rbp-90h] BYREF
unsigned __int64 v6; // [rsp+198h] [rbp-8h]

v6 = __readfsqword(0x28u);
memset(s1, 0, sizeof(s1));
qmemcpy(s1, "C$", 2);
s1[2] = -27;
s1[3] = -95;
s1[4] = -59;
s1[5] = 29;
s1[6] = 114;
s1[7] = -46;
s1[8] = 40;
s1[9] = -17;
s1[10] = -66;
s1[11] = -22;
s1[12] = -91;
s1[13] = -105;
s1[14] = 68;
s1[15] = 96;
s1[16] = -39;
s1[17] = 15;
s1[18] = 44;
s1[19] = 111;
s1[20] = 94;
s1[21] = 38;
s1[22] = -77;
s1[23] = 10;
s1[24] = -4;
s1[25] = -44;
s1[26] = -77;
memset(v4, 0, sizeof(v4));
memset(s2, 0, 0x80uLL);
scanf((const char *)0x3DBE, v4, s2);
v0 = strlen("hgame!@#");
_sub_whyiaminhere(0, "hgame!@#", v0);
v1 = strlen(v4);
_sub_whatthefuckisit(0, v4, v1, s2);
if ( !strcmp(s1, s2) )
printf("success!");
else
printf("failed");
putchar(10);
return __readfsqword(0x28u) ^ v6;
}

经典rc4加密,用脚本直接出,这个负数统统用16进制表示。

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
import base64


def rc4_main(key="init_key", message="init_message"):
print("RC4解密主函数调用成功")
print('\n')
s_box = rc4_init_sbox(key)
crypt = rc4_excrypt(message, s_box)
return crypt


def rc4_init_sbox(key):
s_box = list(range(256))
print("原来的 s 盒:%s" % s_box)
print('\n')
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
print("混乱后的 s 盒:%s" % s_box)
print('\n')
return s_box


def rc4_excrypt(plain, box):
print("调用解密程序成功。")
print('\n')
plain = base64.b64decode(plain.encode('utf-8'))
plain = bytes.decode(plain)
res = []
i = j = 0
for s in plain:
i = (i + 1) % 256
j = (j + box[i]) % 256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j]) % 256
k = box[t]
res.append((ord(s) ^ k))
print("res用于解密字符串,解密后是:%res" % res)
print('\n')
cipher = "".join(res)
print("解密后的字符串是:%s" % cipher)
print('\n')
return cipher

#a=[0xE0,0xB2,0x5F,0x3D,0x8F,0xFA,0x94,0xB6,0xE7,0x9D,0x6C,0x98,0x66,0xD2,0x0F,0xEA,0x6D,0x6F,0xBE,0xC5,0x71,0x40,0x08,0x1B,0xF6,0xF3,0xBD,0xA8,0x8D,0x09,0x7B,0x7C]
a = [67,36,0XE5,0XA1,0XC5,29,114,0XD2,40,0XEF,0XBE,0XEA,0XA5,0X97,68,96,0XD9,15,44,111,94,38,0XB3,10,0XFC,0XD4,0XB3]
s = ""
for i in a:
s += chr(i)
s = str(base64.b64encode(s.encode('utf-8')), 'utf-8')
rc4_main("hgame!@#", s)

#hgame{th1s_f4ke_re4l_w0rld}

拿下!

normal12

这个题用了OLLVM。

OLLVM是一款是由瑞士西北科技大学开发的一套开源的针对LLVM的代码混淆工具,旨在加强逆向的难度,整个项目包含数个包含独立功能的LLVM Pass,每个Pass会对应实现一种特定的混淆方式,这些Pass将在后面进行细说,通过这些Pass可以改变源程序的CFG和源程序的结构。后期转向商业项目strong.protect。Github目前已支持OLLVM-4.0.

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
char v4; // al
int v5; // ecx
char v6; // al
int v7; // ecx
char v8; // al
int v9; // ecx
char v10; // al
int v11; // ecx
char v12; // al
int v13; // ecx
int v15; // [rsp+4Ch] [rbp-154h]
int dest[38]; // [rsp+50h] [rbp-150h] BYREF
int v17; // [rsp+E8h] [rbp-B8h]
int v18; // [rsp+ECh] [rbp-B4h]
char v19[64]; // [rsp+F0h] [rbp-B0h] BYREF
char s[108]; // [rsp+130h] [rbp-70h] BYREF
int v21; // [rsp+19Ch] [rbp-4h]

v21 = 0;
printf("please input string:\n");
gets(s, argv);
v17 = strlen(s);
v18 = 5;
v15 = -1046111848;
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( v15 == -2012804730 )
{
memcpy(dest, "J", 0x90uLL);
v4 = fun_check1(s);
v5 = -1855144052;
if ( (v4 & 1) != 0 )
v5 = 1890735184;
v15 = v5;
}
if ( v15 != -1855144052 )
break;
v15 = -1153978545;
printf("what a shame !!!\n");
}
if ( v15 != -1612797716 )
break;
v10 = fun_check4(s);
v11 = -1855144052;
if ( (v10 & 1) != 0 )
v11 = -842747696;
v15 = v11;
}
if ( v15 == -1153978545 )
break;
switch ( v15 )
{
case -1046111848:
v3 = -2012804730;
if ( v18 < v17 - 1 )
v3 = -370117910;
v15 = v3;
break;
case -842747696:
v12 = fun_check5(v19, dest);
v13 = -1855144052;
if ( (v12 & 1) != 0 )
v13 = -194644933;
v15 = v13;
break;
case -370117910:
v19[v18 - 5] = s[v18];
v15 = 805361575;
break;
case -194644933:
v15 = -1153978545;
printf("you got it !\n");
break;
case 805361575:
++v18;
v15 = -1046111848;
break;
case 1222385267:
v8 = fun_check3(s);
v9 = -1855144052;
if ( (v8 & 1) != 0 )
v9 = -1612797716;
v15 = v9;
break;
default:
v6 = fun_check2(s);
v7 = -1855144052;
if ( (v6 & 1) != 0 )
v7 = 1222385267;
v15 = v7;
break;
}
}
return 0;
}

我们发现有5个fun_check函数:

先看第一个函数fun_check3:

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
int64 __fastcall fun_check1(char *a1)
{
int v1; // eax
int v2; // eax
int v4; // [rsp+18h] [rbp-18h]
int v5; // [rsp+1Ch] [rbp-14h]
char v6; // [rsp+2Bh] [rbp-5h]

v5 = strlen(a1);
v4 = -1212486993;
while ( 1 ) // 进入这里,如果字符串长度大于50,v4=v1=-2141247101
{
while ( 1 ) // 第一次不进入,退回第二个循环
{
while ( v4 == -2141247101 )
{
v6 = 0; // 如果大于50,第二次进入
v4 = -288944633; // v4=-288944633,再进入下一个循环,退出
}
if ( v4 != -1212486993 )
break;
v1 = 304458961;
if ( v5 >= 50 )
v1 = -2141247101;
v4 = v1;
}
if ( v4 == -288944633 )
break;
if ( v4 == 304458961 )
{
v2 = 1722401369;
if ( v5 <= 0 )
v2 = -2141247101;
v4 = v2;
}
else
{
v6 = 1;
v4 = -288944633;
}
}
return v6 & 1; // 说明该函数判断字符串长度是否小于50
}

这个函数说明了字符串小于等于50.

第二个函数fun_check2:

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
int64 __fastcall fun_check2(char *a1)
{
int v1; // eax
int v2; // eax
int v4; // [rsp+2Ch] [rbp-24h]
int v5; // [rsp+30h] [rbp-20h]
int v6; // [rsp+34h] [rbp-1Ch]
char s[6]; // [rsp+3Ah] [rbp-16h] BYREF
char *v8; // [rsp+40h] [rbp-10h]
char v9; // [rsp+4Fh] [rbp-1h]

v8 = a1;
strcpy(s, "flag{");
v6 = strlen(s);
v5 = 0;
v4 = -1692016886;
while ( 1 )
{
while ( 1 )
{
while ( v4 == -1951541847 )
{
++v5;
v4 = -1692016886;
}
if ( v4 != -1692016886 )
break;
v1 = 1623142970;
if ( v5 <= v6 - 912394623 + 912394622 )
v1 = 1747921827;
v4 = v1;
}
if ( v4 == 373027714 )
break;
switch ( v4 )
{
case 819155342:
v4 = -1951541847;
break;
case 1603812802:
v9 = 0;
v4 = 373027714;
break;
case 1623142970:
v9 = 1;
v4 = 373027714;
break;
default:
v2 = 819155342;
if ( s[v5] != v8[v5] )
v2 = 1603812802;
v4 = v2;
break;
}
}
return v9 & 1;
}

这个函数就很明显是判断开头五个是不是flag{

第三个函数fun_check3:

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
int64 __fastcall fun_check3(char *a1)
{
int v1; // eax
int i; // [rsp+14h] [rbp-14h]
char v4; // [rsp+23h] [rbp-5h]

for ( i = 275100227; ; i = 2019489044 )
{
while ( 1 )
{
while ( i == -389150027 )
{
v4 = 0;
i = 2019489044;
}
if ( i != 275100227 )
break;
v1 = 735669791;
if ( a1[41] != '}' )
v1 = -389150027;
i = v1;
}
if ( i != 735669791 )
break;
v4 = 1;
}
return v4 & 1;
}

好家伙,更明显了,是判断最后一个是否是},而且我们还知道这个字符串长度是42

我们再看fun_check4:

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
int64 __fastcall fun_check4(char *a1)
{
int v1; // eax
int v2; // eax
int v3; // eax
int v4; // eax
int v6; // [rsp+20h] [rbp-14h]
char v7; // [rsp+2Fh] [rbp-5h]

v6 = -181591648;
while ( 1 )
{
while ( v6 == -2042693465 )
{
v4 = 135449342;
if ( a1[28] != 45 )
v4 = 129082224;
v6 = v4;
}
if ( v6 == -261631822 )
break;
switch ( v6 )
{
case -181591648:
v1 = 147625658;
if ( a1[13] != 45 )
v1 = 129082224;
v6 = v1;
break;
case 129082224:
v7 = 0;
v6 = -261631822;
break;
case 135449342:
v7 = 1;
v6 = -261631822;
break;
case 147625658:
v2 = 1254423680;
if ( a1[18] != 45 )
v2 = 129082224;
v6 = v2;
break;
default:
v3 = -2042693465;
if ( a1[23] != 45 )
v3 = 129082224;
v6 = v3;
break;
}
}
return v7 & 1;
}

45代表的ascii码是“-”,所以我们要判断字符串数组中第23,18,28位是否是“ - ”

由此我们大致推出了flag的样式:

flag{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

第五个函数fun_check5:

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
int64 __fastcall fun_check5(char *a1, int *a2)
{
int v2; // eax
int v3; // eax
int v4; // eax
int v5; // eax
int v6; // eax
int v7; // eax
int v8; // eax
int v9; // eax
int v11; // [rsp+58h] [rbp-E8h]
int v12; // [rsp+5Ch] [rbp-E4h]
int v13[50]; // [rsp+60h] [rbp-E0h]
int *v14; // [rsp+128h] [rbp-18h]
char *v15; // [rsp+130h] [rbp-10h]
char v16; // [rsp+13Fh] [rbp-1h]

v15 = a1;
v14 = a2;
v12 = 0;
v11 = -624695604;
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( v11 == -1771681815 )
{
v6 = 1740029224;
if ( v15[v12] >= 97 ) //如果大于a,v6 = -1207418117,之后break
v6 = -1207418117;
v11 = v6;
}
if ( v11 != -1490231676 )
break;
++v12;
v11 = -768723158;
}
if ( v11 != -1407902233 )
break;
v4 = -1188300396;
if ( v15[v12] <= 57 ) //小于等于9
v4 = -478229440;
v11 = v4;
}
if ( v11 != -1207418117 )
break;
v7 = 1740029224;
if ( v15[v12] <= 122 ) //小于等于z
v7 = 2096910144;
v11 = v7;
}
if ( v11 != -1188300396 )
break;
v5 = -1771681815;
if ( v15[v12] == 45 ) //等于“ - ”
v5 = -1167333891;
v11 = v5;
}
if ( v11 != -1167333891 )
break;
v13[v12] = v15[v12];
v11 = -118846692;
}
if ( v11 != -995934932 )
break;
v3 = -1188300396;
if ( v15[v12] >= 48 ) //大于等于0
v3 = -1407902233;
v11 = v3;
}
if ( v11 != -991718889 )
break;
v11 = -1490231676;
}
if ( v11 != -768723158 )
break;
v8 = 1681851953;
if ( v12 < 36 )
v8 = 434013166;
v11 = v8;
}
if ( v11 != -624695604 )
break;
v2 = 659899916;
if ( v12 < 36 )
v2 = -995934932;
v11 = v2;
}
if ( v11 != -478229440 )
break;
v13[v12] = v15[v12] + 17;
v11 = 1926387427;
}
if ( v11 != -451717645 )
break;
++v12;
v11 = -624695604;
}
if ( v11 != -118846692 )
break;
v11 = 1926387427;
}
if ( v11 != 329160926 )
break;
v16 = 0;
v11 = 1269730414;
}
if ( v11 != 434013166 )
break;
v9 = -991718889;
if ( v13[v12] != v14[v12] ) //经一系列变换与dest对比
v9 = 329160926;
v11 = v9;
}
if ( v11 != 659899916 )
break;
v12 = 0;
v11 = -768723158;
}
if ( v11 == 1269730414 )
break;
switch ( v11 )
{
case 1681851953:
v16 = 1;
v11 = 1269730414;
break;
case 1740029224:
v11 = -118846692;
break;
case 1926387427:
v11 = -451717645;
break;
default:
v13[v12] = v15[v12] - 1347911315 + 1347911267;
v11 = 1740029224;
break;
}
}
return v16 & 1;
}

我们动态调试一下,设三个断点,快速查看,dest的值可知:J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB

我输入flag{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx1}进去后,直接断点到return查看v13发现x变为H再查ascii表发现是减去了48

那么1变为了B是增加了17,那么很明显我们可以把脚本分析出来了

1
2
3
4
5
6
7
8
9
10
11
12
flag=""
data="J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB"
for i in range(len(data)):
if data[i]>='A' and data[i]<='J':
flag += chr(ord(data[i])-17)
elif data[i]>='1' and data[i]<='A':
flag += chr(ord(data[i])+48)
elif data[i]=='-':
flag += "-"
print("flag{"+flag+"}")

#flag{9bbfa2fc-c8b8-464d-8122-84da0e8e5d71}

normal13

这个题还是比较难的,主要还是混淆的比较恶心人,这种类型的题叫做ollvm的控制流平坦化。

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // eax
int v5; // ecx
int v6; // eax
int v7; // eax
int v8; // eax
int v9; // eax
int v10; // eax
char v11; // al
char v12; // al
char v13; // al
char v14; // al
char v15; // al
int v16; // ecx
int v17; // eax
int v18; // eax
int v19; // eax
int v20; // eax
int v21; // eax
int v22; // ecx
char v24; // al
char v25; // al
char v26; // al
char v27; // al
int v28; // [rsp+9Ch] [rbp-94h]
char v29[8]; // [rsp+A0h] [rbp-90h] BYREF
char v30[8]; // [rsp+A8h] [rbp-88h] BYREF
char v31[8]; // [rsp+B0h] [rbp-80h] BYREF
char v32[8]; // [rsp+B8h] [rbp-78h] BYREF
char v33[8]; // [rsp+C0h] [rbp-70h] BYREF
char v34[7]; // [rsp+C8h] [rbp-68h] BYREF
char v35; // [rsp+CFh] [rbp-61h]
int v36; // [rsp+D0h] [rbp-60h]
int v37; // [rsp+D4h] [rbp-5Ch]
int v38; // [rsp+D8h] [rbp-58h]
int v39; // [rsp+DCh] [rbp-54h]
char s; // [rsp+E0h] [rbp-50h] BYREF
char v41[23]; // [rsp+E1h] [rbp-4Fh] BYREF
char v42[8]; // [rsp+F8h] [rbp-38h] BYREF
char v43[8]; // [rsp+100h] [rbp-30h] BYREF
char v44[8]; // [rsp+108h] [rbp-28h] BYREF
char v45[4]; // [rsp+110h] [rbp-20h] BYREF
int v46; // [rsp+114h] [rbp-1Ch]
const char **v47; // [rsp+118h] [rbp-18h]
int v48; // [rsp+120h] [rbp-10h]
int v49; // [rsp+124h] [rbp-Ch]
int v50; // [rsp+128h] [rbp-8h]
bool v51; // [rsp+12Eh] [rbp-2h]
bool v52; // [rsp+12Fh] [rbp-1h]

v49 = 0;
v48 = argc;
v47 = argv;
v46 = time(0LL);
puts("func(?)=\"01abfc750a0c942167651c40d088531d\"?");
s = getchar();
fgets(v41, 21, stdin);
v39 = time(0LL);
v38 = v39 - v46; // 0
v50 = v39 - v46; // 0
v28 = 1883240069;
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( v28 == -2090540314 )
{
v35 = v38 ^ v41[v36 - 1];// 因为异或0,所以v35=v41[v36-1]
v34[0] = main::$_0::operator()((__int64)v44, v35);// 返回v35,v34=v35=v41[v36-1]
v33[0] = main::$_1::operator()((__int64)v42, *(&s + v38 + v36 - 1));// 返回后面参数
v11 = main::$_1::operator() const(char)::{lambda(int)#1}::operator()(v33, 7);// 返回a1%7
v35 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()((__int64)v34, v11);// 字符串v34+v11后返回
v32[0] = main::$_2::operator()((__int64)v45, v35);// 只是单纯的把上一个函数的结果再返回。
v31[0] = main::$_2::operator()((__int64)v45, *(&s + v38 + v36 - 1));// 只是单纯的把上一个函数的结果再返回。
v12 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v31, 18);// 异或18
v30[0] = main::$_3::operator()(v43, (unsigned int)v12);// 只是单纯的把上一个函数的结果再返回。
v13 = main::$_3::operator() const(char)::{lambda(char)#1}::operator()(v30, 3LL);// 乘3
v29[0] = main::$_0::operator()((__int64)v44, v13);// return v13
v14 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()((__int64)v29, 2);// 相加后返回
v15 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v32, v14);// 异或
v16 = 1299792285;
v35 = v15;
v52 = enc[v36 - 1] != v15;// 比较处
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v16 = -424557443;
v28 = v16;
}
if ( v28 != -1957245689 )
break;
v28 = 1587023630;
}
if ( v28 != -1884297895 )
break;
v28 = -984930794;
puts("You win");
}
if ( v28 != -1852837876 )
break;
v18 = 1375414539;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v18 = 1154698238;
v28 = v18;
}
if ( v28 != -1220297252 )
break;
v21 = -1884297895;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v21 = -984930794;
v28 = v21;
}
if ( v28 != -984930794 )
break;
puts("You win");
v22 = -1884297895;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v22 = 456293525;
v28 = v22;
}
if ( v28 != -740226431 )
break;
v4 = 2137069843;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v4 = 739060228;
v28 = v4;
}
if ( v28 == -459161563 )
exit(0);
if ( v28 != -424557443 )
break;
v17 = 1856799435;
if ( v52 )
v17 = -1852837876;
v28 = v17;
}
if ( v28 != -350248402 )
break;
v28 = -55540564;
}
if ( v28 != -294402024 )
break;
v6 = 1721328217;
if ( v51 )
v6 = -459161563;
v28 = v6;
}
if ( v28 != -226137905 )
break;
v28 = 24093646;
}
if ( v28 != -55540564 )
break;
v20 = -350248402;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v20 = -226137905;
v28 = v20;
}
if ( v28 != 24093646 )
break;
++v36;
v28 = 1587023630;
}
if ( v28 == 456293525 )
break;
switch ( v28 )
{
case 506113758:
puts("Let the silent second hand take the place of my doubt...");
exit(0);
case 623475433:
v36 = 1;
v28 = 1132336453;
break;
case 739060228:
v37 = strlen(&s);
v51 = v37 != 21;
v5 = 2137069843;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v5 = -294402024;
v28 = v5;
break;
case 1011555671:
v10 = 1299792285;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v10 = -2090540314;
v28 = v10;
break;
case 1132336453:
v8 = 623475433;
v36 = 1;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v8 = -1957245689;
v28 = v8;
break;
case 1154698238:
exit(0);
case 1299792285:
v35 = v38 ^ v41[v36 - 1];
v34[0] = main::$_0::operator()((__int64)v44, v35);
v33[0] = main::$_1::operator()((__int64)v42, *(&s + v38 + v36 - 1));
v24 = main::$_1::operator() const(char)::{lambda(int)#1}::operator()(v33, 7);
v35 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()((__int64)v34, v24);
v32[0] = main::$_2::operator()((__int64)v45, v35);
v31[0] = main::$_2::operator()((__int64)v45, *(&s + v38 + v36 - 1));
v25 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v31, 18);
v30[0] = main::$_3::operator()(v43, (unsigned int)v25);
v26 = main::$_3::operator() const(char)::{lambda(char)#1}::operator()(v30, 3LL);
v29[0] = main::$_0::operator()((__int64)v44, v26);
v27 = main::$_0::operator() const(char)::{lambda(char)#1}::operator()((__int64)v29, 2);
v35 = main::$_2::operator() const(char)::{lambda(char)#1}::operator()(v32, v27);
v28 = -2090540314;
break;
case 1375414539:
exit(0);
case 1587023630:
v9 = -1220297252;
if ( v36 < 21 )
v9 = 1011555671;
v28 = v9;
break;
case 1721328217:
v7 = 623475433;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v7 = 1132336453;
v28 = v7;
break;
case 1856799435:
v19 = -350248402;
if ( y < 10 || ((((_BYTE)x - 1) * (_BYTE)x) & 1) == 0 )
v19 = -55540564;
v28 = v19;
break;
case 1883240069:
v3 = -740226431;
if ( v50 > 0 )
v3 = 506113758;
v28 = v3;
break;
default:
v37 = strlen(&s);
v28 = 739060228;
break;
}
}
return 0;
}

做这一类题只用看关键的函数,上面的已经批注了。

我们只看几个关键函数

1
main::$_0::operator() const(char)::{lambda(char)#1}::operator()
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
int64 __fastcall main::$_0::operator() const(char)::{lambda(char)#1}::operator()(__int64 a1, char a2)
{
int v2; // eax
int v3; // eax
char *v5; // [rsp+0h] [rbp-40h]
int v6; // [rsp+8h] [rbp-38h]
int v7; // [rsp+Ch] [rbp-34h]
int v8; // [rsp+10h] [rbp-30h]
int v9; // [rsp+14h] [rbp-2Ch]
char *v10; // [rsp+18h] [rbp-28h]
char v11; // [rsp+23h] [rbp-1Dh]
int v12; // [rsp+24h] [rbp-1Ch]
bool v13; // [rsp+2Ah] [rbp-16h]
bool v14; // [rsp+2Bh] [rbp-15h]
unsigned int v15; // [rsp+2Ch] [rbp-14h]

v13 = ((((_BYTE)x_5 - 1) * (_BYTE)x_5) & 1) == 0;
v14 = y_6 < 10;
v12 = 1023500310;
v11 = a2;
v10 = (char *)a1;
do
{
while ( 1 )
{
while ( 1 ) // 往下走
{
while ( 1 )
{
v9 = v12;
v8 = v12 + 2037067308;
if ( v12 != -2037067308 )
break;
v5 = v10;
*((_BYTE *)&v5 - 16) = v11;
v12 = -1418698808;
}
v7 = v9 + 1418698808;
if ( v9 != -1418698808 )
break;
v3 = -2037067308;
v5 = v10;
*((_BYTE *)&v5 - 16) = v11;
v15 = *((char *)&v5 - 16) + *v5; // 重点的地方,是将两个字符串相加,返回v15
if ( y_6 < 10 || ((((_BYTE)x_5 - 1) * (_BYTE)x_5) & 1) == 0 )
v3 = 1456142001;
v12 = v3;
}
v6 = v9 - 1023500310;
if ( v9 != 1023500310 )
break;
v2 = -2037067308;
if ( v14 || v13 )
v2 = -1418698808;
v12 = v2;
}
HIDWORD(v5) = v9 - 1456142001;
}
while ( v9 != 1456142001 );
return v15;
}

这个函数就是将字符串加起来

1
main::$_2::operator()
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
char __fastcall main::$_2::operator()(__int64 a1, char a2)
{
int v2; // eax
int v3; // eax
__int64 v5; // [rsp+0h] [rbp-50h]
int v6; // [rsp+Ch] [rbp-44h]
int v7; // [rsp+10h] [rbp-40h]
int v8; // [rsp+14h] [rbp-3Ch]
int v9; // [rsp+18h] [rbp-38h]
int v10; // [rsp+1Ch] [rbp-34h]
__int64 v11; // [rsp+20h] [rbp-30h]
char v12; // [rsp+2Fh] [rbp-21h]
int v13; // [rsp+30h] [rbp-20h]
bool v14; // [rsp+35h] [rbp-1Bh]
bool v15; // [rsp+36h] [rbp-1Ah]
char v16; // [rsp+37h] [rbp-19h]

v14 = ((((_BYTE)x_11 - 1) * (_BYTE)x_11) & 1) == 0;
v15 = y_12 < 10;
v13 = -1990873412;
v12 = a2;
v11 = a1;
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
v10 = v13;
v9 = v13 + 1990873412;
if ( v13 != -1990873412 )
break;
v2 = -1373097315;
if ( v15 || v14 )
v2 = 1457028246;
v13 = v2;
}
v8 = v10 + 1373097315;
if ( v10 != -1373097315 )
break;
v5 = v11;
*((_BYTE *)&v5 - 16) = v12;
LOBYTE(v5) = *((_BYTE *)&v5 - 16);
v13 = 1457028246;
}
v7 = v10 + 961146335;
if ( v10 == -961146335 )
break;
v6 = v10 - 1457028246;
if ( v10 == 1457028246 )
{
v3 = -1373097315;
v5 = v11;
*((_BYTE *)&v5 - 16) = v12;
LOBYTE(v5) = *((_BYTE *)&v5 - 16);
v16 = v5;
if ( y_12 < 10 || ((((_BYTE)x_11 - 1) * (_BYTE)x_11) & 1) == 0 )
v3 = -961146335;
v13 = v3;
}
}
return v16;
}

这个函数还是比较难看懂的,最后是我写脚本猜出来的,这个函数就是返回上一个函数return出来的值。

看主函数我们可以在对比处提取enc的值,然后我们逆向的时候要先用enc与v14异或得到v32,用v32来求flag,这个地方还有一个坑

1
func(?)=\"01abfc750a0c942167651c40d088531d\"    //指的是#的md5

给出脚本:

1
2
3
4
5
6
enc =[0xF3, 0x2E, 0x18, 0x36, 0xE1, 0x4C, 0x22, 0xD1, 0xF9, 0x8C, 0x40, 0x76, 0xF4, 0x0E, 0x00, 0x05, 0xA3, 0x90, 0x0E, 0xA5]
flag='#'
for i in range(20):
flag+=chr(((enc[i]^((ord(flag[i])^18)*3+2))-(ord(flag[i])%7))&0xff)
print(flag)
# #flag{mY-CurR1ed_Fns}

注意我不加&0xff的时候,会出现ValueError: chr() arg not in range(0x110000),加上后是取低8位在256范围内!

normal14

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
int64 __fastcall main(int a1, char **a2, char **a3)
{
char v4[16]; // [rsp+0h] [rbp-4A0h] BYREF
char v5[16]; // [rsp+10h] [rbp-490h] BYREF
char v6[16]; // [rsp+20h] [rbp-480h] BYREF
char v7[16]; // [rsp+30h] [rbp-470h] BYREF
char v8[112]; // [rsp+40h] [rbp-460h] BYREF
char v9[1000]; // [rsp+B0h] [rbp-3F0h] BYREF
unsigned __int64 v10; // [rsp+498h] [rbp-8h]

v10 = __readfsqword(0x28u);
puts("[sign in]");
printf("[input your flag]: ");
__isoc99_scanf("%99s", v8);
sub_96A(v8, (__int64)v9);
__gmpz_init_set_str((__int64)v7, (__int64)"ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
__gmpz_init_set_str((__int64)v6, (__int64)v9, 16LL);
__gmpz_init_set_str(
(__int64)v4,
(__int64)"103461035900816914121390101299049044413950405173712170434161686539878160984549",
10LL);
__gmpz_init_set_str((__int64)v5, (__int64)"65537", 10LL);
__gmpz_powm((__int64)v6, (__int64)v6, (__int64)v5, (__int64)v4);
if ( (unsigned int)__gmpz_cmp((__int64)v6, (__int64)v7) )
puts("GG!");
else
puts("TTTTTTTTTTql!");
return 0LL;
}

这个题我想查看函数发现没东西,那么证明这个函数是c中自带的,但是这个我感觉好熟悉。看到65537,多半是RSA,当时极客大挑战做过几道,就直接给脚本了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from gmpy2 import*
from libnum import*
from Crypto.Util.number import long_to_bytes
import gmpy2
n=103461035900816914121390101299049044413950405173712170434161686539878160984549
c=0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
e=65537
p=366669102002966856876605669837014229419
q=282164587459512124844245113950593348271
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=pow(c,int(d),n)
print(n2s(flag))
#b'suctf{Pwn_@_hundred_years}'

我们将n分为两个质因数,则剩下的就是c,由此可以求flag

normal16

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
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
DWORD v3; // eax
DWORD v4; // eax
char Str[260]; // [esp+4Ch] [ebp-310h] BYREF
int v7; // [esp+150h] [ebp-20Ch]
char String1[260]; // [esp+154h] [ebp-208h] BYREF
char Destination[260]; // [esp+258h] [ebp-104h] BYREF

memset(Destination, 0, sizeof(Destination));
memset(String1, 0, sizeof(String1));
v7 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", Destination);
if ( strlen(Destination) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
v7 = atoi(Destination); //将Destination转成int类型说明Destination只能是数字,如果有字母,return 0
if ( v7 < 100000 )
ExitProcess(0);
strcat(Destination, "@DBApp"); //六位数字后连接字符串
v3 = strlen(Destination);
sub_40100A((BYTE *)Destination, v3, String1); //第一个函数
if ( !_strcmpi(String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
{
printf("continue...\n\n");
printf("pls input the first passwd(2): ");
memset(Str, 0, sizeof(Str));
scanf("%s", Str);
if ( strlen(Str) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
strcat(Str, Destination); //password2加上password1
memset(String1, 0, sizeof(String1));
v4 = strlen(Str);
sub_401019((BYTE *)Str, v4, String1);
if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", String1) )
{
if ( !(unsigned __int8)sub_40100F(Str) )
{
printf("Error!!\n");
ExitProcess(0);
}
printf("bye ~~\n");
}
}
return 0;
}

这道题只看主函数应该是很好理解的 。

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
int __cdecl sub_401230(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
DWORD i; // [esp+4Ch] [ebp-28h]
CHAR String2[4]; // [esp+50h] [ebp-24h] BYREF
BYTE v6[20]; // [esp+54h] [ebp-20h] BYREF
DWORD pdwDataLen; // [esp+68h] [ebp-Ch] BYREF
HCRYPTHASH phHash; // [esp+6Ch] [ebp-8h] BYREF
HCRYPTPROV phProv; // [esp+70h] [ebp-4h] BYREF

if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
return 0;
if ( CryptCreateHash(phProv, 0x8004u, 0, 0, &phHash) )
{
if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
{
CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0);
*lpString1 = 0;
for ( i = 0; i < pdwDataLen; ++i )
{
wsprintfA(String2, "%02X", v6[i]);
lstrcatA(lpString1, String2);
}
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 1;
}
else
{
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 0;
}
}
else
{
CryptReleaseContext(phProv, 0);
return 0;
}
}

这个里面全是api函数,根据参数来确定是哪种hash加密。0x8004u对应sha1加密,我学习了一下脚本的写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib
password1 = ""
arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
for i1 in arr:
for i2 in arr:
for i3 in arr:
for i4 in arr:
for i5 in arr:
for i6 in arr:
password1 = i1 + i2 + i3 + i4 + i5 + i6 + "@DBApp"
if(hashlib.sha1(password1.encode("utf-8")).hexdigest().upper() =="6E32D0943418C2C33385BC35A1470250DD8923A9"):
print(password1)
break
#hash引入hashlib库,用hashlib.sha1(a.encode("utf-8"))来编码,要指名编码的格式,不然会报错,hexdigest函数是转换成16进制,upper是将小写转换成大写。
#password1=123321@DBApp

从参数来看第二个函数:

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
int __cdecl sub_401040(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
DWORD i; // [esp+4Ch] [ebp-24h]
CHAR String2[4]; // [esp+50h] [ebp-20h] BYREF
BYTE v6[16]; // [esp+54h] [ebp-1Ch] BYREF
DWORD pdwDataLen; // [esp+64h] [ebp-Ch] BYREF
HCRYPTHASH phHash; // [esp+68h] [ebp-8h] BYREF
HCRYPTPROV phProv; // [esp+6Ch] [ebp-4h] BYREF

if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
return 0;
if ( CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash) )
{
if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
{
CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0);
*lpString1 = 0;
for ( i = 0; i < pdwDataLen; ++i )
{
wsprintfA(String2, "%02X", v6[i]);
lstrcatA(lpString1, String2);
}
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 1;
}
else
{
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
return 0;
}
}
else
{
CryptReleaseContext(phProv, 0);
return 0;
}
}

参数为:0x8003u是个md5函数,但md5爆破的话是很慢的。所以我们找到最后对比时的函数:

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
char __cdecl sub_4014D0(LPCSTR lpString)
{
LPCVOID lpBuffer; // [esp+50h] [ebp-1Ch]
DWORD NumberOfBytesWritten; // [esp+58h] [ebp-14h] BYREF
DWORD nNumberOfBytesToWrite; // [esp+5Ch] [ebp-10h]
HGLOBAL hResData; // [esp+60h] [ebp-Ch]
HRSRC hResInfo; // [esp+64h] [ebp-8h]
HANDLE hFile; // [esp+68h] [ebp-4h]

hFile = 0;
hResData = 0;
nNumberOfBytesToWrite = 0;
NumberOfBytesWritten = 0;
hResInfo = FindResourceA(0, (LPCSTR)0x65, "AAA");
if ( !hResInfo )
return 0;
nNumberOfBytesToWrite = SizeofResource(0, hResInfo);
hResData = LoadResource(0, hResInfo);
if ( !hResData )
return 0;
lpBuffer = LockResource(hResData);
sub_401005(lpString, (int)lpBuffer, nNumberOfBytesToWrite);
hFile = CreateFileA("dbapp.rtf", 0x10000000u, 0, 0, 2u, 0x80u, 0);
if ( hFile == (HANDLE)-1 )
return 0;
if ( !WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0) )
return 0;
CloseHandle(hFile);
return 1;
}

查阅了一下:FindResourceA:确定指定模块中指定类型和名称的资源的位置。

RTF格式:{\rtf1\ansiHello!\parThis is some {\b bold} text.\par}

我们分析一下,首先用ResourceHacker软件查找名为“AAA”的资源并取出数据,接着进入sub_401005,取出的数据跟

输入的密码2+输入的密码1+“@DBApp”进行了异或,最后生成了.rtf文件,最后的flag应该就在.rtf文件里。

那么如何求密码2呢,我们只需要找到rtf文件将其文件头和AAA前6位异或就行了

1
2
3
4
5
6
7
8
9
rtf="{\\rtf1"
AAA=[0x05,0x7D,0x41,0x15,0x26,0x01]
password2=""
for i in range(6):
password2 += chr(AAA[i] ^ ord(rtf[i]))
print(password2)
#~!3a@0


我们运行程序输入密码,回出现一个文件里面存有flag

Flag{N0_M0re_Free_Bugs}

normal17

刚开始没法反编译,

我们找到这里,是栈帧不平衡导致的,将pop处的改为0x0,即可。修改的原则是,只需在出现负数的那个地方的上一行,按alt+k,调整成跟这个数一摸一样的值就可以了。

我们找到main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
HANDLE Thread; // [esp+D0h] [ebp-14h]
HANDLE hObject; // [esp+DCh] [ebp-8h]

sub_4110FF();
::hObject = CreateMutexW(0, 0, 0);
j_strcpy(Destination, &Source);
hObject = CreateThread(0, 0, StartAddress, 0, 0, 0);
Thread = CreateThread(0, 0, sub_41119F, 0, 0, 0);
CloseHandle(hObject);
CloseHandle(Thread);
while ( dword_418008 != -1 )
;
sub_411190();
CloseHandle(::hObject);
return 0;
}

稍微能看懂一点,hObject一般代表句柄,CreateThread代表着创建线程,看来这个题创建了两个线程.

  1. 进程
    进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

  2. 线程
    线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

一个正在运行的软件(如迅雷)就是一个进程,一个进程可以同时运行多个任务( 迅雷软件可以同时下载多个文件,每个下载任务就是一个线程), 可以简单的认为进程是线程的集合。

  • 对于单核CPU而言:多线程就是一个CPU在来回的切换,在交替执行。
  • 对于多核CPU而言:多线程就是同时有多条执行路径在同时(并行)执行,每个核执行一个线程,多个核就有可能是一块同时执行的。

第一个线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
char *__cdecl sub_411940(int a1, int a2)
{
char *result; // eax
char v3; // [esp+D3h] [ebp-5h]

v3 = *(_BYTE *)(a2 + a1);
if ( (v3 < 'a' || v3 > 122) && (v3 < 65 || v3 > 90) )
exit(0);
if ( v3 < 97 || v3 > 122 )
{
result = off_418000[0];
*(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 38];
}
else
{
result = off_418000[0];
*(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 96];
}
return result;
}

这个线程的很清楚,就是加加减减。

第二个线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
void __stdcall __noreturn sub_411B10(int a1)
{
while ( 1 )
{
WaitForSingleObject(hObject, 0xFFFFFFFF);
if ( dword_418008 > -1 )
{
Sleep(0x64u);
--dword_418008;
}
ReleaseMutex(hObject);
}
}

CreateThread API 会创建新线程,这个题是一个典型的双线程问题.CreateMutex 创建一个互斥体,用于防止多线程中出现资源争用,即多个线程同时读写同一个资源的情况,所创建的互斥体的句柄会存到全局变量 hObject 中,WaitForSingleObject 等待互斥体的使用权空闲出来,并获取使用权,然后再访问和其他线程共享的资源,访问完后,用 ReleaseMutex 释放使用权,给其他线程使用的机会。那么这两个线程共享的数据是什么呢,看参数我们就知道是dword_418008。

这两个线程一前一后创建,理论上是 StartAddress 先获得使用权,后来的 sub_41119F 进入等待状态,前者执行一次循环后释放使用权,与此同时后者等待结束、获得使用权,进入循环,循环完后释放使用权,前者又获得使用权,如此循环往复。

所以就相当于我给出的字符串是第一位照抄,第二位进行线程一的变化。经过线程后与Source对比

1
2
3
4
5
6
7
8
9
10
int sub_411880()
{
int i; // [esp+D0h] [ebp-8h]
for ( i = 0; i < 29; ++i )
{
if ( Source[i] != off_418004[i] )
exit(0);
}
return printf("\nflag{%s}\n\n", Destination);
}

给出脚本:

1
2
3
4
5
6
7
8
9
10
11
12
data1="TOiZiZtOrYaToUwPnToBsOaOapsyS"
data2="QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"
flag=""
for i in range(len(data1)):
if i%2==0:
flag+=data1[i]
else:
if ord(data1[i])>ord('a') and ord(data1[i])<ord('z'):
flag+=chr(data2.find(data1[i])+38)
else:
flag+=chr(data2.find(data1[i])+96)
print(flag)

最后这个E是什么都行,因为dword_418008只有29位!

得到ThisisthreadofwindowshahaIsES

normal18

这个题看着很难。

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
int __usercall wmain@<eax>(int a1@<ebx>)
{
FILE *v1; // eax
FILE *v2; // eax
char v4; // [esp+3h] [ebp-405h]
char v5[256]; // [esp+4h] [ebp-404h] BYREF
char Format[256]; // [esp+104h] [ebp-304h] BYREF
char v7[256]; // [esp+204h] [ebp-204h] BYREF
char v8[256]; // [esp+304h] [ebp-104h] BYREF

printf("Come one! Crack Me~~~\n");
memset(v8, 0, sizeof(v8));
memset(v7, 0, sizeof(v7));
while ( 1 )
{
do
{
do
{
printf("user(6-16 letters or numbers):");
scanf("%s", v8);
v1 = (FILE *)sub_4024BE();
fflush(v1);
}
while ( !sub_401000(v8) );
printf("password(6-16 letters or numbers):");
scanf("%s", v7);
v2 = (FILE *)sub_4024BE();
fflush(v2);
}
while ( !sub_401000(v7) );
sub_401090(v8);
memset(Format, 0, sizeof(Format));
memset(v5, 0, sizeof(v5));
v4 = ((int (__cdecl *)(char *, char *))loc_4011A0)(Format, v5);
if ( sub_401830(a1, (int)v8, v7) )
{
if ( v4 )
break;
}
printf(v5);
}
printf(Format);
return 0;
}

先输入账号,账号已给出welcomebeijing,再输入密码。首先能看出来这个是个死循环,如果想跳出去,只能是让

sub_401830函数为1,我们进入跟踪一下。

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
bool __usercall sub_401830@<al>(int a1@<ebx>, int a2, const char *a3)
{
int v4; // [esp+18h] [ebp-22Ch]
signed int v5; // [esp+1Ch] [ebp-228h]
signed int v6; // [esp+28h] [ebp-21Ch]
unsigned int v7; // [esp+30h] [ebp-214h]
char v8; // [esp+36h] [ebp-20Eh]
char v9; // [esp+37h] [ebp-20Dh]
char v10; // [esp+38h] [ebp-20Ch]
unsigned __int8 v11; // [esp+39h] [ebp-20Bh]
unsigned __int8 v12; // [esp+3Ah] [ebp-20Ah]
char v13; // [esp+3Bh] [ebp-209h]
unsigned int v14; // [esp+3Ch] [ebp-208h] BYREF
char v15; // [esp+40h] [ebp-204h] BYREF
char v16[255]; // [esp+41h] [ebp-203h] BYREF
char v17[256]; // [esp+140h] [ebp-104h] BYREF

v5 = 0;
v6 = 0;
v12 = 0;
v11 = 0;
memset(v17, 0, sizeof(v17));
v15 = 0;
memset(v16, 0, sizeof(v16));
v10 = 0;
v7 = 0;
v4 = 0;
while ( v7 < strlen(a3) )
{
if ( isdigit(a3[v7]) )
{
v9 = a3[v7] - 48;
}
else if ( isxdigit(a3[v7]) )
{
if ( *((_DWORD *)NtCurrentPeb()->ProcessHeap + 3) != 2 )// 反调试
a3[v7] = 34;
v9 = (a3[v7] | 0x20) - 87;
}
else
{
v9 = ((a3[v7] | 0x20) - 97) % 6 + 10;
}
__rdtsc();
__rdtsc();
v10 = v9 + 16 * v10; //以上的意思是把输入的密码(要求是十六进制字符)从hex_string转换位内存中的bytes,代表v16为密码
if ( !((int)(v7 + 1) % 2) )
{
v16[v4++ - 1] = v10;
a1 = v4;
v10 = 0;
}
++v7;
}
while ( v6 < 8 )
{
v11 += byte_416050[++v12];
v13 = byte_416050[v12];
v8 = byte_416050[v11];
byte_416050[v11] = v13;
byte_416050[v12] = v8;
if ( (NtCurrentPeb()->NtGlobalFlag & 0x70) != 0 )// 反调试
v13 = v11 + v12;
v17[v6] = byte_416050[(unsigned __int8)(v8 + v13)] ^ v16[v5 - 1]; //只需找到byte_416050,就可推得密码
if ( (unsigned __int8)*(_DWORD *)&NtCurrentPeb()->BeingDebugged )// 反调试
{
v11 = -83;
v12 = 43;
}
sub_401710((int)v17, (const char *)a2, v6++);
v5 = v6;
if ( v6 >= (unsigned int)(&v16[strlen(&v15)] - v16) )
v5 = 0;
}
v14 = 0;
sub_401470(a1, v17, &v14);
return v14 == 43924; // v14必须要等于43924
}

首先我们得让v14=43924,那么我们就要跟踪sub_401470函数,我们跟踪进去

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
unsigned int *__usercall sub_401470@<eax>(int a1@<ebx>, _BYTE *a2, unsigned int *a3)
{
unsigned int _EAX; // eax
char v5; // al
char _AL; // al
unsigned int *result; // eax

if ( *a2 != 'd' )
*a3 ^= 3u;
else
*a3 |= 4u;
if ( a2[1] != 'b' )
{
*a3 &= 0x61u;
_EAX = *a3;
}
else
{
_EAX = (unsigned int)a3;
*a3 |= 0x14u;
}
__asm { aam }
if ( a2[2] != 'a' )
*a3 &= 0xAu;
else
*a3 |= 0x84u;
if ( a2[3] != 'p' )
*a3 >>= 7;
else
*a3 |= 0x114u;
if ( a2[4] != 'p' )
*a3 *= 2;
else
*a3 |= 0x380u;
if ( *((_DWORD *)NtCurrentPeb()->ProcessHeap + 3) != 2 )
{
if ( a2[5] != 'f' )
*a3 |= 0x21u;
else
*a3 |= 0x2DCu;
}
if ( a2[5] != 's' )
{
v5 = (char)a3;
*a3 ^= 0x1ADu;
}
else
{
*a3 |= 0xA04u;
v5 = (char)a3;
}
_AL = v5 - (~(a1 >> 5) - 1);
__asm { daa }
if ( a2[6] != 'e' )
*a3 |= 0x4Au;
else
*a3 |= 0x2310u;
if ( a2[7] != 'c' )
{
*a3 &= 0x3A3u;
return (unsigned int *)*a3;
}
else
{
result = a3;
*a3 |= 0x8A10u;
}
return result;
}

这个函数中我们只需要判断a2[5]是等于‘ f ’还是‘ s ’。答案是s,所以我们得到了,a2也就是v17的字符串”dbappsec”,那么再看上个函数,跟v17有关的是个异或: v17[v6] = byte_416050[(unsigned __int8)(v8 + v13)] ^ v16[v5 - 1] ,由上面的分析,我们知道v16就是我们要找的,那么我们需要找到byte_416050,这个sbox里的字符串,我们用od来进行查找。

在异或处下断点,观察ecx的值就是这个字符串,即[0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd]。

写脚本

1
2
3
4
5
6
code=[]
data1=[0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd]
data2="dbappsec"
for i in range(len(data2)):
code.append(hex(ord(data2[i])^data1[i]).replace("0x",""))
print(code)

得到:[‘4e’, ‘b5’, ‘f3’, ‘99’, ‘23’, ‘91’, ‘a1’, ‘ae’],连起来即可。

还有一个问题啊,我在用od调试的时候并没有遇到wp上说的反调试,我在此补充一下

1
if ( *(_DWORD *)(__readfsdword(0x30u) + 2) & 0xFF )

我们的IsDebuggerPresent最后寻找的东西其实就是BeingDebugged字段。

1
if ( *(_DWORD *)(__readfsdword(0x30u) + 104) & 0x70 )

这个其实从PEB的结构中我们也不难看出也是反调试中经常出现的字段NtGlobalFlag

1
if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )

这个也是经常用在反调试中的字段ProcessHeap。

如果在题目中出现__readfsdword(0x30u)意味着动调的时候参数会不对,最好用od来调试,若用ida调试,方法如下:

动调时手动修改代码,比如汇编下把jz改成jmp/jnz,可以改成jnz,机器码是74改成75。

normal19

太摧毁我的自信心了,太难了,第一次遇见花指令

这么一大坨东西,没加壳就是花指令了。

先用idapython去花

1
2
3
4
arr = [[0x4009A9,0x4009C7],[0x4009E0,0x4009FE],[0x400ACA,0x400AE8],[0x400B1A,0x400B38],[0x400B65,0x400B92],[0x400BEF,0x400C00]]
for i in range(len(arr)):
for j in range(arr[i][0],arr[i][1]):
ida_bytes.patch_byte(j,0x90)

去花后反编译就比较简单了

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbx
int v4; // er12
int v5; // edi
unsigned int v6; // eax
int name_by_pid; // ebp
__pid_t v8; // eax
__pid_t v9; // er13
__int64 v10; // rdx
__int64 v11; // rcx
__int64 v12; // rbx
int v14; // ebx
int v15[2]; // [rsp+0h] [rbp-4D8h] BYREF
char v16[4]; // [rsp+8h] [rbp-4D0h] BYREF
char v17[8]; // [rsp+Ch] [rbp-4CCh] BYREF
char v18[56]; // [rsp+14h] [rbp-4C4h] BYREF
char v19; // [rsp+4Ch] [rbp-48Ch] BYREF
int v20[20]; // [rsp+50h] [rbp-488h]
char v21[1032]; // [rsp+A0h] [rbp-438h] BYREF
unsigned __int64 v22; // [rsp+4A8h] [rbp-30h]

v3 = (char *)v15;
v22 = __readfsqword(0x28u);
v4 = time(0LL);
do
{
v3 += 4;
*((_DWORD *)v3 - 1) = _IO_getc(_bss_start);
}
while ( v3 != &v19 );
v20[0] = 83;
v20[1] = 64;
v20[2] = 121;
v20[3] = 82;
v20[4] = 116;
v20[5] = 102;
v20[6] = 84;
v20[7] = 108;
v20[8] = 48;
v20[9] = 43;
v20[10] = 97;
v20[11] = 103;
v20[12] = 45;
v20[13] = 76;
v20[14] = 95;
v20[15] = 51;
v20[16] = 77;
v20[17] = 125;
v20[18] = 123;
if ( ptrace(PTRACE_TRACEME, 0LL, 1LL, 0LL) < 0 )
{
v14 = 10000000;
do
{
sleep(1u);
--v14;
}
while ( v14 );
exit(-1);
}
v5 = time(0LL) - v4;
if ( v5 > 1 )
goto LABEL_16;
func3(v18, 2LL, 7LL, 14LL);
func3(v16, 4LL, 6LL, 17LL);
func3(&v18[16], 3LL, 5LL, 10LL);
v6 = getppid();
name_by_pid = get_name_by_pid(v6, v21);
if ( name_by_pid )
return -1;
func3(v15, 6LL, 9LL, 15LL);
func3(&v18[24], 3LL, 6LL, 8LL);
v5 = time(0LL) - v4;
if ( v5 > 2 )
LABEL_16:
exit(v5);
func3(v18, 1LL, 5LL, 14LL);
v8 = getpid();
v9 = getsid(v8);
if ( v9 != getppid() )
{
puts("what are you doing?!");
v5 = 1;
goto LABEL_16;
}
func3(v15, 0LL, 2LL, 19LL);
func3(v17, 3LL, 5LL, 16LL);
func3(&v18[40], 1LL, 3LL, 4LL);
func3(&v18[12], 3LL, 6LL, 11LL);
func3(v15, 0LL, 7LL, 19LL);
func3(v15, 0LL, v10, v11);
func3(&v18[20], 0LL, 2LL, 9LL);
v5 = time(0LL) - v4;
if ( v5 > 3 )
goto LABEL_16;
v12 = 0LL;
func3(&v18[24], 1LL, 3LL, 8LL);
func3(&v18[44], 0LL, 2LL, 3LL);
do
{
if ( v20[v12] != v15[v12] )
{
puts("You failed");
v5 = v12;
goto LABEL_16;
}
++v12;
}
while ( v12 != 19 );
puts("win");
return name_by_pid;
}

fun3很复杂所以可以猜测这个题跟前面的一道题很像,直接输进去数就行,然后观察变化即可。

我们发现很多goto ,会goto到exit,去除!

1
2
3
4
arr = [[0x400972,0x400978], [0x400987,0x40098D],[0x400A2F,0x400A35],[0x400A77,0x400A7D],[0x400AAB,0x400AB1],[0x400BBC,0x400BC2]]
for i in range(len(arr)):
for j in range(arr[i][0],arr[i][1]):
ida_bytes.patch_byte(j,0x90)

大致就是将goto的首地址和下一行地址写进arr列表中,然后全部nop掉,找goto的汇编可以看旁边有指引的线。

接下来我们动调,发现不行,里面有很多_sleep等的反调试,我们将其nop掉。

1
2
3
4
5
6
7
8
data1="0123456789abcdefghi"
data2="8f6c90e1dg237abh5i4"
t="S@yRtfTl0+ag-L_3M}{"
flag=""
for i in range(len(t)):
flag+=t[data2.find(data1[i])]
print(flag)
#flag{My-StL_R0T@+3}

结束!

normal20

又是一道z3题,这个题看起来非常简单,但是逆过来确实不好逆,所以用z3最好解决

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // esi
unsigned int v4; // kr00_4
char v5; // bl
unsigned int i; // eax
char *v7; // edx
char v8; // cl
int v9; // eax
char v11[80]; // [esp+8h] [ebp-A4h] BYREF
char v12[80]; // [esp+58h] [ebp-54h] BYREF

sub_401020("Please input your flag: ");
sub_401050("%40s", v12);
memset(v11, 0, sizeof(v11));
v3 = 0;
v4 = strlen(v12);
if ( v4 )
{
do
{
v5 = v12[v3];
for ( i = 0; i < 32; ++i )
{
v7 = &v11[i + v3];
v8 = v5 ^ byte_41C658[i];
*v7 += v8;
}
++v3;
}
while ( v3 < v4 );
}
v9 = strcmp(v11, aR); // v9必须是1,也就是说v11就是aR
if ( v9 )
v9 = v9 < 0 ? -1 : 1;
if ( v9 )
puts("No, it isn't.");
else
puts("Yes, it is.");
return 0;
}

讲一下?的用法:<表达式1>?<表达式2>:<表达式3>
在运算中,首第一个表达式进行检验,如果为真,则返回表达式2的值;如果为假,则返回表达式3的值

直接给出z3脚本:

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
from z3 import*
s=Solver()
aR=[0x72, 0xE9, 0x4D, 0xAC, 0xC1, 0xD0, 0x24, 0x6B, 0xB2, 0xF5, 0xFD, 0x45, 0x49, 0x94, 0xDC, 0x10, 0x10, 0x6B, 0xA3, 0xFB, 0x5C, 0x13, 0x17, 0xE4, 0x67, 0xFE, 0x72, 0xA1, 0xC7, 0x04, 0x2B, 0xC2, 0x9D, 0x3F, 0xA7, 0x6C, 0xE7, 0xD0, 0x90, 0x71, 0x36, 0xB3, 0xAB, 0x67, 0xBF, 0x60, 0x30, 0x3E, 0x78, 0xCD, 0x6D, 0x35, 0xC8, 0x55, 0xFF, 0xC0, 0x95, 0x62, 0xE6, 0xBB, 0x57, 0x34, 0x29, 0x0E, 0x03]
data=[0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x7B, 0x7C, 0x7D, 0x7E]
flag = [BitVec("flag%d" % i,8) for i in range(0x22)]
v5=[0]*0x41
for i in range(len(flag)):
s.add(flag[i] < 127)
s.add(flag[i] > 32)
v3=0
for i in range(0x22):
for j in range(32):
v5[i+j] += flag[i] ^ data[j]
v3 += 1
for t in range(len(aR)):
s.add(aR[t] == v5[t])
if s.check() == sat:
m = s.model()
res = []
for i in range(0x22):
res.append(chr(m[flag[i]].as_long()))
s=''.join(res)
print(s)
else:
print("nope")
print(v5)
#SYC{4+mile+b3gin+with+sing1e+step}

看来是极客的题。。。

normal21

这个题终极难,还是感觉自己写脚本能力太差,这个寒假要努力将自己编程能力提升上去。

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
_DWORD *v4; // [esp+1Ch] [ebp-A0h]
_WORD v5[4]; // [esp+20h] [ebp-9Ch] BYREF
int v6; // [esp+28h] [ebp-94h]
int v7; // [esp+2Ch] [ebp-90h]
char v8[32]; // [esp+30h] [ebp-8Ch] BYREF
char v9[32]; // [esp+50h] [ebp-6Ch] BYREF
char v10[76]; // [esp+70h] [ebp-4Ch] BYREF

sub_402620();
strcpy((char *)v5, "qweee");
v5[3] = '\0';
v6 = 0;
v7 = 0;
v4 = malloc(0x408u);
puts("Plz solve the puzzle:");
sub_40ED00("%32s", v8);
if ( (unsigned __int8)sub_401C70(v8) // flag的区间
&& (sub_401B60(
(int)v9,
v8), // 16进制字符转换成byte
sub_401850(v4, (int)v5, strlen((const char *)v5)),
sub_4018D0(v4, v9, 8),
sub_401950(v9)) )
{
sub_401BA0(v8, (int)v10);
sub_40ED20("Congrats!\n%s\n", v10);
}
else
{
puts("Failed!");
}
return 0;
}

这个题主要有5个函数,我们逐一查看

函数一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int __cdecl sub_401C70(char *Str)
{
char *v2; // edx

if ( strlen(Str) != 16 )
return 0;
v2 = Str;
while ( (unsigned __int8)(*v2 - 58) > 0x26u && (unsigned __int8)(*v2 - 48) <= 0x36u )
{
if ( ++v2 == Str + 16 )
return 1;
}
return 0;
}

这个函数限定了str长度为16,那么能取那些字符呢?是用下面的while循环进行的判断。写出脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for i in range(256):
a=i
if (a-58)&0xff > 0x26 and (a-48)&0xff <= 0x36:
print(chr(i))
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f

我们要注意在c语言中:范围是不同的,所以0-9也ok

int

int8取值范围是-128 - 127
unsigned int8 0-255

Int16 意思是16位整数(16bit integer),相当于short 占2个字节 -32768 ~ 32767

Int32 意思是32位整数(32bit integer), 相当于 int 占4个字节 -2147483648 ~ 2147483647

Int64 意思是64位整数(64bit interger), 相当于 long long 占8个字节 -9223372036854775808 ~ 9223372036854775807Byte 相当于byte(unsigned char) 0 ~ 255

WORD 等于 unsigned short 0 ~ 65535

接下来看第二个函数。

函数二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int __cdecl sub_401B60(int a1, _BYTE *a2)
{
_BYTE *i; // ebx
int result; // eax
_BYTE *v5; // [esp+0h] [ebp-1Ch]
int v6; // [esp+8h] [ebp-14h]

for ( i = a2; *i; result = sub_40ED40(v5, "%02X", v6) )// sprintf格式化输出
{
v6 = a1;
v5 = i;
i += 2;
++a1;
}
return result;
}

这个函数无法理解,但从动态调试中可以猜测是将输入的16进制字符串转换为byte型数组,并用sprintf格式化输出。

这里补充一下sprintf的用法:

1
sprintf``(s, ``"%8d%8d"``, 123, 4567); ``// 产生:"  123  4567"

例如这个,很好的代表了其用法,第二个参数用来规定格式化的形式,第二个参数后面可以加多个参数,后面的参数都要按照第二个参数来规定。

第三个函数:

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
int __cdecl sub_401850(_DWORD *a1, int a2, int a3)
{
int v3; // eax
_DWORD *v4; // edi
int *v5; // ebx
int v6; // ecx
int result; // eax
int v8; // esi
char v9; // dl
int *v10; // edx

v3 = 0;
v4 = a1 + 2;
*a1 = 0;
a1[1] = 0;
do
{
v4[v3] = v3;
++v3;
}
while ( v3 != 256 );
v5 = a1 + 2;
v6 = 0;
LOBYTE(result) = 0;
do
{
v8 = *v5;
v9 = *(_BYTE *)(a2 + v6++) + *v5;
result = (unsigned __int8)(v9 + result);
v10 = &v4[result];
*v5 = *v10;
*v10 = v8;
if ( v6 >= a3 )
v6 = 0;
++v5;
}
while ( v5 != a1 + 258 );
return result;
}

这个函数应该是凭借密钥的顺序,来改变自身,从而生成一个data盒。我们通过动态调试是能够找到data的。

1
[0x00000071, 0x000000A2, 0x00000062, 0x00000031, 0x0000004D, 0x00000097, 0x00000014, 0x0000000D, 0x000000ED, 0x000000A3, 0x000000D6, 0x000000FC, 0x000000F1, 0x0000003B, 0x0000003C, 0x00000033, 0x000000B5, 0x00000022, 0x00000012, 0x0000001A, 0x00000017, 0x0000001D, 0x00000098, 0x00000091, 0x00000006, 0x0000002A, 0x0000008B, 0x00000023, 0x000000E6, 0x00000055, 0x00000046, 0x0000003A, 0x00000065, 0x00000028, 0x00000030, 0x00000039, 0x000000D4, 0x0000000C, 0x00000001, 0x0000002D, 0x00000025, 0x00000010, 0x00000009, 0x0000008F, 0x0000006A, 0x0000003F, 0x00000044, 0x000000D8, 0x0000006D, 0x000000C5, 0x000000A6, 0x00000072, 0x00000007, 0x00000083, 0x00000040, 0x000000C6, 0x0000008E, 0x0000001F, 0x00000077, 0x00000061, 0x00000096, 0x0000004A, 0x00000008, 0x000000FE, 0x00000053, 0x0000005A, 0x000000A1, 0x000000DF, 0x000000B6, 0x00000067, 0x00000066, 0x0000005C, 0x00000057, 0x000000B8, 0x000000D3, 0x00000011, 0x00000052, 0x00000021, 0x000000CC, 0x00000056, 0x0000002E, 0x000000C2, 0x00000088, 0x000000AA, 0x000000F9, 0x00000020, 0x0000007A, 0x0000006F, 0x0000004E, 0x00000076, 0x000000E8, 0x000000C1, 0x000000D5, 0x000000BD, 0x000000CE, 0x0000009E, 0x00000038, 0x00000095, 0x00000050, 0x000000F2, 0x0000009F, 0x000000B2, 0x0000009A, 0x0000000B, 0x00000047, 0x00000016, 0x00000060, 0x000000BF, 0x000000FD, 0x00000092, 0x00000035, 0x00000089, 0x000000DA, 0x000000FF, 0x0000009B, 0x000000BA, 0x00000013, 0x000000AB, 0x000000F4, 0x00000079, 0x00000087, 0x000000AC, 0x0000008C, 0x00000073, 0x00000084, 0x000000B3, 0x0000000E, 0x000000C8, 0x00000026, 0x000000A5, 0x000000E7, 0x00000015, 0x000000E9, 0x000000C3, 0x00000069, 0x00000070, 0x000000E0, 0x00000068, 0x00000042, 0x00000081, 0x000000CD, 0x000000EB, 0x000000DE, 0x0000007D, 0x000000EF, 0x000000D0, 0x00000024, 0x00000000, 0x000000F0, 0x00000041, 0x000000A0, 0x000000EE, 0x00000005, 0x00000094, 0x00000085, 0x000000BB, 0x00000043, 0x00000002, 0x000000F7, 0x000000C0, 0x000000D1, 0x0000001B, 0x0000007F, 0x0000005B, 0x000000EC, 0x000000F6, 0x0000002B, 0x0000001E, 0x000000E2, 0x00000027, 0x000000FB, 0x00000078, 0x00000054, 0x00000058, 0x000000E4, 0x00000032, 0x000000DB, 0x000000B7, 0x000000C7, 0x00000090, 0x0000007C, 0x000000F8, 0x0000005D, 0x0000005F, 0x00000063, 0x000000BE, 0x0000002C, 0x0000000A, 0x000000DD, 0x0000009C, 0x00000075, 0x00000019, 0x000000C4, 0x000000A8, 0x00000086, 0x00000036, 0x000000BC, 0x0000008D, 0x000000D7, 0x0000007B, 0x000000B4, 0x0000005E, 0x0000003E, 0x000000A7, 0x000000B1, 0x000000E1, 0x00000059, 0x00000082, 0x000000B9, 0x000000AE, 0x000000D9, 0x0000007E, 0x000000AF, 0x000000CF, 0x0000009D, 0x000000F5, 0x000000FA, 0x00000048, 0x0000004F, 0x000000A9, 0x0000006C, 0x00000064, 0x0000006E, 0x00000049, 0x0000004B, 0x0000006B, 0x00000029, 0x00000045, 0x000000E5, 0x00000004, 0x000000A4, 0x0000004C, 0x00000034, 0x00000080, 0x000000D2, 0x0000003D, 0x000000E3, 0x00000099, 0x00000037, 0x000000DC, 0x00000093, 0x000000C9, 0x000000CA, 0x000000CB, 0x000000EA, 0x000000B0, 0x0000000F, 0x00000003, 0x0000008A, 0x000000F3, 0x00000051, 0x0000001C, 0x000000AD, 0x00000074, 0x00000018, 0x0000002F]

这个就是生成的data盒。

第四个函数:

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
DWORD *__cdecl sub_4018D0(_DWORD *a1, _BYTE *a2, int a3)
{
int v3; // edx
int v4; // ecx
_DWORD *v5; // esi
_BYTE *v6; // ebx
int v7; // edi
int *v8; // eax
int v9; // edx
int v10; // ebp
_DWORD *result; // eax
int *v12; // [esp+0h] [ebp-18h]

v3 = *a1;
v4 = a1[1];
v5 = a1 + 2;
if ( a3 > 0 )
{
v6 = a2;
v7 = *a1;
do
{
v7 = (unsigned __int8)(v7 + 1);
v8 = &v5[v7];
v9 = *v8;
v4 = (unsigned __int8)(*v8 + v4);
v12 = &v5[v4];
v10 = *v12;
*v8 = *v12;
*v12 = v9;
*v6++ ^= v5[(unsigned __int8)(v9 + v10)]; // v6是输入的字符串,v5是生成的data
}
while ( v6 != &a2[a3] );
v3 = v7;
}
result = a1;
*a1 = v3;
a1[1] = v4;
return result;
}

这个异或函数是最有用的,我们从中能看出很多东西,比如,v5是data盒,我们是根据v9+v10来从data中选择数据的。我们在这一行设断点,来查看生成的数据。发现分别为[0x7C,0xAB,0x2D,0x91,0x2F,0x98,0xED,0xA9]。也就是说我们输入的字符串和这个固定的字符串异或后产生了新的字符串,那么我们只要找到新的字符串。

第5个函数:

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
bool __cdecl sub_401950(_BYTE *a1)
{
_BYTE *v1; // ecx
bool result; // al

v1 = a1;
do
{
switch ( *v1 ) // v1是输入的字符串
{
case 0:
dword_40F028 &= dword_40F038;
dword_40F02C *= dword_40F028;
break;
case 1:
if ( !dword_40F02C )
return 0;
dword_40F028 /= dword_40F02C;
dword_40F024 += dword_40F034;
break;
case 2:
dword_40F030 ^= dword_40F034;
dword_40F03C += dword_40F020;
break;
case 3:
dword_40F03C -= dword_40F030;
dword_40F030 &= dword_40F024;
break;
case 4:
dword_40F034 *= dword_40F020;
dword_40F02C -= dword_40F038;
break;
case 5:
dword_40F020 ^= dword_40F02C;
dword_40F038 -= dword_40F03C;
break;
case 6:
if ( !dword_40F03C )
return 0;
dword_40F034 |= dword_40F024 / dword_40F03C;
dword_40F024 /= dword_40F03C;
break;
case 7:
dword_40F038 += dword_40F028;
dword_40F034 |= dword_40F024;
break;
case 8:
dword_40F020 *= dword_40F02C;
dword_40F030 -= dword_40F03C;
break;
case 9:
dword_40F028 += dword_40F034;
dword_40F02C ^= dword_40F030;
break;
default:
return 0;
}
++v1;
}
while ( v1 != a1 + 8 );
result = (dword_40F038 == 231)

+ (dword_40F034 == 14456)
ord_40F030 == 14961)
+ (dword_40F02C == -13264)
ord_40F028 == 16)
+ (dword_40F024 == 104)
ord_40F020 == -951) == 7;
if ( dword_40F03C != -239 )
return 0;
return result;
}


我们惊喜的发现,这个函数所做的操作正是对变换后的字符串的操作,所以我们只需要看这个函数就行,这个函数逆向是不可能的,所以采用爆破是最好的方法,但属实不会写脚本,就照着wp写了一遍。

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
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
bool Check(char *str);
int main(){
int i = 0;
long a = 99999999;
while(i <= a){
char str[10] = {0};
sprintf(str,"%08d",i);
if(Check(str)){
printf("TRUE!!!!!: %s",str);
goto label;
break;
}
if(i % 1000 == 0){
puts(str);
}
i++;
}
puts("falied\n");
label:
getchar();
getchar();
}
bool Check(char *str){
int dword_40F000 = 0xA;
int dword_40F020 = 0x8A;
int dword_40F024 = 0x1A1;
int dword_40F028 = 0x12A
int dword_40F02C = 0x269;
int dword_40F030 = 0x209;
int dword_40F034 = 0x68;
int dword_40F038 = 0x39F;
int dword_40F03C = 0x2C8;
int result = 0;
for(int i = 0;i < 8;i++){
switch (str[i] - 48)
{
case 0:
dword_40F028 &= dword_40F038;
dword_40F02C *= dword_40F028;
break;
case 1:
if ( !dword_40F02C )
goto LABEL_6;
dword_40F028 /= dword_40F02C;
dword_40F024 += dword_40F034;
break;
case 2:
dword_40F030 ^= dword_40F034;
dword_40F03C += dword_40F020;
break;
case 3:
dword_40F03C -= dword_40F030;
dword_40F030 &= dword_40F024;
break;
case 4:
dword_40F034 *= dword_40F020;
dword_40F02C -= dword_40F038;
break;
case 5:
dword_40F020 ^= dword_40F02C;
dword_40F038 -= dword_40F03C;
break;
case 6:
if ( !dword_40F03C )
goto LABEL_6;
dword_40F034 |= dword_40F024 / dword_40F03C;
dword_40F024 /= dword_40F03C;
break;
case 7:
dword_40F038 += dword_40F028;
dword_40F034 |= dword_40F024;
break;
case 8:
dword_40F020 *= dword_40F02C;
dword_40F030 -= dword_40F03C;
break;
case 9:
dword_40F028 += dword_40F034;
dword_40F02C ^= dword_40F030;
default:
break;
}
}
result = (((dword_40F038 == 0xE7)
+ (dword_40F034 == 0x3878)
+ (dword_40F030 == 0x3A71)
+ (dword_40F02C == 0xFFFFCC30)
+ (dword_40F028 == 0x10)
+ (dword_40F024 == 0x68)
+ (dword_40F020 == 0xFFFFFC49)) == 7);
if ( dword_40F03C != 0xFFFFFF11 )
goto LABEL_6;
if(result == 1){
return true;
}
LABEL_6:
return false;
}
//得到爆破后的字符串61495072

师傅写的很清楚明了,学习了!

我们接下来异或一下得到我们要输入的:

1
2
3
4
5
6
7
a=[0x7C,0xAB,0x2D,0x91,0x2F,0x98,0xED,0xA9]
b=[0x06,0x01,0x04,0x09,0x05,0x00,0x07,0x02]
flag=""
for i in range(8):
flag+="%x"%(a[i]^b[i]) #转化成16进制
print(flag)
#7aaa29982a98eaab

输入终端,得到flag

flag{5cb92582-66a8-e5b7-d3bf-3b99df8ac7f0}

noraml22

这个题比较简单,但我没看出来提示怎么用,好家伙,提示是23题。

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
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
char v4; // [esp+0h] [ebp-134h]
char v5; // [esp+0h] [ebp-134h]
char Buffer[48]; // [esp+D0h] [ebp-64h] BYREF
size_t i; // [esp+100h] [ebp-34h]
FILE *Stream; // [esp+10Ch] [ebp-28h]
char v9; // [esp+118h] [ebp-1Ch] BYREF

__CheckForDebuggerJustMyCode(&unk_41C008);
sub_41137A("Input Your Flag:\n", v4);
sub_41137F("%19s", (char)&v9);
if ( argc != 2 )
{
sub_41137A("Input error!\n", v5);
exit(1);
}
sub_41137A("%s\n", (char)argv[1]);
for ( i = 0; i < j_strlen(argv[1]); ++i )
argv[1][i] += i;
if ( !j_strcmp(Str1, argv[1]) && (Stream = fopen(argv[1], "r")) != 0 )
{
fgets(Buffer, 40, Stream);
if ( j_strlen(Buffer) != 32 || j_strlen(Buffer) % 2 == 1 )
exit(1);
sub_4113B1(Buffer, (int)&unk_41A4E0); //*
if ( sub_4113B6((int)&unk_41A4E0) ) //*
sub_41137A("flag{%s}", (char)Buffer);
else
sub_41137A("Input Error!\n", v5);
return 0;
}
else
{
sub_41137A("Input Error!\n", v5);
return 0;
}
}

这个主函数没什么用,我们主要来看标星号的函数先看第一个

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
size_t __cdecl sub_414E50(char *Str, int a2)
{
size_t result; // eax
char v3; // [esp+0h] [ebp-E4h]
int v4; // [esp+D0h] [ebp-14h]
signed int i; // [esp+DCh] [ebp-8h]

__CheckForDebuggerJustMyCode(&unk_41C008);
dword_41A078[8] = '\xA7';
dword_41A078[9] = '\xDE';
dword_41A078[10] = '\xDA';
dword_41A078[11] = 'F';
dword_41A078[12] = '\xAB';
dword_41A078[13] = 0x2E;
dword_41A078[14] = '\xFF';
dword_41A078[15] = '\xDB';
for ( i = 0; ; i += 2 )
{
result = j_strlen(Str);
if ( i >= result )
break;
if ( Str[i] >= 48 && Str[i] <= 57 )
{
*(_DWORD *)(a2 + 4 * (i / 2)) = Str[i] - 48;
}
else
{
if ( Str[i] < 'a' || Str[i] > 'f' )
{
sub_41137A("Input Error!\n", v3);
exit(0);
}
*(_DWORD *)(a2 + 4 * (i / 2)) = Str[i] - 87;
}
*(_DWORD *)(a2 + 4 * (i / 2)) *= 16;
if ( Str[i + 1] >= '0' && Str[i + 1] <= '9' )
{
v4 = Str[i + 1] - 48;
}
else
{
if ( Str[i + 1] < 'a' || Str[i + 1] > 'f' )
{
sub_41137A("Input Error!\n", v3);
exit(0);
}
v4 = Str[i + 1] - 87;
}
*(_DWORD *)(a2 + 4 * (i / 2)) += v4;
}
return result;
}

很长没用,只用看 dword_41A078这个数组藏了什么,由于反编译出来的是8-15位,那么这个数组进去的还存在0-7位。

再看第二个函数

1
2
3
4
5
6
7
8
9
10
11
12
int __cdecl sub_411D90(int a1)
{
int i; // [esp+D0h] [ebp-8h]

__CheckForDebuggerJustMyCode(&unk_41C008);
for ( i = 0; i < 16; ++i )
{
if ( *(_DWORD *)(a1 + 4 * i) + 1 != dword_41A078[i] )
return 0;
}
return 1;
}

就是对比,好了flag出来了

1
2
3
4
5
6
data=[0x50,0xC6,0xF1,0xE4,0xE3,0xE2,0x9A,0xA1,0XA7,0XDE,0XDA,0XF,0XAB,0X2E,0XFF,0XDB]
flag=""
for i in range(16):
flag += "%x"%(data[i]-1)
print(flag)
#4fc5f0e3e2e199a0a6ddd9eaa2dfeda

normal23

这道题是c#写的,相比极客的题,这个属实不好看明白,老样子,先找main函数

这个好像是先进行密钥iriszero的加密,用到的是ICEKEY加密方法。

下面的内容就很惊喜了,从字面意思就能看出,一个加密,一个解密,我们只要解密就行了。

我们只需要在解密前对比的时候设断点,然后修改数据,再运行到结束,查看内存就行了。

先在array中修改数据,再在bytes中查看flag,但注意要记得刷新

直到出来true就行了

3561636230363233313732346338633336396261653731313136366462653835,擦复制出来是ascii

flag:5acb06231724c8c369bae711166dbe85

normal24

我已经被这个题折磨死了,太难了有一说一,但还是收获了许多知识,令我不再那么害怕这么多代码。

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned __int64 v3; // rbx
__int64 len; // rax
__int128 *v5; // rax
__int64 v6; // r11
__int128 *v7; // r14
int v8; // edi
__int128 *v9; // rsi
char v10; // r10
int v11; // edx
__int64 v12; // r8
unsigned __int64 v13; // rcx
__int64 v14; // rcx
unsigned __int64 v15; // rax
unsigned __int64 i; // rax
_BYTE *v17; // rax
size_t v18; // rsi
_BYTE *v19; // rbx
_BYTE *v20; // r9
int v21; // er11
char *v22; // r8
__int64 v23; // rcx
char v24; // al
__int64 v25; // r9
__int64 v26; // rdx
__int64 v27; // rax
size_t Size; // [rsp+20h] [rbp-48h] BYREF
__int128 key; // [rsp+28h] [rbp-40h] BYREF
int v31; // [rsp+38h] [rbp-30h]
int v32; // [rsp+3Ch] [rbp-2Ch]
int Code[4]; // [rsp+40h] [rbp-28h] BYREF
int v34; // [rsp+50h] [rbp-18h]

*(_OWORD *)Code = 0i64;
v34 = 0;
sub_7FF6B91D18C0(std::cin, (__int64)argv, (__int64)Code);
v3 = -1i64;
len = -1i64;
do
++len;
while ( *((_BYTE *)Code + len) );
if ( len != 19 )
{
sub_7FF6B91D1620(std::cout, "error\n");
_exit((int)Code);
}
v5 = (__int128 *)operator new(5ui64);
v6 = *(_QWORD *)&::Code;
v7 = v5;
v8 = 0;
v9 = v5;
do
{
v10 = *((_BYTE *)v9 + (char *)Code - (char *)v5);
v11 = 0;
*(_BYTE *)v9 = v10;
v12 = 0i64;
v13 = -1i64;
do
++v13;
while ( *(_BYTE *)(v6 + v13) );
if ( v13 )
{
do
{
if ( v10 == *(_BYTE *)(v6 + v12) )
break;
++v11;
++v12;
}
while ( v11 < v13 );
}
v14 = -1i64;
do
++v14;
while ( *(_BYTE *)(v6 + v14) );
if ( v11 == v14 )
_exit(v6);
v9 = (__int128 *)((char *)v9 + 1);
}
while ( (char *)v9 - (char *)v5 < 4 );
*((_BYTE *)v5 + 4) = 0;
do
++v3;
while ( *((_BYTE *)Code + v3) );
v15 = 0i64;
key = *v7;
while ( *((_BYTE *)&key + v15) )
{
if ( !*((_BYTE *)&key + v15 + 1) )
{
++v15;
break;
}
if ( !*((_BYTE *)&key + v15 + 2) )
{
v15 += 2i64;
break;
}
if ( !*((_BYTE *)&key + v15 + 3) )
{
v15 += 3i64;
break;
}
v15 += 4i64;
if ( v15 >= 0x10 )
break;
}
for ( i = v15 + 1; i < 0x10; ++i )
*((_BYTE *)&key + i) = 0;
v17 = xxtea((__int64)Code, v3, (unsigned __int8 *)&key, &Size); //第一部分
v18 = Size;
v19 = v17;
v20 = operator new(Size);
v21 = 1;
*v20 = v19[2]; // 求v20,求v19,第二部分
v22 = v20 + 1;
v20[1] = *v19;
v20[2] = v19[3];
v20[3] = v19[1];
v20[4] = v19[6];
v20[5] = v19[4];
v20[6] = v19[7];
v20[7] = v19[5];
v20[8] = v19[10];
v20[9] = v19[8];
v20[10] = v19[11];
v20[11] = v19[9];
v20[12] = v19[14];
v20[13] = v19[12];
v20[14] = v19[15];
v20[15] = v19[13];
v20[16] = v19[18];
v20[17] = v19[16];
v20[18] = v19[19];
v20[19] = v19[17];
v20[20] = v19[22];
v20[21] = v19[20];
v20[22] = v19[23];
for ( v20[23] = v19[21]; v21 < v18; ++v22 ) //第三部分
{
v23 = 0i64;
if ( v21 / 3 > 0 )
{
v24 = *v22;
do
{
v24 ^= v20[v23++];
*v22 = v24;
}
while ( v23 < v21 / 3 );
}
++v21;
}
*(_QWORD *)&key = 0xC0953A7C6B40BCCEui64;
v25 = v20 - (_BYTE *)&key;
*((_QWORD *)&key + 1) = 0x3502F79120209BEFi64;
v26 = 0i64;
v31 = 0xC8021823;
v32 = 0xFA5656E7;
do
{
if ( *((_BYTE *)&key + v26) != *((_BYTE *)&key + v26 + v25) )// 我们得到key是要和data对比的
_exit(v8 * v8);
++v8;
++v26;
}
while ( v26 < 24 );
v27 = sub_7FF6B91D1620(std::cout, "You win!");
std::ostream::operator<<(v27, sub_7FF6B91D17F0);
return 0;
}

这个题分为3个部分,我们跟踪一下flag的路线,首先v17是xxtea加密得到的,v19得到的密文转移到v20,v20又转移到v22,然后进行对比,所以我们从第三部分开始搞,我们选择z3来求解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from z3 import*
cmp_data = [206, 188, 64, 107, 124, 58, 149, 192, 239, 155, 32, 32, 145, 247, 2, 53, 35, 24, 2, 200, 231, 86, 86, 250]
s = Solver()
flag = [BitVec(('x%d' % i),8) for i in range(24) ]
for i in range(24):
a = flag[i]
for j in range(i // 3):
a ^= flag[j]
flag[i] = a
for i in range(24):
s.add(flag[i] == cmp_data[i])
if s.check() == sat:
model = s.model()
print(model)
else:
print("unsat")
#得到data =[206,188,64,165,178,244,231,178,157,169,18,18,200,174,91,16,6,61,29,215,248,220,220,112]

然后在进行移位:

1
2
3
4
5
6
7
arr1 = [2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21]
data = [206,188,64,165,178,244,231,178,157,169,18,18,200,174,91,16,6,61,29,215,248,220,220,112]
data1 = [0 for i in range(24)]
for i in range(24):
data1[arr1[i]] = data[i]
print(data1)
#得到data1 = [188, 165, 206, 64, 244, 178, 178, 231, 169, 18, 157, 18, 174, 16, 200, 91, 61, 215, 6, 29, 220, 112, 248, 220]

那么最后再看第一个函数,就是xxtea加密,我只找到了python2的解密脚本,直接在网站上跑:

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
import struct
_DELTA = 0x9E3779B9
def _long2str(v, w):
n = (len(v) - 1) << 2
if w:
m = v[-1]
if (m < n - 3) or (m > n): return ''
n = m
s = struct.pack('<%iL' % len(v), *v)
return s[0:n] if w else s
def _str2long(s, w):
n = len(s)
m = (4 - (n & 3) & 3) + n
s = s.ljust(m, "\0")
v = list(struct.unpack('<%iL' % (m >> 2), s))
if w: v.append(n)
return v
def decrypt(str, key):
if str == '': return str
v = _str2long(str, False)
k = _str2long(key.ljust(16, "\0"), False)
n = len(v) - 1
z = v[n]
y = v[0]
q = 6 + 52 // (n + 1)
sum = (q * _DELTA) & 0xffffffff
while (sum != 0):
e = sum >> 2 & 3
for p in xrange(n, 0, -1):
z = v[p - 1]
v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff
y = v[p]
z = v[n]
v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff
y = v[0]
sum = (sum - _DELTA) & 0xffffffff
return _long2str(v, True)
if __name__ == "__main__":
key = "flag"
data1 = [188, 165, 206, 64, 244, 178, 178, 231, 169, 18, 157, 18, 174, 16, 200, 91, 61, 215, 6, 29, 220, 112, 248, 220]
s = "".join(map(chr, data1))
s = decrypt(s, key)
print repr(s)

得到flag,之后介绍以下xxtea加密,rc4和tea加密。

normal25

终于碰到一道简单题了,这道题,先查字符串,发现很明显的base64加密。

1
2
3
4
5
6
7
8
9
10
11
12
Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xV
mpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW
01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWx
ob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZS
R1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT
2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1
ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1d
sWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1Ex
WlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGS
nJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSl
lUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnR
lRXRXTVZaSFVsUnNVVlZVTURrPQ==

解密得到网址,看到三年前的网友在要flag哈哈哈哈哈哈哈哈哈哈哈哈,比较有乐趣。

但实际上并没有flag,我们可以在base64下看到引用的另一个函数,交叉引用进去才是真正解密函数。

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
unsigned __int64 sub_400D35()
{
unsigned __int64 result; // rax
unsigned int v1; // [rsp+Ch] [rbp-24h]
int i; // [rsp+10h] [rbp-20h]
int j; // [rsp+14h] [rbp-1Ch]
unsigned int v4; // [rsp+24h] [rbp-Ch]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]

v5 = __readfsqword(0x28u);
v1 = sub_43FD20(0LL) - qword_6CEE38;
for ( i = 0; i <= 1233; ++i )
{
sub_40F790(v1);
sub_40FE60();
sub_40FE60();
v1 = sub_40FE60() ^ 0x98765432;
}
v4 = v1;
if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 'g' )
{
for ( j = 0; j <= 24; ++j )
sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
}
result = __readfsqword(0x28u) ^ v5;
if ( result )
sub_444020();
return result;
}

这个函数最主要的是在if这里,我们看到是和一个已知的数组异或,异或出的结果是flag,所以我们能搞出未知的字符串。

然后用这个未知的字符串再异或出我们要找到flag,给出脚本:

1
2
3
4
5
6
7
8
9
10
11
12
data=[0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B]
code=""
s="flag"
flag=""
for i in range(4):
code += chr(data[i] ^ ord(s[i]))
print(code)
#&YA1
for j in range(25):
flag += chr(data[j] ^ ord(code[j%4]))
print(flag)
#flag{Act1ve_Defen5e_Test}

normal30

这个题是一个小游戏,不管游戏直接分析

这个题通过汇编看就是一堆数与两个固定的数进行异或,然后打印这个flag,那么我们直接写脚本

1
2
3
4
5
6
a = [0x8E, 0x9D, 0x94, 0x98, 0xBB, 0x89, 0xF3, 0xEF, 0x83, 0xEE, 0xAD, 0x9B, 0x9F, 0xEC, 0x9F, 0x9A, 0xF0, 0xEB, 0x9F, 0x97, 0xF6, 0xBC, 0xF1, 0xE9, 0x9F, 0xE7, 0xA1, 0xB3, 0xF3, 0xA3]
data = [a[0] ^ ord("N"),a[1]^ord("C")]
flag = ""
for i in range(len(a)):
flag += chr(a[i] ^ data[i % 2])
print(flag)

normal31

很难的一道题:我们进入main函数后发现没有踪迹,我们这时候在输入设断点,动调时发现,少了个hook的dll文件,所以只能参照wp来复现了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __stdcall sub_812AB0(int a1, int a2, int a3, int a4)
{
size_t i; // [esp+D8h] [ebp-8h]

for ( i = 0; i < j_strlen(Str); ++i )
{
if ( Str[i] <= 122 && Str[i] >= 97 )
{
Str[i] -= 32;
}
else if ( Str[i] <= 'Z' && Str[i] >= 'A' )
{
Str[i] += ' ';
}
}
MessageBoxA(0, "hooked", "successed", 0);
AddVectoredExceptionHandler(0, Handler);
return 0;
}

这个函数是一个变表函数,即将大写变小写,小写变大写,然后弹出对话框,接下来是一个异常函数,这个异常可以使函数跳跃到另一个函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
int __stdcall Handler_0(_DWORD **a1)
{
char v2[20]; // [esp+D0h] [ebp-18h] BYREF

if ( **a1 == -1073741819 )
{
qmemcpy(v2, "where_are_u_now?", 16);
sub_811172((int)&unk_81A218, (int)v2); // sm4自解密初始化
SetUnhandledExceptionFilter(TopLevelExceptionFilter);// 触发异常,转到sub_412EA0
}
return 0;
}
//SetUnhandledExceptionFilter函数是异常捕获函数,返回设置的回调函数,就是跟异常跳转一样,跳转到另一个函数

我们接着动态调试,发现到了下面的函数:

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
unsigned int __cdecl sub_811F50(int a1, unsigned int *a2)
{
unsigned int result; // eax
unsigned int v3; // [esp+D0h] [ebp-B8h]
unsigned int v4; // [esp+DCh] [ebp-ACh]
unsigned int v5; // [esp+E0h] [ebp-A8h]
unsigned int v6; // [esp+E4h] [ebp-A4h]
int v7[35]; // [esp+E8h] [ebp-A0h]
unsigned int v8; // [esp+174h] [ebp-14h]
unsigned int v9; // [esp+178h] [ebp-10h]
unsigned int v10; // [esp+17Ch] [ebp-Ch]
unsigned int v11; // [esp+180h] [ebp-8h]

v3 = 0;
v8 = _byteswap_ulong(*a2);
v9 = _byteswap_ulong(a2[1]);
v10 = _byteswap_ulong(a2[2]);
v11 = _byteswap_ulong(a2[3]);
v4 = v8 ^ 0xA3B1BAC6;
v5 = dword_817A68[1] ^ v9;
v6 = dword_817A68[2] ^ v10;
result = 12;
v7[0] = dword_817A68[3] ^ v11;
while ( v3 < 0x20 )
{
v7[v3 + 1] = *(&v4 + v3) ^ sub_8114E0(dword_817A78[v3] ^ v7[v3] ^ v7[v3 - 1] ^ *(&v5 + v3));
*(_DWORD *)(a1 + 4 * v3) = v7[v3 + 1];
result = ++v3;
}
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
unsigned int __cdecl sub_8114E0(int a1)
{
unsigned int v2; // [esp+D0h] [ebp-2Ch]
unsigned int v3; // [esp+F4h] [ebp-8h]

LOBYTE(v2) = sub_8119A0(SHIBYTE(a1));
BYTE1(v2) = sub_8119A0(SBYTE2(a1));
BYTE2(v2) = sub_8119A0(SBYTE1(a1));
HIBYTE(v2) = sub_8119A0(a1);
v3 = _byteswap_ulong(v2);
return ((v3 >> 9) | (v3 << 23)) ^ v3 ^ ((v3 >> 19) | (v3 << 13));
}

以上函数都是sm4加密典型特征,其中sub_8119A0和dword_817A78这两个数组是典型代表。

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
int __cdecl sub_812C30(_DWORD *a1)
{
int result; // eax
char v2; // [esp+D3h] [ebp-11h]
size_t i; // [esp+DCh] [ebp-8h]

result = (int)a1;
if ( *(_DWORD *)*a1 == -1073741819 )
{
for ( i = 0; i < j_strlen(Str2); i += 2 )
{
v2 = Str2[i];
Str2[i] = Str2[i + 1];
Str2[i + 1] = v2;
}
Str1 = (char *)sub_81126C(byte_81A180);
*(_DWORD *)(a1[1] + 176) = *(_DWORD *)(*a1 + 20);
*(_DWORD *)(a1[1] + 164) = *(_DWORD *)(*a1 + 24);
*(_DWORD *)(a1[1] + 172) = *(_DWORD *)(*a1 + 28);
*(_DWORD *)(a1[1] + 168) = *(_DWORD *)(*a1 + 32);
*(_DWORD *)(a1[1] + 156) = *(_DWORD *)(*a1 + 36);
*(_DWORD *)(a1[1] + 160) = *(_DWORD *)(*a1 + 40);
*(_DWORD *)(a1[1] + 184) = sub_811136; //这个函数与字符串进行对比
return -1;
}
return result;
}
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
_BYTE *__cdecl sub_813090(char *Str)
{
int k; // [esp+E4h] [ebp-5Ch]
int v3; // [esp+F0h] [ebp-50h]
int j; // [esp+FCh] [ebp-44h]
int v5; // [esp+108h] [ebp-38h]
signed int i; // [esp+114h] [ebp-2Ch]
_BYTE *v7; // [esp+120h] [ebp-20h]
signed int v8; // [esp+12Ch] [ebp-14h]
int v9; // [esp+138h] [ebp-8h]

v5 = 0;
v8 = j_strlen(Str);
if ( v8 % 3 )
v9 = 4 * (v8 / 3) + 4;
else
v9 = 4 * (v8 / 3);
v7 = malloc(__CFADD__(v9, 1) ? -1 : v9 + 1);
v7[v9] = 0;
for ( i = 0; i < v8; i += 3 )
{
v3 = 0;
for ( j = 0; j < 3; ++j ) //每3位形成缓冲区
v3 |= (unsigned __int8)Str[j + i] << (8 * (2 - j));
for ( k = 0; k < 4; ++k )
{
if ( k >= 4 - (i + 3 - v8) && i + 3 > v8 )//不足4位用!补齐
v7[v5] = 33;
else
v7[v5] = ::Str[sub_8110FF((v3 >> (6 * (3 - k))) & 0x3F)]; //注意这点
++v5;
}
}
return v7;
}

sub_81126C这个函数就是个base64加密

1
2
3
4
int __cdecl sub_812760(int a1)
{
return (a1 + 24) % 64;
}

这里+24,相当于变表的值为原表取值右移24位

1
2
3
4
5
6
Str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
Str1 = ''
for i in Str:
Str1 += Str[(Str.find(i)+24) % len(Str)]
print (Str1)
#yzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/abcdefghijklmnopqrstuvwx

得到变表。

写脚本:

1
2
3
4
5
6
7
8
9
10
11
import base64
base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
diy_base = 'yzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/abcdefghijklmnopqrstuvwx'
s = 'U1ATIOpkOyWSvGm/YOYFR4!!'
ss = ''
for i in range(len(s)-2):
ss += base[diy_base.find(s[i])]
ss += '=='
a = base64.b64decode(ss)
print(list(map(hex,a)))
#['0x59', '0xd0', '0x95', '0x29', '0xd', '0xf2', '0x40', '0x6', '0x14', '0xf4', '0x8d', '0x27', '0x69', '0x6', '0x87', '0x4e']

得到sm4加密后的密文,where_are_u_now?是密钥,转换成hex

1
2
3
4
5
from pysm4 import encrypt, decrypt
cipher_num = 0x59d095290df2400614f48d276906874e
mk = 0x77686572655f6172655f755f6e6f773f
clear_num = decrypt(cipher_num, mk)
print(hex(clear_num)[2:].replace('L',''))

用pysm4来解密,得到16进制,转换一下:

SM4foRExcepioN?!

normal32

终于是最后一道题了,

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
int __thiscall sub_C22810(void *this)
{
int v1; // eax
int v2; // ecx
int v3; // eax
int v4; // esi
signed int v5; // edi
unsigned int v6; // kr00_4
int *v7; // ecx
int *input_copy; // ecx
int *v9; // ecx
__int128 *v10; // edx
unsigned int v11; // edi
int v12; // eax
int v13; // eax
bool v14; // cf
unsigned __int8 v15; // al
unsigned __int8 v16; // al
unsigned __int8 v17; // al
const char *v18; // edx
int v19; // eax
int v20; // eax
int v22; // [esp-14h] [ebp-D8h]
int v23; // [esp-10h] [ebp-D4h]
int *input; // [esp+24h] [ebp-A0h]
int v25; // [esp+34h] [ebp-90h]
unsigned int v26; // [esp+38h] [ebp-8Ch]
__int128 v27; // [esp+3Ch] [ebp-88h]
__int128 v28; // [esp+4Ch] [ebp-78h]
int v29; // [esp+5Ch] [ebp-68h]
__int128 v30; // [esp+60h] [ebp-64h]
__int128 v31; // [esp+70h] [ebp-54h]
int v32; // [esp+80h] [ebp-44h]
__int64 v33; // [esp+84h] [ebp-40h]
int v34; // [esp+8Ch] [ebp-38h]
__int16 v35; // [esp+90h] [ebp-34h]
int v36; // [esp+94h] [ebp-30h]
int v37; // [esp+98h] [ebp-2Ch]
int v38; // [esp+9Ch] [ebp-28h]
int v39; // [esp+A0h] [ebp-24h]
int v40; // [esp+A4h] [ebp-20h]
int v41; // [esp+A8h] [ebp-1Ch]
int v42; // [esp+ACh] [ebp-18h]
int v43; // [esp+B0h] [ebp-14h]
int v44; // [esp+C0h] [ebp-4h]

v25 = 0;
v26 = 15;
LOBYTE(input) = 0;
v44 = 0;
LOBYTE(v44) = 1;
v1 = printf(this, "Please input your flag: ");
printf_(v1);
sub_C237B0(&dword_C50068, &input); // 获取输入input
v34 = 'TC_9'; // v33~v35:"SWPU_2019_CTF"
v33 = qword_C4B9A0;
v35 = 'F';
if ( v25 == 32 ) // flag长度为32
{
v40 = 0xBA143D17;
v41 = 0x1D730350;
v42 = 0x9404607A;
v43 = 0x290AF070;
v5 = 0;
v30 = 0i64;
v32 = 0;
v31 = 0i64;
v6 = strlen((const char *)&v33);
do // 进行input和"SWPU_2019_CTF"循环异或
{
v7 = (int *)&input;
if ( v26 >= 16 )
v7 = input;
*((_BYTE *)v7 + v5) ^= *((_BYTE *)&v33 + v5 % v6);
++v5;
}
while ( v5 < 32 );
input_copy = (int *)&input;
v4 = (int)input;
if ( v26 >= 0x10 )
input_copy = input;
v29 = 0;
v27 = 0i64;
v28 = 0i64;
*(_QWORD *)&v30 = *(_QWORD *)input_copy;
*((_QWORD *)&v30 + 1) = *((_QWORD *)input_copy + 1);
*(_QWORD *)&v31 = *((_QWORD *)input_copy + 2);
*((_QWORD *)&v31 + 1) = *((_QWORD *)input_copy + 3);
sub_C225C0(v22, v23, 256, (unsigned int)&v30, (unsigned int)&v27);// 对异或后的input进行处理,结果放在v27和v28
v36 = 0xF80F37B3;
v37 = 0x5DAEBCBC;
v9 = &v36;
v38 = 0x864D5ABA;
v10 = &v27;
v39 = 0xD3629744;
v11 = 28;
v40 = 0x1624BA4F;
v41 = 0x1A729F0B;
v42 = 0x266D6865;
v43 = 0x67C86BBA;
while ( 1 ) // while循环体是sub_C225C0函数对异或后input的处理结果与v36~v43比较
{
v12 = *v9;
if ( *v9 != *(_DWORD *)v10 )
break;
++v9;
v10 = (__int128 *)((char *)v10 + 4);
v14 = v11 < 4;
v11 -= 4;
if ( v14 ) // v14为1,即v11<4时,验证正确
{
v13 = 0;
goto LABEL_19;
}
}
v14 = (unsigned __int8)v12 < *(_BYTE *)v10;
if ( (_BYTE)v12 != *(_BYTE *)v10
|| (v15 = *((_BYTE *)v9 + 1), v14 = v15 < *((_BYTE *)v10 + 1), v15 != *((_BYTE *)v10 + 1))
|| (v16 = *((_BYTE *)v9 + 2), v14 = v16 < *((_BYTE *)v10 + 2), v16 != *((_BYTE *)v10 + 2))
|| (v17 = *((_BYTE *)v9 + 3), v14 = v17 < *((_BYTE *)v10 + 3), v17 != *((_BYTE *)v10 + 3)) )
{
v13 = -v14 | 1;
}
else
{
v13 = 0;
}
LABEL_19:
if ( v13 ) // v13为0时,验证正确
v18 = "Try again!\r\n";
else
v18 = "Congratulations! I always knew you could do it.";
v19 = printf(v9, v18);
printf_(v19);
sub_C2ADBE("pause");
}
else
{
v3 = printf(v2, "Try again!\r\n");
printf_(v3);
sub_C2ADBE("pause");
v4 = (int)input;
}
if ( v26 >= 0x10 )
{
v20 = v4;
if ( v26 + 1 >= 0x1000 )
{
v4 = *(_DWORD *)(v4 - 4);
if ( (unsigned int)(v20 - v4 - 4) > 0x1F )
sub_C2AFF7(v26 + 36);
}
sub_C264DE(v4);
}
return 0;
}

输入为abcdefghijklmnopqrstuvwxyz123456,经过与”SWPU_2019_CTF”的循环异或及变量赋值后,v30即为input循环异或后的结果可知sub_C225C0函数是对循环异或后的input的结果的再一次异或,但是不知道异或的是哪些值,由于我们输入是“abcdefghijklmnopqrstuvwxyz123456”,与”SWPU_2019_CTF”异或后的结果v30是确定的,可以通过调试得到sub_C225C0函数调用完后,结果v27和v28的值,再用v30异或v27和v28得到sub_C225C0函数中参与异或运算的另一些值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#a是两次异或后,v27和v28的数据
a=[0xB4, 0x39, 0x0D, 0xFB, 0xA2, 0x83, 0xF9, 0x40, 0xB2, 0x42,
0x43, 0x9E, 0x41, 0x9C, 0x4F, 0x90, 0x4D, 0xBC, 0x76, 0x41,
0x3E, 0xB6, 0x53, 0x0B, 0x6E, 0x66, 0x29, 0x75, 0xE5, 0x1C,
0xBE, 0x2C]
#b是input第一次异或后,v30的数据
b=[0x32, 0x35, 0x33, 0x31, 0x3A, 0x54, 0x57, 0x59, 0x50, 0x35,
0x28, 0x38, 0x2B, 0x3D, 0x38, 0x20, 0x24, 0x2D, 0x41, 0x44,
0x44, 0x4F, 0x28, 0x3B, 0x2D, 0x3C, 0x62, 0x65, 0x63, 0x61,
0x6A, 0x04]
#a^b即可得到sub_C225C0函数中参与异或运算的另一些值
#cipher是最后要比较的数据
cipher=[0xB3, 0x37, 0x0F, 0xF8, 0xBC, 0xBC, 0xAE, 0x5D, 0xBA, 0x5A,
0x4D, 0x86, 0x44, 0x97, 0x62, 0xD3, 0x4F, 0xBA, 0x24, 0x16,
0x0B, 0x9F, 0x72, 0x1A, 0x65, 0x68, 0x6D, 0x26, 0xBA, 0x6B,
0xC8, 0x67]
s="SWPU_2019_CTF"
flag=""
for i in range(len(cipher)):
flag+=chr(a[i]^b[i]^cipher[i]^ord(s[i%len(s)]))
print(flag)
#flag{Y0uaretheB3st!#@_VirtualCC}