Page 1 of 1
[Undocumented] Variables __CD__ & __APPDIR__
Posted: 23 Dec 2014 14:07
by carlos
Hello. I found a new undocumented variable, in addition to %__CD__% it is %__APPDIR__%
%__APPDIR__%have the path (with a backlash at the end) where the application that request the variable is located.
For example, if we run C:\Windows\system32\cmd.exe , %__APPDIR__% will expand to C:\Windows\system32\
If we copy cmd to C:\dev\cmd.exe and run it %__APPDIR__% will expand to C:\dev\
Also I re document the %__CD__%
%__CD__%have the current directory (with a backlash at the end) of the application that request the variable.
Both, really are pseudo environment variables, found in the function RtlQueryEnvironmentVariable_U of windows in ntdll.dll
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 23 Dec 2014 14:10
by carlos
I found %__APPDIR__% investigating %__CD__%. I suspect that %__CD__% was unrelated to environment variables of cmd.exe, because I programming a c code, and inside this application I change the directory of my application (not the directory of cmd.exe).
This was my output:
Code: Select all
C:\dev>test.exe
ExpandEnvironmentStringsW("%__CD__%")=C:\dev\
GetEnvironmentVariableW("__CD__")=C:\dev\
Directory changed to C:\
ExpandEnvironmentStringsW("%__CD__%")=C:\
GetEnvironmentVariableW("__CD__")=C:\
C:\dev>
This was my code:
test.c
Code: Select all
#include <windows.h>
#include <stdio.h>
DWORD WINAPI ExpandEnvironmentStrings(LPCTSTR lpSrc, LPTSTR lpDst, DWORD nSize);
DWORD WINAPI GetEnvironmentVariable(LPCTSTR lpName, LPTSTR lpBuffer,DWORD nSize);
void print__cd__(void);
void print__appdir__(void);
int main(int argc, char ** argv)
{
print__cd__();
if (! SetCurrentDirectoryW(L"C:\\")) {
wprintf(L"Cannot change to directory C:\\");
return 1;
}
wprintf(L"Directory changed to C:\\\n");
print__cd__();
getchar();
return 0;
}
void print__cd__()
{
DWORD chrs;
wchar_t buf[MAX_PATH];
chrs = ExpandEnvironmentStringsW(L"%__CD__%", buf, MAX_PATH);
buf[chrs] = 0;
wprintf(L"ExpandEnvironmentStringsW(\"%%__CD__%%\")=%ls\n", buf);
chrs = GetEnvironmentVariableW (L"__CD__", buf, MAX_PATH);
buf[chrs] = 0;
wprintf(L"GetEnvironmentVariableW(\"__CD__\")=%ls\n", buf);
}
and investigating I look the function RtlQueryEnvironmentVariable_U of windows in ntdll.dll and next to %__CD__% I found %__APPDIR__%
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 23 Dec 2014 14:47
by dbenham
Very interesting.
Another pseudo "environment variable" that operates at a very low level windows call.
Code: Select all
D:\test>echo %__appdir__%
C:\Windows\System32\
D:\test>set "__appdir__=override"
D:\test>set __
__appdir__=override
D:\test>echo %__appdir__%
C:\Windows\System32\
So a true environment variable can be defined, but you cannot retrieve the user specified value except via SET. This is showing the exact same behavior as %__CD__%. If so, than the behavior should be different on XP.
You may be interested in my StackOverflow Q&A:
Why can't I access a variable named __CD__ on Windows 7?I wonder if there are any more %__var__% variables yet to be discovered
Dave Benham
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 23 Dec 2014 15:45
by penpen
The behaviour using winXp home 32 bit is this:
Code: Select all
Z:\>echo %__appdir__%
C:\WINDOWS\system32\
Z:\>set "__appdir__=override"
Z:\>set __
__appdir__=override
Z:\>echo %__appdir__%
override
penpen
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 23 Dec 2014 20:44
by Liviu
dbenham wrote:I wonder if there are any more %__var__% variables yet to be discovered
It's not a "double-underscore" variable, but NUMBER_OF_PROCESSORS behaves the same way as __CD__ under Win7 (and, I assume, later).
Code: Select all
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\>echo %NUMBER_OF_PROCESSORS%
4
C:\>set NUMBER_OF_PROCESSORS
NUMBER_OF_PROCESSORS=4
C:\>set NUMBER_OF_PROCESSORS=1
C:\>echo %NUMBER_OF_PROCESSORS%
4
C:\>set NUMBER_OF_PROCESSORS
NUMBER_OF_PROCESSORS=1
C:\>
It also behaves like __CD__ under XP, too, where explicitly setting it _is_ reflected in both 'echo %var%' and 'set var' afterwards.
Liviu
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 23 Dec 2014 21:58
by dbenham
Whoa

That is a shocker

Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 23 Dec 2014 23:27
by carlos
Thanks Liviu.
NUMBER_OF_PROCESSORS in windows 8 is a pseudo variable (the unicode text "NUMBER_OF_PROCESSORS" is present in ntdll.dll), but in windows xp, it is not present in ntdll.dll, if you do this in xp:
Code: Select all
C:\dev>SET "NUMBER_OF_PROCESSORS="
C:\dev>ECHO %NUMBER_OF_PROCESSORS%
%NUMBER_OF_PROCESSORS%
but if you do the same on windows 8:
Code: Select all
C:\dev>SET "NUMBER_OF_PROCESSORS="
C:\dev>ECHO %NUMBER_OF_PROCESSORS%
4
In windows xp, NUMBER_OF_PROCESSORS is a real environment variable, and in windows 7 is a pseudo variable.
Thus, in windows xp are present the next pseudovariable:
and in windows 7:
Code: Select all
%__CD__%
%__APPDIR__%
%NUMBER_OF_PROCESSORS%
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 24 Dec 2014 10:09
by npocmaka_
Great !
Just took a look at ntdll.dll and its strings.
Found this:
EDIT.
it's not presented on my XP image.Probably only from windows 8 and above -
http://msdn.microsoft.com/en-us/library ... 20(v=vs.85).aspx
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 24 Dec 2014 11:04
by Squashman
I used the Sysinternals STRINGS.exe to see what I else we could dump from that DLL. I couldn't see much more.
Code: Select all
for /F "delims=" %G in ('strings -u -q ntdll.dll') do @if defined %G echo %G
output
Code: Select all
NUMBER_OF_PROCESSORS
__APPDIR__
__CD__
PROCESSOR_ARCHITECTURE
CommonProgramW6432
CommonProgramFiles(x86)
CommonProgramFiles
ProgramW6432
ProgramFiles(x86)
ProgramFiles
tmp
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 24 Dec 2014 11:22
by Squashman
Re: [Undocumented] Variables __CD__ & __APPDIR__
Posted: 26 Dec 2014 15:13
by npocmaka_
Squashman wrote:I used the Sysinternals STRINGS.exe to see what I else we could dump from that DLL. I couldn't see much more.
Code: Select all
for /F "delims=" %G in ('strings -u -q ntdll.dll') do @if defined %G echo %G
output
Be braver :
Code: Select all
@echo off
pushd %windir%\system32
for %%# in (*.dll *.exe) do (
rem echo ## %%# ##
for /F "delims=" %%G in ('strings -n 7 %%#') do (
@if defined %%G if /i %%G neq "temp" echo %%G
)
)
POPD
Have found this:
Again not available on the XP image .But not sure if its only on my machine.
It's visible with
SET USERDOMAIN so it's not dynamic pseudo variable , just cant find a documentation for it (
only this).