Web : http://kickme.to/mxbnet
Contact Me : dheeraj_xp@yahoo.com


Main | Index

Flash 5.0



Type : Animation Program
Protection : RSAgent
Tech : Patching & Redirection of CRC Check


Crack : RSAgent changed its registration algorithm in new release..
like in Flash 5.0
Let us see how to crack this baby.

Go to the folder where you have installed the program.
Example : C:\Program Files\Macromedia\Flash 5

Rename the file : FLASHPOP.TTY ==>> FLASHPOP.EXE

Now run this file i.e. double click it...what will you
see ...

First we will see a window with animation telling something like
"PLEASE WAIT WHILE YOUR SOFTWARE IS BEINGING PREPARED"

After this you will get a warning messagebox like ..
"YOU CAN'T RUN THIS APPLICATION AT THIS TIME......"

What is the secret behind this FLASHPOP.EXE ??? :)

FLASHPOP.EXE actually looks for a file named "LICENSE.951396" and if it
is not found it will warn us ,other wise if it found a file and checked
its virginity and make sure that it is real ,then this program will
unpack the original file and we get a full version of desired program :)

So our attack point is to reach the point where it opens the LICENSE file :)
For this we will do a simple trick ; before running the program FLASHPOP.EXE
in SICE
BPX CREATEWINDOWEXA
Now run the file FLASHPOP.EXE

When we break in to SICE
BPX CREATEFILEA
And continue ...
And trace ...till we reach ...

Note : This place can also be reached in just single BPX i.e. BPX MESSAGEBOXA
0x401869 JNE 0x4018AF >> GOOD BOY
.....................
0x4018A9 CALL EDI >> WARNING ERROR DIALOG BOX
0x4018AB PUSH 00
0x4018AD CALL EBX
0x4018AF CALL 0x4016A0 >> SET FLAG
0x4018B4 CMP ESI,01 >> MAKE ESI = 1 TO CRACK THIS BABY
0x4018B7 JNZ 0x4019D6 >> BAD BOY | 0F 85 19 01 00 00

After this the program will automaticaly unpack and we get a full version :)

Patching :

Why don't we patch the file so that :

0x401869 JMP 0x4018AF | EB 44 OFFSET = 1869
.....................
0x4018B7 - 0x4018BC => FILL WITH NOP | 90 OFFSET = 0x18B7 - 0x18BC

Ok after patching FLASHPOP.EXE just try to run this file :
Opps we get a divide error : So it is using CRC checking : )

Defeating CRC Check :

The program opens the file from the disk itself and does CRC checking.
Suppose we just try to redirect this check to a original and virgin
copy of this file i.e FLASHPOP.TTY,then we will be able to pass this
check.The program will check FLASHPOP.TTY instead of our file FLASHPOP.EXE

So the attack point is to find where the program is trying to open file
FLASHPOP.EXE.

So in SICE BPX GETMODULEFILENAMEA

We can see that at three places if we redirect or change the file name i.e
FLASHPOP.EXE ==> FLASHPOP.TTY
our program will work without divide error :)

0x4010B5 CALL [GETMODULEFILENAMEA]
0x4010BB LEA ECX,[ESP+00] >> FULL PATH OF THE FLIE NAME
C:\PROGRAM FILES\MACROMEDIA\FLASH 5\FLASHPOP.EXE
.........................
0x4010C2 CALL 0x419970 >> AFTER THIS CALL EAX POINTS TO '\FLASHPOP.EXE'

Same sequence is found at :

(i) 0x401221 CALL [GETMODULEFILENAMEA]
0x401227 LEA EDX,[ESP+5C]
.........................
0x40122E CALL 0x419970

(ii)0x403F5A CALL [GETMODULEFILENAMEA]
0x403F60 LEA ECX,[ESP+00]
.........................
0x403F67 CALL 0x419970

Suppose we change the file name after CALL 0x419970 then we can pass this check :)

i.e MOV DWORD PTR[EAX+9],5954542E | C740092E545459

i.e FLASHPOP.EXE ==> FLASHPOP.TTY | .TTY = '2E545459'

So we should find a place to write our code.We can see that above
CALL [GETMODULEFILENAMEA] there is sufficient place :)


So our code :

(1) 0x401084 MOV DWORD PTR[EAX+9],5954542E | C7 40 09 2E 54 54 59 OFFSET = 0x1084
0x40108B JMP 0x4010CE | EB 41
.....................
0x4010B5 CALL [GETMODULEFILENAMEA]
..................................
0x4010C2 CALL 0x419970
0x4010C7 ADD ESP,08
0x4010CA TEST EAX,EAX
0x4010CC JMP 0x401084 | EB B6 OFFSET = 0x10CC
0X4010CE CONTINUE ....

(2) 0x401206 MOV DWORD PTR[EAX+9],5954542E | C7 40 09 2E 54 54 59 OFFSET = 0x1206
0x40120D JMP 0x401246 | EB 37
.....................
0x401221 CALL [GETMODULEFILENAMEA]
..................................
0x40122E CALL 0x419970
0x401233 ADD ESP,08
0x401236 TEST EAX,EAX
0x401238 JMP 0x401206 | EB CC OFFSET = 0x1238

(3) 0x403F33 MOV DWORD PTR[EAX+9],5954542E | C7 40 09 2E 54 54 59 OFFSET =0x3F33
0x403F3A JMP 0x403F73 | EB 37
.....................
0x403F5A CALL [GETMODULEFILENAMEA]
..................................
0x403F67 CALL 0x419970
0x403F6C ADD ESP,08
0x403F6F TEST EAX,EAX
0x403F71 JMP 0x403F33 | EB C0 OFFSET = 0x3F71


Arial, Helvetica, sans-serif">Now break in the FCShare.dll module [just use some API]
and give this command ....

u 00C36AB1

This will show ..

015F:00C36AB1 E819000000 CALL 00C36ACF <-- Armadilo Calls some other API
015F:00C36AB6 C6055811C50001 MOV BYTE PTR [00C51158],01
015F:00C36ABD E8D7AA0000 CALL 00C41599 <-- Armadilo Stuff
015F:00C36AC2 FF742404 PUSH DWORD PTR [ESP+04]
015F:00C36AC6 FF154491C400 CALL [KERNEL32!ExitProcess] <-- Real API called last
015F:00C36ACC C20400 RET 0004

It is seen that Armadilo does something first and then it calls our real API last.

All invalid pointers can be filled like this ... now fix dumpfile ....

Working Dump File :

Now replace orginal packed file with dump file .... and try to save flash or take a snapshot ..
It will show a crazy messagebox "Is the program protected ?"
What the heck is going on ???
Problem is that one API returns false ..

015F:60082A8C 51 PUSH ECX
015F:60082A8D 688CD20A60 PUSH 600AD28C --> "USERNAME"
015F:60082A92 AA STOSB
015F:60082A93 FF1560620A60 CALL [KERNEL32!GetEnvironmentVariableA]
015F:60082A99 85C0 TEST EAX,EAX
015F:60082A9B 7526 JNZ 60082AC3

If we make EAX = 01 .. program works finely in registered mode.

One easy method is to change "USERNAME" --> "TEMP" Offset = 2D28C
So that GetEnvironmentVariableA API will never fail ..

 


15F:00C400B7 FF152491C400 CALL [KERNEL32!VirtualProtect]
015F:00C400BD 8B8550FEFFFF MOV EAX,[EBP-01B0]
015F:00C400C3 8985B4ECFFFF MOV [EBP+FFFFECB4],EAX

SICE Detection:

015F:00C400B6 50 PUSH EAX
015F:00C400B7 FF152491C400 CALL [KERNEL32!VirtualProtect]
015F:00C400BD 8B8550FEFFFF MOV EAX,[EBP-01B0]
015F:00C400C3 8985B4ECFFFF MOV [EBP+FFFFECB4],EAX
015F:00C400C9 FFB5B4ECFFFF PUSH DWORD PTR [EBP+FFFFECB4]
015F:00C400CF E8F8240000 CALL 00C425CC
015F:00C400D4 59 POP ECX
015F:00C400D5 E94DFDFFFF JMP 00C3FE27
015F:00C400DA 8325041EC50000 AND DWORD PTR [00C51E04],00
015F:00C400E1 66C78558FEFFFF7546 MOV WORD PTR [EBP-01A8],4675
015F:00C400EA 66C74590F3B5 MOV WORD PTR [EBP-70],B5F3
015F:00C400F0 C745FC01000000 MOV DWORD PTR [EBP-04],00000001
015F:00C400F7 B900000000 MOV ECX,00000000
015F:00C400FC 668CC9 MOV CX,CS
015F:00C400FF 32C9 XOR CL,CL
015F:00C40101 E361 JECXZ 00C40164
015F:00C40103 B443 MOV AH,43
015F:00C40105 CD68 INT 68 <----
015F:00C40107 66338558FEFFFF XOR AX,[EBP-01A8]
015F:00C4010E 663B4590 CMP AX,[EBP-70]
015F:00C40112 7550 JNZ 00C40164

EAX=601105B3 ; [EBP-70] = SS:0058B30C=B5F3

UnPacking :

BPMB #0030:00C3D79C W DR3

FCShare.text1

015F:600BD511 50 PUSH EAX
015F:600BD512 8B47F8 MOV EAX,[EDI-08]
015F:600BD515 0345FC ADD EAX,[EBP-04]
015F:600BD518 50 PUSH EAX
015F:600BD519 E8D20B0000 CALL 600BE0F0 <--- Unpack
015F:600BD51E 83C728 ADD EDI,28
015F:600BD521 83C40C ADD ESP,0C
015F:600BD524 8D47EC LEA EAX,[EDI-14]
015F:600BD527 3BC3 CMP EAX,EBX
015F:600BD529 72DE JB 600BD509
015F:600BD52B 8B7DFC MOV EDI,[EBP-04]
015F:600BD52E 3B7DF4 CMP EDI,[EBP-0C]
015F:600BD531 7423 JZ 600BD556 <--- Loop
015F:600BD533 8B86A0000000 MOV EAX,[ESI+000000A0]
015F:600BD539 FFB6A4000000 PUSH DWORD PTR [ESI+000000A4]
015F:600BD53F 03C7 ADD EAX,EDI
015F:600BD541 50 PUSH EAX
015F:600BD542 FF75F4 PUSH DWORD PTR [EBP-0C]
015F:600BD545 57 PUSH EDI
015F:600BD546 E8D8000000 CALL 600BD623
015F:600BD54B 83C410 ADD ESP,10
015F:600BD54E 84C0 TEST AL,AL
015F:600BD550 0F84C9000000 JZ 600BD61F ---> Extraction Error
015F:600BD556 FFB680000000 PUSH DWORD PTR [ESI+00000080]
015F:600BD55C 57 PUSH EDI
015F:600BD55D E852010000 CALL 600BD6B4
015F:600BD562 59 POP ECX
015F:600BD563 84C0 TEST AL,AL
015F:600BD565 59 POP ECX
015F:600BD566 0F84B3000000 JZ 600BD61F ---> Extraction Error
015F:600BD56C 8D86F8000000 LEA EAX,[ESI+000000F8]

Quickly restoring the patch in memory avoids page fault.
So each section act as an decryption key.

Patch :

Write String "Asshole" at end of file FCShare.dll and run it ... we can
see that there is no page fault.So that part is not part of key.

File offset : 46F60
In memory :

015F:6011CF60 41 73 73 68 6F 6C 65 00-00 00 00 00 00 00 00 00 Asshole.........
015F:6011CF70 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

So we will use this place to write our code.


Winnt.h

#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_GUARD 0x100
#define PAGE_NOCACHE 0x200
#define PAGE_WRITECOMBINE 0x400


Text1.Section
Flag : 60000020 -- Contains executable code + readable
Offset : 2DF


The section we where looking to patch have only Execute and Readonly permission.So we can't use runtime patching directly [ we will end up in page fault ].But there are loop holes ... If we can use some api with Ring0 prvg we can bypass this protection.

How To Patch This Baby :

What we are going to do is to change OEP to 6011CF40 using hex editor and quickly restore its OEP in memory so that Armadillo will think every thing is OKand do our stuff and then jump to real OEP

015F:6011CF40 60 PUSHAD -- NEW EP
015F:6011CF41 33FF XOR EDI,EDI
015F:6011CF43 E8EE79E65F CALL KERNEL32!GetCurrentProcessId
015F:6011CF48 50 PUSH EAX
015F:6011CF49 57 PUSH EDI
015F:6011CF4A 6A38 PUSH 38
015F:6011CF4C E8FC8CE75F CALL KERNEL32!OpenProcess
015F:6011CF51 8BF0 MOV ESI,EAX ---> Let us restore OEP in memory
015F:6011CF53 B804000000 MOV EAX,00000004 <-- Count
015F:6011CF58 B930CF1160 MOV ECX,6011CF30 <-- Buffer:Data To Write "40ED0300"
015F:6011CF5D BA48010860 MOV EDX,60080148 <-- Addr To Write
015F:6011CF62 6A00 PUSH 00
015F:6011CF64 50 PUSH EAX
015F:6011CF65 51 PUSH ECX
015F:6011CF66 52 PUSH EDX
015F:6011CF67 56 PUSH ESI
015F:6011CF68 E8687AE75F CALL KERNEL32!WriteProcessMemory --- Write orginal OEP
015F:6011CF6D 90 NOP -----> ===== Start Hook Routine =====
015F:6011CF6E A1C0C00C60 MOV EAX,[KERNEL32!VirtualProtect]
015F:6011CF73 A394120D60 MOV [600D1294],EAX
015F:6011CF78 C705C0C00C6090CF1160MOV DWORD PTR [600CC0C0],6011CF90
015F:6011CF82 61 POPAD
015F:6011CF83 E9B81DFAFF JMP 600BED40 -- JMP TO OEP
015F:6011CF88 0000 ADD [EAX],AL
015F:6011CF8A 0000 ADD [EAX],AL
015F:6011CF8C 0000 ADD [EAX],AL
015F:6011CF8E 0000 ADD [EAX],AL == Hook Function ===
015F:6011CF90 66C78090C70000EB28 MOV WORD PTR [EAX+0000C790],28EB -- Patch
015F:6011CF99 A194120D60 MOV EAX,[KERNEL32!VirtualProtect]
015F:6011CF9E A3C0C00C60 MOV [600CC0C0],EAX -- Restore API Address
015F:6011CFA3 B820000000 MOV EAX,00000020
015F:6011CFA8 6890120D60 PUSH 600D1290 <-- Buffer
015F:6011CFAD 6A00 PUSH 00
015F:6011CFAF 6A00 PUSH 00
015F:6011CFB1 6800CE1160 PUSH 6011CE00 <-- THread Func
015F:6011CFB6 6A00 PUSH 00
015F:6011CFB8 6A00 PUSH 00 -- Create a Thread to Patch after Some time
015F:6011CFBA E8AB9FE55F CALL KERNEL32!CreateThread
015F:6011CFBF C3 RET

At line 6011CF90 --- EAX=00C31000
Eax + C790 = 00C3D790

Thread Function :

015F:6011CE00 C60584D20A6045 MOV BYTE PTR [600AD284],45
015F:6011CE07 6A00 PUSH 00
015F:6011CE09 E8D1D0E65F CALL KERNEL32!ExitThread

It is seen that while we reach here data is ready to patch

Note : I get a PAge Fault while closing IE ? But program is working in registered mode..

Special Note to Armadillo programers : You $%#$%^! ,you have no right
to control my PC ... which is my private property.Kick Ass $%^$#%!


http://kickme.to/mxbnet
dheeraj_xp@yahoo.com

 

border:none;mso-border-alt:solid windowtext .5pt;