#16のKG(コンソール)
はい〜。こんにちは。
16にやってきました。
これは、ちょっとややこしいけど、全体を把握しながらやっていけば簡単です。
時間もないのでチャチャっと書きます。
まず全体を見てみましょう。
12345-67890-ABCDE-FGHIJ
こうあるとすれば
FGHIJからABCDEを作り・・・と後ろから作ってゆけば良かったですね。
途中で一部 '-' を読みとる部分がありました。
普通にトレースすると、最後らへんの
00401419 |> 0FBE4431 04
|/MOVSX EAX,BYTE PTR
DS:[ECX+ESI+4]
ここです。どう考えても'-'を使います。
それでは、変数から作りましょう。今回は全部最初に作ります。
言い忘れましたが、このKGはは2種類作れます。
パスを表示する方法、と、KEYファイルを作る方法です。
今回はKEYファイルを作ろうと思っています。
では、変数に戻りまして。
まずループがあります。ループの中にループがあるので
int
i,j;
です。次は、パスを保管する変数、パスの一区切りを保管する変数、256個のキーを保存する変数です。
char
seri[4][6],id[6]="-",key[256];
さて、seriが気になったと思います。
これは、一区切りずつを配列の配列で表そうと思ったのでこう書きました。
idは、一区切りを保存します。(いい名前が思いつかなかった:汗)
"-" が最初から設定しているのは、上でも書いた通り'-'を使うので最初に書いておきました。
さて、あとはキーを作る時に計算が入ります。二つ必要なので
unsigned long x,y;
ファイルを出力するので
FILE
*fp;
FILEは全部大文字です。
さて、中身に入っていきます。
まず最後の5文字を作りましょう。
最後は
1文字目は1〜9、2文字目はA〜Z、3文字目はa〜z、4文字目はE〜U、5文字目はk〜s と考えられます。
(図書室調べ)
ですので、範囲内で考えましょう。
作るのに当たって15でも使ったrand()を使います。
まず、同じパターンにならないように
srand((unsigned)time(NULL));
を書きます。次にランダムで文字を決めるのですが、範囲内に持ってくるために
seri[3][0] = id[1] = rand()%9 + 0x30;
seri[3][1] = id[2] =
rand()%25 + 0x41;
seri[3][2] = id[3] = rand()%25 + 0x61;
seri[3][3] =
id[4] = rand()%16 + 0x45;
seri[3][4] = id[5] = rand()%8 +
0x6B;
こうします。
最後の部分から作るのでseriにも書き込んでおきます。
後で書くとめんどくさいのでseriに'-'も書き込んでおきましょう
seri[0][5] =
seri[1][5] = seri[2][5] = '-';
これで、最後の5文字は決定しました。
計算に入って行きます。
004013EB |. B9 03000000 MOV ECX,3
004013F0 |> 51
/PUSH ECX
ここから大きなループがあります。
3回ループなので
for(i=3;i>0;i--){
回ってくるたびにxを初期化しましょう。
x=0;
さて、次行きます。
004013F1 |. B9 05000000 |MOV ECX,5 004013F6 |. 33D2 |XOR EDX,EDX 004013F8 |> C1E2 04 |/SHL EDX,4 004013FB |. 0FBE4431 05 ||MOVSX EAX,BYTE PTR DS:[ECX+ESI+5] 00401400 |. 83E0 0F ||AND EAX,0F 00401403 |. 0BD0 ||OR EDX,EAX 00401405 |.^E2 F1 |\LOOPD SHORT crkme16.004013F8
この部分は、5回ループですね。
for(j=5;j>0;j--){
で、SHL4がありますので
x
<<= 4;
その後は、入力したパスから1文字読みとって&0xfをしてEDXにおさめています。ですので
x |= id[j] & 0xf;
}
これでイイです。(id[0]は'-'なので)
次は256キーを作ります。
0040102E |. B9 00010000 MOV ECX,100 00401033 |> 51 /PUSH ECX 00401034 |. 8BC3 |MOV EAX,EBX 00401036 |. B9 3E000000 |MOV ECX,3E 0040103B |. 33D2 |XOR EDX,EDX 0040103D |. F7F1 |DIV ECX 0040103F |. 83FA 09 |CMP EDX,9 00401042 |. 77 05 |JA SHORT crkme16.00401049 00401044 |. 83C2 30 |ADD EDX,30 00401047 |. EB 0D |JMP SHORT crkme16.00401056 00401049 |> 83FA 23 |CMP EDX,23 0040104C |. 77 05 |JA SHORT crkme16.00401053 0040104E |. 83C2 37 |ADD EDX,37 00401051 |. EB 03 |JMP SHORT crkme16.00401056 00401053 |> 83C2 3D |ADD EDX,3D 00401056 |> 59 |POP ECX 00401057 |. 8891 7F304000 |MOV BYTE PTR DS:[ECX+40307F],DL 0040105D |. 81F3 5B7CCB3D |XOR EBX,3DCB7C5B 00401063 |. 81C3 F56ED76F |ADD EBX,6FD76EF5 00401069 |. C1C3 07 |ROL EBX,7 0040106C |.^E2 C5 \LOOPD SHORT crkme16.00401033
EBXをEAXに写し3Eで割っています。
とりあえず、xの値をyに保管しましょう
y=x;
次に、xを0x3Eで割るのですが、あまりを使っているので
x
%= 0x3e;
となります。さて、次は、数字か大文字か小文字に分けています。
分け方は個人の自由です。そのまんまでもイイですし、私の場合は、成り行きに任せていたらこうなりました。
if(x
> 9){
if(x >0x23){
x += 0x3d;
} else {
x += 0x37;
}
}
else {
x += 0x30;
}
そして、その結果keyに保存していきます。
注意は、0は最後に通らないので
key[j-1] =
x;
こうなります。いや、めんどくさかったら最初に0xFF>=0、でもいいんですよ。
いや、むしろそっちの方が・・・
で、最後に計算があります。見たまんまですので、説明はしません
x = _lrotl(((y ^
0x3dcb7c5b) + 0x6fd76ef5),7);
}
解らなかったら掲示板にでも・・・と、逃げてみる(^^;
これで、256keyが作れました。
おぅ、あと20分しかない(私の勝手な時間ですが:笑)
ラストスパートです。
00401410 |. B9 05000000 |MOV ECX,5 00401415 |. C60439 00 |MOV BYTE PTR DS:[ECX+EDI],0 00401419 |> 0FBE4431 04 |/MOVSX EAX,BYTE PTR DS:[ECX+ESI+4] 0040141E |. F7E1 ||MUL ECX 00401420 |. BB FF000000 ||MOV EBX,0FF 00401425 |. F7F3 ||DIV EBX 00401427 |. 0FBE82 8030400>||MOVSX EAX,BYTE PTR DS:[EDX+403080] 0040142E |. 884439 FF ||MOV BYTE PTR DS:[ECX+EDI-1],AL 00401432 |.^E2 E5 |\LOOPD SHORT crkme16.00401419
この部分をやっちゃいましょう。
まずは5ループ
for(j=5;j>0;j--){
でパスを作り出す文字の4文字目から321文字と抜き取り最後に'-'を抜き取ります。
作り出す部分ですので、今のid[6]でいいです。
その抜き出した文字にECX=ループ回数をかけて、0xFFを割ります。
あまりを使うので%を使います。
x = (id[j-1]*j) % 0xff;
j-1の部分は4文字目からだからです。
そして、その結果のxを使い、key[x]でパスが抜き取れます。ループする計算に向けてidとパスに書き込んでおきましょう
seri[i-1][j-1] = id[j] = key[x];
}
}
これで、終わりです。
ループがすべて終わるとあとは、ファイルに書き出すだけです。
まずファイルをオープンします。
fp = fopen("crackme16.ini","w+");
crackme16.iniを言うファイルをw+と言うモードで開きます。
w+、というのは、ファイルがあれば上書きで作り直し、無ければ作る。というモードです。
ですので、何度実行しても、ファイルは一つと言うことです。
一応、ファイルが無かった場合の処理を書きます。(何かで作れなかった場合など)
if(fp ==
NULL){
printf("きゃ〜。緊急脱出!");
exit(-1);
}
exitは、プログラムを終了します。
急に終了しても意味がわからないので、何かメッセージを書いておきましょう。
そして、ファイルに書き込みます。
fprintf(fp,
"%s", "[Regist]\nSerial=");
fprintf(fp, "%s",seri);
printfにfを付け加えただけです
最初のfpは、そのファイルに書くか、後はprintfと同じです。
seriは多重配列(だったかな?)ですが、こう書けば最初から書き出していってくれます。終わりまで
あとは、ファイルをクローズして、出力したメッセージを書きます。
fclose(fp);
printf("keyファイル[crackme16.ini]を出力しました。\n"
"crkme16.exeと同じフォルダーに入れて起動して下さい。");
getch();
return 0;
}
で、終わりです。
まとめたソース書いておきます。
#include <tdio.h> #include <dlib.h> #include <time.h> #include <conio.h> int main(){ char seri[4][6],id[6]="-",key[256]; int i,j; unsigned long x,y; FILE *fp; srand((unsigned)time(NULL)); seri[3][0] = id[1] = rand()%9 + 0x30; seri[3][1] = id[2] = rand()%25 + 0x41; seri[3][2] = id[3] = rand()%25 + 0x61; seri[3][3] = id[4] = rand()%16 + 0x45; seri[3][4] = id[5] = rand()%8 + 0x6B; seri[0][5] = seri[1][5] = seri[2][5] = '-'; for(i=3;i>0;i--){ x=0; /* 004013F8 |> C1E2 04 |/SHL EDX,4 〜 00401405 |.^E2 F1 |\LOOPD SHORT crkme16.004013F8 */ for(j=5;j>0;j--){ x <<= 4; x |= id[j] & 0xf; } /*キーワード作り 0040102E |. B9 00010000 MOV ECX,100 00401033 |> 51 /PUSH ECX 00401034 |. 8BC3 |MOV EAX,EBX 〜 00401069 |. C1C3 07 |ROL EBX,7 0040106C |.^E2 C5 \LOOPD SHORT crkme16.00401033 */ for(j=0x100;j>0;j--){ y=x; x %= 0x3e; if(x > 9){ if(x >0x23){ x += 0x3d; } else { x += 0x37; } } else { x += 0x30; } key[j-1] = x; x = _lrotl(((y ^ 0x3dcb7c5b) + 0x6fd76ef5),7); } /* 00401410 |. B9 05000000 |MOV ECX,5 00401415 |. C60439 00 |MOV BYTE PTR DS:[ECX+EDI],0 00401419 |> 0FBE4431 04 |/MOVSX EAX,BYTE PTR DS:[ECX+ESI+4] 0040141E |. F7E1 ||MUL ECX 00401420 |. BB FF000000 ||MOV EBX,0FF 00401425 |. F7F3 ||DIV EBX 00401427 |. 0FBE82 8030400>||MOVSX EAX,BYTE PTR DS:[EDX+403080] 0040142E |. 884439 FF ||MOV BYTE PTR DS:[ECX+EDI-1],AL 00401432 |.^E2 E5 |\LOOPD SHORT crkme16.00401419 */ for(j=5;j>0;j--){ x = (id[j-1]*j) % 0xff; seri[i-1][j-1] = id[j] = key[x]; } } fp = fopen("crackme16.ini","w+"); if(fp == NULL){ printf("きゃ〜。緊急脱出!"); exit(-1); } fprintf(fp, "%s", "[Regist]\nSerial="); fprintf(fp, "%s",seri); fclose(fp); printf("keyファイル[crackme16.ini]を出力しました。\n" "crkme16.exeと同じフォルダーに入れて起動して下さい。"); getch(); return 0; }
はい、終わりです。
今回は、説明が少なかったかと思います。
ちょっと解らないことは、自分なりに考えてみてください。
それでも、ダメなら気軽に聞いて下さいね〜♪
それでは、#16を終わります。例っ!(笑