[ACTF新生赛2020]Splendid_MineCraft
解密字节码
反编译源码:
|
|
条件判断:
|
|
第一个判断是输入的flag的最后一个字符的地址-v11的起始地址是否等于26,应该就是需要flag的长度为26:
|
|
后面两个判断就是判断flag的格式为:ACTF{xxxx}
strtok,用_
将字符串分隔开,v3取的是最左边的一段字符,ACTF{xxxx
,注意v17是从第六个字符开始,取4个字符的长度,然后v18是从第10个字符开始,取两个字符,这样其实都可以推断出来整个flag的格式为ACTF{xxxxxx_xxxxxx_xxxxxx}
|
|
往下存在一个unk_4051D8
:
发现把unk_4051D8
当成函数执行:((int (__cdecl *)(int *))unk_4051D8)(&v17)
,说明上面的一大段数据应该是字节码,然后将v17当成参数传入该函数中,重新运行,输入ACTF{aaaaaa_bbbbbb_cccccc}
,用x32dbg动态跟:
第一个循环:
|
|
异或结果:
看到EIP,发现就是通过循环解密出后面需要执行的字节码:
第一部分解密
解密之后的push ebp才是真正的函数开始,该函数先是往内存写值,一个是3@1b;b
,一个是Welcome
:
往下对刚刚写入的字符串的进行循环异或,
|
|
6次循环后得到:yOu0y*
最后出循环,test eax, eax,说明eax是作为函数执行结果,
重新运行执行输入:
ACTF{abcdef_hijklm_opqrst}
处理完第一个strtok之后会得到一个字符串为:abcdefRvabcdef
,中间的Rv是固定的
三次strtok处理完之后会得到这样的结果:
然后来到字节码部分,注意传进来的字符串为:abcdefRvabcdef
进来之后先对字节码进行解密,解谜之后从0x9F515C开始才是函数处理的开始,注意传入的参数由EDX指向:
随后生成3@1b;b
和welcome
,对这两个值进行异或再加上0x23,然后跟传入的字符串进行对比,不难发现预期值应该是两个相等的,往下走完循环拿完处理后的结果为yOu0y*
重新运行:
此时相等了,跳转不实现:
将edx作为计数器来存储相等的个数,最后对比是否全部相等,将返回值置为1:
第二部分解密
往下来到第二个部分的验证:
|
|
异或之后的值作为key,然后对:405018开始的值进行异或,跟第一个函数一样,通过这个key对字节码进行解密,然后再执行,这里的内容就是第二部分字符串的验证:
开局几个循环啥事都没干就是将输入的第二部分字符串进行memcpy,到这个位置才真正对字符串进行处理:
往下的mov很重要,EAX此时的值为0x705018,也就是该函数的字节码首地址,这里异或的结果作为数组下标,将字节码以byte的形式存储到EBX:
往下从0x705018+0x166取值与上面通过偏移拿到的值进行比较:
edi作为计数器,回到异或之前可以看到ecx的值来自于edi:
得到异或逻辑为:
|
|
exp:
|
|
byte_405018,用Ghidra的字节复制复制下来:
|
|
得到flag2:
第三部分解密
第三部分字符串发现就是直接进行strncmp:
可以得到第三部分的字符串为:5mcsM<
,最终flag:
ACTF{yOu0y*_knowo3_5mcsM<}
Exp
|
|