I was wondering if anybody knew how to get the strings that are available as descriptions for the windows Built-in accounts.
For example the Administrator is described as Built-in account for administering the computer/domain and the Guest is described as Built-in account for guest access to the computer/domain. Where can I find these strings in a language independent way?
I do not want to pull them out from the system (using say NetUserGetInfo API calls) because they may have been tampered with. Is there a dll or any other file that contains these strings?
The same goes for the default usernames (Administrator, Guest). Is there a library where they are stored so that I can get them out? Especially if the original names have been changed (and I still want to know what the original name was).
CF
Windows Built-In strings
46 posts
I think you can check the SID or somthing like that and tell who the original admin was
Thanks for the input Anders, but I do not think that this is what I am after ... If the original account has been renamed all I can get is the new name using its SID. What I need is to find, say in a French version of windows, what is the equivalent of 'Administrator' without asking the system for the administrator's SID (since that SID may point to a renamed account). The same for any other language ...
CF
CF
If I remember correctly, the Administrator *ALWAYS* has the same (special, reserved) SID...
Maybe my initial post was not clear enough …
I know that the admin's SID is ALWAYS S-1-5-xx-xxx-xxx-xxx-500 for the local machine (do not pay attention to the number of xs used here). However you can rename that account (change the username) from 'Administrator' or whatever it is in your language to anything you like. So the question was 'how do I find what the original name was, in any language, if all I have is the SID?' Obviously in english it would be 'Administrator' How about in any other language? Is there a file that contains those names?
For example, if you create a shortcut to cmd.exe and you name it @shell32.dll,-22022 then the above will show a localized version of 'Command Prompt'. So the string is picked from shell32.dll regardless of the language used and is always localized. Is there something similar for the default windows accounts?
...
CF
I know that the admin's SID is ALWAYS S-1-5-xx-xxx-xxx-xxx-500 for the local machine (do not pay attention to the number of xs used here). However you can rename that account (change the username) from 'Administrator' or whatever it is in your language to anything you like. So the question was 'how do I find what the original name was, in any language, if all I have is the SID?' Obviously in english it would be 'Administrator' How about in any other language? Is there a file that contains those names?
For example, if you create a shortcut to cmd.exe and you name it @shell32.dll,-22022 then the above will show a localized version of 'Command Prompt'. So the string is picked from shell32.dll regardless of the language used and is always localized. Is there something similar for the default windows accounts?
...
CF
You may want to read this interesting article and the linked resources to get an idea of why your approach seems to be a bad idea 🙂
http://blogs.msdn.com/michkap/archiv...27/507404.aspx
Here is a list of "well-known SIDs" for your reference:
And some sample code about how to deal with localized names etc.:
http://blogs.msdn.com/michkap/archiv...27/507404.aspx
Here is a list of "well-known SIDs" for your reference:
And some sample code about how to deal with localized names etc.:
🙂
Thanks for the tip, however it is still out of context ...
I am using the SID to get the name. The problem is that if the name has been altered by a user, I still want to find out what the original name was.
In other words, if in a Chinese system the administrator has been renamed to root, can you tell how to find out what the original username was, in Chinese? How do you do that? That's why I assumed that there may be a localized string somewhere that I could use ...
I do not have an approach yet, this is what I am trying to get through, I don't know how to do this, but I need to know what the original name was 🙂
CF
Thanks for the tip, however it is still out of context ...
I am using the SID to get the name. The problem is that if the name has been altered by a user, I still want to find out what the original name was.
In other words, if in a Chinese system the administrator has been renamed to root, can you tell how to find out what the original username was, in Chinese? How do you do that? That's why I assumed that there may be a localized string somewhere that I could use ...
I do not have an approach yet, this is what I am trying to get through, I don't know how to do this, but I need to know what the original name was 🙂
CF
Geez, first of all, why would you need the original name? It isn't useful anymore after the rename. One hint though: if I remember correctly, your "My Files" folder does not change when you rename your account. Dirty hack but probably functional 🙂
Taking a step backward here:
Why would you need to know the name of the Administrator account? It sounds a lot like perhaps all you really need is Administrator permissions, correct? If so, perhaps a plugin like the xtinfo plugin or the user manager plugin might be of more help.
But, maybe I'm just not seeing the whole picture here...😕
Why would you need to know the name of the Administrator account? It sounds a lot like perhaps all you really need is Administrator permissions, correct? If so, perhaps a plugin like the xtinfo plugin or the user manager plugin might be of more help.
But, maybe I'm just not seeing the whole picture here...😕
Geez, first of all, why would you need the original name?To avoid any further misunderstandings I should probably explain exactly what I am after:
I have a scenario where, after renaming the Administrator account in any language I want to create a fake account called 'Administrator', or whatever that name should be in the local language. The new account is stripped from all its privileges and is disabled by default. Some people feel that this will save their system from an attack that will try to get the administrator's password or some other info/function. In my point of view this is useless since, if I where to hack anything out of a system, I would use the SID of the administrator and not the username.
However, the need remains in the above scenario to create an account called Administrator. In the rare case that the original admin account has already been renamed, there is no way (to my knowledge) to get the original name. In a US/UK version of windows, that's easy, you call that account 'Administrator'. What about in the rest of the languages? Hence my question: How do I find the default name of the admin account? Is there a string stored somewhere?
I hope this is as clear as I think it is ... The 'dirty hack' suggested by OldGrumpy is the only option until now, but I am still thinking that the system stores the default names in some dll and then the APIs are reading them.
CF
I'll post that question to a specialist board. Let's see what they come up with 🙂 Maybe these accounts are only created by the Windows installation program 😉 I'll keep you updated on the results.
> How do I find the default name of the admin account? Is there a string stored somewhere?
Yes there is. You can retreive the info from a DLL resource string. Do first on a clean OS a search in ALL files (suprgrep) and the ntake a resource hacker e.g. http://www.heaventools.com/ PE tools etc.
Change the resource, retry if it worked.
Yes there is. You can retreive the info from a DLL resource string. Do first on a clean OS a search in ALL files (suprgrep) and the ntake a resource hacker e.g. http://www.heaventools.com/ PE tools etc.
Change the resource, retry if it worked.
Onad, I did that today on my W2K machine, and couldn't find any suitable occurrences 🙂
Try using PE-Explorer on something like advapi32.dll and you'll see why it wont work 🙂
I have tried looking for the string 'Administrator' before but could not find it. Not to mention that using PEExplorer for each DLL in system32 is probably not the way to go. Or at least not until you post the question in case somebody has alreday tried it before 😁
CF
I have tried looking for the string 'Administrator' before but could not find it. Not to mention that using PEExplorer for each DLL in system32 is probably not the way to go. Or at least not until you post the question in case somebody has alreday tried it before 😁
CF
You can simply search for string (both ANSI and Unicode) in multiple files - there's plenty of tools that can do that, (including some of the better text editors) out there, you don't need PEExplorer for that.
However, these are probably set during installation of OS and such default names/desriptions would be present only somewhere in setup files on CD.
So probably there's no reliable way to get them without asking user to insert installation disk.
However, these are probably set during installation of OS and such default names/desriptions would be present only somewhere in setup files on CD.
So probably there's no reliable way to get them without asking user to insert installation disk.
galil's suggestion made me look up again inside the system folder, for unicode equivalents of the strings I was after. I finally used UltraEdit to do a unicode search and got all the strings I was after in samsrv.dll. I am not sure if this is what I am after but it is a good start 🙂
I will experiment with that file to see if I can indeed get what I want but if anyone knows of another way it would be most helpful if you could post it here
CF
I will experiment with that file to see if I can indeed get what I want but if anyone knows of another way it would be most helpful if you could post it here
CF
I think I managed to achieve what I was after, although I cannot check it on another language since I am running an english version of windows.
Here is what I did:
I think this should work for every system. The main trick is the usage of the language ID (here I pass it as zero on the 4th parameter of FormatMessage). A better way would be to detect the system default (or the user default) language and then pass it on to the system call.
As always any input is welcome 🙂
CF
Here is what I did:
I had to call FormatMessageW twice: the first time I got the size of the message that I extracted and the second time I allocated an appropriate buffer to store it. Since it is a unicode string I don't want to pass it to a variable in NSIS, but leave it at a buffer instead and then pass that buffer to the next function (not shown here)!define LOAD_LIBRARY_AS_DATAFILE 0x00000002
!define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
!define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
System::Call 'kernel32::LoadLibraryExW(w "$SYSDIR\SAMSRV.DLL", i n, i ${LOAD_LIBRARY_AS_DATAFILE}) i .R0'
StrCpy $0 ${FORMAT_MESSAGE_FROM_HMODULE}
IntOp $0 $0 + ${FORMAT_MESSAGE_ALLOCATE_BUFFER}
StrCpy $1 8192 ; messageID for string 'Administrator'
System::Call 'kernel32::FormatMessageW(i r0, i R0, i r1, i 0, *w .R3, i 0, i n) i .R4'
IntOp $9 $R4 * 4
System::Call '*(&w$9)i.R3'
System::Call 'kernel32::FormatMessageW(i r0, i R0, i r1, i r2, i R3, i r3, i n) i .R4 ?e'
System::Call '*$R3(w .R9)'
System::Call 'kernel32::LocalFree(i R3)i.R8'
System::Free $R0
I think this should work for every system. The main trick is the usage of the language ID (here I pass it as zero on the 4th parameter of FormatMessage). A better way would be to detect the system default (or the user default) language and then pass it on to the system call.
As always any input is welcome 🙂
CF
I'm very surprised because I though my favorite search tool would be capable of doing unicode searches too. Obviously, it is not 🙁
Thanks for the investigations, CancerFace. BTW, and fully OT, why did you choose this strange nickname? 🙂
Thanks for the investigations, CancerFace. BTW, and fully OT, why did you choose this strange nickname? 🙂
Hmmm, it may be a bit more complicated after all. By default FormatMessage appends a trailing new line character at the end of the message unless an array of formatting instructions is supplied. And this is where I am lost since this page doesn't make much sense 🙁
I'll have to play a bit more with this ...
Also I should probably unload the DLL using FreeLibrary :
CF
[Edit] Looking at the code I posted again I reallized that I am allocating far more space than needed for my buffer. No need to run the FormatMessage function twice, just create the buffer and call the function in one go:
I'll have to play a bit more with this ...
Also I should probably unload the DLL using FreeLibrary :
instead of using System::FreeSystem::Call 'kernel32:FreeLibrary(i R1) i.R8'
BTW, and fully OT, why did you choose this strange nickname?I chose that nickname when I was 18 or so and have been using it ever since without realizing most of the time how awful it sounds ... It used to be a joke from a sailing instructor that I had as a kid, and I can assure you that it sounded funny in my mother language (Greek) but certainly not in English ... Nothing to do with my face or any form of cancer, if that's what you're asking 😁
CF
[Edit] Looking at the code I posted again I reallized that I am allocating far more space than needed for my buffer. No need to run the FormatMessage function twice, just create the buffer and call the function in one go:
!define LOAD_LIBRARY_AS_DATAFILE 0x00000002
!define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
!define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
System::Call 'kernel32::LoadLibraryExW(w "$SYSDIR\SAMSRV.DLL", i n, i ${LOAD_LIBRARY_AS_DATAFILE}) i .R0'
StrCpy $0 ${FORMAT_MESSAGE_FROM_HMODULE}
IntOp $0 $0 + ${FORMAT_MESSAGE_ALLOCATE_BUFFER}
StrCpy $1 8192 ; messageID for string 'Administrator'
System::Call '*(&w4)i.R3'
System::Call 'kernel32::FormatMessageW(i r0, i R0, i r1, i r2, i R3, i r3, i n) i .R4'
System::Call '*$R3(w .R9)'
System::Call 'kernel32::LocalFree(i R3)i.R8'
System::Call 'kernel32:FreeLibrary(i R1) i.R8'
I think it's worth to expand the functionality and put it into a separate plugin. When I get to have some idle time at my hands, I'll take a shot at it. The code will look much nicer and cleaner when all that formatting stuff is put into a dll. And the string manipulation will become easier, too 😉
This is tricky.
The string that I am extracting from SAMSRV.DLL has a new line appended at its end. I do not want to copy the string to an NSIS variable since it is unicode, but I want to get rid of the new line. Is there an easy way to trim a string while it exists on a memory buffer, without getting it into a variable? The FormatMessage API call returns the number of TCHARS stored in the buffer (including the new line?) so I also know its size.
I can't seem to find an easy way to do this. 😠
Any input is welcome as usual
CF
The string that I am extracting from SAMSRV.DLL has a new line appended at its end. I do not want to copy the string to an NSIS variable since it is unicode, but I want to get rid of the new line. Is there an easy way to trim a string while it exists on a memory buffer, without getting it into a variable? The FormatMessage API call returns the number of TCHARS stored in the buffer (including the new line?) so I also know its size.
I can't seem to find an easy way to do this. 😠
Any input is welcome as usual
CF
I just had a look at the resources of samsrv.dll and it has no new line char at the end. Did you make sure to create a buffer large enough to carry the wide string and a terminating wide char (zero)? Did you fill the buffer with zeros before using it? It's a common mistake to allocate a buffer and just use it. A call to RtlZeroMemory doesn't take much time but can help a lot 🙂
I have to take a look at the plugin SDK before I can write up an appropriate plugin. But I am sure it's much more comfort to have a plugin sorting out all that crap 😉
And by the way, wouldn't it be nice to have the string converted to ANSI? I know there are pros and cons about that, what do you think?
I have to take a look at the plugin SDK before I can write up an appropriate plugin. But I am sure it's much more comfort to have a plugin sorting out all that crap 😉
And by the way, wouldn't it be nice to have the string converted to ANSI? I know there are pros and cons about that, what do you think?
Check out my previous posts, the whole point is to have the string in a buffer as unicode. The buffer is allocated by the FormatMessage function automatically (I am using ${FORMAT_MESSAGE_ALLOCATE_BUFFER}) so it doesn't really matter what I allocate. I could even use '*(&w1)i.R3' and still the API would expand this, in order to accommodate the string. Not to mention that if I try to allocate the buffer myself (without allowing the API to do so) I don't get anything out. That's why at some point I was calling the function twice so that I would get the string size first, and then allocate a buffer based on that size.
The new line is appended by the API and there should be an easy way to get rid of it. I was unable to track down something similar on the web, since all the examples I came across use 'i n' or 'i 0' as the last parameter for the call (ie no formatting array). According to MSDN it should be possible to define formatting options. I found a page that shows how to use different inserts in order to format a message but this doesn't make any sense in my case. I should be able to use an escape sequence (%0) to tell the function to remove the new line but I have failed so far to achieve that ...
Thanks for the input though 🙂
CF
The new line is appended by the API and there should be an easy way to get rid of it. I was unable to track down something similar on the web, since all the examples I came across use 'i n' or 'i 0' as the last parameter for the call (ie no formatting array). According to MSDN it should be possible to define formatting options. I found a page that shows how to use different inserts in order to format a message but this doesn't make any sense in my case. I should be able to use an escape sequence (%0) to tell the function to remove the new line but I have failed so far to achieve that ...
Thanks for the input though 🙂
CF
From looking at how FormatMessageW works, you have to supply the %0 at the end as wide chars. Did you try that? If you supply the wide char equivalent of "%1%0" as the formatting template to the API, you should get what you want 🙂
If you supply the wide char equivalent of "%1%0" as the formatting template to the API, you should get what you wantHaven't figured how to do this yet. I think this can be done if you extract the string from the buffer, but I may be wrong ... 🙂
However I just realized that if you look at something for looooong enough you tend to forget what it says ...
The function ignores regular line breaks in the message definition text. The function stores hard-coded line breaks in the message definition text into the output buffer. The function generates no new line breaks.So if I add FORMAT_MESSAGE_MAX_WIDTH_MASK to the call the line break disappears! I am still left with a space at the end of the string but I am sure the answer in getting rid of that is here as well 🙂
So now this is working and I am not getting the new line appended:
CF!define LOAD_LIBRARY_AS_DATAFILE 0x00000002
!define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
!define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
!define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
System::Call 'kernel32::LoadLibraryExW(w "$SYSDIR\SAMSRV.DLL", i n, i ${LOAD_LIBRARY_AS_DATAFILE}) i .R0'
StrCpy $0 ${FORMAT_MESSAGE_FROM_HMODULE}
IntOp $0 $0 + ${FORMAT_MESSAGE_ALLOCATE_BUFFER}
IntOp $0 $0 + ${FORMAT_MESSAGE_MAX_WIDTH_MASK}
StrCpy $1 8192 ; messageID for string 'Administrator'
StrCpy $2 0
StrCpy $3 0
System::Call '*()i.R3'
System::Call 'kernel32::FormatMessageW(i r0, i R0, i r1, i r2, i R3, i r3, i n) i .R4'
System::Call '*$R3(w .R9)'
System::Call 'kernel32::LocalFree(i R3)i.R8'
System::Call 'kernel32:FreeLibrary(i R1) i.R8'
[Edit] I kept forgetting to define $2 and $3 as 0 throughout the thread ...
I saw that statement in the docs, too - I just wasn't sure about what it would do. MSDN tends to be cryptic 😉 Can't you just get the string length and write two zeros at the end of it? 🙂 Additional zero bytes won't do any harm as long as you don't write beyond the end of the buffer.
I am stuck with this. Although I get the wide string in a buffer, a space is appended at the end and I do not know how to get rid of it. I tried copying the buffer over to a shorter one with no success. I tried setting the size of the buffer before calling FormatMessage (removing the FORMAT_MESSAGE_ALLOCATE_BUFFER parameter and using the 6th parameter to define the buffer size) without any results either. If anyone can see a way out I will appreciate the help 🙂
CF
CF
Tried to specify /SIZE for System::Copy?
Without any success. For any size (>2) the whole string with the space at the end is copied over to the new buffer even if the new buffer is allocated in advance:
CF
$R9 always contains a space at the end ...System::Alloc 2
Pop $R6
System::Copy /2 $R6 $R3
System::Call '*$R6(w.R9)'
CF
I guess it would be a good idea to convert it to a plugin as already suggested. There is no API for trimming newlines that I could find on MSDN.
-Stu
-Stu