Youngter-drive 1

发布时间 2023-05-06 15:43:25作者: TFOREVERY

查壳:

有壳32位,脱了,看看运行:无法运行,那么进IDA看看:

找个主函数:

发现没了,那么再找找

密文?不确定,跟进看看:

来到一个输出正确flag的地方,可以知道Des就是我们要找的东西:去看看有谁调用过它:

有两,第一个就是上图的输出,那么我们看第二个:

在这里我们看到一个方法:sub_411190() --> 这不就是输出正确的flag的方法吗?说明这里才是正确的主函数:

那么我们往上看:

这个就是我们一开始以为的主函数的方法的调用,接下去看看:

将Source赋值给Des,那么我们看看Source是个啥,跟进:

发现内存里是空的?那么我们猜测,这是不是初始化空间?接着向下看:

不认识这两:查呗:

构建两个线程?跟进第一个线程:

又出现了Source,后边还跟了一个内存,里边是一个数据:1D --> 29,看看调用他两的方法:sub_41112C(有些人进不去伪代码,这是由于堆栈不平衡,调成平衡后就好了),发现是将字符经过变化后给Source

这里大概是讲,先判断是否是字母,再判断是否是小写字母,然后操作result和off_418000中的数据。先看看off_418000中是个啥:"QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"

跟进第二个线程:


hObject?Wait?(暂停第一个线程吗?)查:

跟我们想的一样:那么主要去分析第一个线程就好了:

在第一个线程中,我们能看到,是先将字符给了result后才进行操作的,结合上述,也就是奇数位不变,偶数位改变,但是先别急,怎么变化我们并没有弄清楚,再看看。它说的是(a2+a1),根据传参我们能知道,这是指想Source中的字符,也就是说,是在off_418000中找到Source的字符然后进行变化。那么Source的字符串就是我们接下来要找的,之前我们访问过它的内存,却没有任何东西,但是还记最后的比较方法吗,那里提供了最后的加密字符串:

回去:

跟进:off_418004查看:"TOiZiZtOrYaToUwPnToBsOaOapsyS"

可以得到Source的字符串:"TOiZiZtOrYaToUwPnToBsOaOapsyS",写个脚本:

Des = 'TOiZiZtOrYaToUwPnToBsOaOapsyS'
D = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasd'
flag = ''
for i in range(len(Des)):
    if i % 2 == 0:
        flag += Des[i]
    else:
        if ord(Des[i]) < ord('A') or ord(Des[i]) > ord('Z'):
            flag += chr(D.find(Des[i]) + 38)
        else:
            flag += chr(D.find(Des[i]) + 96)
print(flag)

这里解释一下为啥还要加上38/96因为我们给定字串中找的是加密后的字符,而我们需要的原来的字符,所以利用加密后的字串还原它。

得到flag{ThisisthreadofwindowshahaIsES}开开心心上交 --> 给w了??????????看了每一个步骤都没错昂,参考了网络上大佬的文章,说是少了一位字符(因为是字串定义的是1D嘛,0~1D自然是30位(我们还原的只有29位))

莫得办法咯,爆破咯

最后flag{ThisisthreadofwindowshahaIsESE}收工。