Youngter-drive
Start
打开发现加了个UPX
壳
想手脱,发现
好吧,直接脱壳机脱吧,脱完重新载入IDA
搜索字符串,将flag
放在Source
中,后面就没了
看看谁用了Source
发现四处引用的地方,除了当前的,还有三处
看到sub_411880
对Source
和off_418004
常量字符串进行比较,这里应该就是最终加密后进行比较的
看到StartAddress_0
发现调用了sub_41112C
进行处理Source
这里有个细节需要注意,dword_418008
是临界资源,所以前面调用了WaitForSingleObject
,用完之后当前线程Sleep,并且之后ReleaseMutex
,先不跟进去看具体怎么处理,先看最后一个调用
main_0
:
发现创建了两个线程对dword_418008
进行共享的操作
这里v2
使用dword_418008
这个资源时只是将其减一
并且两个线程轮流使用临界资源,用完一次就释放给另外一个线程使用
那么往下看到hObject
中的关键函数,这里栈有误,修改一下就可以
修改完栈后就可以成功反编译了
off_418008[0] = QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm
这里的逻辑就是,当flag
的某个字符中的值是大写字母时,就减去38
作为下标,更改为off_418008
中的值
如果是小写字母,就减去96
大写字母的范围为65 ~ 90
,减去38
的话得到的范围就是27 ~ 52
小写字母的范围为97 ~ 122
,减去96
的话得到的范围就是1 ~ 26
可以得出下标是不会重复的,所以只需要将
off_418004 = TOiZiZtOrYaToUwPnToBsOaOapsyS
的字符去找off_418008[0] = QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm
的下标即可
最后需要注意一点,dword_418008
由于是轮流使用的,所以对Source
的处理是隔一个字符进行处理的
exp.py
key = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'
encrypt = 'TOiZiZtOrYaToUwPnToBsOaOapsyS'
encrypt = encrypt[::-1]
tmp = ''
for i in range(len(encrypt)):
if i % 2 == 0:
tmp += encrypt[i]
else :
index = key.find(encrypt[i])
if index >= 1 and index <= 26:
tmp += chr(index + 96)
else:
tmp += chr(index + 38)
flag = tmp[::-1]
print(flag)
# ThisisthreadofwindowshahaIsES
emmmm,最后提交的时候还有个坑,临界资源dword_418008
的初始值为29
,下标为29
,说明有flag
有30位,最终得到的只有29
位,查了一下wp,发现加个E
就可以提交,emm。