Page 1 of 2 12 LastLast
Results 1 to 15 of 30

Thread: Harlequins Task 3 Challenge

  1. #1
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries

    Harlequins Task 3 Challenge

    Hi All,

    Mitrix posted a question on one of the tasks in Harlequin's course. After looking at it I thought it was so good that I thought it'd make a great Project. Since it's actually the final task of a section and I think the course should be started from the beginning without giving away the answers to the previous task, I deleted the original link Mitrix had posted and will just post the download link for Task 2/3:

    In case of difficulties (I couldn't d/l it with Opera), I'll attach it here (11KB zip)

    Here is what Harlequin says about this task:

    "I should warn you here though, this is the last Task in this section and as such is therefore the most difficult. Some may struggle with this one a little. I can only assure you that in the CodeWoods things are not always as they seem, there is (despite everything you may think) a solution to this task and, if you have made it this far you have more than the skills required to complete it successfully."

    The rest is self-explanatory, find the correct serial number. I've posted Mitrix's original post and my reply.

    I encourage you to try the complete course, which begins at:

    Good Luck,

  2. #2
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    ORIGINAL POST (slightly modified):

    In the program the DD [0040209F] is 00401124 and the [00401124] is E8. I think it should be EB.

    :00401124 E8B5000000 Call 004011DE
    :00401129 83F80A cmp eax, 0000000A
    :0040112C 757B jne 004011A9
    :0040112E BAA7204000 mov edx, 004020A7
    :00401133 33DB xor ebx, ebx \
    :00401135 8A1A mov bl, byte ptr [edx] |
    :00401137 42 inc edx |
    :00401138 33C0 xor eax, eax \the first serials must 4
    :0040113A 8B0D9F204000 mov ecx, dword ptr [0040209F] /
    :00401140 8A01 mov al, byte ptr [ecx] |
    :00401142 80F3DC xor bl, DC |
    :00401145 3AD8 cmp bl, al /
    :00401147 7560 jne 004011A9
    :00401149 8A02 mov al, byte ptr [edx]
    :0040114B 42 inc edx
    :0040114C 3430 xor al, 30
    :0040114E C1E008 shl eax, 08
    :00401151 8A02 mov al, byte ptr [edx]
    :00401153 42 inc edx
    :00401154 3430 xor al, 30
    :00401156 C0E004 shl al, 04
    :00401159 66C1E804 shr ax, 04
    :0040115D 8A1A mov bl, byte ptr [edx]
    :0040115F 42 inc edx
    :00401160 2AC3 sub al, bl
    :00401162 3C3C cmp al, 3C
    :00401164 7543 jne 004011A9
    :00401166 B104 mov cl, 04
    * Referenced by a (U)nconditional or ©onditional Jump at Address:
    :00401168 8A02 mov al, byte ptr [edx]
    :0040116A 42 inc edx
    :0040116B 3433 xor al, 33
    :0040116D 2C03 sub al, 03
    :0040116F 3AC1 cmp al, cl
    :00401171 7536 jne 004011A9
    :00401173 FEC9 dec cl
    :00401175 80F900 cmp cl, 00
    :00401178 75EE jne 00401168
    :0040117A 668B02 mov ax, word ptr [edx]
    :0040117D 663D3033 cmp ax, 3330
    :00401181 7526 jne 004011A9
    :00401183 A0A7204000 mov al, byte ptr [004020A7]
    :00401188 3C37 cmp al, 37 ; the first serials must 7
    :0040118A 751D jne 004011A9
    :0040118C 6A00 push 00000000

  3. #3
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    Hi Mitrix,

    Looks that way doesn't it? As you mention, the 1st part of the algorithm

    :00401124 E8B5000000 Call 004011DE ;GetDlgItemTextA
    :00401129 83F80A cmp eax, 0000000A ;length must be 10
    :0040112C 757B jne 004011A9
    :0040112E BAA7204000 mov edx, 004020A7 ;your entered s/n
    :00401133 33DB xor ebx, ebx
    :00401135 8A1A mov bl, byte ptr [edx] ;1st char of s/n
    :00401137 42 inc edx
    :00401138 33C0 xor eax, eax
    :0040113A 8B0D9F204000 mov ecx, dword ptr [0040209F] ;address 401124
    :00401140 8A01 mov al, byte ptr [ecx] ;1st byte of opcode (E8 )
    :00401142 80F3DC xor bl, DC ;xor 1st char s/n w/ DC
    :00401145 3AD8 cmp bl, al ;must be = E8
    :00401147 7560 jne 004011A9

    If 1st char XOR DC = E8
    DC XOR E8 = 1st char = 34h = 4

    The 1st char MUST be 4 then. However, the last part of the algorithm indicates it MUST be 7:

    :00401183 A0A7204000 mov al, byte ptr [004020A7]
    :00401188 3C37 cmp al, 37
    :0040118A 751D jne 004011A9

    Can't be both. Harlequin must've goofed. Nope. (I love this guy's work

    You followed the algorithm perfectly and came to the conclusion Harlequin wanted you to come to. As a matter of fact, I like this one so much I hope you'll forgive me if I move it to the Mini Project Forum, I think it'll make a great project and there's some interesting instruction to come out of it.


  4. #4
    Hi Kayaker,

    I've taken a look at this and i know this guy's work it's always quite funny
    But anyway, i don't know if you have a valid Serial but i have a valid "bugged" Serial ;D
    I'm not going to tell more, i think
    Just tell me if you got that too....?


    I promise that I have read the FAQ and tried to use the Search to answer my question.

  5. #5
    Hi Kayaker,

    Not quite the garden variety serial fishing / key gen exercise, but you wouldn't know it until that little caveat at the end

    So far I've generated a serial that passes all checks but the last... But I have made a couple of observations about both the first and last checks (ie. the significance of E8 vs. EB). Interestingly, I noticed that in the following lines ecx actually holds the pointer to an address within the proggy's code section.

    :0040113A 8B0D9F204000 mov ecx, dword ptr [0040209F]
    :00401140 8A01 mov al, byte ptr [ecx]

    This address corresponds to
    :00401124 E8B5000000 Call 004011DE

    And hence you get your E8 from the hex opcode for "call" in the function call to GetDlgItemTextA. Now in the last check, we'd rather this E8 be EB because this would allow the first check to pass with a 7 (ie 37h) rather than a 4 (34h). Making this realization, I looked up what EB is in my asm hex opcode reference and its apparently a jmp command. So the only thing I can come up with as of yet to make a valid serial is to change the instruction at address 00401124 from a call to a jump. BUT I'm not quite sure that you can jump directly to an API like GetDlgItemTextA because you would ultimately need to jump back to the correct position in the code from where you made the original jump in order to continue execution since a jump doesn't return like a call does. I haven't actually tried this yet, but I guess you could maybe write a patch that simulates the process that occurs when a call is executed (ie. saves the instruction pointer on the stack and then jumps to the address where GetDlgItemTextA begins in memory. According to my asm reference, the RET instruction just pops the previous instruction pointer off the stack right back into eip so execution can resume where it left off. Anyway, I'm just speculating here.

    And assuming, you could make it work by changing the instruction I'm not even sure if this observation is on the correct path to a valid serial because it would be necessary patch the .exe to do it.

    So, here are my 2 questions (and I don't want the solution yet... just a little guidance / reaffirmation)....
    1) Is any kind of patching allowed ??
    2) Am I looking in the right direction or do I need to completly revise my strategy ??

    If no patching is allowed at all, I'm gonna be really stumped


    PS: Kayaker, that last post of yours in Code_Inside's crackme was a really impressive explanation on how to rebuild a PE file ! Just wanted you to know that it was very helpful and that I haven't given up on it yet. Gotta hit the PE docs again. ....Just got a little distracted in the last couple of days

  6. #6
    Me again,

    ...After a little more investigation.

    I think I may have answered my own question from above. I don't think I'll be able to patch in the way I was thinking simply because I just realized something about the EB opcode. Not only is EB an opcode for jmp, but moreover it is the opcode for a SHORT jump. Alas, a short jump won't get me to the empty space at the end of the code section to insert my patch. Guess I'll have to keep thinking


  7. #7
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    Clandestiny (05-22-2001 06:17):

    1) Is any kind of patching allowed ??
    2) Am I looking in the right direction or do I need to completly revise my strategy ??
    1) No
    2a) No
    2b) Yes


  8. #8
    Hiya Kayaker,


    I got the serial! And man do I feel stupid now :-o

    Oops, I swallowed Harlequin's bait (and then some) !

    I'd post my solution, but I don't want to ruin the fun for anyone else who might be trying it. Besides, there's really not that much to write about once you get the point of it ;-) As some wise man said, "to assume makes an ass out of you and me (although its only me in this case)" ...A very good lesson.


  9. #9
    Kayaker the idea is good!I think its not so hard for newbies but they will loose some time with this like Clavidestina did for nothing !heh

    This task is very common for apps and crackmes!If they think good they will see the solution alredy posted by you.They only need to read harder and they will put two and two together.

    It was nice working on it !heh but i found serial soon so better luck next time !

    I think i will join the course to see !Is it hard Kayaker ??

    I promise that I have read the FAQ and tried to use the Search to answer my question.

  10. #10
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries

    You're right Neo, the real answer isn't particularly hard to find if you have a suspicious mind and look beyond the obvious. Once the obvious becomes suspicious that is

    But what I found interesting wasn't the "trick" per se, but, because this is such a simple program, you can easily follow how the trick *works*, how it is implemented from a programming point of view. This is the kind of program one could truly "reverse engineer" and create workable source code from.

    For example, the code at the program entry point is:

    :00401000 PUSH 00
    :00401002 CALL KERNEL32!GetModuleHandleA
    :00401007 TEST EAX,EAX
    :00401009 JZ 00401026
    :0040100B MOV [0040209B],EAX
    :00401010 PUSH 00
    :00401012 PUSH 0040102D ;entry point of DlgProc
    :00401017 PUSH 00
    :00401019 PUSH 64 ; DialogID_0064 seen in W32Dasm
    :0040101B PUSH DWORD PTR [0040209B]
    :00401021 CALL USER32!DialogBoxParamA
    :00401026 PUSH 00
    :00401028 CALL KERNEL32!ExitProcess

    If you've done a bit of ASM programming you'd recognize this as the skeleton of a modal dialog box:

    invoke GetModuleHandle, NULL
    mov hInstance,eax
    invoke DialogBoxParam, hInstance, ADDR DlgName, NULL, ADDR DlgProc, NULL
    invoke ExitProcess,eax


  11. #11
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    The next section is the DlgProc itself and you can see the Windows messages being processed:

    :0040102D ENTER 0000,00
    :00401031 PUSH EBX
    :00401032 PUSH EDI
    :00401033 PUSH ESI
    :00401034 CMP DWORD PTR [EBP+0C],02 ;constant for WM_DESTROY
    :00401038 JZ 00401040
    :0040103A CMP DWORD PTR [EBP+0C],10 ;WM_CLOSE
    :0040103E JNZ 00401044
    :00401040 JMP 00401068
    :00401042 JMP 0040105F
    :00401044 CMP DWORD PTR [EBP+0C],00000111 ;WM_COMMAND
    :0040104B JNZ 00401051
    :0040104D JMP 0040108E
    :0040104F JMP 0040105F
    :00401051 CMP DWORD PTR [EBP+0C],00000110 ;WM_INITDIALOG
    :00401058 JNZ 0040105F
    :0040105A JMP 004010DD
    :0040105F XOR EAX,EAX
    :00401061 POP ESI
    :00401062 POP EDI
    :00401063 POP EBX
    :00401064 LEAVE
    :00401065 RET 0010
    :00401068 PUSH 00
    :0040106A PUSH DWORD PTR [EBP+08]
    :0040106D CALL USER32!EndDialog
    :00401072 PUSH 00
    :00401074 CALL KERNEL32!ExitProcess

    And it looks like the source could be represented with something like:

    DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    invoke EndDialog, hWnd,NULL
    invoke ExitProcess,NULL

    JMP 0040108E ;this is where it gets interesting

    JMP 004010DD ;whatever initialization code is used


  12. #12
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    The jump to 40108E when the WM_COMMAND (111) message is received is where it gets interesting because this is Self Modifying Code (SMC).

    :0040108B ADD [EAX],AL
    :0040108D ADD [ESI-7D],AH
    :00401090 JGE 004010A2
    :00401092 INSB
    :00401093 JNZ 0040109D


    :0040108E CMP WORD PTR [EBP+10],6C ;button pushed?
    :00401093 JNZ 0040109D
    :00401095 PUSH DWORD PTR [EBP+08]
    :00401098 CALL 0040110F
    :0040109D CMP WORD PTR [EBP+10],6B ;edit box received input?
    :004010A2 JNZ 004010D6
    :004010A4 MOV EAX,USER32!GetWindowTextA
    :004010A9 PUSH 00000080
    :004010AE PUSH 00402127
    :004010B3 PUSH DWORD PTR [004021AB]
    :004010B9 CALL EAX ;GetWindowText of edit box
    :004010BB CMP DWORD PTR [00402127],73704F4F

    Rather than just blindly flailing away at a crackme until you get the right answer, here is where you can use your knowledge of how Windoze operates to *understand* how the crackme works, and use other clues to assist you.

    After the uMsg parameter of a Windows message is processed, in this case 111 for WM_COMMAND, the other parameters may be processed.

    wNotifyCode = HIWORD(wParam); // notification code
    wID = LOWORD(wParam); // item, control, or accelerator identifier
    hwndCtl = (HWND) lParam; // handle of control

    In the code above, the ControlID's in wParam are being examined. W32Dasm itself tells you that 6C and 6B are the ControlID's for the button and for the edit box:

    002 - ControlID:006C, Control Class:"BUTTON" Control Text:"Try It!"
    004 - ControlID:006B, Control Class:"EDIT" Control Text:"Your Serial"

    If you set a 'BMSG hwnd WM_COMMAND' breakpoint in SoftIce on the hwnd of the main window, you'll break when either control receives input. For example,

    Break due to BMSG 0690 WM_COMMAND (ET=1.83 seconds)
    hWnd=0690 wParam=006B lParam=01000694 msg=0111 WM_COMMAND

    From this break you can trace back into program code and follow the action...

    By being able to understand what ALL the code in a program is doing, even the boring looking stuff, you've got a better chance of finding where the real protection lies. Here, does something happen only when you push the button, or is there a hidden check when you type something in the edit box? This seems to be a popular deception with Delphi programs where the programmer can use an OnChange Event as you're typing your s/n into the registration edit box. There's another nifty bit of SMC that opens the final door if you successfully pass the real protection check above.

    So the point is not to just come up with the quick answer, but like Clandestiny (sp?) ^_^ "waste" the time, examine all angles, including fancy patching, and try to *understand* the code, learning all the while.


  13. #13
    Hi Kayaker,

    Heh, I guess I lacked "zen" in my approach to this one but I actually found the real solution while reading my whole 8 page disassembled listing. After you told me patching was not an option, there was NO logical solution to that serial check routine and I knew I had to look elsewhere... Of course, after comprehending the protection I realized I'd REALLY missed the obvious in the list of imports

    And you're right, the program is actually quite small and easy to follow and therefore would not be impossible to re-engineer / recode. So here's my suggestion... Why don't we extend the scope of this project a bit ??

    Part 1 could include reverse engineering and rewriting the complete source code of Harlequins crackme from the dead listing (only 8 pages) in a language of your choice...

    And Part 2 could include inventing a clever way to modify Harlequin's crackme / improve the protection.

    Well there's my 2 cents for now ;-)


  14. #14
    heh True Kayaker what can i say !But i think that if newbies would like to learn they should join the course !Because i think they can must to learn from simple step to hard one.

    Because so fare i didnt find i really good course and that would teach you from step to step but only course when you show you knowledge if you have it.If not the learn and come back.SO this kind of courses are ment for good coders and crackers and their main good is to put more ppl to quite it!

    But this one i like because i give you all tuts and tools to do it!You must just use some brains !!heh

    I promise that I have read the FAQ and tried to use the Search to answer my question.

  15. #15
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries

    Sounds like an interesting challenge Clandestiny. I'm going to give it a shot as soon as I get a chance. I've got a little "trick" in mind that I'd like to see if it works just for fun.

    If anyone tries the rest of Harlequin's course and has any questions, maybe we can start a project thread on it too.


Similar Threads

  1. RDP Botnets : Malware Google Dorking - Not an Easy Task
    By OpenRCE_adityaks in forum Blogs Forum
    Replies: 0
    Last Post: December 4th, 2007, 13:00
  2. My Challenge To You
    By KSR0x2b in forum Mini Project Area
    Replies: 25
    Last Post: February 21st, 2002, 22:33
  3. Rsa Challenge
    By int21hex in forum RCE Cryptographics
    Replies: 10
    Last Post: January 29th, 2002, 12:07
  4. Help! Task & Ldt & Hwnd?!
    By dzhiguo in forum Malware Analysis and Unpacking Forum
    Replies: 1
    Last Post: August 28th, 2001, 05:15
  5. Task 4 CRC hints
    By Kayaker in forum Mini Project Area
    Replies: 2
    Last Post: November 30th, 2000, 00:31


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts