> cat writeups/reverse-engineering/caos1986s-neslevel1-tutorial.md

caos1986's NesLevel1 Tutorial

Published: 2015-07-27 - Estimated reading time: 3 minutes

Target: caos1986’s NesLevel1
URL: http://crackmes.de/users/caos1986/neslevel1/
Protection: Serial.
Description: NES-crackme with a serial protection.
Tools: NESDisassembler

If we run the crackme in a NES Emulator we are presented with a screen prompting us to enter a serial.

[ LOADING IMAGE... ]
Initial screen

If we press the start-button we see that the only thing that happens is that an “x” shows up after the serial.

[ LOADING IMAGE... ]
Invalid input screen

So lets disassemble the rom to see what it does.

NESDisassembler.exe NesLevel1.nes 0 1 > dump.asm

Lets find the input-scanning routine.

lbl_c08a:    lda #$0
        sta $1000
lbl_c08f:    lda #$1
        sta $4016      ;Joypad #1
        lda #$0
        sta $4016      ;Joypad #1
        lda $1000
        cmp #$9
        bne lbl_c0ee
        lda $4016      ;Joypad #1
        and #$1            ; Check if a-button is pressed
        lda $4016      ;Joypad #1
        and #$1            ; Check if b-button is pressed
        lda $4016      ;Joypad #1
        and #$1            ; Check if select-button is pressed
        lda $4016      ;Joypad #1
        and #$1            ; Check if start-button is pressed
        beq lbl_c0b9        ; jump if not pressed
        jsr lbl_c0ef        ; if pressed jump to lbl_c0ef
lbl_c0b9:    lda $4016      ;Joypad #1
        and #$1            ; check if UP-button is pressed
        beq lbl_c0c8        ; jump if not pressed
        jsr lbl_c135        ; if pressed jump to lbl_c135
        lda #$27
        sta $215
lbl_c0c8:    lda $4016      ;Joypad #1
        and #$1            ; check if DOWN-button is pressed
        lda $4016      ;Joypad #1
        and #$1            ; check if LEFT-button is pressed
        lda $4016      ;Joypad #1
        and #$1            ; check if RIGHT-button is pressed
        beq lbl_c0ee        ; jump if not pressed
        lda $213
        cmp #$70
        beq lbl_c0e9
        clc
        adc #$8
        sta $213
        jmp lbl_c0ee
;--------------------
lbl_c0e9:    lda #$58
        sta $213
lbl_c0ee:    rti

Lets take a look at the code at lbl_c0ef

lbl_c0ef:    lda $201     ; load first char
        cmp #$4      ; compare first char to 4
        bne lbl_c12f ; jump if not equal
        lda $205     ; load second char
        cmp #$2      ; compare second char to 2
        bne lbl_c12f ; jump if not equal
        lda $209     ; load third char
        cmp #$1      ; compare third char to 1
        bne lbl_c12f ; jump if not equal
        lda $20d     ; load fourth char
        cmp #$8      ; compare fourth char to 8
        bne lbl_c12f ; jump if not equal
        lda #$25
        sta $215
        lda #$17
        sta $249
        lda #$e
        sta $24d
        lda #$1c
        sta $251
        lda #$1c
        sta $255
        lda #$12
        sta $259
        lda #$e
        sta $25d
        rts
;--------------------
lbl_c12f:    lda #$26
        sta $215
        rts

Here we see four comparisons to the entered values. Lets enter 4218 as our serial.

[ LOADING IMAGE... ]
Valid input screen

There we go! The flag is NESSIE!