key的标准验证方案:
(0)key = input
(1)deckey1 = base64.b64decode(key)
(2)deckey2 = base64.b64decode(deckey1)
(3)deckey3 = morse_decode(deckey2)
(4)sm3_hash(deckey2,3)==tail of key
(5)deckey3 can step out game_map
即输出key讲过二次base64解密得到deckey2
deckey2讲过摩斯解码得到deckey3
其中需校验deckey2前三字符的"国密3"的杂凑(哈希)值是否与输出key尾部相等
其次deckey3表示在迷宫中行走,zlqp分别表示往下、往右、往上、往左行走,
此方式假定坐标从上到下,从左到右表示的迷宫图,最后" "空格表示停止。
能走的坐标必须是"0"标记值,而走过之后都会在原来坐标标记"4",
而迷宫又是全局静态变量,所以标准走法只能验证一次。
而又由于” “表示停止,而后续没有检测走过不数或目的坐标的检测,
导致其存在地图校验bug,bug可以知道导致不走迷宫而直接跳过迷宫校验,
同时也可以只完成部分迷宫路径走动,而不必全部走出迷宫就可以完成校验。
废话少说,清除反调试检测
下述函数都是反调试逆向的操作,需要返回0才能继续正常功能,否则退出。
它们是对后面所列地址函数的封装,这里我们批量修改为指令
xor eax,eax
ret
即机器码 "\x33\xC0\xC3",用pefile处理原pe程序另存为CTF03_dbg.exe即可。
Hi_check_reverse_info1_sub_42D681 .text 0042D681 00000005 R . . . . . .
Hi_check_reverse_info2_sub_42E26B .text 0042E26B 00000005 R . . . . . .
Hi_check_reverse_info3_sub_42D7F8 .text 0042D7F8 00000005 R . . . . . .
Hi_check_reverse_info4_sub_42D23F .text 0042D23F 00000005 R . . . . . .
Hi_check_reverse_info5_sub_42D334 .text 0042D334 00000005 R . . . . . .
Hi_check_reverse_info6_sub_42DD66 .text 0042DD66 00000005 R . . . . . .
Hi_check_reverse_info7_sub_42D92E .text 0042D92E 00000005 R . . . . . .
Hi_check_reverse_info8_sub_42DF7D .text 0042DF7D 00000005 R . . . . . .
Hi_check_reverse_info9_sub_42E31F .text 0042E31F 00000005 R . . . . . .
Hi_check_reverse_infoA_sub_42DA7D .text 0042DA7D 00000005 R . . . . . .
Hi_check_reverse_infoB_sub_42D389 .text 0042D389 00000005 R . . . . . .
Hi_check_reverse_infoC_sub_42D6BD .text 0042D6BD 00000005 R . . . . . .
Hi_check_reverse_infoD_sub_42D807 .text 0042D807 00000005 R . . . . . .
Hi_check_reverse_infoE_sub_42D39D .text 0042D39D 00000005 R . . . . . .
Hi_check_reverse_infoF_sub_42D1CC .text 0042D1CC 00000005 R . . . . . .
Hi_check_reverse_info10_sub_42DA96 .text 0042DA96 00000005 R . . . . . .
Hi_check_reverse_info11_sub_42D8CA .text 0042D8CA 00000005 R . . . . . .
Hi_check_reverse_info12_sub_42DD48 .text 0042DD48 00000005 R . . . . . .
Hi_check_reverse_info13_sub_42DBC7 .text 0042DBC7 00000005 R . . . . . .
Hi_check_reverse_info15_sub_42E428 .text 0042E428 00000005 R . . . . . .
Hi_check_reverse_info16_sub_42D825 .text 0042D825 00000005 R . . . . . .
Hi_check_reverse_info17_sub_42E27F .text 0042E27F 00000005 R . . . . . .
Hi_check_reverse_info18_sub_42E162 .text 0042E162 00000005 R . . . . . .
Hi_check_reverse_info19_sub_42D4F6 .text 0042D4F6 00000005 R . . . . . .
Hi_check_reverse_info1A_sub_42DA41 .text 0042DA41 00000005 R . . . . . .
Hi_check_reverse_info1B_sub_42D096 .text 0042D096 00000005 R . . . . . .
Hi_check_reverse_info1C_sub_42E45A .text 0042E45A 00000005 R . . . . . .
Hi_check_reverse_info1D_sub_42D203 .text 0042D203 00000005 R . . . . . .
#反反调试处理脚本如下
#------- ------- ------- ------- ------- ------- -------
rvas = '''430B10
431190
430E80
430030
430170
4302A0
4303D0
4304F0
430610
431070
4313C0
431420
4314F0
4317C0
431C40
431CE0
431D80
431F20
431FD0
4338D0
42D0B4
42FA20
42FAF0
42FC90
4323B0
4325D0
4326C0
432840
4329C0
432B30
432D20'''
import pefile
pe = pefile.PE(r'.\CTF03.exe')
def cpy_rpl_nk_fn(pe,fn):
xor_eax_eax_ret = "\x33\xC0\xC3"
for eastr in rvas.split('\n'):
rva = int(eastr,0x10)-0x400000
pe.set_bytes_at_rva(rva,xor_eax_eax_ret)
pe.write(r'.\CTF03\{}'.format(fn))
cpy_rpl_nk_fn(pe,"CTF03_dbg.exe")
#------- ------- ------- ------- ------- ------- -------
三个函数
base64 解码 Hi_base64decode_sub_42D267
莫斯码 解码 Hi_sgd_morse_xsym_decode_sub_42D96A
国密3 杂凑 Hi_sm3_hash_sub_42DA78
base64可用python的base64模块替换
国密3可以用网络开源测试,实际我找到的一份只有计算'/\x00\x00'三个字符时的杂凑值一样,
所以还是直接用样例程序的
莫斯码解码分三种,5字节长的0~9,4字节的a~z,7字节长的特殊符号,
4字节长的都是在原莫斯码基础上补*对齐,7字节长也是补*对齐7,然后再加上所代表的符合
莫斯码解码与编码功能模拟,mnstr,sgdstr,xsymstr可通过GetString获取,如
mnstr GetString(0x49B1E0,-1,ASCSTR_C)
sgdstr = GetString(0x49B218,-1,ASCSTR_C)
xsymstr = GetString(0x49B218,-1,ASCSTR_C)
mnstr = '-----.----..---...--....-.....-....--...---..----.'
morse_n = {}
for i in xrange(0,0xA):
tmnstr = mnstr[i*5:i*5+5]
morse_n[chr(0x30+i)] = tmnstr
morse_n[tmnstr] = chr(0x30+i)
sgdstr='.-**-...-.-.-..*.***..-.--.*......**.----.-*.-..--**-.**---*.--.--.-.-.*...*-***..-*...-.--*-..--.----..'
sgd_az = {}
for i in xrange(0,0x1A):
tsgdstr = sgdstr[i*4:i*4+4]
sgd_az[chr(0x61+i)] = tsgdstr
sgd_az[tsgdstr] = chr(0x61+i)
xsymstr='.-.-.-*.---...*:--..--*,-.-.-.*;..--..*?-...-**=.----.*\'-..-.**/-.-.--*!-....-*-..--.-*_.-..-.*"-.--.**(-.--.-*)...-..-$.-...**&.--.-.*@.-**-...-.-.-..*.***..-.--.*......**.----.-*.-..--**-.**---*.--.--.-.-.*...*-***..-*...-.--*-..--.----..'
xsym = {} #.:,;?='/!-_"()$&@
a = ""
for i in xrange(0,0x11):
txsymstr = xsymstr[i*8:i*8+8]
symch = txsymstr[7]
xstr = txsymstr[:7]
xsym[symch] = xstr
xsym[xstr] = symch
a += symch
def get_encodestr_of__sgd_az__morse_n__xsymstr(gmap_steps_key=''):
global sgd_az,morse_n,xsym
xstr = ''
for ch in gmap_steps_key:
if ch == ' ':
xstr += '/'
return xstr
else:
if ch in sgd_az:
xstr += (sgd_az[ch]+' ')
if ch in morse_n:
xstr += (morse_n[ch]+' ')
if ch in xsym:
xstr += (xsym[ch]+' ')
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课