You know, I like intelligent and handy software. I really do. But I hate with my all heart when the application (or the application's author?) is eee... "too smart". ;-) And what especially makes me nervous is when author calls some idiotic application's behavior "a feature". I think Skype is a nice example of it. Look at this:
I have the default system language in Windows set up as English, but the default one for the non-Unicode programs is set to Polish. Nothing wrong with it, right. So when I start Skype for the first time it happily detects this setting and switches its language accordingly to the Polish too. Chaaarming. ;-)
Now let's imagine that I want to change the default Skype's language permanently to English (well, I much prefer English UI in all apps, ok). Seems life is easy: click the main menu, then Tools --> Change language --> English ... and the language is changed. Now try to close Skype and open it again... What you you see: the application's language is immediately switched back to Polish! Ok, you may try to attack the problem from the different side: Tools --> Options --> Tab: General setting --> Languages combo: English, then Save. Unfortunately the effect is exactly the same: when Skype is restarted - it switches the language to the one set up as the default for non-Unicode programs (in my case: Polish). God knows why this proggy has such amazing feature, but believe me - to change the language manually after each restart is becoming pretty annoying after some time.
As usual, I google the problem and quickly found out that I am not alone: look here for example http://portableapps.com/node/21644. So can we do anything? Yes we can®! :-)
I wrote a small program which runs the Skype and then simulates mouse clicks on the main menu and kind of "pseudo-manually" switches the application's language to the default one (English). This is also a nice small example how you may access the main menu of the application "B" from the code of application "A" and execute some functionality in application "B". No worries, we are not "literally" moving the mouse cursor the the menu, but issuing some appropriate system messages - so everything is pretty elegant.
Ok, if someone needs only executables here they are (with the source code in Delphi):
- The one should be used with the Skype Portable (recommended): http://itsecuritylab.eu/files/...
- The one may be used with the regular Skype: http://itsecuritylab.eu/files/...
Usage is very simple: extract the executable and put it to the same folder where your SkypePortable.exe or Skype.exe is located and then run. My little program runs Skype, waits until it is loaded and switches the language to English. Job done! :-)
Some technical background
Ok, so this is how it works. First of all we have to find the Skype window in the system (assure it exists, so we may get it's handle and access its child elements). This is rather trivial, so no need to explain anything. Once the window is found this is what we are doing:
var menu: HMenu; id: integer; s: Array[0..255] of char; begin tmrMain.Enabled := false; h := findWindow(pchar('tSkMainForm.UnicodeClass'), nil); //--- find Skype's window menu := getMenu(h); //--- find the main menu GetMenuString(menu, 5, @s, 255, MF_BYPOSITION); //--- get the text of 6th menu item (should be '&Help') if string(s) <> '&Help' then //--- current language is NOT English begin menu := getMenu(h); //--- main menu menu := GetSubMenu(menu, 4); //--- find the 5th menu item //--- activate this (5th) menu item, so all subitems can be redrawn. This is IMPORTANT! SendMessage(h, WM_INITMENU, WPARAM(menu), 0); SendMessage(h, WM_INITMENUPOPUP, WPARAM(menu),0); menu := GetSubMenu(menu, 2); //--- find the 3rd submenu item id := GetMenuItemID(menu, 9); //--- 10th menu item (select "English") PostMessage(h, WM_COMMAND, id, 0); //--- click it! :-) end; SendMessage(h, WM_SYSCOMMAND, SC_MINIMIZE, 0); application.Terminate; end;
So 1st thing we have to do - we have to check what language is set up currently. We are getting the text of the 6th menu item and checking if it is equal to "&Help" or not. Currently it's "&Pomoc", which means the current language is not English (yea, it's Polish actually).
This is the code used for checking:
h := findWindow(pchar('tSkMainForm.UnicodeClass'), nil); //--- find Skype's window menu := getMenu(h); //--- find the main menu GetMenuString(menu, 5, @s, 255, MF_BYPOSITION); //--- get the text of 6th menu item (should be '&Help') if string(s) <> '&Help' then //--- current language is NOT English begin [...] end;
Now we have to iterate through the menus and sub-menus and run some action on the target item. Look at this code:
menu := getMenu(h); //--- main menu menu := GetSubMenu(menu, 4); //--- find the 5th menu item //--- activate this (5th) menu item, so all subitems can be redrawn. This is IMPORTANT! SendMessage(h, WM_INITMENU, WPARAM(menu), 0); SendMessage(h, WM_INITMENUPOPUP, WPARAM(menu),0); menu := GetSubMenu(menu, 2); //--- find the 3rd submenu item id := GetMenuItemID(menu, 9); //--- 10th menu item (select "English") PostMessage(h, WM_COMMAND, id, 0); //--- click it! :-)
Important detail: look at strings highlighted in red: this is important element of the code as the sub-menu with the list of languages is generated "on-the-fly" once the parent menu item is activated. Without it: the 10th menu item (language "English") simply does not exist, (hence can't be called).
One more remark: the proposed solution requires Skype user interface (Visual Style of the window) get running in "Classic Windows" mode.
- Knowledge sharing event: Risk-based approaches to protecting your data – London, Tuesday 19th April
- Training – Hacking and Securing Oracle Database (11g)
- Changed language does not persist when Skype is restarted: how to solve the annoying issue
- More 3D Fun with Kinect and Delphi. You can grab and save still 3D frames!
- Having Fun with Kinect and Delphi (examples of 2D and 3D visualization)
- Smuggling .NET code inside batch files. Impossible? Who said that?
- Cross-site scripting explained (video)
- Innocent comment regarding sensitive information disclosure…
- Pentesting privilege escalation in web applications
- TinyWeb: Pocket-size Portable Web Server With CGI And PHP Support (!)
- April 2011 (2)
- January 2011 (1)
- December 2010 (3)
- October 2010 (1)
- September 2010 (8)
- August 2010 (8)
- July 2010 (8)
- June 2010 (2)
- .NET (1)
- Binary application security (11)
- Cryptography (2)
- Delphi (12)
- Exploitation practice (16)
- Fun (5)
- Java (1)
- Kinect (2)
- Mobile devices security (1)
- Pentesting (15)
- PHP (2)
- Skype (3)
- SQL (5)
- SQL injection (6)
- Uncategorized (9)
- Windows security (6)
- No public Twitter messages.