²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² ²² ____ __ __ ²²ßÛ ²² / _/_ _ __ _ ___ ____/ /____ _/ / ²² ÛßÛ ²² _/ // ' \/ ' \/ _ \/ __/ __/ _ `/ / ²² Û Û ²² /___/_/_/_/_/_/_/\___/_/ \__/\_,_/_/ ²² Û Û ²² ____ __ __ ²² Û Û ²² / __ \___ ___ _______ ___ ___/ /__ ____ / /____²² Û Û ²² / /_/ / -_|_-"Note: This is an unregistered " ->"evaluation copy. %d days remaining. " | :00405076 6852A74400 push 0044A752 :0040507B 68882B4800 push 00482B88 :00405080 E837800100 call 0041D0BC :00405085 83C40C add esp, 0000000C :00405088 8B06 mov eax, dword ptr [esi] :0040508A 6A40 push 00000040 ------------------------------------------------------------------------------- If we follow this routine further down, we can see references to other strings, such as "CGI*Star Pro has expired". This is a good thing, because it means the entire routine is all in one place. Let's change that conditional jump above, from jne to je. Restart the program, and we have no nag! Since we know the program has a 30-day time limit, let's set our system clock to at least 30 days ahead, and restart the program. Now we get a message box stating "PROGRAM HAS EXPIRED. The SAVE buttons do not work anymore !". So, let's look for this string now. Double click on it, and you should land here: ------------------------------------------------------------------------------- :004050A4 833D9C9A440000 cmp dword ptr [00449A9C], 00000000 :004050AB 7430 je 004050DD :004050AD 8B06 mov eax, dword ptr [esi] :004050AF 6A40 push 00000040 * Possible StringData Ref from Data Obj ->"CGI*StarPro has expired." | :004050B1 6825A94400 push 0044A925 * Possible StringData Ref from Data Obj ->"PROGRAM HAS EXPIRED. The SAVE " ->"buttons do not work anymore !" | :004050B6 68E8A84400 push 0044A8E8 :004050BB FF700C push [eax+0C] :004050BE FF7068 push [eax+68] :004050C1 E8C62D0300 call 00437E8C :004050C6 83C414 add esp, 00000014 ------------------------------------------------------------------------------- We can also see further down, a string that says "The program has expired! Will not write anything to files" This is another good thing, because we know the entire routine is in one place. So, as before, let's change the above conditional jump from je to jne. Restart the program, and we have no nag! But, we forgot to set our system time back, so do that, then restart again. The nag is back!!! We just changed the conditional jump to it's reverse... so let's make the jump unconditional. Change the jne, to a jmp. Restart the program, and the nag is gone. We've successfully removed the nags and time limit. Now we want to remove the string that says "CGI*StarPro - 30 days remaining" in the titlebar, so search for this string. Double click on it, and you should land here: ------------------------------------------------------------------------------- :00404CC5 8D5DF8 lea ebx, dword ptr [ebp-08] :00404CC8 B802A34400 mov eax, 0044A302 :00404CCD E80E6C0100 call 0041B8E0 :00404CD2 833DA09A440000 cmp dword ptr [00449AA0], 00000000 :00404CD9 753E jne 00404D19 :00404CDB 833D9C9A440000 cmp dword ptr [00449A9C], 00000000 :00404CE2 7518 jne 00404CFC :00404CE4 FF358C9A4400 push dword ptr [00449A8C] * Possible StringData Ref from Data Obj ->"CGI*StarPro - %d days remaining" | :00404CEA 681DA54400 push 0044A51D :00404CEF 68F41B4600 push 00461BF4 :00404CF4 E8C3830100 call 0041D0BC :00404CF9 83C40C add esp, 0000000C * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00404CE2(C) | :00404CFC 833D9C9A440000 cmp dword ptr [00449A9C], 00000000 :00404D03 7426 je 00404D2B * Possible StringData Ref from Data Obj ->"CGI*StarPro - Program Expired" | :00404D05 683DA54400 push 0044A53D :00404D0A 68F41B4600 push 00461BF4 :00404D0F E8A8830100 call 0041D0BC :00404D14 83C408 add esp, 00000008 :00404D17 EB12 jmp 00404D2B * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00404CD9(C) | * Possible StringData Ref from Data Obj ->"CGI*StarPro" | :00404D19 685BA54400 push 0044A55B ------------------------------------------------------------------------------- Again, we see more strings below. This is a good thing. We want the title bar to display ONLY "CGI*StarPro", and we can see that by changing the FIRST conditional jump above, we can jump directly to this string. So, change the first conditional jump from jne to je (it's always best to try and change the least amount of bytes possible), and restart the program. Now the title bar always displays only "CGI*StarPro". Now all we have left are the disabled "Save" nags. Let's search for the string "Unregistered evaluation version. The SAVE buttons do not work !". Double click on it, and you should land here: ------------------------------------------------------------------------------- :0040EACE FF7508 push [ebp+08] :0040EAD1 E876580000 call 0041434C :0040EAD6 59 pop ecx :0040EAD7 833DA09A440000 cmp dword ptr [00449AA0], 00000000 :0040EADE 7536 jne 0040EB16 :0040EAE0 8B5508 mov edx, dword ptr [ebp+08] :0040EAE3 8B02 mov eax, dword ptr [edx] :0040EAE5 6A40 push 00000040 * Possible StringData Ref from Data Obj ->"CGI*StarPro Unregistered." | :0040EAE7 68E74E4500 push 00454EE7 * Possible StringData Ref from Data Obj ->"Unregistered evaluation version. " ->"The SAVE buttons do not work !" | :0040EAEC 685C4E4500 push 00454E5C ------------------------------------------------------------------------------- I forgot to mention earlier, that it is always a good idea to check for more than one instance of this string. In the previous cases, we were ok, as there was only one instance, but in this case, there are FOUR routines. The first three routines look similar to the above one, but the final instance has the conditional jump AFTER the string... not before. In any case, let's change all the conditional jumps from jne to je, and vise versa. NOTE: Up until this point, the author has kept the routines all in one place. Now the routine is in four places, which indicates that the check is performed for each of the four buttons on the toolbar. This is most likely inefficient programming, as he could have just referenced one routine for each of the checks. Or, he just decided to make it tougher for us :) After changing all the conditional jumps, test all the buttons and functions. Looks like everything works! We could quit here, but I decided I wanted to see if I could get rid of that ugly background bitmap that advertises other programs and such. So, let's move the bitmap (CSPROBG.BMP) from the program directory, to a different one. Restart the program, and we get a message box stating "Unable to load background bitmap from resources". After searching the String Refs of the program, we know that this comes from somewhere else. So, run Filemon, and see which files the program accesses. We can see that the program accesses a .dll file called "pvplus32.dll". It looks like this is the right file, because the message box said "ProtoView" in the title bar, and if you view the properties of the .dll, it says "ProtoView Screen Management" under the Version tab. Make a copy of the dll, and disassemble it. The string is there, so double click it, and you should land here: ------------------------------------------------------------------------------- :10021857 833D8086021000 cmp dword ptr [10028680], 00000000 :1002185E 0F8536000000 jne 1002189A :10021864 6808750210 push 10027508 * Possible StringData Ref from Data Obj ->"Unable to load background bitmap " ->"from resources." | :10021869 681CE00210 push 1002E01C :1002186E 68A08C0210 push 10028CA0 * Reference To: USER32.wsprintfA, Ord:0249h | :10021873 FF154CF80210 Call dword ptr [1002F84C] ------------------------------------------------------------------------------- Change the above conditional jump from jne to je, and restart the program. No annoying background!!! You can now safely delete the bitmap, and either move the .dll back to c:\windows, or directly into the program directory. NOTE: The LoadBitmapA function in Soft-Ice would have worked equally as well in removing the bitmap function. If you have any questions, feel free to e-mail me at Volatility@ImmortalDescendants.com or Volatility@prodigy.net. ------------------------------------------------------------------------------- Copyright (c) 1999 Volatility And The Immortal Descendants All Rights Reserved