To help you i wrote a quick tutorial just a few minutes ago, Lol. Bypassing as
always been easier then KeyGenerating for me but here's the basic concept at least?:
I started with a C++ program to use as example, I realize this is a Visual Basic Section but these are basic functions easy to transfer and the Assembly is the focus, anywho:
Code:
#include <iostream>
using namespace std;
int main() {
int x;
int y;
int z;
cout<<"Please enter number: \n";
cin>>x;
y=x*2;
y+=1;
cout<<"Please enter Serial Key: \n";
cin>>z;
if ( y == z ) {
cout<<"Correct Welcome! \n";
}
else {
cout<<"You fail, bye \n";
}
system("pause");
}
So compiled into an exe like the program you want to keygen, we run it,
Attach it with OllyDBG...REWIND, Scroll Down - find the function in dissasembly:
Obviousally reversing skills are a must. After noting out each part - you'll inevitably run across:
Code:
...(start removed unnececary for example)
...
004013BA |. C74424 04 0000>MOV DWORD PTR SS:[ESP+4],Untitled.004400>; ASCII
"Please enter number:
"
004013C2 |. C70424 C033440>MOV DWORD PTR SS:[ESP],Untitled.004433C0
004013C9 |. E8 FAAC0300 CALL Untitled.0043C0C8
004013CE |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
004013D1 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
004013D5 |. C70424 6034440>MOV DWORD PTR SS:[ESP],Untitled.00443460
004013DC |. E8 AF6D0200 CALL Untitled.00428190
004013E1 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004013E4 |. 01C0 ADD EAX,EAX
004013E6 |. 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
004013E9 |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
004013EC |. FF00 INC DWORD PTR DS:[EAX]
004013EE |. C74424 04 1700>MOV DWORD PTR SS:[ESP+4],Untitled.004400>; ASCII
"Please enter Serial Key:
"
004013F6 |. C70424 C033440>MOV DWORD PTR SS:[ESP],Untitled.004433C0
004013FD |. E8 C6AC0300 CALL Untitled.0043C0C8
00401402 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
00401405 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
00401409 |. C70424 6034440>MOV DWORD PTR SS:[ESP],Untitled.00443460
00401410 |. E8 7B6D0200 CALL Untitled.00428190
00401415 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00401418 |. 3B45 F4 CMP EAX,DWORD PTR SS:[EBP-C]
0040141B |. 75 16 JNZ SHORT Untitled.00401433
0040141D |. C74424 04 3200>MOV DWORD PTR SS:[ESP+4],Untitled.004400>; ASCII
"Correct Welcome!
"
00401425 |. C70424 C033440>MOV DWORD PTR SS:[ESP],Untitled.004433C0
0040142C |. E8 97AC0300 CALL Untitled.0043C0C8
00401431 |. EB 14 JMP SHORT Untitled.00401447
00401433 |> C74424 04 4500>MOV DWORD PTR SS:[ESP+4],Untitled.004400>; ASCII "You
fail, bye
"
0040143B |. C70424 C033440>MOV DWORD PTR SS:[ESP],Untitled.004433C0
00401442 |. E8 81AC0300 CALL Untitled.0043C0C8
00401447 |> C70424 5500440>MOV DWORD PTR SS:[ESP],Untitled.00440055 ; |ASCII
"pause"
0040144E |. E8 8DF20000 CALL <JMP.&msvcrt.system> ; \system
00401453 |. B8 00000000 MOV EAX,0
00401458 |. C9 LEAVE
00401459 \. C3 RETN
Remember, direct numerical input stores in EAX on default. You can see how they move it into accessible pointers slowly which serves no more then to trick you, in my book.
The primary focus here is the only two times memory is mathetmatically manipulated in value...
004013E4 |. 01C0 ADD EAX,EAX
004013EC |. FF00 INC DWORD PTR DS:[EAX]
Noted they move EAX elsewhere as well as mentioned above, it's still added, and EAX is still increased (+1) , after being doubled, as the only two direct value manipulations...
Therefore your keygenerator is no other then
Code:
#include <iostream>
using namespace std;
int main(){
int x;
int y;
cout<<"Please enter number: \n";
cin>>x;
y=x*2;
y+=1;
cout<<"Serial Key Is: \n";
cout<<""<<y<<"";
system("pause");
}
Done, hope it helps at least a lil...