忙碌了一周,虽然很辛苦,但屏幕上不时跳出的KEY还是会让我们信心倍增。这次参加西南某大学的信息安全大赛,收获挺多,也深刻了解到自己和大牛的差距,这里分享三个简单的逆向题。
比赛还有一个多小时就结束了,大家都没做题了,希望这时候发破文出来对比赛没有影响。
第一题:
这是一个非常简单的CrackMe,找注册码很容易,写注册机也只需简要分析。
首先载入OD,在GetDlgItemTextA函数处下断,运行后来到这里。
00401241 |. 6A 0A PUSH 0A ; /Count = A (10.)
00401243 |. 52 PUSH EDX ; |Buffer => CrackMe.0040300C
00401244 |. 68 F2030000 PUSH 3F2 ; |ControlID = 3F2 (1010.)
00401249 |. FFB5 FCFEFFFF PUSH DWORD PTR SS:[EBP-104] ; |hWnd
0040124F |. E8 1A010000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
00401254 |. 8D05 0C304000 LEA EAX,DWORD PTR DS:[40300C]
0040125A |. 50 PUSH EAX ; /Arg1 => 0040300C ASCII "Speday"
0040125B |. E8 2DFEFFFF CALL CrackMe.0040108D ; \CrackMe.0040108D
00401260 |. 8D15 0C304000 LEA EDX,DWORD PTR DS:[40300C]
00401266 |. 6A 0A PUSH 0A ; /Count = A (10.)
00401268 |. 52 PUSH EDX ; |Buffer => CrackMe.0040300C
00401269 |. 68 F3030000 PUSH 3F3 ; |ControlID = 3F3 (1011.)
0040126E |. FFB5 FCFEFFFF PUSH DWORD PTR SS:[EBP-104] ; |hWnd
00401274 |. E8 F5000000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
00401279 |. 68 20304000 PUSH CrackMe.00403020 ; /String2 = ""
0040127E |. 68 0C304000 PUSH CrackMe.0040300C ; |String1 = "Speday"
00401283 |. E8 3A010000 CALL <JMP.&kernel32.lstrcmpA> ; \lstrcmpA
00401288 |. 85C0 TEST EAX,EAX
0040128A |. 75 1B JNZ SHORT CrackMe.004012A7
0040128C |. 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040128E |. FF35 A1204000 PUSH DWORD PTR DS:[4020A1] ; |Title = "成功"
00401294 |. FF35 A5204000 PUSH DWORD PTR DS:[4020A5] ; |Text = "注册成功!"
0040129A |. FFB5 FCFEFFFF PUSH DWORD PTR SS:[EBP-104] ; |hOwner
004012A0 |. E8 E7000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
0040108D /$ 55 PUSH EBP
0040108E |. 8BEC MOV EBP,ESP
00401090 |. 83C4 F4 ADD ESP,-0C
00401093 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; 计算name字段的长度
00401096 |. 50 PUSH EAX ; /String
00401097 |. E8 2C030000 CALL <JMP.&kernel32.lstrlenA> ; \lstrlenA
0040109C |. 48 DEC EAX ; 长度减1,后面有用
0040109D |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
004010A0 |. 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
004010A3 |. 8D3D 20304000 LEA EDI,DWORD PTR DS:[403020]
004010A9 |. 33DB XOR EBX,EBX
004010AB |. 895D F8 MOV DWORD PTR SS:[EBP-8],EBX
004010AE |. EB 4B JMP SHORT CrackMe.004010FB
004010B0 |> 33C0 /XOR EAX,EAX
004010B2 |. 8A0433 |MOV AL,BYTE PTR DS:[EBX+ESI] ; 取name的第一个字符
004010B5 |. C1F8 04 |SAR EAX,4 ; 右移4位
004010B8 |. 8845 F7 |MOV BYTE PTR SS:[EBP-9],AL ; 存到变量中
004010BB |. 33D2 |XOR EDX,EDX
004010BD |. 8B45 F8 |MOV EAX,DWORD PTR SS:[EBP-8]
004010C0 |. B9 02000000 |MOV ECX,2
004010C5 |. F7F1 |DIV ECX ; eax=eax/2
004010C7 |. 33C0 |XOR EAX,EAX ; edx=eax%ecx
004010C9 |. 33C9 |XOR ECX,ECX
004010CB |. 83FA 01 |CMP EDX,1 ; 判断edx(余数)是否等于1
004010CE |. 74 0F |JE SHORT CrackMe.004010DF
004010D0 |. 8A4433 01 |MOV AL,BYTE PTR DS:[EBX+ESI+1] ; 取后一个字符
004010D4 |. C1E0 1C |SHL EAX,1C ; 左移28位
004010D7 |. C1E8 1C |SHR EAX,1C ; 右移28位
004010DA |. 83C0 41 |ADD EAX,41 ; 加上大写字母A的ascii码
004010DD |. EB 0D |JMP SHORT CrackMe.004010EC
004010DF |> 8A4433 FF |MOV AL,BYTE PTR DS:[EBX+ESI-1] ; 取前一个字符
004010E3 |. C1E0 1C |SHL EAX,1C ; 左移28位
004010E6 |. C1E8 1C |SHR EAX,1C ; 右移28位
004010E9 |. 83C0 61 |ADD EAX,61 ; 加上小写字母a的ascii码
004010EC |> 8A4D F7 |MOV CL,BYTE PTR SS:[EBP-9] ; 取出上面变量中存的值
004010EF |. 03C1 |ADD EAX,ECX ; 加在eax上
004010F1 |. 88043B |MOV BYTE PTR DS:[EBX+EDI],AL ; 存起来
004010F4 |. 8B5D F8 |MOV EBX,DWORD PTR SS:[EBP-8]
004010F7 |. 43 |INC EBX
004010F8 |. 895D F8 |MOV DWORD PTR SS:[EBP-8],EBX
004010FB |> 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004010FE |. 3BD8 |CMP EBX,EAX ; 判断是不是倒数第二个字符
00401100 |.^ 7C AE \JL SHORT CrackMe.004010B0
00401102 |. 8A0433 MOV AL,BYTE PTR DS:[EBX+ESI] ; 取最后一位字符
00401105 |. C1E0 1C SHL EAX,1C ; 左移28位
00401108 |. C1F8 1C SAR EAX,1C ; 右移28位
0040110B |. 83C0 31 ADD EAX,31 ; 加上数字1的ascii码
0040110E |. 88043B MOV BYTE PTR DS:[EBX+EDI],AL ; 存起来
00401111 |. 33C0 XOR EAX,EAX
00401113 |. 43 INC EBX
00401114 |. 88043B MOV BYTE PTR DS:[EBX+EDI],AL ; 末尾置0
00401117 |. C9 LEAVE
00401118 \. C2 0400 RETN 4
#include<stdio.h>
#include<string.h>
#include<windows.h>
main()
{
char name[100];
char key[100];
unsigned int i,j,a,b,c,d;
int m;
printf("Please input a name:\t");
scanf("%s",name);
j=lstrlen(name);
for(i=0;i<j-1;i++)
{
m=name[i];
a=m>>4;
c=a;
d=i%2;
if(d==1)
{
a=name[i-1];
a=a<<0x1c;
a=a>>0x1c;
a=a+0x61;
a=a+c;
key[i]=a;
}
else
{
a=name[i+1];
a=a<<0x1c;
a=a>>0x1c;
a=a+0x41;
a=a+c;
key[i]=a;
}
}
m=name[j-1];
m=m<<0x1c;
m=m>>0x1c;
m=m+0x31;
key[i]=m;
key[i+1]=0;
printf("The key is :\t%s\n",key);
getchar();
getchar();
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)