Essay : Cracking a thermal simulation program - Written by MTB.
Published by +Tsehp Dec 2001
Protection
**********
Sentinnel dongle
Tools
*****
w32dsm89 for a check not really necessary (usefull for quick string
searching)
IDA PRO 4.04
with the following plugins
CyberHeg for Ida Hasp plugin
killer_3k for Ida Sentinel SuperPro plugin
Amante4 for Ida string plugin
All formerly available on crackz'z site, who knows where now.
Some experie
HIEW (a good Hex editor)
A brain and time
Usefull Tutorials
*****************
Dongle Bashing by Frog's print
Zen and the Art of Dongle Cracking by
zeezee
+HCU's special Project: 'How to
undongle' All of it!
Dongle reverse engineering by Zafer/BSCA
Program history
***************
This program is a graphics front end for
SINDA and Trasys. Besides being able
to write out a Sinda, etc decks it can also run it's own biult in
Sinda solver in
graphical form.
You can get it by asking, go to
http://www.harvardthermal.com
go to demo download, follow the instructions. Hint say you are
analyzing circuit cards or heat exchangers.
GOAL OF THIS TUTORIAL
*********************
To enable a newbie with proper tools, to
reverse engineer a target
to make it usable ie, it can run without limitation, open files and
save files. Note the save in
this program works via a work around.
We will NOT be doing any fa
Just JMP's and NOP's,
lots of them.
The key is for you the newbie to find
the dongle calls, and go UP in
the code to locate where that information is used! This is not as
simple as it seems. In this
example I named the routines by either
the error messages they printed out, or by what I think they are called
for. This is why IDA is used.
Running program
***************
We first get the nasty nag running in
demo mode key not found blah,
blah etc.
Now lets attack it with IDA, apply the
sentinel dongle sigature and
go to bed it will take a while.
Save the IDA file to text form. Using a text editor search
for "demo".
The reason why you doing in a text
editor is because IDA is SLOW for
text searches, even on a 1000MHz machine. You also could use the
IDA string pluggin (if
you can find it).
This first bit of a subroutine I named
"help about"
0059B352
push edi
0059B353
cmp [ebp+110h], ebx
0059B359
jz loc_59B3E2 << this jump happens
0059B35F
lea ecx, [esp+1E0h+var_1CC]
etc.
0059B3C1
push edx
0059B3C2
call sub_4C8A90
0059B3C7
or edi, 0FFFFFFFFh
0059B3CA
lea ecx, [esp+1E0h+var_1CC]
0059B3CE
mov [ebp+108h], eax
0059B3D4
mov [esp+1E0h+var_4],
edi
0059B3DB call
??1CString@@QAE@XZ ; CString::~CString(void)
0059B3E0
jmp short loc_59B412 ;
0059B3E2 ;
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
0059B3E2
0059B3E2 loc_59B3E2: ; CODE XREF: help_about?+29j
0059B3E2
mov ecx, ebp
0059B3E4
call software_mainta
0059B3E9
cmp eax, ebx
0059B3EB
mov [ebp+108h], eax << NOP
0059B3F1
jz short loc_59B40F << JMP
0059B3F3
lea ecx, [ebp+334h]
0059B3F9
call time_limited_dongle
0059B3FE
test eax, eax
0059B400
jz short loc_59B40F
0059B402
mov ecx, ebp
0059B404
call check_for_demo_mode
0059B409
mov [ebp+108h], eax ; 1 or 0
0059B40F
0059B40F loc_59B40F: ; CODE XREF: help_about?+C1j
0059B40F
; help_about?+D0j
0059B40F
or edi, 0FFFFFFFFh
0059B412
0059B412 loc_59B412: ; CODE XREF: help_about?+B0j
0059B412
cmp [ebp+108h], ebx ;
<< NOP
0059B418
jnz short good_jump ;
<< change to JMP
0059B41A
push ebx
0059B41B
push ebx
0059B41C
push offset aThisProgramIsN ;
"This program is not licensed\nRunning in"...
0059B421
call sub_641FE9 ; ?AfxMessageBox@@YGHPBDII@Z
0059B421
; doubtful name
0059B426
0059B426 good_jump: ; CODE XREF: help_about?+E8j
0059B426
lea ecx, [esp+1E0h+var_19C]
0059B42A call
??0CCommandLineInfo@@QAE@XZ ; CCommandLineInfo::CCommandLineInfo(void)
0059BEC0
0059BEC0
0059BEC0 software_mainta
0059BEC0
; .text:0059C3A3p
0059BEC0
push esi
0059BEC1
mov esi, ecx
0059BEC3
push edi
0059BEC4
mov eax, [esi+7F8h]
0059BECA
mov ecx, [esi+124h]
0059BED0
lea edi, [esi+334h]
0059BED6
push eax
0059BED7
push ecx
0059BED8
mov ecx, edi
0059BEDA
call check_key_3 ;
0059BEDF
test eax, eax << NOP
0059BEE1
jnz short loc_59BEE6 << NOP
0059BEE3
pop edi
0059BEE4
pop esi
0059BEE5
retn
Obviously you do NOT want to execute ANY
of the code below!
0059BEE6 ;
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
0059BEE6
0059BEE6 loc_59BEE6: ; CODE XREF: software_mainta
0059BEE6
mov ecx, edi
0059BEE8
call call_check_key_2
0059BEED
cmp eax, 1
0059BEF0
jnz short loc_59BF1F
0059BEF2
mov eax, [esi+124h]
0059BEF8
push 0
0059BEFA
cmp eax, 2
0059BEFD
push 0
0059BEFF
jnz short loc_59BF15
0059BF01
push offset aYourSoftwareMa ;
"Your software maintena
0059BF06
call sub_641FE9 ; ?AfxMessageBox@@YGHPBDII@Z
0059BF06
; doubtful name
0059BF0B
mov ecx, edi
0059BF0D
call is_the_key_attached
0059BF12
pop edi
0059BF13
pop esi
0059BF14
retn
0059BF15 ;
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
0059BF15
0059BF15 loc_59BF15: ; CODE XREF: software_mainta
0059BF15
push offset aYourSoftware_0 ;
"Your software maintena
0059BF1A
call sub_641FE9 ; ?AfxMessageBox@@YGHPBDII@Z
0059BF1A
; doubtful name
0059BF1F
0059BF1F loc_59BF1F: ; CODE XREF: software_mainta
0059BF1F
mov ecx, edi
0059BF21
call is_the_key_attached
0059BF26
pop edi
0059BF27
pop esi
0059BF28
retn
0059BF28 software_mainta
0059BF28
All we did is by pass the messages! The programers gave us the flags to
follow. If the messages
where not in the code obviously this becomes a more difficult task!! But don't worry, almost
every program will have these stupid messages. (See Dongle Bashing by Frog's Print).
Now run the program, those nasty
greetings dissapear!
The next step is to be able to export
the model. We find this piece of code
called by
all these nice exporting fu
0059BF30 top_level_key_check proc
near ; CODE XREF:
.text:0059BFCBp
0059BF30 ;
send_the_model+46p
0059BF30 ;
export_the_model+46p
0059BF30 ;
export_the_model_3+46p
0059BF30 ; export_the_model_4+46p
0059BF30 ;
export_and_solve_model+34p
0059BF30 ;
export_and_solve_transient+34p
0059BF30 ;
unknown_security_check+18p
0059BF30 ;
.text:005A9438p
0059BF30 ;
.text:005A94A8p
0059BF30 push esi
0059BF31 mov esi, ecx
0059BF33 mov
eax, [esi+110h]
<< looks familiar
0059BF39 test eax, eax << NOP
0059BF3B jz short loc_59BF57 << NOP
0059BF3D mov eax, [esi+7F4h]
0059BF43 lea ecx, [esi+7C8h]
0059BF49 push eax
0059BF4A call sub_4C8A90
0059BF4F mov [esi+108h], eax
0059BF55 pop esi
0059BF56 retn
0059BF57 ; ---------------------------------------------------------------------------
0059BF57
0059BF57 loc_59BF57: ; CODE
XREF: top_level_key_check+Bj
0059BF57 lea ecx, [esi+334h]
0059BF5D call is_the_key_attached << obviously we
don't want to call this
0059BF62 mov [esi+108h], eax
0059BF68 pop esi
0059BF69 retn
0059BF69 top_level_key_check endp
0059BF69
first call
005A3FF0 send_the_model proc near ; CODE XREF: .text:004C20A9p
005A3FF0
005A3FF0 var_5FC = qword ptr -5FCh
etc.
005A4015 call sub_5ACFD0
005A401A test eax, eax
005A401C jz loc_5A444A
005A4022 call ?AfxGetModuleState@@YGPAVAFX_MODULE_STATE@@XZ
; AfxGetModuleState(void)
005A4027 mov esi, [eax+4]
005A402A mov eax, [esi+108h]
005A4030 test eax, eax
005A4032 jz short loc_5A4045
005A4034 mov ecx, esi
005A4036 call top_level_key_check
005A403B mov eax, [esi+108h]
005A4041 test eax, eax ; << NOP the test
005A4043 jnz short loc_5A4064 ;<< JMP
005A4045
005A4045 loc_5A4045: ; CODE
XREF: send_the_model+42j
005A4045 cmp dword ptr [edi+84h], 12Ch
005A404F jle short loc_5A4064
005A4051 push
0
005A4053 push 0
005A4055 push offset aCannotExportOv ;
"Cannot export over 300 nodes in demo mo"...
005A405A call sub_641FE9 ; ?AfxMessageBox@@YGHPBDII@Z
005A405A ; doubtful name
005A405F jmp loc_5A444A
005A4064 ;
---------------------------------------------------------------------------
005A4064
005A4064 loc_5A4064: ; CODE
XREF: send_the_model+53j
005A4064 ;
send_the_model+5Fj
005A4064 push edi
005A4065 lea ecx, [esp+4BCh+var_49C]
005A4069 call sub_47B110
005A406E push 0
005A4070 push 4
005A4072 push offset aCompactNodesBe ;
"Compact nodes before exporting?"
005A4077 mov [esp+4C4h+var_4],
0
005A4082 mov esi, 1
Now there are several other routines
that use the exact logic, it is your mission to FIX it.
005A79B0 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
005A79B0
005A79B0
005A79B0 export_and_solve_model proc
near ; CODE XREF: .text:004C1F39p
005A79B0
etc.
005A79CE mov esi, ecx
005A79D0 call ?AfxGetModuleState@@YGPAVAFX_MODULE_STATE@@XZ
; AfxGetModuleState(void)
005A79D5 mov edi, [eax+4]
005A79D8 xor ebx,
ebx
005A79DA cmp [edi+108h], ebx
005A79E0 jz short loc_5A79F1
005A79E2 mov ecx, edi
005A79E4 call top_level_key_check
005A79E9 cmp [edi+108h], ebx << NOP
005A79EF jnz short loc_5A7A0F ;
<< JMP
005A79F1
005A79F1 loc_5A79F1: ; CODE
XREF: export_and_solve_model+30j
005A79F1 cmp dword ptr [esi+84h], 12Ch
005A79FB jle
short loc_5A7A0F
005A79FD push 0FFFFFFFFh
005A79FF push ebx
005A7A00 push 0F00Ah
005A7A05 call ?AfxMessageBox@@YGHIII@Z
; AfxMessageBox(uint,uint,uint)
005A7A0A jmp exit_subroutine
etc.
Notice this bit of sneaky code, we check a different value for a flag to see weather
we are
permitted to solve the model, or just export it. FYI I missed this the first time through!
005A7A0F ; ---------------------------------------------------------------------------
005A7A0F
005A7A0F loc_5A7A0F: ; CODE
XREF: export_and_solve_model+3Fj
005A7A0F ;
export_and_solve_model+4Bj
005A7A0F cmp dword ptr [edi+124h], 2
; NOP
005A7A16 jnz short loc_5A7A24 ;
JMP
005A7A18 mov ecx, esi
005A7A1A call compact_nodes_b4_exporting
005A7A1F jmp exit_subroutine
005A7A24 ;
---------------------------------------------------------------------------
005A7A24
005A7A24 loc_5A7A24: ; CODE
XREF: export_and_solve_model+66j
Now there is another set of calls just
like the one above, go and find it!
The last part of this excercise is the
first piece of code that calls our checking routine.
Notice the cmp to 2, and jnz after
it. Look up a few lines, what did we
do? Good now do it
again. Now was that hard? It just takes patie
The first thing calls
top_level_check_key, skip this for the moment
0059BFCB call top_level_key_check
0059BFD0 cmp dword ptr [esi+124h], 2
0059BFD7 jnz short loc_59C02E
0059BFD9 lea ecx, [esp+4]
0059BFDD call display_version
etc.
0059C01B call ??1CString@@QAE@XZ ; CString::~CString(void)
0059C020 mov dword ptr [esp+74h],
0FFFFFFFFh
0059C028
lea ecx, [esp+4]
0059C02C jmp short loc_59C081
0059C02E ;
---------------------------------------------------------------------------
0059C02E
0059C02E loc_59C02E: ; CODE
XREF: .text:0059BFD7j
0059C02E lea ecx, [esp+4]
0059C032 call display_version_2
0059C037 lea ecx, [esp+4]
etc.
0059C070 call ??1CString@@QAE@XZ ; CString::~CString(void)
0059C075 mov dword ptr [esp+74h],
0FFFFFFFFh
0059C07D lea ecx, [esp+4]
0059C081
I haven't a clue what differe
The last thing to fix is right below,
see above! The other way is do a NOP and
JMP, if
it doesn't work try NOP and NOP!
005A87B0 unknown_security_check proc
near ; DATA XREF: .rdata:0069C350o
005A87B0 ;
.rdata:006AB208o
005A87B0 push esi
005A87B1 push
edi
005A87B2 mov edi, ecx
005A87B4 call ?AfxGetModuleState@@YGPAVAFX_MODULE_STATE@@XZ
; AfxGetModuleState(void)
005A87B9 mov esi, [eax+4]
005A87BC mov eax, [esi+108h]
005A87C2 test eax, eax
005A87C4 jz short loc_5A87D7
005A87C6 mov ecx, esi
005A87C8 call top_level_key_check
005A87CD mov eax, [esi+108h]
005A87D3 test eax, eax << NOP
005A87D5 jnz short loc_5A87E0 << JMP
005A87D7
005A87D7 loc_5A87D7: ; CODE
XREF: unknown_security_check+14j
005A87D7 mov eax, [edi]
005A87D9 push 0
005A87DB mov ecx, edi
005A87DD call dword ptr [eax+64h]
005A87E0
005A87E0 loc_5A87E0: ; CODE
XREF: unknown_security_check+25j
005A87E0
mov ecx, edi
005A87E2 call sub_63EA55
005A87E7 pop edi
005A87E8 pop esi
005A87E9 retn
005A87E9 unknown_security_check endp ; sp = -4
How long should this take you? Good question, it took overnight to
dissassemble, then 5 nights
to fix the code, where most of the time was spent naming subroutines
and finding error messages.
Ok what about the save, easy in the
first menu just hit reinitialize key, it will bring the save
and saveas buttons back for one use until you hit the reinitialize key
again.
The secret to this
patie
Greetz go to :
**************
+fravia for showing the way
crackz for putting it all together for me
CyberHeg for Ida Hasp plugin
killer_3k for Ida Sentinel SuperPro plugin
Amante4 for Ida string plugin
And all those fellow crackers who write tutorials