View Full Version : Menu Enabling Project
Kayaker
December 20th, 2000, 18:25
Menu Enabling Project
Hi All,
I thought I'd suggest this as a project to explore the process of enabling a disabled menu item and hopefully fully restoring its functionality.
Target: MixVibes PRO 2.23a 880Kb
h*ttp://www.mixvibes.com/mixvibes/download/mixvibespro223.zip
f*tp://ftp.axinet.com/pub/mixvibes/mixvibespro223.zip (may be corrupt)
Other d/l locations at h*ttp://www.mixvibes.com/
This is a 30 day registerable Save-disabled audio mixer. While it can be registered, the main tasks will be to:
1. Enable (ungray) the Save and SaveAs menu items.
2. Enable the Save functionality.
There are at least 2 required readings for this:
Theory and practice of menus reversing by +Spath.
http://www.woodmann.net/fravia/menusspa.htm
Enabling Menu Items - Techniques by Lord Soth
http://www.immortaldescendants.org/database/essays/lordsoth/menu-items.txt
I've used some of the techniques in a couple of tuts that might help as well
Enabling Print-Challenged PDF Files
http://www.searchlores.org/pdffing.htm
Implementing an Inline Patch from the Menu
http://www.woodmann.net/fravia/TracePlus_MenuPatch.html
An API monitor with all the 'menu' APIs enabled is indispensible here, as is the Win32 Programmers Reference. A couple of tips - the decision to enable or disable a menu item in a drop down list is usually made when the main menu item is clicked on. As for actually restoring the Save functionality, familiarize yourself with a couple of the Common Dialogs dll (Comdlg32.dll) functions used in this program, and study closely Lord Soth's tut.
Have fun.
Cheers,
Kayaker
?ferret
December 22nd, 2000, 22:16
've been kickin a few ideas around in my head for save disabled protections for awhile, but I haven't run across any for some time. Thanks Kayaker, this will give me a chance to test my theories ;-)
Kayaker
December 22nd, 2000, 22:47
Quote:
?ferret (12-22-2000 11:16):
've been kickin a few ideas around in my head for save disabled protections for awhile, but I haven't run across any for some time. Thanks Kayaker, this will give me a chance to test my theories ;-) |
Hi ?ferret,
Believe me, I had a hard time finding one. Had to wade through a huge search listing for "Save Disabled". They don't seem as common as I thought they'd be. Them shareware programmers are just gettin' too darn sophisticated

meRlin
December 25th, 2000, 04:20
Hello,
It was a nice target you have chosen Kayaker!
Should be no problem to enable all items.
If one want's to "cheet" it's really easy to enable all menus, I suppose you already know that. (Don't want to spoil the challange for other reverser

)
About finding targets with disabled menuitems, all adobe trial, calgari (truespace) and Bryce (3x) has some function disabled, they're maybe to big for us who still use a modem but we can grab them from any "cover-cd".
cheers
meRlin
Clandestiny
December 25th, 2000, 21:58
Hi Kayaker,
Good choice for a target! I've been wanting to try my hand at enabling disabled functions for a while :-)
After reading the suggested tuts I've managed to ungrey all of the menu items, but I'm a bit stuck now on how to activate them. I'll explain my approach and findings and then hopefully you will kindly help me back on the right track...
First thing I did was run the target to see exactly which functions were disabled. The disabled functions were new, open, save, save as, export file, recent file, and options. I was a little puzzled that the new and open functions should also be disabled since that pretty much renders the app useless? But anyway, I deadlisted it in Wdasm where I was able to determine that the menus are created using a template rather than at runtime. From here I was able to get the menu ID's (save=E103h && saveas=E104h).
At this point I checked the menu definition in Hex Workshop. The options were all 00, or active so I then figured it must be disabling itself during runtime.
After examining the assorted imported functions pertaining to menus, I saw EnableMenuItem which I set a breakpoint on IF the menu item flag == 01. SoftIce broke at the following code.
:0049A76A 8B4C240C mov ecx, dword ptr [esp+0C]
:0049A76E F7D9 neg ecx
:0049A770 1BC9 sbb ecx, ecx
:0049A772 83E1FD and ecx, FFFFFFFD
:0049A775 83C103 add ecx, 00000003
:0049A778 80CD04 or ch, 04
:0049A77B 51 push ecx
:0049A77C FF7608 push [esi+08]
:0049A77F FF7004 push [eax+04]
* Reference To: USER32.EnableMenuItem, Ord:00B0h
|
:0049A782 FF150C264C00 Call dword ptr [004C260C]
:0049A788 EB53 jmp 0049A7DD
Stepping through the code here a couple of times in SoftIce I could see that the flag was 403 for disabled and 400 for enabled menu items. Since the flag parameter was being passed in ecx, I figured it should always be 400 so all items would be enabled and I did a patch at:
:0049A778 mov cl,0
:0049A77A nop
:0049A77B push ecx
Now 400 would always be passed to the enable menu function enabling all of the selections. . Possibly this wasn't the most elegent patch, but it worked since all of the menu items are now ungreyed.
Unfortunately, my work is not done. Though the items are ungreyed, they still need to be activated. It is here that I am having some difficulties. BTW, I've read each of the suggested readings a good 3+ times trying to glimpse the vagaries of reversing windows message structures without a great deal of sucess (alas my win32 asm knowledge is *basic* and +Spath's discussion a bit *advanced*).
*** ran out of space: message continued in following post ***
Clandestiny
December 25th, 2000, 22:00
*** message continued ***
I did follow what I read enough to realize that windows sits in a loop waiting for various messages, (wm_command among them) and that wm_command is the message sent when a menu item is clicked. So from this it makes sense that we would want to intercept this wm_command message to see exactly where the program branches in response to a particular menu item being clicked.
Now, taking your advice Kayaker, in the Trace32 tut, I found the class name for MixVibes to be Afx:400000:b:1466 using Windowse. Then I got the taskname and HWND of the menu bar. Now I set a bmsg Hwnd wm_command where the Hwnd is the menu handle I just found. SoftIce then broke when I attempted to select a menu item...so far so good...
...Now borrowing the bpxK32Thk1632Prolog trick (how this works I have no idea!) I was able to get back into the MixVibes code. And from what little I understand, I think the program has to do a comparison to determine what menu item was actually selected. I entered the code here:
:004969A3 817D0C60030000 cmp dword ptr [ebp+0C], 00000360
:004969AA 7505 jne 004969B1
:004969AC 6A01 push 00000001
:004969AE 58 pop eax
:004969AF EB1A jmp 004969CB
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004969AA(C)
|
:004969B1 FF7508 push [ebp+08]
:004969B4 E863FFFFFF call 0049691C
:004969B9 FF7514 push [ebp+14]
:004969BC FF7510 push [ebp+10]
:004969BF FF750C push [ebp+0C]
:004969C2 FF7508 push [ebp+08]
:004969C5 50 push eax
:004969C6 E8BDFCFFFF call 00496688
There is only one comparison here and I can't fathom the significance of 360. Beyond that, stepping down though the remaining instructions throws me out into a shit load of Kernel and User32 code and then back into the K32Thk1632Prolog / Epilog functions. I tried going through a few iterations, but I seemed to be running around in circles. I certainly don't see any place that is comparing my selected menu item ID with anything. Help me Kayaker !!!
BTW, Merry Christmas and a Happy New Year
Cheers,
Clandestiny
Kayaker
December 26th, 2000, 06:11
Hi Clandestiny,
Hey, you really got into some good stuff there! While you took the hard route

it's probably much more instructive.
I thought having the New and Open items disabled were kind of useless too until I realized, if you can't save a mix, why should you be able to open one? heh, heh. So I guess we need to enable all of them. My first choice might be to try something like I did with the PDF files, do a TRACE and see if you can find a unique patch point somewhere close to the EnableMenuItem call that would both enable the menu items and restore their functionality.
This isn't always possible though. It could be a pure demo without the code to call the menu item functionality, but if you're lucky the code IS there and just needs to be activated. In this case it's a registered/not registered flag. If you can't backtrace from the EnableMenuItem call then you need to trace from the selection of the menu item.
I don't think there's any definitive method to doing this, but here's a few things I've noticed.
You followed the BPX K32Thk1632Prolog trick perfectly. One thing I've noticed is that as soon as you break on Bmsg Hwnd WM_COMMAND after selecting the menu item,
:BMSG 06d4 WM_COMMAND
Break due to BMSG 06D4 WM_COMMAND (ET=8.89 seconds)
hWnd=06D4 wParam=E103 lParam=00000000 msg=0111 WM_COMMAND
you land in KernelAlloc at
141F:05B8 6668A0694900 PUSH 004969A0
and the address PUSHed is the same one that you reach after going through K32Thk1632Prolog and the Call in Kernel32.dll at
BFF73637 65FF5608 CALL GS:[ESI+08] ; Call 4969A0
So if you restart the program and set a BPX 4969A0, you end up at the start of program code where you want to be without having to set the BPX K32Thk1632Prolog. I've seen this many times, and at least with certain languages, there's always a PUSH statement in KernelAlloc that has the return address. Either way, you end up at the code you listed.
continued...
Kayaker
December 26th, 2000, 06:14
What I try to do is watch what params are being pushed in each call as I trace (usually the MenuID as wparam, Hwnd, lparam and Msg). And I usually F8 into Calls that are indirect, i.e. Call [EAX + 64] or that are just before a RET.
So if you step into the 2nd call after you return to program code after selecting a menu item
:004969C6 E8BDFCFFFF call 00496688
you reach the 1st indirect call
:004966EB FF5064 call [eax+64] ; 4978A5
F8 into this and you reach the next
:004978C1 FF90A4000000 call dword ptr [eax+000000A4] ; 4978E9
and the next
:00497912 FF9080000000 call dword ptr [eax+00000080] ; 4AC0E7
Now the next section doesn't have an indirect call, but if you step into the direct call just before the RETurn, you continue on the right path
:004AC153 E830BDFEFF call 00497E88
which leads to the next indirect call at
:00497EC1 FF5014 call [eax+14] ; 4ACAE4
a few more of these and you get to another indication of something important happening - lots of parameters pushed!
:0049A53B FF7514 push [ebp+14]
:0049A53E FF7010 push [eax+10]
:0049A541 FF7510 push [ebp+10]
:0049A544 FF7014 push [eax+14] ; 45AF20
:0049A547 FF750C push [ebp+0C]
:0049A54A FF7508 push [ebp+08]
:0049A54D 57 push edi
:0049A54E E80E000000 call 0049A561
and the stack:
dd esp
016F:0075FA58 0050F070 0000E103 FFFFFFFF 0045AF20
016F:0075FA68 0075FAC0 0000002C 00000000
Suddenly there's an address in the .text section being pushed! This may lead somewhere...
Step into this call and you reach
:0049A628 FF5514 call [ebp+14] ; 45AF20
This is where all the action happens. It's also where you'd end up by doing a backtrace from EnableMenuItem in the first place ^_^
The other thing that's interesting to explore here is when you find the compare with the registered/not registered flag, which controls all checks in the program, do a BMSG RW on the address of the flag and start the program again. You find all kinds of interesting addresses like when it's first mapped into memory in the .data section (can't set it there), when it's checked for the opening nag, and it leads right to the main registration routine.
There's more than one way to skin a cat
Hope this helps,
Regards,
Kayaker
Kayaker
December 26th, 2000, 06:41
Sorry, in that last paragraph that was supposed to be BPM address RW, not BMSG
Lord Rhesus
December 26th, 2000, 17:35
I don't want to sound like I am pluging my site but I resently put up a site related to adding functionality (or code injection) where I have archived a few useful tutorials which are related to this topic. The address is http://www.codeinjection.cjb.net hope it can be of use!
Kayaker
December 26th, 2000, 22:16
Nice! A site dedicated to adding functionality. Let's hope to see more of it in the future. Thanks Lord Rhesus.
Regards,
Kayaker
Clandestiny
December 26th, 2000, 23:23
Thx Kayaker,
That helped a lot, but I have a couple of questions for ya...
I found the register / unregister flag and enabled all of the menu items. However, I'm doing my best to try to *understand* what is happening as much as possible and not follow *blindly*.
You gave me 2 pieces of advice:
1)trace into the indirect calls first
2)trace into direct calls that are before a return.
To my amazement, both of these tips worked like a charm and I'm wondering *why* you trace this type of code like that? Beyond your advice, I found there to be very few "landmarks" in this section of code. Indeed, without it I would have remained hopelessly lost in a maze. Is this approach a result of your experience? ...Intuition? ...Something having to do with the structure of the code surrounding menus? ...Possibly this wasn't the best approach toward enabling menu functions? That was an awful lot of calls. Is that pretty standard? I think I will try to reverse it again using your TRACE approach.
Now, my second question...I fear it is a bit mundane :-) I was going to put a bpm on the address of the reg / unreg flag so I could explore the possibility of removing the nag. Unfortunately, SoftIce won't break on my bpm. This has been a constant problem...90% of the time it won't break on any bpm I set and I've never been able to figure out why. Usually, I am breaking on API's so this has generally not been a problem...but I would really like to figure out whats going on. Likewise, I have a problem with setting a single bpx on an arbitrary line of code. For example, I tried to directly set a bpx directly on 004969a0, the location after the K32Thk1632 prolog trick, but SICE would not break!
Here is exactly what I did...
bpx 017f:004969a0
bpm 0187:0050f8a4 rw
I don't think there is anything wrong with my syntax and I have re-read the break point section in the manual. If this is a lame question I apologize.
Thx Kayaker,
Clandestiny
Clandestiny
December 26th, 2000, 23:41
To Lord Rhesus,
Interesting site...and I love the disclaimer
Cheers,
Clandestiny
Kayaker
December 27th, 2000, 01:20
Quote:
Clandestiny (12-26-2000 12:23):
To my amazement, both of these tips worked like a charm and I'm wondering *why* you trace this type of code like that? Is this approach a result of your experience? ...Intuition? ...Something having to do with the structure of the code surrounding menus?
|
Experience? Intuition? Zen? Snicker. ^_^
Nah, I've just cheated a few times and kind of noticed this before. Call it what you want. What I did here just to make sure this would work again was to set a BP on the critical JZ at 45AF28 and then started tracing from the return to program code after selecting the menu item. Every time I stepped OVER an indirect call or a call just before a return, the BP kicked in, ergo you step INTO them.
I haven't done this enough times to prove it statistically, but it *sort of* makes sense. There's usually dozens of menu items that need to be redirected from the same start point, so indirect calls (or jumps in some cases) which can change when necessary (different Msg, wparam, lparam) are logical, especially when you consider how many times K32Thk1632Prolog returns to the same code over and over again.
I like the TRACE approach in a lot of different circumstances when I'm trying to understand what's going on. Here it's simple to use, just set a trace between GetMenuItemID of a disabled menu item and the next EnableMenuItem. Then repeat with an enabled menu item and compare.
BPM's seem to give me a problem as well unless I delete and retype them each time. You could try SuperBPM from one of the tool sites, seems to work well with Asprotect anyway. I'm curious though why your register offset is so different between the two breakpoint types - 17F and 187? I know it changes on everyones system, but mine is always 167/16F. Maybe try it without the CS/DS offset?
You may have also noticed that when you first break into a program with Loader you need to F8 once to change the code window from all INVALID to code, before setting a direct address BPX.
Cheers,
Kayaker
meRlin
December 27th, 2000, 14:36
Hi,
here is a nice place to enable all items, if you do it this way it's not registered and the nag is still left to remove
mov eax, dword ptr [ecx+00000834]..
test eax, eax..
jne 0045AF34..
mov ecx, dword ptr [esp+04]..
push 00000000..
mov eax, dword ptr [ecx]..
call dword ptr [eax]..
figure it out by yourself.
meRlin
JaneK
December 27th, 2000, 15:17
Hi Kayaker,
Well, I decided to post few words so you know that more people are working on this
project

.
First of all I have to admit that I was beaten here - I did not manage to reverse the target fully, neither to follow the way I was planning to.
My approach was similar to what Clandestiny already mentioned:
1. I set bpx on EnableMenuItem and then clicking on "File" triggered the bpoint. In the Mixvibes code I noticed 3 pushes before EnableMenuItem was called. The first one (ecx) should keep menu items flags. From Spath's tutorial I know that 03h means MF_Grayed+MF_Disabled. I changed it to 00h (MF_Enabled) and got "Save" and "Save As" (among others) ungrayed. BTW all other menu items that were active before, now became grayed/not active.
2. Ungrayed does not mean enabled, so I decided to find the piece of code that corresponds to the "Save" function, so to bp when "Save" is clicked. After reading about wm_command (0111h) I searched for "cmp register, 00000111" in deadlisting and tried to bpoint on corresponding addresses. No success. Then I used hwnd mixvibes, but that gave a lot of handles. Finally handle for Afx:400000:8:148e worked and I landed at 0177:00495F11.
From there I tried to trace further on, but after some time I realized I am not sure what to look for! What I wanted to do was to have "Save" and "Save As" enabled while the prog remains unregistered! I could not do it.
3. I have the feeling that searching for a serial is easier - at least I'm sure what to look for. I'll do it now just to see both things enabled!
Finally I have to say that this challange was beyond my reach. I mostly regret I wasn't able to follow Spath's tut (I feel all the anwers are there) as much as I wanted. Although I did not manage to complete the crack, I've learnt quite a lot and that was my point. Maybe next time...
Thanks
JaneK
P.S. Just saw above post from meRlin. Something to study for me

()whore
December 27th, 2000, 16:28
Hello everyone I have been following this one quietly,
Kayaker I have to say thanks for the project but DAMN this one was hard to follow. I have never done a menu disabled project befor and I am haveing alot of trouble understanding this one.
I can enable the menuitems fine by bpx on enablemenuitem and changing what value was being pushed in ecx. I even traced backward following all the returns to the getmenuitemid loop. This seamed promising for finding where the program was deciding they were disabled. However there was way to much code to look through and I realy didn't know what I was looking for.
I then tried following the WM_COMMAND from my enabled menu item to find the code for this function. But Lord Soth's tute talked about finding the CMP memory location, Const. I searched through alot of code looking for this but no luck (Is this because it is MFC?).
Finaly I got a few clues from +spath's tut. Specificly the second program he cracks. This is the MFC target and mixvibes is MFC also. HE described perfectly what I had seen in mixvibes:
:7FB21074 cmp ebx, 00000111 ; 111h = WM_COMMAND
:7FB2107A je 7FB2110C
:7FB21080 cmp ebx, 0000004E ; 4Eh = WM_NOTIFY
:7FB21083 je 7FB21138
:7FB21089 cmp ebx, 00000006 ; 06h = WM_ACTIVATE
:7FB2108C je 7FB21176
I also found the indirect calls that he talked about. He goes on to try and explain about lookup tables (which I didn't understand) and finaly trails off; like once you found this table everything else was a done deal. ?
Finaly I read your post about following the inderect calls then finding 45af20. I had acctualy traced through this call several times befor but nothing there stood out to me ( I was looking for the cmp mem,cont ). When traceing through this program what exactly were we looking for ??? I enabled all the functions by fixing this test jnz. But how we arrieved at this spot I still can't figure out.
Another note. +spath mentioned the stack command. I used it with a bpx on enablemenuitem. I found something very interesting with a dissabled menuitem, stacked looked like enablemenuitem,00099553,000abb40,00099920,000ac21a,ect But when an active item triggered this bpx the stack command went from enablemenuitem, to 000ac21a. This happened with every enabled and disabled item. I was unable to translate this into anything productive. Could this have lead anywhere?
I am going to try and do a backtrace with this one and see what happens.
peace,
()whore
Kayaker
December 29th, 2000, 03:16
Hi All,
So you thought I was brutal posting the disabled menu project did ya? Just wait until you see the next one! Nah, just kidding ^_^
I suppose it wasn't all that easy because you can really get messed up trying to trace the code, but that's pretty well what you're up against with a function disabled situation. I think it was well worth it though to introduce a few new concepts to anyone unfamiliar with them.
I just wanted to mention another tut that's quite good and easy to understand which covers most of what we went over:
Re-enabling functions - Cool Edit 2000 by UmE
http://www.immortaldescendants.org/database/essays/ume/ce-2000.txt
I think it's worth reading just to see a slightly different route to the critical compare which restores the Save functionality. In this case there's a direct CMP with the MenuItemID and a jump to the good/bad flag.
I'm still kicking around some ideas for future projects. Somebody want to give the next one a go?
Regards,
Kayaker
JaneK
December 29th, 2000, 16:11
Hi,
I thought I should be able to find E103h (Menu ID value for "Save"

in the deadlisting, but it's not there!
Why? Where is it?
Thanks
Janek
Clandestiny
December 29th, 2000, 21:14
Quote:
JaneK (12-29-2000 05:11):
Hi,
I thought I should be able to find E103h (Menu ID value for "Save" in the deadlisting, but it's not there!
Why? Where is it?
Thanks
Janek |
Hi JaneK,
When I first deadlisted MixVibesPro I too was a little puzzled about why I could not find the menu ID's in the listing. After researching / reading quite a few tutorials about menus and such, I don't think the program has these indentifiers hard wired into the code, but instead uses the GetMenuItemID API to obtain the menu item ID's during runtime when it needs to figure out which item was selected.
From the API Reference:
The GetMenuItemID function retrieves the menu item identifier of a menu item located at the specified position in a menu.
UINT GetMenuItemID(
HMENU hMenu, // handle of menu
int nPos // position of menu item
);
Parameters
hMenu
Identifies the menu that contains the item whose identifier is to be retrieved.
nPos
Specifies the zero-based relative position of the menu item whose identifier is to be retrieved.
BTW, this is also my first crack of a crippled menu target, so I could be wrong about this. Kayaker (or someone else who has more experience) is probably more qualified to answer your question :-)
Regards,
Clandestiny
Clandestiny
December 29th, 2000, 21:57
Quote:
Kayaker (12-28-2000 16:16):
I just wanted to mention another tut that's quite good and easy to understand which covers most of what we went over:
Re-enabling functions - Cool Edit 2000 by UmE
http://www.immortaldescendants.org/database/essays/ume/ce-2000.txt
|
Hi Kayaker,
Funny that you should mention Cool Edit 2000. Actually, I tried reversing it myself a while ago (and failed miserably I might add

). Hard as I tried, I couldn't get past the CRC check which would not let me patch so much as a *single* random byte in a string resource. I had a look at the essay you mentioned hoping that it could show me where I went wrong. Unfortunately,UmE didn't address the CRC in his essay. After comparing the addresses in Wdasm though, I think it might be a different version. Anyway, I thought I would throw out the possibility of removing the CRC on Cool Edit 2000 as an upcoming project. It can be downloaded from:
h*ttp://www.syntrillium.com/download/getfile.html?001
BTW, there is also the demo version of Cool Edit Pro (by the same authors) which I also unsuccesfully attempted to reverse since it seems to use the same type of CRC as Cool Edit 2000...another menu disabled project perhaps although I don't know if the functions on this one can be enabled...It might be a pure DEMO.
Well anyway, project or not, I'd surely be grateful if you could give me a few pointers on CRCs.
Cheers,
Clandestiny
Kayaker
December 29th, 2000, 22:03
Hi Janek,
I think Clandestiny pretty much has it right, it just means the program never uses the MenuItemID directly, as in a direct CMP. Some disabled menu programs apparently do (CoolEditPro), some don't.
Like the majority of Windoze programs, this one uses the Comdlg32.dll functions GetOpenFileNameA and GetSaveFileNameA to open the appropriate Common Dialog box. Even where Mixvibes decides which one to use, it's only a flag compare:
:00493F18 JZ 00493F21
:00493F1A CALL comdlg32!GetOpenFileNameA
:00493F1F JMP 00493F26
:00493F21 CALL comdlg32!GetSaveFileNameA
I backtraced from here using BPM address X a bunch of times at the start of code sections and found the main branch point for all menu items. It starts with the program sitting in a loop checking all the MenuItemID's in turn and if any one was selected:
--------Start Loop
:0049A53B PUSH DWORD PTR [EBP+14]
:0049A53E PUSH DWORD PTR [EAX+10]
:0049A541 PUSH DWORD PTR [EBP+10]
:0049A544 PUSH DWORD PTR [EAX+14]
:0049A547 PUSH DWORD PTR [EBP+0C]
:0049A54A PUSH DWORD PTR [EBP+08] ; cycles through MenuItemID's
:0049A54D PUSH EDI
:0049A54E CALL 0049A561
.
.
:0049A583 CMP EAX,0C ; 2C if no menu item selected, 0C if there was user input
:0049A586 JA 0049A5A5
--------End this section of Loop
:0049A588 JZ 0049A59A
.
.
:0049A59A MOV ECX,[EBP+08]
:0049A59D CALL [EBP+14] ; main branch to menu routines
The stack display at this last Call shows the wparm (=MenuItemID =E103 for Save) and Msg (111) from WM_COMMAND:
dd esp
016F:0075FA08 004E3328 00000111 0075FA40 0049A553
016F:0075FA18 00D90078 0000E103
And the program branches to the appropriate routine for the menu item selected.
OK, so what good is all this? Well, it could be another route for finding the critical compare in menu disabled programs. It seems that this checking loop is pretty important because it's also run through on startup. Now if you put a BP on the loop at
:0049A54E CALL 0049A561
with say BPX 49A54E do "dd esp"
and start the unpatched program, again you see each of the MenuItemID's being checked. When it's one of the disabled ones, bypass the
:0049A583 CMP EAX,0C
by editing the EAX register to 0C, pretending that the menu item was selected. If you do that the address at
:0049A59D CALL [EBP+14]
happens to be **45AF20**, which if you remember was the address that led to the critical compare that we got to by other routes (manual tracing from selection of the patched enabled menu item, or doing a TRACE).
I hope everybody understands what I'm getting at here. It's sort of why I alluded to the Comdlg32.dll functions GetOpenFileNameA and GetSaveFileNameA in my original post - as being a potential avenue for tracing to figure out how to actually get them called and restoring full functionality once you've ungrayed the menu items.
Regards,
Kayaker
JaneK
December 30th, 2000, 06:39
Thanks a lot.
I'm back to work now
JaneK
Ignatz
January 3rd, 2001, 04:34
interesting project here....
not being a cracker myself really (more of a ~coder who finds reversing interesting~) i havent paid much attention to this section before..... but i have been wanting to try menu-disabled programs for a while... gonna grab the proggie and the tuts and give it a whirl!
(and gonna try to do it without reading ppl's posts on here about it , fingers crossed)
Kayaker
January 4th, 2001, 00:12
Quote:
Ignatz (01-02-2001 17:34):
interesting project here....
not being a cracker myself really (more of a ~coder who finds reversing interesting~) i havent paid much attention to this section before..... but i have been wanting to try menu-disabled programs for a while... gonna grab the proggie and the tuts and give it a whirl! |
Great! Please reply with any results you might want to post.
You speak the truth, it IS the Reversing that's interesting, not the Cracking 8)
Regards,
Kayaker
BlackB
January 4th, 2001, 09:33
Well, great project kayaker

When I first saw you on a messageboard (don't remember which one) about Guitar Pro about a year ago (or something), I knew you would become a good reverser

and now you are
Maybe an additional task for all people following this project: get the "Save" or "Save as..." function enabled in Guitar Pro v2.20 or v3.0. They are not grayed

The challenge here is to change the program that way it saves any .GTP file no matter how many notes and bars.
Before you start this one I can tell you: This one is hard

For the hardcore reversers, who get bored very quickly: crack the whole program

.And please try not to cheat by reading my tutorial I wrote on it :P Use it as a "lender of last resort" when you're REAL stuck.
To end: greetz kayaker....remember the guitarpro dayz?
cya all
greetz
The Blackbird aka BlackB
Kayaker
January 4th, 2001, 23:32
Hi BlackB,
Hey, how's it going? Thanks for the compliment man, but then I had plenty of good teachers including you and your great site ;-) Cracking 4 Newbies should be required reading for everyone! I especially found your unpacking tuts very useful and still use 'em as reference.
Ahh yes, the GuitarPro days... ^_^
Yeah!! Anybody wants a Full-Monty demo, mega-crippled example of real reversing, check this one out! I thought the guy was going to choke on it 'till he puked 8)
Hey, keep up the good work.
P.S. There's a good true reversing project coming soon from Clandestiny, stay tuned... (Sorry Clan, you're in for it now, heh heh ^_^
Cheers,
Kayaker
Lord Rhesus
January 5th, 2001, 11:34
Looks like a really interesting project that you have going. If I didn't have so much work to do at the moment I would love to have a go at the project.
I had a go at something similar to this with HyperSnap-Dx v3.50 (which is a screen capture program) a year ago. I had a go at the serial number but couldn't get my head around it at the time, so I decided to take a different approach and try to make the program look like it's registered. It is a similar challenge like you have going here.
This program has been cracked/keygened black and blue by many different crackers so there isn't any damage that can be done to the makers. The program features anti-SoftICE routines (unfortunately it's plain old MeltICE

) and CRC checking. The problem with the shareware version of this program is that there is a big nag screen at the begining, and if you save your screen capture then there is a little message tagged to the top left hand side of the capture saying that the screen capture has been taken by a shareware version of the program. If your interested in the challenge then here are the tasks that I set myself last year:
1) Neutralise CRC code
2) Prevent tagging of screen captures
3) Kill nag screen at beginning
4) Disable all links to register and buy screens
5) Change about box so it looks registered
There is a newer version of the program out now (version 3.63 I think) which you can get from www.hyperionics.com if your interested. Also I started writing a tutorial for this a year ago but I lacked the will and I didn't finish it. If anyone really wants I'll rewrite the tutorial and update it to the newer version of HyperSnap, but only after the end of January when my workload vanishes. For interest, Douby also wrote an essay on reversing the CRC check for version 3.30. If your interested and you can't find Douby's essay then e-mail me at lordrhesus@yahoo.co.uk and I'll send you his tutorial.
Ignatz
January 16th, 2001, 19:13
oooooooooops....
hehe had some system probs before i got very far along...
two reformatted and repartitioned hard drives,
one reinstalled windows98, one reinstalled linux mandrake 7.0, one reinstalled openbsd 2.8 and a bunch of dowloads (not to mention a new soundcard) later... here i am lol
gonna get back after it soon but right now am grabbing the october platform sdk (and thinking next time it might be better to order the "inexpensive cd"
anyways found the "required readings" interesting.. think ill play around with the toolhelp funcs a bit
x!
January 30th, 2001, 17:56
Thanks to Kayaker and Clandestiny for pointing me to the mini projects page. Great thing to have going here.
I'll check the other posts out in 14 days.
in case someone wanted a different gray-challenge, I'll post the link:
http://www.woodmann.net/cgi-bin/Ultraboard/UltraBoard.cgi?action=Read&BID=8&TID=684&SID=
greets guys!
JaneK
February 20th, 2001, 17:49
Hi,
I know ppl are busy with the new project, but maybe someone can help with MixVibesPro (still).
I tried to find the correct serial, but without success. I start to suspect that it's not appearing in memory as a string, but rather some checks of single characters (one by one) is performed.
Is it possible at all or am I looking in the wrong place?
Thanks
JaneK
Kayaker
February 21st, 2001, 22:56
Hi Janek,
Heh, I had never looked at the s/n routine before. I traced what was happening to the s/n just enough to follow the code as it was being transferred from one memory address to another, ignoring the details, then I noticed a comparison starting at
:004censored

lea esi, dword ptr [esp+08] ;some 4 char number
:004censored

lea eax, dword ptr [esp+1A] ;your s/n
At first I couldn't really clue in on what was happening until I used the maximum length s/n for the edit box, then I realized there was a pattern it was expecting xxxxx-xxx-xxxx, because it breaks your s/n into these chunks. When I filled it this way it started to become clear what was happening in the routine. The 4 char number in esi is compared with the last 4 digits of your s/n. If you pass you continue to a routine which checks the middle 5 chars. This part's a little different, it's expecting a delimiter, but not the "-" (2D) that I had guessed at. 2 of the 5 chars can be "us" or "fr", though this doesn't seem to change any language setup. Finally, the 1st 5 chars are totally ignored because these are apparently the ones which determine what the final 4 chars should be. I don't know what their relationship is but if you find out let me know for interests sake.
If you can match up a working s/n (keep the 1st 5 chars the same and glean from the code what the rest should be), you find after all that trouble - it doesn't give a hoot what your name is!
If you need any uncensored help, just say so
Cheers,
Kayaker
JaneK
March 4th, 2001, 18:10
Hi Kayaker,
First of all thanks for your help. With your hints I managed to find the correct serial.
Here is what I have found so far:
Expected pattern is xxxxx/xxx/xxxx.
As you mentioned, 1st 5 characters are used for calculating the last part of the serial. Seems that hex notation is assumed, because I found them in eax exactly as they were entered in the dialog box.
In the middle part, 1st and 2nd char can be f and r and the 3rd one can be any number between 1 and 9.
Delimiter is "/".
Looks to me that entire serial never appears in memory as string (there are many correct serials).
I have to look a bit more in few places, but main job is done.
Thanks again
JaneK
Kiran
March 7th, 2001, 02:05
Hello everyone,
I have been working on this project as well. However, I have a problem using the TRACE functionality. I am trying to learn this advanced option in SI, following Kayaker's comments on this subject in order to solve this lesson. Well, I am not having muck luck. I tried to put a bpr between GetMenuItemID and the end of EnableMenuItem. That did not give me any results. Actually it does not show much... only 20 or so indexes which do not differ between an enabled item and a disabled item. So I tried from different locations without much success.
The only thing that I could think of was to TRACE small parts at a time from when the GetMenuItem gets call up until the end of EnableMenuItem. But that doesn't look too smart as there is a lot of code and nested calls in between, therefore, defeating the purpose of using TRACE.
Sooooo.... Kayaker, can you explain me how should I put the bpr?!? It does not look like I am fully comprehending the TRACE option in SI.
Also, when use TRACE can you go inside a call?!?
Hopefully, I am confusing only myself and no one else.
Thanks,
Kiran
Kayaker
March 7th, 2001, 20:53
Hi Kiran,
To get the Trace function to work OK for you, you should first make sure you've got enough memory allocated for the back trace buffer. The default is I think 8K, I normally use 16K which was enough for Mixvibes. You set it in winice.dat with the line TRA=16 or you can set it with the SoftIce loader. The buffer is linear in that once it's filled, that's it. So if it's too small, and you've got lots of traced instructions to index you may never see the final target breakpoint reached.
For this particular target set a BPX GetMenuItemID and click on the File menu. SI should immediately break. If you continue to press F5 you should see the 2nd stack parameter, or the zero-based position of the menu item, displayed in EAX. 0 for the 1st, 1 for the 2nd, etc. Save and SaveAs are 2 and 3.
Disable ALL other BP's other than GetMenuItemID and set your Trace. You can specify the memory range, but it's just as easy to set the whole program address range with 'BPR module T' where module is the name you see when you type TASK. Make sure you get the right module name, it's cut off after 8 letters in SI, but the BPR command will need the full name as listed by 'MOD' to work properly. (just make it easy and shorten the filename). Then set a BPX EnableMenuItem and press F5 again. The backtrace buffer should now be filled with all the instructions traced, including those within Calls, that are within the address range specified.
I usually hide the Code and Data windows with WC and WD then type 'SHOW 1' where 1 is the very last instruction traced, which *should* be EnableMenuItem if all went well. If you just type SHOW it will display the very first instructions traced, numbered somewhere in the 900's. You can use the PgUp/Dwn or arrow keys to move around. You can also check out the TRACE command as well, but I usually only use SHOW.
Unfortunately you can't easily save the backtrace as you see it displayed, though there is a way to dump the memory and convert at least the addresses, though not the opcodes, to a listing, though I've never bothered doing it. Usually I just look for interesting addresses to set BP's on or /screendump pages and compare them between enabled/disabled menu item tracings.
Make sure you disable the Trace BPR before you do anything else or it'll keep tracing when you exit SI, tying up the CPU and overwriting the buffer. Also be sure to use XRSET to clear the buffer when you want to start afresh.
Hope this works for you.
Cheers,
Kayaker
Kiran
March 8th, 2001, 00:54
Thanks Kayaker. I will try your suggestion and not use the memory range approach I was using.
Thanks,
Kiran
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.