Originally I had been a Beta tester for this freely available program from ftp://ftp.mcneel.com/pub/rhino/rhino32.exe.
Now ftp://ftp.mcneel.com/pub/1.00/demo. Go there and have a look around if you'r
interested.
I did. The "latest" demo is still
there, along with models, plugs for 3DS Max, etc.
How nice for us! Since I work on 3D projects I had a personal
interest in this nice piece of software, and had grown to like
its easy user interface and its capabilities.
Also, I suspected that my beta format would have been very close to
the version 1.00 release that we were told would be
shipping after the expiration... the "full" version
would retail for only around $795. Thanks, but no thanks, there's no way I can pay such
a sum for a 'full' version, when my own beta could work just the same.
Since
the last beta had a "Cinderella protection" dated October 1998, and
used a very bad protection scheme, I could have used it for the
infinity just resetting my PC clock everytime I needed it... as I
suspect most lusers around are doing. But, hey, after all I'm (beginning to be)
a reverser! And I decided to have a look at the code!
Since this was only the second reversing I had tried, I was a
little scared to tell the truth. After I had read Tristan's
essay from 31 December 1997, and he encouraged "newbies, to try your hand," I was more encouraged and bold. Also I had
read and "studied intensely" at least 30 of the other essays from
the +HCU 'student essays' area. Additionally, I thought to
myself, " If I can do this reverse, I'll have a nice useful tool to study.
If not, well then I'll have at least learned something about code!"
Time was running out and I didn't want to keep setting my clock
time to run that program to suit its fancy. I put my gray cells to work.
A brief note: you will need at least close to 200 meg of free space on whatever drive you use to disassemble this with
WDASM 89 or your time is wasted. The rhino_main.exe is what we'll be disassembling and it creates an 80 meg file to
start! Enjoy.Take 20-30 minutes and go do something else while WDASM 89 does its thing.
As always when you reverse, take good notes. It will save you hours of needless toil in the future. Get a good assembly
and WinAPI reference also. If possible even a Win95,98 or NT programming book.They are invaluable.
Reversing Started:
There are two separate areas that will be involved in the successful reversing of this prog. Both involve time in some
way. A note- I want to make sure you have already installed this program and are not trying to reverse the initial
executable that needs to be unpacked first. We need to be at the same start point. Thanks :-)
* Reference To: KERNEL32.GetLocalTime, Ord:00F5h | :00488AE9 FF15088D8C00 Call dword ptr [008C8D08] :00488AEF 66817C2404CE07 cmp word ptr [esp+04], 07CE <== Here and :00488AF6 7508 jne 00488B0E :00488AF8 66837C24060B cmp word ptr [esp+06], 000B <== Here :00488AFE 7D00 jnl 00488B0EAs you can see, these two compares above check local time against the "factory" authorized times. Both factory times are in hex. The first will jump you out if the year isn't exactly 1998 and the second will jump you out if the month isn't less than November. These come out of the WinAPI function for GetLocalTime. But wait. See below at 00488B00. There soon follows a ret which completes our local time function--IF everything is okay. If not you are sent to the 00488B0E expired nag and then out the door.
:00488B00 33C0 xor eax, eax :00488B02 5B pop ebx :00488B03 83C410 add esp, 00000010 :00488B06 C3 ret :00488B07 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"Beta copy expired" | :00488B09 6810C67F00 push 007FC610 * Possible StringData Ref from Data Obj ->"This beta version of Rhino has " ->"expired." | :00488B0E 68E8C47F00 push 007FC4E8 :00488B13 6A00 push 00000000So we must change some things to help us out. Change
:00488AF6 7508 jne 00488B0E <== Here to EB08 jmp 00488B00 (be sure to get the right offset first) :00488AF8 66837C24060B cmp word ptr [esp+06], 000B :00488AFE 7D00 jnl 00488B0E <== Here to EB00 jmp 00488B00Now we get to stay no matter what time it is. Yippee! Case solved
* Reference To: KERNEL32.FreeLibrary, Ord:0098h | :00417832 FF15A88C8C00 Call dword ptr [008C8CA8] :00417838 8B857CFFFFFF mov eax, dword ptr [ebp+FFFFFF7C] :0041783E 25FFFF0000 and eax, 0000FFFF :00417843 898578FFFFFF mov dword ptr [ebp+FFFFFF78], eax :00417849 33C0 xor eax, eax :0041784B 668B857EFFFFFF mov ax, word ptr [ebp+FFFFFF7E] :00417852 898564FFFFFF mov dword ptr [ebp+FFFFFF64], eax :00417858 8B8578FFFFFF mov eax, dword ptr [ebp+FFFFFF78] :0041785E 39856CFFFFFF cmp dword ptr [ebp+FFFFFF6C], eax [Here eax has the current year loaded from ] [GetLocalTime, whereas [ebp+FFFFFF6C] has 07C ] [(1998) already loaded ] :00417864 0F8516000000 jne 00417880 :0041786A 8B8564FFFFFF mov eax, dword ptr [ebp+FFFFFF64 :00417870 3945F8 cmp dword ptr [ebp-08], eax [Here eax has the current month loaded from ] [GetLocalTime, whereas [ebp-08] has 000B (11) ] [already loaded ] :00417873 0F8E07000000 jle 00417880 :00417879 33C0 xor eax, eax :0041787B E925000000 jmp 004178A5As seen below this current point (00417880) has two important jump points to it and they will both kick you out quickly The very ones we need to fix in order to be able to save our files any time we want to. I tried several different methods to fix this and the one that worked best was to simply (see above )use 6 nops at 00417864 and 6 nops at 00417873. The program then correctly places us at 004178A5 (see below) after xoring eax, as seen from above jump. Thereafter the program runs perfectly and forever. I used times from 1980 to 2095 without any hassle. Now go fix these in your hex editor and enjoy Rhino!
* Referenced by a Jump at Addresses: | :00417880 C70508488C0000000000 mov dword ptr [008C4808], 00000000 :0041788A E8514F0300 call 0044C7E0 :0041788F A1844F8C00 mov eax, dword ptr [008C4F84] :00417894 50 push eax * Reference To: USER32.DestroyWindow, Ord:008Ah | :00417895 FF1544918C00 Call dword ptr [008C9144] :0041789B B801000000 mov eax, 00000001 :004178A0 E900000000 jmp 004178A5 * Referenced by a Jump at Addresses:
|:004177FD(U), :0041781F(U), :0041787B(U), :004178A0(U) | :004178A5 5F pop edi :004178A6 5E pop esi :004178A7 5B pop ebx :004178A8 C9 leave :004178A9 C3 ret
Your text, duh
You should know that nothing is ever easy, even if it looks like it is.
It took hours of piddling around for me (a newbie) to come up with this
info. Experience helps a lot as well as what +orc decribes as "zen", but experience
is not everything, if you don't have some sound teachings.
I can't thank enough everyone who has taken time
to write their own essays. We need good teachers (and good tools, tools made by
ourself). Keep up the good work! All of you! Research! Delve inside the code! Write!
So that crackers and protectors alike can learn and evolve!
Future Requests: More to do with calls to outside .dlls! Also how about a REAL listing of the various ways to trap
functions, windows, messages, etc. in SoftIce which are more specific for reversers. Thanks! :-)