How to reverse Overbloated Notepad by Flipper (upg).

After all as usual lets 'enter in contact' with the program and then
extract some conclutions:

        * Register option is available.
        * Heavy disk activity.
        * Check for a good 'Code' is done at next sesion.
        * App1.dat is necesary.
        * App1.cfg is generated if it doens't exist.
        * It was writen in VB :-)
        * A nagscreen appears if you are 'Unregistered' .-)
         

Why there are so much disk activity?
Let's use FileMonitor filtered with App1 and the current directory.

Seek    \APP1.EXE       SUCCESS  Beginning Offset: 1024 
Read    \APP1.EXE       SUCCESS  Offset: 1024 Length: 4096      
Seek    \APP1.EXE       SUCCESS  Beginning Offset: 5120 
Read    \APP1.EXE       SUCCESS  Offset: 5120 Length: 4096      
Seek    \APP1.EXE       SUCCESS  Beginning Offset: 28160        
Read    \APP1.EXE       SUCCESS  Offset: 28160 Length: 512      
Seek    \APP1.EXE       SUCCESS  Beginning Offset: 9216 
Read    \APP1.EXE       SUCCESS  Offset: 9216 Length: 4096      
Seek    \APP1.EXE       SUCCESS  Beginning Offset: 21504        
Read    \APP1.EXE       SUCCESS  Offset: 21504 Length: 4096     
Open    \APP1.EXE       SUCCESS  OPENEXISTING OPENALWAYS        
Open    \APP1.EX~       NOTFOUND         CREATEALWAYS REPLACEEXISTING   
Open    \APP1.EX~       SUCCESS  CREATENEW CREATEALWAYS 
                                        OPENALWAYS REPLACEEXISTING      
Read    \APP1.EXE       SUCCESS  Offset: 0 Length: 65024        
Write   \APP1.EX~       SUCCESS  Offset: 0 Length: 35840        
Read    \APP1.EXE       SUCCESS  Offset: 35840 Length: 65024    
Close   \APP1.EX~       SUCCESS         
Close   \APP1.EXE       SUCCESS         
Open    \APP1.EXE       SUCCESS OPENEXISTING OPENALWAYS         
Open    \APP1.EX~       SUCCESS OPENEXISTING OPENALWAYS         
Attrib.\APP1.EXE        SUCCESS Get Creation    
Attrib.\APP1.EXE        SUCCESS Get Access      
Attrib.\APP1.EXE        SUCCESS Get Modify      
Attrib.\APP1.EX~        SUCCESS Set Creation    
Attrib.\APP1.EX~        SUCCESS Set Access      
Attrib.\APP1.EX~        SUCCESS Set Modify      
Close   \APP1.EXE       SUCCESS         
Close   \APP1.EX~       SUCCESS         
Open    \APP1.EX~       SUCCESS CREATENEW CREATEALWAYS 
                                        OPENEXISTING OPENALWAYS         
Open    \APP1.DAT       SUCCESS OPENEXISTING OPENALWAYS         
Read    \APP1.DAT       SUCCESS Offset: 0 Length: 512   
Seek    \APP1.EXE       SUCCESS Beginning Offset: 13312 
Read    \APP1.EXE       SUCCESS Offset: 13312 Length: 4096      
Seek    \APP1.EX~       SUCCESS Beginning Offset: 12941 
Read    \APP1.EX~       SUCCESS Offset: 12941 Length: 5 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 12996 
Read    \APP1.EX~       SUCCESS Offset: 12996 Length: 28        
Seek    \APP1.EX~       SUCCESS Beginning Offset: 13992 
Read    \APP1.EX~       SUCCESS Offset: 13992 Length: 5 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 14014 
Read    \APP1.EX~       SUCCESS Offset: 14014 Length: 22        
Seek    \APP1.EX~       SUCCESS Beginning Offset: 17626 
Read    \APP1.EX~       SUCCESS Offset: 17626 Length: 8 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 18313 
Read    \APP1.EX~       SUCCESS Offset: 18313 Length: 5 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 23555 
Read    \APP1.EX~       SUCCESS Offset: 23555 Length: 9 
Read    \APP1.DAT       SUCCESS Offset: 220 Length: 512 
Seek    \APP1.EXE       SUCCESS Beginning Offset: 25600 
Read    \APP1.EXE       SUCCESS Offset: 25600 Length: 2560      
Close   \APP1.DAT       SUCCESS         
Close   \APP1.EX~       SUCCESS         
FindOp.\APP1.EX~        SUCCESS APP1.ex~        
FindOp.\APP1.EX~        SUCCESS APP1.ex~        
FindCl.\APP1.EX~        SUCCESS         
Delete  \APP1.EX~       SUCCESS         
FindNe.\APP1.EX~        NOMORE          
FindCl.\APP1.EX~        SUCCESS         
Seek    \APP1.EXE       SUCCESS Beginning Offset: 17408 
Read    \APP1.EXE       SUCCESS Offset: 17408 Length: 4096      
Open    \VALIDATE.DAT   NOTFOUND OPENEXISTING OPENALWAYS        
Open    \APP1.KEY       NOTFOUND OPENEXISTING OPENALWAYS        
Open    \CHCKSUM.DAT    NOTFOUND OPENEXISTING OPENALWAYS        
Open    \A_VERIFY.REG   NOTFOUND OPENEXISTING OPENALWAYS        
Open    \EB6A           NOTFOUND OPENEXISTING OPENALWAYS        
Open    \EB6B           NOTFOUND OPENEXISTING OPENALWAYS        
Open    \EB6C           NOTFOUND OPENEXISTING OPENALWAYS        
..
..
Open    \ED9H           NOTFOUND OPENEXISTING OPENALWAYS        
Open    \ED9I           NOTFOUND OPENEXISTING OPENALWAYS        
Open    \ED9J           NOTFOUND OPENEXISTING OPENALWAYS        
Open    \PATCH.EXE      NOTFOUND OPENEXISTING OPENALWAYS        
Open    \A.DAT          NOTFOUND OPENEXISTING OPENALWAYS        
Open    \APP1.CFG       SUCCESS  OPENEXISTING OPENALWAYS        
Read    \APP1.CFG       SUCCESS  Offset: 0 Length: 512  
Read    \APP1.CFG       SUCCESS  Offset: 180 Length: 512        
Close   \APP1.CFG       SUCCESS         



Conclutions:

        1. Files named EB6A,EB6B...ED9J  are generated
           by a bucle and are fog to our eyes...so ignore them.
        2. Files APP1.KEY, VALIDATE.DAT, CHCKSUM.DAT and
           A_VERIFY.REG are only opened and closed (not read),
           so it may only check for it existence.
        3. The only file read is APP1.DAT.
        4. File App1.ex~ is copy of App1.exe ==> file check
                                                 integrity?

Let's use the normal aproach to all UserName/RegisterCode schemes.
bpx at nagscreen====>bpx rtcmsgbox (this is the MessageBoxA 
VB function) and F11.

Now, write down the address (4055A0) and W32Dasm.


* Referenced by a CALL at Address:00404030   
|
405512     push ebp
405513     mov ebp, esp
..
..
405595     lea eax, dword ptr [ebp-20]
405598     push 00000010
40559A     push eax
40559B     Call 00401396                ;rtcMsgBox
4055A0     lea eax, dword ptr [ebp-50]


And at 404030:

* Referenced by a  Jump at Address:403ED8(C)
|
404030 E8DD140000              call 00405512


So 

* Referenced by a Jump at Address:0040252A(U)
|
403E43    push ebp
403E44    mov ebp, esp
403E46    sub esp, 0000000C
403E49    push 004012A6
403E4E    mov eax, dword ptr fs:[00000000]
403E54    push eax
403E55    mov dword ptr fs:[00000000], esp
403E5C    sub esp, 000000F8
403E62    mov eax, dword ptr [ebp+08]
403E65    and dword ptr [ebp+08], FFFFFFFE
403E69    and eax, 00000001
403E6C    mov [ebp-08], 00401038
403E73    push ebx
403E74    mov dword ptr [ebp-04], eax
403E77    mov eax, dword ptr [ebp+08]
403E7A    push esi
403E7B    push edi
403E7C    mov ebx, dword ptr [eax]
403E7E    mov dword ptr [ebp-0C], esp
403E81    push eax
403E82    call [ebx+04]
403E85    mov ax, word ptr [00408030] <== Ok 
this is our flag!!! 
403E8B xor esi, esi 
403E8D cmp ax, 03FB 
403E91 mov dword ptr [ebp-18], esi .. .. 
403EB8 mov dword ptr [ebp+FFFFFF50], esi 
403EBE mov dword ptr [ebp+FFFFFF40], esi
403EC4 jnl 00404035 
403ECA cmp ax, 001B
403ECE jle 00404035
403ED4 cmp ax, 00FE
403ED8 jle 00404030 <="=" Here .. So the flag is at [408030]: 

But, where is modified our flag (searching for 408030 we 
find ocurrences at: 403E85 4042A0 404B95 405242 405296 Let's 
see:
:00403E81 50 push eax 
:00403E82 FF5304 call [ebx+04] 
:00403E85 66A130804000 mov ax, word ptr [00408030] 
:00403E8B 33F6 xor esi, esi 
:00403E8D 663DFB03 cmp ax, 03FB 
:0040429C 50 push eax 
:0040429D FF5104 call [ecx+04] 
:004042A0 66A130804000 mov ax, word ptr [00408030] 
:004042A6 33FF xor edi, edi 
:004042A8 663DFB03 cmp ax, 03FB 
:00404B8E 5E pop esi 
:00404B8F 8D8D18FFFFFF lea ecx, dword ptr [ebp+FFFFFF18] 
:00404B95 66893D30804000 mov word ptr [00408030], di 
:00404B9C 89BDD4FEFFFF mov dword ptr [ebp+FFFFFED4], edi 
:00404BA2 89B5CCFEFFFF mov dword ptr [ebp+FFFFFECC], esi 
:00405231 50 push eax 
:00405232 E807C2FFFF Call 0040143E ;__vbaVarTstEq 
:00405237 6685C0 test ax, ax 
:0040523A 7457 je 00405293 
:0040523C 393D10804000 cmp dword ptr [00408010], edi 
:00405242 66C70530804000FF00 mov word ptr [00408030], 00FF 
:0040524B 750F jne 0040525C 
:0040524D 6810804000 push 00408010 
:00405293 8B4508 mov eax, dword ptr [ebp+08] 
:00405296 66C70530804000FE00 mov word ptr [00408030], 00FE Ok!!! solution is in front of you at this time!!!!! Look at 405237="="> FF Good Guy.
                   FE Bad  Guy.

bpx at 405232 and wait.
Look at the stack:

ss:esp+0 ==> 2nd Value to Tst
ss:esp+4 ==> 1st Value to Tst

e ss:esp+0 => arguments to the function, looking at address 
referenced by the 3er dword  you can see the correct code.

So: Name: +HCU
    Code: 6AB76748

Let's see the posible file integrity check.

Seek    \APP1.EX~       SUCCESS Beginning Offset: 12941 
Read    \APP1.EX~       SUCCESS Offset: 12941 Length: 5 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 12996 
Read    \APP1.EX~       SUCCESS Offset: 12996 Length: 28        
Seek    \APP1.EX~       SUCCESS Beginning Offset: 13992 
Read    \APP1.EX~       SUCCESS Offset: 13992 Length: 5 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 14014 
Read    \APP1.EX~       SUCCESS Offset: 14014 Length: 22        
Seek    \APP1.EX~       SUCCESS Beginning Offset: 17626 
Read    \APP1.EX~       SUCCESS Offset: 17626 Length: 8 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 18313 
Read    \APP1.EX~       SUCCESS Offset: 18313 Length: 5 
Seek    \APP1.EX~       SUCCESS Beginning Offset: 23555 
Read    \APP1.EX~       SUCCESS Offset: 23555 Length: 9


And now look at app1.dat

14989 6338FE068C
15044 0A886E04050563381E050A8B640405056338FB050A8B570405056F0F
16040 6338FE068C
16062 0A888E05050563381E050A8B840505056338FA05787E
19674 3EC20A81A9070505
20361 EC49F8FAFA
25603 5755FA545D80C5780B

Do you see something in common????????

14989-2048=12941
15044-2048=12996
16040-2048=13992
16062-2048=14014
19674-2048=19626
20361-2048=18313
25603-2048=23555


12941: 66 3D FB 03 89  (from App1.exe offset 12941) 
Xor:   63 38 FE 06 8C  (from App1.dat)
--------------------- 
       05 05 05 05 05 

12996: 0F 8D 6B 01-00 00 66 3D 1B 00 0F 8E 61 01 00 00 66 3D FE ...
Xor:   0A 88 6E 04 05 05 63 38 1E 05 0A 8B 64 04 05 05 63 38 FB ...
-------------------------------------------------------------------
       05 05  05 05 ...


and more....


Ok!!! now you can patch is because you know the correct code in
file App1.dat.


But, why it not checks at:

:00405231 50                      push eax
:00405232 E807C2FFFF              Call 0040143E  ;__vbaVarTstEq
:00405237 6685C0                  test ax, ax
:0040523A 7457                    je 00405293 <== Here 'Nopping' 
at 40523A is more than enough to patch the program. The 'KeyMaker' 
Let's use a zen approach. Let's make a table using different 
UserNames and getting the correct code. 

UserName Code 
A        6AB65BEC
AA       6AB6B1F4
AAA      6AB707FC
B        6AB65D3F
BB       6AB6B499
BBB      6AB70BF4 	
C        6AB65E91
CC       6AB6B73F
CCC      6AB70FED . . . 
Z        6AB67D02 

ZZ ... ZZZ ... + 6AB63ECD Nothing 6AB605E3 Look, the increment 
between two consecutive values can be 152h or 153h. Lets make 
the next operation: value of nothing-value of letter. Letter Value 
at first position difference at other positions + 38EA EVEN ODD A 5609 (-1) (+1) B 575B (-1) (0) C 58AD (+1) (0) D 5A01 () E 5B54 () F 5CA7 () G 5DF9 (0) (0) H 5F4C (0) (O) I 609F () J 61F2 () K 6345 () L 6498 (-1) (0) M 65EA () N 674C () O 6890 () P 69E3 (0) (-1) Q 6B36 () R 6C89 (+1) (0) S 6DDB () T 6F2D () U 7081 (0) (0) V 71D4 () W 7327 () X 747A () Y 75CC () Z 771E () The formula is="=">  6AB605E3+(sum of every letter)+differences

Now, lets create some codes:

        +ABC = 6AB605E3+(38EA+5609+575B+58AD)-1+1=6AB744DE
        +HCU = 6AB605E3+(38EA+5F4E+58AF+7085)+0=6AB76748
        +ALL = 6AB605E3+(38EA+5609+6498+6498)-1-1=6AB75E04
        +RCG = 6AB605E3+(38EA+6C89+58AD+5DF9)+1+0+0=6AB761FD
        APP =  6AB605E3+(5609+69E3+69E3)+0-1=6AB72FB1
        

Now, you can find out the missing values and create your own
keymaker.


+Rcg 1997