View Full Version : My Challenge To You
KSR0x2b
January 21st, 2002, 11:49
Maybe I cam across to strong about my opinion about this forum without giving any real help.
So here I will try: with the newbye in mind.
Ok I’ve looked through this forum quite a few times and could not find the examples that I am going to give you.
It was made by +RCG.
They are really easy but I think if you take the time and learn from them then you might be able to do some of these keygen that are here. I love to read about people looking to to increase their knowledge and I will assist every way possible to do that.
Well anyway here is a short snippet of the posting by +RCG and his examples. Download them and tell all how you were able to solve them.
By +RCG
Simple: download the first's three examples, and learn from them all you can, and then, try your own protections, use your mind, don’t ever be a zombie anymore, spend your useless TV hours developing your own protections schemes... it's fun and at the same time you will be preventing your premature cerebral deterioration (known as Alzheimer's disease) did you know that the TV-drooling zombies have a bigger probability to catch it?)
Read first the next guidelines. I know these first three examples are not the 'panacea' in programming neither in protections, but I think it's a good, and easy, framework for new byes.
Tips:
Example 1: A simple register code scheme.
Example 2: Like 1 plus a Nag Screen
(Find the trapdoor inside it)
Example 3: Just like 2 but a little Win Ice
Hostile :-( (You are able to recover the
System, use the stack to find the real
Return and restore the stack).
Well anyway there you have it:
Good Luck!
Kayaker
January 21st, 2002, 13:43
NICE! Examples designed to teach, progressing from a basic level to a bit more involved, with full source code so the student can learn the full workings of the code they are tracing, rather than just blindly cracking it and not really knowing why or how it works.
A blast from the +HCU past designed with the newbie in mind, but offering more than just an easy protection routine. This is great, I'd like to see some of the new members become involved in this forum. You are right KSR0x2b, that the encryption routines in some of the other projects are difficult, but that's OK because we want to offer challenges at all different levels.
But at the same time I **ENCOURAGE** newbies to feel free to participate and ask questions about anything they are unsure of. Please don't feel hesitant about joining in because you think you are not at the *apparent* level of what some of these projects may appear to be. Nothing makes me happier than seeing a new face (name?) of someone who is trying to learn and making an obvious effort at it.
These 3 examples in particular, I would like to see many new people give a try at. If you've always wanted to learn how to write a keygen or are just starting out or just want to make your presence known, this is a good project to get your feet wet and your brain fired up.
As always, read the manuals first and do some background research, but this is a Newbie-friendly forum that the 'uninitiated' should not feel uncomfortable asking questions in. There is always someone willing to help those who are giving an honest effort to increase their knowledge.
Have fun all, and thanks for contributing KSR0x2b
Cheers,
Kayaker
Woodmann
January 21st, 2002, 16:42
Howdy,
It's funny when I get to thinking about how to expand peoples
brains........
Next thing I know, someone has magically appeared!!
My thanks to KSROx2b.
Peace, Woodmann
UrgeOverKill
January 21st, 2002, 17:21
Very nice KSR! btw I am in the process of writing some tuts that can help newbies see the difference between using IDA and W32Dasm. Keeping in mind of very little assm knowkedge. Hopefully they will like it and contribute.
Sometimes its too easy to get lost in our tangents and go over the heads of ppl trying to learn.
Hoof Arted
January 22nd, 2002, 03:54
Thanks for the contribution. Just would like to say that the Example 1 and 3 crash in XP. Have not checked in Win2k. Anyway, Have had a look at 2 and I think that you have a very good idea here. This learning will be much more fun for newbies.
4oh4
January 22nd, 2002, 07:19
Examples 1 and 3 crash in 2kpro and 98se as well. At first I thought it might just be a 2k problem, but it's apparently with all os's.
Viper
January 23rd, 2002, 19:54
I can run the first two but the third one crashes with a gfp
BTW: im running on Win98SE
KSR0x2b
January 25th, 2002, 00:13
Just a few thoughts:
I have run all 3 examples on winxp winme win98 and win95. They work just fine for me.
Let me explain a little bit further on these examples.
The first one is no big deal.
Just register it.
Enter your name and then follow what it does with your name and then reverse it to get the key to enter the serial number.
The second one.
If you are running softice it will know it and crash the system if you try to debug it.
So you have to watch your stacks and follow it closely.
The third one.
This one is a beauty and is very hard to do. It is not for the beginner at all. This one is what we call modifying the code on the fly. I will post 2 very good essays on this example. Follow it closely. When they start writing programs like that it will be very hard to crack, but that is why we are here: So continue to seek that knowledge and grow in wisdom. And thus you have a birth of a mind. And they will say who was responsible for that and I will say Mea Culpa.
Good Luck All.
KSR+
4oh4
January 26th, 2002, 00:16
First off.....great idea. I had a bit of fun with example #2.
Second, example #2 IS the only one that will properly run on 98se or 2kpro (the only 2 windows os's I've got installed right now). I've got no reason at all to lie to you brother.
Example #2 occupied a couple of hours of my time and was a bit of fun. I didn't (and still haven't) looked at the source because I was afraid it would ruin my fun. I dare say that that's not much of a serial algo though.

But I suppose the point was to get the rest of us to code decent newbie-type crackmes/keygenmes eh.
Anyways, I'd like to be able to run the #1 and #3 crackmes but they keep error'ing out on me. In the meantime maybe I'll finally get around to coding a decent keygenme or even a good crackme.
thanks again, and if anyone gets #1 and/or #3 working on an english version of win98se or win2k let us know.
Kayaker
January 26th, 2002, 01:46
Hiyas,
For those of you having problems with #1 crashing on Win98SE, it must be some weird configuration error because, like some others, I have no problems with it on Win98SE (4.10.2222A). Sooo, what's the error you're getting? That's the beauty of reversing, it (should) allow us not to be enslaved by our OS or the software operating on it. Perhaps the error message or tracing in SI will give a clue to the source of the problem. I don't know what it might be though because there's nothing particularly unusual about it other than it uses an export table defining its own WndProc as an export.
As for #3 crashing, as KSR mentions this IS by design

. Rather interesting little implementation actually the way it uses an external file. There's probably many ways around it. I was actually thinking about implementing a loader for it to patch it in memory, or hook the interrupt it's using by modifying the IDT to redirect it to your own handler routine and return the value it's looking for, or any of the other documented ways of handling this (now old) Softice detection trick.
Other than the crashing problems, is anybody having difficulties with the rest of any of the crackmes?
Cheers,
Kayaker
KSR0x2b
January 27th, 2002, 11:19
Ok:
I am glad to see that we have people trying to crack this.
However all the recent post about the program not working on certain OS systems has made me look more into this. And I must say I have found the problem. So in the first exercise I have the program working on all OS systems. I like what I am reading but if you want to be a good reverse engineer then you must first make a program behave the way you want it to. Cracking a program is more then just trying to get a keygen or to make the program last past the trial time. It is making the program behave the way you want it to. Programmers are good people and they are good at what they do, but do not let somebody dictate to you how something should work especially since you have a brain and can think of a way to make it work better for yourself. So this first exercise is what I would call a bit of lagniappe you get to do 2 things. First make it work then crack it.
If you do not want the first challenge then here it is zipped and ready for you. However if you want the first challenge the figure it out trust me you can make it work on your OS.
If you need help trying to figure it out just let me know I will be more than glad to help you.
Happy Cracking:
KSR+
KSR0x2b
January 27th, 2002, 23:05
Upon playing around with example 1 some more.
I found that I did not patch it correctly.
Here it is patched right.
Download this one instead.
KSR0x2b
February 3rd, 2002, 18:10
I have been looking for a reply to Exer1. How are you coming along with it?
Well anyway I have a solution to it.
I hope you can understand it. I also wrote a keygen for it.
Just ask and I will give it to you.
Well anyway download the solution and try to follow it.
If you need help just ask.
4oh4
February 4th, 2002, 14:00
Just wanted to apologize. I've been so busy lately with real-life/work type stuff that I haven't had a chance to play with your exercises again. I do appreciate the effort and will try to budget some time to have a go at "fixing" #1.

crUsAdEr
February 4th, 2002, 14:55
I have just registered with the board recently and i would like to try the crackme but i cant download from teh link :<
vortex168
February 5th, 2002, 16:12
Whew. Just plowed through the Import table project from a little while ago. Jumped on that bandwagon a little late, but it's all squared away now.
KSR, these look like some great projects, I haven't looked at them too in-depth yet, just popping in to let everyone know that I'm going to start working on them and I'll be back (very soon probably) with questions. One other thing, just so it doesn't get redundant, KSR, does the solutions.zip have the solution for making project one work? I don't want to look at it myself because that'd kind of spoil things.
vortex
vortex168
February 12th, 2002, 22:59
I know I know, I'm hella slow at this. Walking through and getting it to pop up the Congrats menu was a walk in the park. Now I'm trying to work on a key gen for it but I'm having extreme difficulty with reversing the algorithm cuz I have zero exp with this and I can't tell what it's doing for the life of me.
I need some help with this 'get_code' function. I can't really figure out what on earth it's doing. Mainly this is because I don't understand the comments given at the beginning of the Includes.asm (ie. [ebp] = Ret Add).
Thanks a lot.
vortex
Kayaker
February 16th, 2002, 03:52
Hi vortex,
You still struggling with this question? Your best friend here is Softice itself and the 'd' display command. Try using 'dd esp' to display the stack just before the call to 'get_code' is made (CALL 00401417) and see how the addresses of the 2 parameters (offset CheckValue and offset Name_Buffer) have been "pushed" onto the stack (in esp). The first thing you see when you step into the call is a 'stack frame' being set up where the esp address is moved into ebp (the old ebp value being saved first).
get_code:
push ebp
mov ebp,esp
All the parameters pushed, including the return address (which is what [ebp] = Ret Add means), as well as any variables used, can now be referenced from ebp (called the frame pointer). This is what is meant in the includes.asm file.
Use the basic Softice commands such as 'dd esp+8' and 'dd *(esp+8)' (or 'dd esp.8') to follow along with what the keygen algorithm is doing and you should be able to reverse the algo. Check the contents of the registers being used before and after each step. Consult the Art of Assembly Language or some other doc for the usage of the shl and other commands. Use the search function of this board or Google and find some basic info on 'stack or stack frame' to understand how a Call is set up so you can recognize its structure in Softice.
If you're writing your own keygen in ASM this should give you a clearer idea of how to interpret what you see in SI. Hope this helps.
Kayaker
vortex168
February 16th, 2002, 20:04
Cool, ok, I worked out the algorithm and I understand how the whole thing works. I have a couple of questions though.
When you say that the Return Address is pushed, what does that mean? Like, does the top of the stack (i'm guessing that's what esp is pointing to) always have the address that the function is meant to return to?
And after finally understanding what the hell the code was doing, I was just wondering if that section that is labelled 'a2b' is a pretty common algo for changing from ascii to binary. Because I don't fully understand how it works. If someone could explain it to me it'd help me out a good deal.
On to #2....doesn't seem like it'll be too hard, but I know I'll hit a brick wall for #3 so you'll hear from me real soon. =)
vortex
Clandestiny
February 17th, 2002, 00:12
Quote:
Originally posted by vortex168
When you say that the Return Address is pushed, what does that mean? Like, does the top of the stack (i'm guessing that's what esp is pointing to) always have the address that the function is meant to return to?
|
Hiya vortex,
Well, I'll have a go at clarifying your first question...
Yup, you're right about that. When a program enters a function call (or handles an interrupt), it has to save its place in the code so it knows where to return to after the call or interrupt handler routine is done. This is accomplished by "pushing" (saving) the current address on the stack before the function is entered.
In the case of a 'near call', the prog only needs to remember the offset of the instruction it will return to. Therefore, only the instruction pointer (eip) register is pushed on the stack before entering the call. The call instruction implies a push eip.
near call == push eip ;push offset
During the course of the function's execution it may push or pop other items on the stack, but by the time the function reaches its final ret, it must have corrected the stack so that the the top element of the stack contains the original address of the instruction that the function will return to in the calling code. Interestingly, the ret instruction is no more than an implied pop eip.
ret == pop eip ;near return simply pops address from stack into eip register
In the case of a 'far call', the prog may be branching off to another code segment when it executes the function so it has to remember both the original code segment selector (cs) and the the offset of the instruction (eip). These actions are implied in the far call instruction.
far call == push eip ;push offset
push cs ;push code segment selector
A far call uses the retf to return to the original calling code. It must restore both the original code segment and the offset. Consequently, the retf is none other than an implied pop cs, pop eip (Remember that the stack is a LIFO "last in, first out" data structure. In other words, the last element pushed will be the first element popped off the top).
retf == pop cs ;restore the original code segment
pop eip ;restore the offset
Likewise, the interrupt is very similar to the far call, with an added step. When the prog looks up the interrupt service routine (function) it will execute in response to having recieved an interrupt, it too must save the offset and code segment selector so it knows where to return exectution in the code that generated the interrupt. Additionally, an interrupt routine goes through the added step of pushing the flags on the stack.
interrupt implies:
push eip ;push offset
push cs ;push code segment selector
pushfd ;push flags
The interrupt uses the iret instruction to return to the original place in the code that generated the interrupt after it has completed servicing the interrupt. The iret is consequently the implied sequence of instructions popfd, pop cs, pop eip.
iret == popfd
pop cs
pop eip
And an iret could therefore be "emulated" with this sequence of instructions. Likewise, we can see that the iret is also equivalent to a popfd, retf and could be "emulated" by also using these 2 instructions.
iret == popfd
retf
Hope this helps to clarify matters a little bit
Regards,
Clandestiny
vortex168
February 17th, 2002, 22:37
Whew! Nice post Clandestiny, it helped a load!
I blew through challenge 2 with no problems, but now I'm trying challenge 3. I haven't even actually disassembled it, because I want to try to figure out this 'use the stack to find the real return and restore the stack' thing. So I fired up the program and got thrown into sice with a beautiful screen full of INVALID
INVALID
INVALID
...
So I decided to check out what the stack was pointing to. And there I couldn't figure out what to do...
I looked at the stack and even though I might suspect some things to be the 'real return', I don't know how to implement it. I tried modifying eip to be what looked like an address (the first thing the stack was pointing to), but that didn't do any good. Any advice or texts you guys would recommend? And another thing, I tried d/ling FrogsIce hoping to get around it, but I have no clue how to use FrogsIce. Can someone refer me to some kind of use-me guide? Thanks again for all the help!
Vortex
Clandestiny
February 18th, 2002, 12:41
Hiya vortex,
You can actually prevent the prog from crashing by modifying the stack in memory inside SI, but this will not cure the underlying cause of the stack corruption which occurs deliberately in consequence to winice being detected. If you look at the stack when you reach that final ret, your stack will look something like this...
00000000 BFF8B560 00000000 817D5420 .....
Now, we know the ret instruction is equivalent to a pop eip... BUT looking at our stack, we can see the top value that will be popped into eip will be 00000000. This is obviously an invalid address and we can conclude that the stack has been corrupted. The next value, however, (BFF8B560) looks a lot more promising. I recognize the BFFXXXXX address range as belonging to a system dll and I can even disassemble it in memory to see what it is if I want (u BFF8B560 in SI). It ends up being Kernel function that is executed when control returns from the program back to the OS. ...Realizing this, we can prevent our prog from crashing if we remove (pop) the 00000000 from the stack before the ret. After removing the 0, our stack will point to the valid return address in kernel code. You can test this out using the SI 'a' (assemble) command when you get to that ret instruction.
a eip
pop eax ;remove the 00000000 from the stack
ret ;esp now points to a valid return address
//******************** Program Entry Point ********
:00401000 6A00 push 00000000
:00401002 E82D050000 call 00401534 //check for SI
:00401007 3D48434142 cmp eax, 42414348 //if SI detected, then crash
:0040100C 7431 je 0040103F //jump to exit prog
:0040100E 90 nop
:0040100F 90 nop
.
.
.
.
:0040103F C3 ret //stack corruption - crash here if SI detected
Making this change in memory just illustrates stack manipulation concepts. It does not, however, correct the real problem (which is the detection of SoftICE). BTW, forget about FrogSICE or IceDump on this one... Using these tools would definately be overkill

Besides, it'll be more educational to find the check yourself

. Now, I don't want to spoil the fun so I'll just give you a little hint. I'm attaching a document containing a description of several anti-SoftICE tricks (and their fixes). Read through this doc, and I guarantee you you'll come accross something familiar in your little target
Good Luck,
Clandestiny
Clandestiny
February 18th, 2002, 14:01
Quote:
Originally posted by Kayaker
I was actually thinking about implementing a loader for it to patch it in memory, or hook the interrupt it's using by modifying the IDT to redirect it to your own handler routine and return the value it's looking for, or any of the other documented ways of handling this (now old) Softice detection trick.
|
Umm... I see where you're going with that, but don't you think that might be overkill on this particular example
I didn't see anything that said patching wasn't allowed
Cheers,
Clandestiny
Kayaker
February 18th, 2002, 17:41
Quote:
Originally posted by Clandestiny
Umm... I see where you're going with that, but don't you think that might be overkill on this particular example 
I didn't see anything that said patching wasn't allowed
Cheers,
Clandestiny |
LOL. Are you kidding? Total Overkill. I was just hoping someone might take the idea and run with it, /myself being too lazy to attempt it
I didn't see anything that said overkill wasn't allowed either
Nice to see you back on the forum btw,
Kayaker
vortex168
February 21st, 2002, 20:04
Hm, so I patched the program so it works. Except, I get an error when I run it. I know it works though, because when I use w32dasm's debugger and load/run it, it works fine. No idea why, I'm not quite that good at reversing to be able to figure that out...
Question though, Kayaker said something about modifying code on the fly, I didn't really see that in the anti-sice code, were you referring to something else? and did you ever get around to putting up those essays on that stuff?
thanks
Vortex
Kayaker
February 21st, 2002, 22:33
Hi Vortex,
I guess I was just trying to remind people to look at every possible angle in attempting to patch exercise 3. Having the source to look at seems to give a bit of latitude for creativity here in particular. I see the examples were downloaded something like 114 times (Woohoo!) which is great (or 1 person d/l it something like 100 times, which isn't great), so I don't want to give too much away if it's still being worked on.
However, one of the interesting things about ex.3 is that it uses an external file to hardcode the call address to the Softice detection routine. In itself this is weak simply because it's a very simplified situation, but if the file was encrypted and the address(es) to various call functions were decrypted runtime, this would give another layer of protection. You can patch the program somewhere after the Sice detection, but you could also patch the external file to point to an address that you wanted to that would bypass the Sice detection entirely. This is one option, though not much more elegant than patching the program itself.
Another option, and one you might want to explore because this is sort of the "next step" in stupid reversing tricks, is to modify the program with an inline patch which gets around the protection. For example, right before the indirect call that contains the address from the external file which points to the Sice detection routine itself are 4 nops. This could be a starting point from which to jump to an empty area of the code section and somehow *change* the address that will be called to one you want.
In the check.asm file this call is
call [Call_Table+0] ;CheckIce
[Call_Table+0] is defined in the main exerc3.asm file as a 64 byte table, the 0 is an index into that table.
Call_Table dd 64 dup (' ') ;Store call addresses.
Another place to put an inline patch might be right after the Sice detection routine itself, leaving the original call to it alone. Again there are 4 nops immediately afterwards that you can use to begin building an inline patch. Since it's obvious that the routine is looking for AX to still contain the value 4 after the INT 3 if Softice isn't installed, then you just need to create a patch which ensures ax will always contain 4, and then replace the original code and anything else you've overwritten.
CheckIce:
push ebp
mov ebp,"BCHK"
mov ax,4
int 3
cmp ax,4
jne Ice_Installed
xor eax,eax
Check_Ret: pop ebp
ret
For example, to start the patch, immediately after the INT 3 you'd patch in a
jmp <some address in a writeable section of the program>
Then at that address you'd patch in the bytes which might look like:
mov ax, 4
jmp back
It's actually a little more involved than this because you have to take into account the number of bytes taken for a far jump (6) and emulate any missing code etc., but you get the idea. There are several tuts on the main site that use inline patching that you can read to try this out if you wish. HIEW is probably the hex editor of choice with which to create an inline patch, and you'll need to learn about finding 'empty' places in code in which to write your patch and ensure that the Code Characteristics of the section is writeable. As a start, I detail this in my TracePlus and Regmon essays, but many others have nicely described the procedure as well over the years. Check out Lord Rhesus' Pages of Code Injection for several good ones.
http://oberon.spaceports.com/~codeinj/
Anyway, just a couple of ideas for something you might want to try that's a little more fun, and ultimately more useful, than a straight JNZ patch. As for my 'overkill' ideas :-) about creating a loader or hooking the interrupt, these were just fanciful ideas which in reality if anyone wanted to do them they'd probably already be doing them on something more important than this crackme, hehe ;-)
BTW, if you have Icedump running, the app *will* crash when it steps over that INT 3 no matter what, this is sort of a 'bug' with Icedump.
Have fun,
Kayaker
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.