Eggi's Arteam Crackme #1

[difficulty: 2][protection: code protected with xor]

This was recently posted to crackmes.de. It is another crackme where your serial is used to decrypt some code that will eventually execute.

Specifically here, a word is made by summing your serial characters with strlen(serial). This word then is xor'd sequentially (no feedback) across 10 words.

Before execution reached the decrypted code, a one byte comparison is made for validity, revealing half of the xor key.

To get the other half, I used z0mbie's XDE engine on trial decryptions (incrementing trial keys) to see which key produced the most normal disassembly; normal meaning it consisted of typical instructions: push, pop, call, etc.

UPDATE: crackme was removed from crackmes.de since it is preferred that the real author submit - a copy is in this site's crackmes folder


  1. hi andrewl,
    thanks for posting another interesting crackme :)
    I found it only used _word to encrypt, thus since one of the bytes must be correct, every 2nd byte in code is correct
    here, we deduce what can happen next: if 'badboy' is called in messagebox, there must be goodboy lying somewhere close
    so here i found the push, then found a push command which can accomodate the correct bytes, produced 'xor', then done :)
    I just thought this crackme would be easier manually--my opnion

  2. I agree.

    In addition to the references to the goodboy strings that you talked about, this line in the setup:

    00401098 mov esi, ds:MessageBoxA

    would lead anyone to believe that a call esi should happen:

    00401115 push 0
    00401117 push offset 00405178
    0040111c push offset 00405138
    00401121 push ebx
    00401122 call esi <-- and it does of course

    And opcode of call esi is two bytes: ff d6 so the other byte of the key is apparent.

    But what if code moved esi into another register before calling it? Or pushed it, then ret'd? What if the address of the goodboy string was not referenced directly, but its half was pushed on the stack, and then adjusted in place? In other words, what if the code was obfuscated? We can't make guesses about the existence of any instruction.

    The ability to disassemble and measure frequency of opcodes is more complicated, but it is more powerful and applicable to a wider range of problems.

    z0mbie_opcode_frequency.txt is uploaded to filedump - it shows that z0mbie anticipated AV's using opcode statistics to find atypical (virus indicative) instructions a long time ago

    "lay back, its all been done before" :(

  3. I see you're assuming that the instructions generated are 'normal'
    Z0mbie's decryptor seems quite cool after checking it out, as it recognizes jumps and analyzes exes a bit, much like debuggers & dissassemblers
    I agree that this is a better solution, given that no strange code (adc, int, etc.) is in decrypted code
    The reason I assumed this is that I highly doubt the author of the crackme would produce such things, as this would sometimes, if the key is long enough, make crackme impossible, also software authors can't make this type of protection, as when key leaks, ppl can just make a dump of it
    I checked out z0mbie's other stuff, seems really innovating :)


  4. nice way to solve it :)

    it's easy since we can guess the key by not using a disasm engine, but should be usefull for real programs if the key is hardest.

    Nice Work by andrewl.

    I did the same using BeaEngine ;)


  5. Hey Artif!

    I am switching to BeaEngine soon too! Unfortunately I have some code (recursive disassembler, ripper, code moving stuff) that still relies on XDE.


thanks for commenting!