📚 OpenRCE is preserved as a read-only archive. Launched at RECon Montreal in 2005. Registration and posting are disabled.








Flag: Tornado! Hurricane!


Created: Friday, August 3 2007 10:16.24 CDT Modified: Friday, August 3 2007 10:17.01 CDT
Printer Friendly ...
Windows Vista environment variables
Author: GynvaelColdwind # Views: 5047

Hi,

I'm currently writing a tutorial (in polish) about Windows .bat scripts. While doing it, I came up with a question: What is the maximum size of a value of an environment variable ? The answer isn't so simple as it may seem.

Let's start with the .bat side of the problem. In this scripting language there is a complex instruction called SET that can set environment variables, enumerate environment variables, prompt the users for values, and even do math. I'll focus on the variable handling side of SET.

The syntax is simple: SET name=value. If we want to display the value of variable name, then SET name or SET ne will do.

So now we write SET sth=AAAAAAAAAAA....1.megabyte.of.A..AAAA and check the systems maximum environment variable length. Oh ? No. Wait. The cmd.exe interpreter says something about "line too long". Oh. So let's check maximum lengths of lines in that case!

Windows NT4  : 2048
Windows 2000 : 2048
Windows XP   : 8192
Windows 2003 : 8192
Windows Vista: it depends

Microsoft Windows Vista is a strange case. Mainly if there is the SET command present, the lines length is unlimited. So setting an environment variable with SET under Vista is not limited by the interpreter. Rather then that, it is limited by the system! Or is it ?

SET command is implemented using SetEnvironmentVariableW API. We can read in MSDN:

The total size of the environment block for a process may not exceed 32,767 characters.

OK. But let's test this. Let's set a 1mb variable data and use SET to print it out. The system should truncate it to 32767 bytes, or less. I've have run a few tests that went like this:
1. Set up the 1mb variable
2. Execute a Windows XXX interpreter
3. Run SET to show the variable

The results are:
Windows Vista: 8192 bytes, \n char was "eaten"
Windows 2003 : The variable was not shown
Windows XP   : The variable was not shown
Windows 2000 : The variable was not shown
Windows NT4  : The interpreter has crashed

OK. It looks like the cmd.exe's SET can't display large variables. I've made a small C program that enumerated environmental variables using the char *envp parameter of main() function.

I've run it only on Vista at this time, and it showed that the whole 1mb of data was saved in the environment variable!

Didn't MSDN said something about there being a limit?

As I said earlier, SET is implemented by SetEnvironmentVariableW. And yes, SetEnvironmentVariableW allows creating environmental variables with an unlimited (limited-by-memory ofc) size (I've checked with 512mb, it works).

But the ANSI version of the API, SetEnvironmentVariableA, does not allow variables larger then 32727. Strange, A version has a size check, W version doesn't. Very strange.

After a little analysis it seems that neither version has a check. The ANSI version fails because RtlInitAnsiStringEx API doesn't allow wide-char string larger then 0xFFFE:


cmp eax, 0FFFEh ; EAX == length of string in wide char
ja loc_ERROR
...
ERROR:
mov eax, 0C0000106h ; STATUS_NAME_TOO_LONG
pop ebp
retn 8


OK. So ...W works with large variables, ...A doesn't. Is this the case on other windows versions ? A simple test program will show that:


#include <stdio.h>
#include <windows.h>

static char big_c[1024*1024];
static short big_s[1024*1024];

int
main(void)
{
  int i;

  for(i = 0; i < 1024*1024 - 1; i++)
  {
    big_c[i] = 'A';
    big_s[i] = 'A';
  }

  printf("W: %i\n", SetEnvironmentVariableW(L"S",big_s));
  printf("A: %i\n", SetEnvironmentVariableA("A",big_c));

  system("cmd.exe");

  return 0;
}



It outputs 0 on fail and 1 on OK. It tests the ...W and ...A versions of the commands with a 1mln chars variable. I've run this code on few Windows versions, and here are the results:

Windows Vista: W 1, A 0
Windows XP   : W 0, A 0
Windows 2000 : W 1, A 0
Windows NT4  : W 1, A 0

At the executed shell, I've also run SET and the envp enumerating tool to see what's up:

Windows Vista: SET shows 8192, envp has all the data
Windows 2000 : SET skips the variable, envp shows 32769 chars (including the variable name)
Windows NT4  : SET crashes cmd.exe, envp shows 32770 chars (including the variable name)

Interesting. Does Vista have more in common with 2000 then XP ? Why does it allow large env. variables (they are well handled and does not crash anything... but they eat a lot of RAM... try setting a 128mb env value and running 10 calc.exe ;>). Only MS knows ;>>>

G.C.




Add New Comment
Comment:









There are 31,328 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06
Question about memor...
Dec/12


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit