Log in

View Full Version : Little BruteMe ex.: Genetic Algorithm


ZaiRoN
May 31st, 2004, 14:20
Hi All !
This is not a crackme but a BruteMe and, the aim is to brute the algo in order to find one of the right serials.
The algo used in this BruteMe has been done to be simple, it's a stupid math formula. The main problem is to code a very fast bruter, it might be not so easy (There are 16 chars inside the serial....)

Which will be the best approach to the target? Is it possible to write a bruter that find a valid serial in... 4/5 seconds?

Good luck,
ZaiRoN

shaddar
May 31st, 2004, 20:12
hi there,

i think this may not be a true brute-forcing attempt but hey, it does work in under 5 secs. (hell, it doesn't even check if it's still calculating with "printable" characters). anyway, here's my ugly code

----------------snip--------------------

int _tmain(int argc, _TCHAR* argv[])
{
//char serial[] = "aAaAaAaAaAaAaAaA"; // these also work in under 5-seconds
//char serial[] = "1234567890123456";
//char serial[] = "zzzzzzzzzzzzzzzz";
char serial[] = "abcdefghijklmnop";
int sum = 0;
int targetsum = 134797;
int changeIndex = 0;
bool lastDir = true;


_recurse:
if( lastDir )
serial[changeIndex]++;
else serial[changeIndex]--;

for( int i = 0; i < 16; i++ )
{
sum += (int)serial[I] * (int)serial[I];
}
if( sum < targetsum )
{
if( lastDir )
{
if( changeIndex > 0 )
changeIndex--;
else changeIndex = 15;
}
else
{
if( changeIndex < 15 )
changeIndex++;
else changeIndex = 0;
}
lastDir = true;
}
else if( sum > targetsum )
{
if( !lastDir )
{
if( changeIndex < 15 )
changeIndex++;
else changeIndex = 0;
}
else
{
if( changeIndex > 0 )
changeIndex--;
else changeIndex = 15;
}
lastDir = false;
}
else if( sum == targetsum )
goto _finish;

sum = 0;
goto _recurse;

_finish:
printf( "yo serial is: %s", serial );
}

serial1: QSayZYZ[\]^_`XPQ
serial2: \[[SSdd\\\\\\\\[
serial3: YYZ[\[UgdXYZ[\]^
etc.

they look funny, but they work

edit: fixed typo

ZaiRoN
June 1st, 2004, 03:45
Hi Shaddar.
Well done, your approach is pretty nice and your program is fast enough (the check over the printable chars does not increase the speed of the program) :-).
Btw, what about if the sum is 16384; yes, you can change the starting serial but do you think it's possible to make your program independent from the final sum? I mean, something that works *fast* with every targetSum without changing the initial serial each time.

Are there others different techniques to use in this type of problems?

Best regards,
ZaiRoN

shaddar
June 1st, 2004, 13:49
Hey again,
ok check out the changes i made. just requires you to enter the no. of chars (the serial has) + the target-sum. funny thing is: with 16 chars and 16384 as targetsum you get 16 spaces as solution

Quote:
Are there others different techniques to use in this type of problems?


patching comes to mind

ZaiRoN
June 1st, 2004, 15:48
Hi shaddar,
nice work!
Quote:
patching comes to mind
What about Genetic Algorithm?

Zai

Aquatic
June 1st, 2004, 16:19
Hey shaddar, that's pretty 1337.

nice one

shaddar
June 1st, 2004, 16:59
thank you

sorry, i don't know much about genetic algorithms (+ isn't the implementation a bit too much work for the given target?), so wait for the pro's to post here

regards

ZaiRoN
June 2nd, 2004, 07:51
Quote:
[Originally Posted by shaddar]isn't the implementation a bit too much work for the given targe
Hmmm, maybe you are right but I need something *easy* to introduce this subject; we had spoken only few times and we never treated the subject in this forum. Take it as an introduction plus a simple example on coding a Genetic Algorithm .

--------------------------------------------------------------------------
The idea behind Genetic Algorithm is simple: you start with an initial population and then, applying some rules the population evolve, trying to reach the goal. In this case the goal is the value of the sum and the members of the population are the serials.

The scheme of a generic GA is:
Code:
BEGIN
1. Create the initial population
while (goal is not yet reached)
BEGIN
2. Calculate the fitness of every member of the population
3. Sort the population using the fitness value

4. if (goal is reached)
Solution is find, quit from the while

; --- Reproduction process ---
5. Elitism
6. CrossOver
7. Mutation
END
Print solution
END


1. Create the initial population
--------------------------------
The initial population is filled with random solutions. In this specific case we will have a lot of 16-chars_serial where each character it is choosen randomly. How many members should be in the population? It's not easy to answer to this question; with a big population you have the possibilities to explore much more solutions than a small population but on the other hand the process could take much more time... as you can see there is not a fixed rule and it's up to you to decide the size of the population.

2. Calculate the fitness of every member of the population
----------------------------------------------------------
For every different problem, we have to create a specific fitness function; the fitness function is the core of the GA. The function is applied to each member of the population; in this way, every member of the population will have a fitness *score*. The score represents the *distance* between the current solution and the goal solution. For many problems, like maths optimization problems, the fitness function is represented by the function itself. Due to the fact that the fitness function is a very important part of the GA process, it is fundamental to find a good fitness function if you want a nice GA.

3. Sort the population
----------------------
The population is sorted, with key equal to fitness value, from the best to the worst current solution. In this task you will have to apply a 'sort' algorithm to the population.

4. Check solution
-----------------
As suggested by the title, this is a simple check to find out if a member has reached the goal... nothing more.


Points number 5,6,7 are part of the reproduction process. These are the rules you can apply in order to evolve the population. You can use all of them or only some of them.

5. Elitism
----------
This strategy was born because when a new population is created there is the possibility to lose the best solution(s); the elitism is used to preserve few best solution(s). Elitism increases the performance of the GA.

6. CrossOver
------------
Crossover is a technique used to evolve the population. There are various version of this technique: One point crossover, Two point crossover, Uniform crossover, Partially Mixed Crossover and so on...
Which is the best? It's not easy to answer this question. I think that each version is suitable for a specific problem; for example, Partially Mixed Crossover is used for problem like 'Traveling Salesman'...
Here is a little description of some techniques:

- One Point Crossover(OPC): we have to choose a CrossOver Point, after that the children are created combining some genes of the father with some of the mother. I.e:
Code:

Father / Mother: 10110110 11100001
^ ^
| |
---------------- CrossOver Point

Children:
10110 + 001 = 10110001 <-- first part is taken from the father and the rest from the mother
11100 + 110 = 11100110 <-- first part is taken from the mother and the rest from the father


- Two point crossover: the idea behind is taken from the OPC. Each member is represented in a ring form, we have to find two crossover points and to exchange the genes of the father with the genes of the mother. I.e:
Code:

Father (10110110) and mother (11100001) in his circular form, the first gene is the one on the top:

1 1
0 0 <-| 1 1 <-|
1 1 | 0 1 |
1 1 | 0 0 |
0 | 0 |
^ | ^ |
| | | |
| ----------------------- First crossover point
| |
| |
| |
----------------------------------- Second crossover point

We will have children like:
1 + 1100 + 110 = 11100110 <-- start and end from father, middle from mother
1 + 0110 + 001 = 10110001 <-- start and end from mother, middle from father


- Uniform CrossOver: given two parents, a mask is used to decide which genes are taken from the father and which are taken from the mother. I.e.:
Code:

Father: 10110110
Mother: 11100001
Mask: 01001100 (1: take from the father, 0: take from the mother)
--------
Children: 10100101


7. Mutation
-----------
Mutation is a very important operation in the evolution process and, it's applied after Crossover. It consists on a simple mutation of a gene, nothing more. In some cases, it's possible to evolve the population with only this operation, removing the Crossover process (think about asexual reproduction...).


Well, (I hope) this might give you a little introdution to the Genetic Algorithm.
--------------------------------------------------------------------------

Now, we can try our first GA with this bruteme exercize...

Later,
ZaiRoN

shaddar
June 2nd, 2004, 13:52
wow, nice post zairon!

ok, i tried to come up with a prog for this, but oh well, the reproduction process is a bit confusing for me ( ok i get that about elitism but i wouldn't know how to use the other two in this case :hmm: )

this one also doesn't sort the population (yet? ). it just creates a random population over and over (bruteforceing again hehe). but please, take a look and tell me if this could be the (very!) basic shape of such a GA.

oh, btw. this time the serial consists only of printable chars at least

bye

ZaiRoN
June 2nd, 2004, 16:44
This is surely a nice start, you have defined a structure for each member, you have created the population... you are on the right way. There is a little error; the program calculates the fitness two times consecutively, the first one inside CreateInitialPopulation and the other in the 'for' statement. When you will introduce Crossover and Mutation you will surely remove it.

Now, the Crossover. Suppose you want to apply a OnePoint Crossover technique. What to do? Well, one way is to choose two random parents and to join them in order to create the children. Suppose that the 2 parents are:
father = "I am the father!"
mother = "I am the mother!"
and the crossover point is 10 (this number is also random... everything is random in GA :P). The children will be:
child1 = "I am the fother!"
child2 = "I am the mather!"

Following this method, the population evolves creating new members.

Mutation: you have to change a gene (or more genes) of a cromosome. You can exchange two bytes, you can change the 3° bit of the second byte, you can... be creative, you have the power and you define all the rules of the world

If you don't understand something else, tell me...

Good luck,
Zai

shaddar
June 2nd, 2004, 17:44
ok, i think i get that now

hmm...well, i don't think i'm going to put that in c++ code right now, since it really involves too much work. maybe someone else will come an do that

anyway, thx again for the lil' introduction , maybe comes in handy sometime

cu

ZaiRoN
June 3rd, 2004, 03:33
Quote:
since it really involves too much work
Are you sure? In this case you can write a GA in more or less 150 lines of c++ code, including comments and white line between instructions.
Why do you think it's too much work?

later...

shaddar
June 3rd, 2004, 10:38
Quote:
Are you sure? In this case you can write a GA in more or less 150 lines of c++ code, including comments and white line between instructions.

Hmm....ok i thought it would need a little more with elitisim, crossover + mutation. anyway....

Quote:
[Originally Posted by ZaiRoN]Why do you think it's too much work?

well, i think it's too much work because i already posted 2 other programs here that seem to solve the 'problem' of bruteMe

bye

ZaiRoN
June 13th, 2004, 10:46
A little genetic algo example...

314159265358979
June 18th, 2004, 18:02
Thanx you very much for this GA explanation, but I have one little question, is it necessary to sort entire population, isn't enought just find k best and then continue? I was thinking of some kind of heapsort, or just one cycle throught population to find the best one.

314159265358979

SvensK
June 20th, 2004, 04:37
Here's a quick asm keygen for it

ZaiRoN
June 20th, 2004, 11:33
314159265358979,
Quote:
isn't enought just find k best and then continue?
Yes; the purpose of the sort function is to find the best k members and then to use them in the evolve process. If you use a more fast way, that is great.


Svensk, and the source?

zai

SvensK
June 20th, 2004, 11:47
PM me if ya want the source. The only interesting thing is this:

Code:

begin:
mov serialSum, 0
lea esi, szSerial
mov ecx, keyLength
xor ebx, ebx

loop1:
xor eax, eax
lodsb ; Get Next Char
mul eax
add ebx, eax
loop loop1

mov serialSum, ebx
cmp serialSum, 20E8Dh ; Is Serial Sum = 20E8Dh ?
jne invalidserial


Regards
SvensK