Some experiments to retrieve the current username without calling whoami.exe or similar binaries.
Get the environment variables from the PEB structure and parse it to find the username.
-
Function NtQueryInformationProcess returns a "PROCESS_BASIC_INFORMATION" structure containing a pointer to the PEB base address.
-
The PEB structure contains a pointer "ProcessParameters" to a RTL_USER_PROCESS_PARAMETERS structure.
-
From that structure you can get a pointer "Environment" to the environment variables and a pointer "EnvironmentSize" to the size of the environment variables.
-
Reading the number of bytes indicated in "EnvironmentSize" from the address "Environment" as UNICODE text, parse the environment variables and print the one called "USERNAME". If you want all the env variables, check this repository
Get access to a token, find the user's SID in string format and translate it using the function LookupAccountSid.
-
Function NtOpenProcessToken creates an access token associated with the current process.
-
Function NtQueryInformationToken gets information from the token we created, using the value "tokenUser" (1) in the field "TOKEN_INFORMATION_CLASS" we get information about the username which is stored in the pointer "TokenInformation".
-
Function ConvertSidToStringSid converts the username's SID in binary format to string format.
-
Function LookupAccountSid takes the SID in string format and returns the username.
Get acccess to a token and a Policy object and get the username with the function LsaLookupSids.
-
Functions NtOpenProcessToken and NtQueryInformationToken are used like in method 2, return a pointer "TokenInformation" with the user's SID in binary format.
-
Function LsaOpenPolicy creates a handle to the Policy object in the current system.
-
Function LsaLookupSids takes a pointer to the SID and returns an structure LSA_TRANSLATED_NAME containing the username.
Create a named pipe and a secondary thread, write and read from the named pipe and get the username from the undocumented function NpGetUsername.
Get username if the computer is domain joined using the CoCreateInstance function as in MSDN example. It uses the class ADSystemInfoClass and the interfaces ADSystemInfo and IADsADSystemInfo from ActiveDS.dll, which are already in the project folder so you don't need the DLL.
If there is no connection with the AD:
If there is connection: