crackme--001
-
首先是查看软件!这就是一个简单输入字符串,然后进行比较就得到结果。
-
查壳!是汇编语言编写的。
-
所以就直接用OD打开,然后跳转到字符处!就发现了Error!这就是结果有误时弹出的结果,所以跟进看看。看到正确和错误起始是放在一起的,通过前面的JE来跳转,爆破的话只需要对其进行修改就可以了。可以进行强制跳转jmp,或者是改成JNE(Jump If Not Equal)如果不相等就跳转。
-
爆破!这时候再运行就除非输入正确结果否者就无法跳转到Error。爆破成功。
-
开始算法分析,跳转是由前面的cmp判断来决定的,而exa所存的值是由前面的函数得到的。所以就对前面的函数进行分析就可以了。
CMP DWORD PTR SS:[EBP+10],65 ; 这里就是函数的入口 /JE SHORT abexcm5.0040106C 这里会跳转到下面,所以在下面设置断点,单步进行并分析 CMP DWORD PTR SS:[EBP+10],2 JE abexcm5.0040112D XOR EAX,EAX LEAVE RETN 10 \PUSH 25 ; /Count = 25 (37.) PUSH abexcm5.00402324 ; |Buffer = abexcm5.00402324 PUSH 68 ; |ControlID = 68 (104.) PUSH DWORD PTR SS:[EBP+8] ; |hWnd CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA PUSH 0 ; /pFileSystemNameSize = NULL PUSH 0 ; |pFileSystemNameBuffer = NULL PUSH abexcm5.004020C8 ; |pFileSystemFlags = abexcm5.004020C8 . 68 90214000 PUSH abexcm5.00402190 ; |pMaxFilenameLength = abexcm5.00402190 . 68 94214000 PUSH abexcm5.00402194 ; |pVolumeSerialNumber = abexcm5.00402194 PUSH 32 ; |MaxVolumeNameSize = 32 (50.) PUSH abexcm5.0040225C ; |VolumeNameBuffer = abexcm5.0040225C PUSH 0 ; |RootPathName = NULL CALL <JMP.&KERNEL32.GetVolumeInformation>; \GetVolumeInformationA PUSH abexcm5.004023F3 ; /StringToAdd = "4562-ABEX" 0PUSH abexcm5.0040225C ; |ConcatString = "" 0CALL <JMP.&KERNEL32.lstrcatA> ; \lstrcatA 0MOV DL,2 /ADD DWORD PTR DS:[40225C],1 |ADD DWORD PTR DS:[40225D],1 |ADD DWORD PTR DS:[40225E],1 |ADD DWORD PTR DS:[40225F],1 |DEC DL \JNZ SHORT abexcm5.004010AF PUSH abexcm5.004023FD ; /StringToAdd = "L2C-5781" PUSH abexcm5.00402000 ; |ConcatString = "" CALL <JMP.&KERNEL32.lstrcatA> ; \lstrcatA PUSH abexcm5.0040225C ; /StringToAdd = "" PUSH abexcm5.00402000 ; |ConcatString = "" CALL <JMP.&KERNEL32.lstrcatA> ; \lstrcatA PUSH abexcm5.00402324 ; /String2 = "" PUSH abexcm5.00402000 ; |String1 = "" CALL <JMP.&KERNEL32.lstrcmpiA> ; \lstrcmpiA CMP EAX,0 JE SHORT abexcm5.00401117 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL PUSH abexcm5.00402434 ; |Title = "Error!" PUSH abexcm5.0040243B ; |Text = "The serial you entered is not correct!" PUSH DWORD PTR SS:[EBP+8] ; |hOwner CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA JMP SHORT abexcm5.0040112D PUSH 0 ; /Style = MB_OK|MB_APPLMODAL PUSH abexcm5.00402406 ; |Title = "Well Done!" PUSH abexcm5.00402411 ; |Text = "Yep, you entered a correct serial!" PUSH DWORD PTR SS:[EBP+8] ; |hOwner CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA JMP SHORT abexcm5.0040112D PUSH 0 ; /Result = 0 PUSH DWORD PTR SS:[EBP+8] ; |hWnd CALL <JMP.&USER32.EndDialog> ; \EndDialog LEAVE RETN 10
-
输入参数11111111,单步运行。
GetDlgItemText是C++中的函数,调用这个函数以获得与对话框中的控件相关的标题或文本。GetDlgItemText成员函数将文本拷贝到lpStr指向的位置并返回拷贝的字节的数目。
所以GetDlgItemText是获取我们输入的字符串<img src="E:\New160CrackMe\002-abexcm5\crackme--001.assets\image-20220902151104173.png" alt="image-20220902151104173" />
-
然后就到第二个函数
GetVolumeInformationA获取磁盘卷标
这里是将我们的磁盘号存入。因为该文件存在于学习这个磁盘下,所以就被读取到了。
-
第三个函数lstrcatA,就是将4562-ABEX和获取到的磁盘号学习连接起来。
-
0MOV DL,2 /ADD DWORD PTR DS:[40225C],1 |ADD DWORD PTR DS:[40225D],1 |ADD DWORD PTR DS:[40225E],1 |ADD DWORD PTR DS:[40225F],1 |DEC DL
这段函数是循环操作锁定到位置可以发现就是对我们的磁盘号进行每一个双字加一的操作,并且循环了两边。然后得到了这个。
-
之后就是再将字符串L2C-5781拿来和我们之前的萤巡4562-ABEX进行拼接。最后将拼接得到的字符串与我们输入的字符串进行比较得到结果。如果相同就会往eax中赋0x00,如果不同就赋0x01.
-
然后就根据得到的结果进行跳转。所以爆破方法就有修改跳转,或者修改判断。
-
-
输入的结果也就是:L2C-5781萤巡4562-ABEX,不用爆破也得到了结果。