crakmeeasy
,0 首先先程序crakmeeasy无壳,所以直接先运行一下:
随便输入一串数字:
拖入IDA,可以看到是strlen这个测字符串长度的函数,感觉从这个strlen入手会比较好一些
分析strlen这段:
text:00401340 add esp, 0FFFFFFF4h .text:00401343 lea eax, [ebp+Str] .text:00401346 push eax ; Str .text:00401347 call strlen //调用strlen .text:0040134C add esp, 10h .text:0040134F mov eax, eax //保存测试的字符串长度默认保存在eax .text:00401351 lea edx, [eax-1] //将eax-1的值传入edx .text:00401354 cmp [ebp+var_10], edx //前面已知ebp+var_10的值为0 .text:00401357 jb short loc_401360 //小于就跳转,跳转 .text:00401359 jmp short loc_401390 .text:00401359 ; --------------------------------------------------------------------------- .text:0040135B align 10h .text:00401360 .text:00401360 loc_401360: ; CODE XREF: DialogFunc+117j .text:00401360 mov eax, [ebp+lpString]//分析ebp+lpString为我们输入的字符串的首地址 .text:00401363 mov edx, [ebp+var_10] .text:00401366 add eax, edx .text:00401368 movsx edx, byte ptr [eax]//将eax地址中的值的一字节移到edx,即字符串中的一个字符 .text:0040136B lea eax, [edx-14h]//字符的ascll码值减20 .text:0040136E lea edx, [ebp+Str] //将ebp+str的结果传给edx .text:00401371 mov ecx, [ebp+var_10] .text:00401374 movsx edx, byte ptr [ecx+edx]//取出str这个字符串中的一个字符,地址为(ecx+edx),str字符串已知为"10445678951" .text:00401378 cmp eax, edx//比较是否相等 .text:0040137A jnz short loc_401389//不相等就跳转 .text:0040137C lea eax, [ebp+Str] .text:0040137F mov edx, [ebp+var_10] .text:00401382 mov byte ptr [edx+eax], 73h .text:00401386 inc [ebp+var_34]//地址ebp+var_34地址里的值加1 .text:00401389 .text:00401389 loc_401389: ; CODE XREF: DialogFunc+13Aj .text:00401389 inc [ebp+var_10]//地址ebp+var_10地址里的值加1
.text:0040138C jmp short loc_401340
text:0040138E align 10h .text:00401390 .text:00401390 loc_401390: ; CODE XREF: DialogFunc+119j .text:00401390 mov eax, offset aCorrect ; "Correct!" .text:00401395 mov edx, [eax] .text:00401397 mov dword ptr [ebp+Text], edx .text:0040139A mov edx, [eax+4] .text:0040139D mov [ebp+var_4C], edx .text:004013A0 mov al, [eax+8] .text:004013A3 mov [ebp+var_48], al .text:004013A6 lea eax, [ebp+var_47] .text:004013A9 add esp, 0FFFFFFFCh .text:004013AC push 1 ; Size .text:004013AE push 0 ; Val .text:004013B0 push eax ; Dst .text:004013B1 call memset .text:004013B6 add esp, 10h .text:004013B9 mov eax, offset aInvalid ; "Invalid!" .text:004013BE mov edx, [eax] .text:004013C0 mov dword ptr [ebp+Caption], edx .text:004013C3 mov edx, [eax+4] .text:004013C6 mov [ebp+var_5C], edx .text:004013C9 mov al, [eax+8] .text:004013CC mov [ebp+var_58], al .text:004013CF lea eax, [ebp+var_57] .text:004013D2 add esp, 0FFFFFFFCh .text:004013D5 push 1 ; Size .text:004013D7 push 0 ; Val .text:004013D9 push eax ; Dst .text:004013DA call memset .text:004013DF add esp, 10h .text:004013E2 mov eax, [ebp+var_10] .text:004013E5 cmp eax, [ebp+var_34]//比较地址ebp+var_34和ebp+var_10地址里的值,相等之后就输出corret .text:004013E8 jnz short loc_401400 .text:004013EA push 0 ; uType .text:004013EC lea eax, [ebp+Text] .text:004013EF push eax ; lpCaption .text:004013F0 lea eax, [ebp+Text] .text:004013F3 push eax ; lpText .text:004013F4 push 0 ; hWnd .text:004013F6 call MessageBoxA .text:004013FB jmp short loc_401411
这个总的比较过程就是:输入一个字符串,程序把输入的字符串与正确的字符串(10445678951)的长度进行比较,如果两个字符串长度相等,那么进行下一步,把输入的字符串逐个减20在于正确的字符串比较,若相等,匹配成功的个数加1,最后吧匹配成功的个数与字符串长度比较,若相等,就输出corret
反向计算,所以应该输入的字符串为:"EDHHIJKLMIE"
反向代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> int main() { char s[]={'1','0','4','4','5','6','7','8','9','5','1'}; int i; for(i=0;i<=strlen(s)-1;i++) printf("%c",s[i]+20); return 0; }
db就是一字节存放的意思,一字节就不区分什么大端小端
never give up