这道题卡了我好久好久,知道今天才好不容易得以解决,题目描述如下:
UBC crackme, simple but you have to find the critical "cmp" first... press "start" then download it. Hint: The checkin key is serial of "HelloWorld"
首先拿到这道题的程序,我本能的第一反应就是在MessageBox上加断点,然后运行的时候,IDA给谈了个窗,我直接没太注意就确定了,可谁想到,就是这不经意的一下,让我掉入了深坑……
点完确定后,IDA就被挂在MessageBox上的断点停住了,一切看起来都很正常,可是,就这样找了好久,一直找不到关键代码,于是也便曾放下了好久,知道今天又拿起来做才终于知道自己怎么掉坑里的了。
仔细看下IDA给的那个提示框:
提示框是说exception发生了,是否传递给程序,这样看起来,我们是进了程序的异常处理部分,这也就难怪我们一步步的像上追踪也没有找到要找的地方。
仔细看下程序给出的提示:
这是要让我们在serial里输入数字,那么我们就按照要求来做,看能不能不进入异常处理部分。
可是,在我们输入的是数字后,程序却没有被我们放在MessageBox上的断点中断住,直接就正常运行了,不过这至少说明,程序没有进入异常处理部分,我们的方向是对的。
接下来就要考虑如何下断点了,我想在获取文本框内容的函数上下断点,可却没找到是哪个函数,然后就想既然MessageBox没用,那应该就是直接产生的一个普通窗口,然后就想到了ShowWindow,下断点,重新运行程序,发现,程序一上来就被暂停了,应该是主窗体的显示,无视就好,然后接下来输入完成后点check it发现程序果然被我们ShowWindow上的断点暂停住了,跟踪下去很轻松就找到了关键代码:
int __usercall sub_458800<eax>(int a1<ebx>) { int v1; // ecx@1 int v2; // ecx@2 unsigned int v4; // [sp-10h] [bp-14h]@1 int v5; // [sp-4h] [bp-8h]@4 int v6; // [sp+0h] [bp-4h]@1 int v7; // [sp+4h] [bp+0h]@1 v4 = __readfsdword(0); __writefsdword(0, (unsigned int)&v4); sub_458760(v4, loc_458874, &v7, a1, 0); sub_4255C0(v1, &v6); if ( sub_407774() == dword_45B844 ) { sub_44496C(); sub_4255F0(v2, "CRACKED"); } else { sub_44496C(); } __writefsdword(0, v4); return sub_4037E8(loc_45887B, v5); }
跟踪调试一下可以发现,sub_4255C0是用来将输入框的内容读入,v7中存的是指向读入的name字符串的指针,v6中存的是指向读入的serial字符串的指针,sub_407774是将serial字符串转为整数,转换失败是抛出异常,也就会进入我们之前掉入的那个坑里。
sub_458760中调用sub_4255C0读入了name字符串并做了一定的处理,观察会感觉sub_458760还是比较麻烦的,于是乎,再按照之前的老方法,在if ( sub_407774() == dword_45B844 )上加断点,直接看dword_45B844的值(填入的name为HelloWorld,题目中有说),然后输入到serial中即可。
成功得到正确的提示框,此题得以解决,正如题目中所说,这题的关键在于找到正确的cmp,只要找到了,基本做就不成问题了。