【2026春节】解题领红包之二 {Windows 初级题}(动态调试详解——菜鸟心得篇)
0x0 致谢
感谢@ahov 大佬的帖子《【2025春节】解题领红包之二 Windows初级题 WriteUp (动态调试详解)》,让我这个小菜鸡找到了解题的窍门。
0x1 试错
先看下程序里的字符串。OD载入程序后,右键“中文搜索引擎”=>“智能搜索”,输入“Enter the password”,获得界面如下:
关键字是:
52pojie, 2026, Happy new year
其中有两个提示是说和长度有关。
然后在一长串的字符中间有一个【52pojie2026Happy】长得浓眉大眼的,和其他的都不一样,那就拿它来开刀试试:
52pojie2026Happy
老土的办法,在【004DD22F】位置【Enter the password】这个字符串这里按F2设置断点,然后多次按F8单步调试至【004DD294】,此处为待输入password的地方,将这行的下一行F2设置断点(因为没有跳转,所以应该是顺序执行),那么程序前期运行至输入密码之后会暂停,后续可以F8单步调试。
接着输入【52pojie2026Happy】进行后续单步调试,可以看到红框内的跳转循环,也就意味着用上述的密码进行单步调试之后就是与【52pojie2026Happy】字符串进行比较。可是,比较完成之后若不进行跳转,则就显示【[!] You're getting closer...】,什么鬼,出师未捷身先死?
0x2 发现陷阱
比较都顺利,怎么就出错失败了呢?回头再仔细看下这个跳转循环内的代码,有一段是【cmp byte】,应该是字符串比较,下一行的【jnz】的话就是另一个跳转,那我们看看这个跳转会跳到哪里呢?点住【jnz】这行,旁边的线提示我们会跳转到【004DD2FB】这行,在这行之后的几行中有一个【call <jmp.&msvcrt.strlen>】,调用了一个函数,看函数的名字是【msvcrt.strlen】,推测功能是求字符串长度,再看下一行【cmp eax,0x1F】,是一个比较操作,紧接着就是一个跳转,那这里应该就是比较字符串的长度,那对应的【0x1F】就是【31】,应该是一个31位的字符串。
0x3 选择正确的长度字符串
重新构建一个31位的字符串“1234567890123456789012345678901”,在【cmp eax,0x1F】之后调用一个函数,之后用【test】之后进行跳转,此处跳转之后会提示【[X] Access Denied!】
【显示Access Denied!】
0x4 找到密码藏身之处
那说明【004DD364】行处的【E8 6743F3FF】执行【 call 】的代码里进行了判断,那重新在此行按F2设置断点。
重新调试运行至此处,按F7单步进入,进入此函数,跳转至【004116D0】,逐次按F8单步调试,发现在运行至【004116F5】处的【test esi,esi】命令时,寄存器里出现了一个字符串【52pojie!!!_2026_Happy_new_year!】,正好长度为31位。
推测前一行【004116F0】运行指令【E8 2BFFFFFF】时生成了正确的密码。
0x5 验证结果
重新运行程序,输入获得的字符串【52pojie!!!_2026_Happy_new_year!】,可以看到正确的提示结果:
至此,密码已经成功获取。
0x6 回顾思路
回顾思路,有好几个关键点。在第一处比较时候对字符串【52pojie2026Happy】,比较成功之后就跳转至错误提示1【You're getting closer...】。其实真正的跳转是在其中判断字符比较不成功的时候跳出到后续的步骤才进行正确的操作。接着是计算字符串的长度,不符合就跳到错误【Hint: The length is your first real challenge.】。最后对输入字符内容的比较,不符合就显示错误【Access Denied!】
0x7 彩蛋
逐步调试至【004DD364】行处的【E8 6743F3FF】执行【 call 】,进行F7单步进入之后,可以发现【00411620】处的代码是通过【mov dword ptr】的方式四位四位地拼接,最终生成一串字符【wp2-(+'cccprpt\n#22;,'5;'】
wp2-(+'cccprpt\n#22;,'5;'
然后将字符串逐个与【0x42】进行异或比较(XOR),最终获得密码。
感谢您最终看到这里,谢谢您耐心地看完我这个菜鸟的解题思路。