|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
Contents
IntroductionHave you ever wanted to change text on start button? If yes you probably know that in order to do that that you will need hex editor, digging in registry and resource editor. Using the code presented here you can rename your start button text with just one click. No more registry editing, hex editors and resource editors. Everything is done for you with just one click! What's more you can rename start button either for the whole system or for the current user only. Even Unicode is supported so now you start button can look like this:
Note: This program has been tested only on Windows XP SP2 with XP-style start menu so if you are using different version of Windows and/or have classic menu it might not work. BackgroundI was interested if start button text could be changed. So I googled and found this: Change Text on XP Start Button. I tried it and it worked. The disadvantage of that method is that for every change you should recompile explorer.exe and make changes to the registry. So I decided to write a program that would do all that for me. How start button text is changedTechnical partThe string which defines text of start button is hardcoded in explorer.exe If you use a hex editor and navigate to address 0xF60A4 you will see something like this:
Notice the string "start". Using the method described in above link I changed start menu text to "12345". When I opened it in hex editor and navigated to the same line I found string "12345" instead of start as I had expected. However when I used file comparison tool of the hex editor it revealed 239 differences. That was too much. Then I changed start button text to "54321". When I compared these two custom explorers I found only three differences. This was a better result. So I decided to write a program that would read everything up to string "12345 "from the custom explorer.exe, then append new text for the button and then append everything remaining. I tried it and it worked but there was one problem to deal with. Cracking five character limit of the start textOvercoming the five character limit of the start text was a little bit problematic but I found a tricky way. The problem is that as you can see from the picture above immediately before the string "start" in explorer.exe there is a byte with value 5 and it defines the length of the start button's text. You might think that you would change it to 6 and then insert 6 character long text but it just won't work. Even worse when you start Windows, taskbar will look very ugly and everything will be upside-down. The problem is that when you insert a 6 character long text you insert two extra bytes. To overcome this you will have to remove two bytes but how do you know which two bytes to remove? Also, what if you wanted 7 character long text? Or 8? Or 9? Or even 20? In that case you will need to remove extra 4 bytes, 6 bytes, 8 bytes or extra 30 bytes. So how do you know address of these bytes to remove from? To find out that I used resource editor and changed text on start button to various length strings and examined the generated explorer.exe. I wanted to find the pattern in the address of the bytes to remove. But there was a problem. The pattern wasn't obvious and even if there had been a pattern, it would not be easy to implement. The only way was to find a trick. After several days an idea came to me and it worked. The TrickThe trick is very simple. I changed start button text to 12345678901234567890 using resource editor. The compiled explorer.exe didn't contain extra 30 bytes and it worked well. The value of byte before the string "12345678901234567890" which shows the length of the text was 20. I decided to change this byte and leave the text untouched. I change it to 5 and it worked! Start button displayed "12345". So explorer.exe was fooled. It doesn't pay attention to text which goes over the length defined by the byte immediately before the text. Registry changesAfter the new explorer.exe has been generated you need to make changes to registry. If you navigate to the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon you will see a string there called Shell and its value is equal to explorer.exe. My program sets its value to the path of new explorer.exe But this will change the default shell for every user. To make it possible to change start button text for current user you will need to change shell for the user who is logged in. So we need to change Shell at HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon However you will discover that there is not such string. To solve the problem I created such string and set its value to the path of custom explorer.exe and it worked. Start button text was changed only in my user. Programming partWhat my application does is quite simple: It just creates a new explorer but the string "12345678901234567890" is replaced by the text user submits and the new length is inserted before the string. The creation process is quite simple. Firstly, A file which contains everything before the string "12345678901234567890" and its length (this file is called begin.exe in the solution folder) is copied to destination folder and length of user submitted text is inserted. Secondly the new string is appended. If the length of the new string is less then 20 then the remaining number of characters are inserted which won't be displayed on the button and then the remaining lines of explorer.exe are appended from the second file (this file is called end.exe in the solution folder). After creating a new explorer the application makes changes in the registry and displays a message box informing user about the work done. If the user chooses to the application will restart Windows which is necessary for the changes to take affect.Restarting WindowsIn order to restart windows I used WindowsController class from here. This class allows you to shutdown, restart or log user off.Using the code
Here is the function that does renaming and changes to the registry. As you can
see it takes new text for the start button as a parameter. The private bool rename(string newname) { if (!File.Exists("begin.exe") || !File.Exists("end.exe")) { MessageBox.Show("Source files not found", "error", MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } string explorerpath = ""; windir = Environment.GetEnvironmentVariable("WINDIR"); appdata = Environment.GetEnvironmentVariable("AppData") + "\\start button rename"; try { explorerpath = getpath(); if (File.Exists(explorerpath + "\\explorer.exe")) { File.Delete(explorerpath + "\\explorer.exe"); } //Copy beginning of custom exe to the destination folder File.Copy("begin.exe", explorerpath + "\\explorer.exe"); FileStream outstr = new FileStream(explorerpath + "\\explorer.exe", FileMode.Append, FileAccess.Write, FileShare.None); BinaryWriter outbr = new BinaryWriter(outstr); //Insert new length outbr.Write((short)newname.Length); //Insert new text byte[] input = Encoding.Unicode.GetBytes(newname); outbr.Write(input); //Insert some text that won't be displayed for (int j = 0; j < 20 - newname.Length; j++) { outbr.Write((short)j); } //Append end of custom exe FileStream infs = new FileStream("end.exe", FileMode.Open, FileAccess.Read, FileShare.None); BinaryReader inbr = new BinaryReader(infs); for (int i = 0; i < 1620; i++) { input = inbr.ReadBytes(16); outbr.Write(input); } input = inbr.ReadBytes(2); outbr.Write(input); inbr.Close(); infs.Close(); outbr.Close(); outstr.Close(); } catch (IOException) { MessageBox.Show("Error during accessing files", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } catch (Exception) { MessageBox.Show("Unkown error", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } //Make changes to the registry try { Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT"+ "\\CurrentVersion\\Winlogon", "Shell", ""); if (skinRadioButton1.Checked) { Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT"+ "\\CurrentVersion\\Winlogon", "Shell",explorerpath + "\\explorer.exe"); } else { Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT"+ "\\CurrentVersion\\Winlogon","Shell", explorerpath + "\\explorer.exe"); } } catch (System.UnauthorizedAccessException) { MessageBox.Show("Error accessing registry", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } catch (System.Security.SecurityException) { MessageBox.Show("Error accessing registry. Make sure you have enough rights.", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return true; } As you can see changes to the registry are made according to user's choice. Points of InterestIn order to display & on the start button you will have to type && Thanks Nishant Sivakumar for the comment. History1 June, 2007 - Initial release
|
||||||||||||||||||||||