нетивный аналог GetTempFileName

Тема в разделе "WASM.WIN32", создана пользователем 984259h, 20 мар 2011.

  1. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    Всем привет интересует вопрос как на Native получить темповый путь с рандомным названием файла начал с этого
    на win api есть ф-я GetTempPath сделал так
    Код (Text):
    1.   WCHAR buffer[0x1FF];
    2.   UNICODE_STRING szwStr,out_szwStr;
    3.   RtlInitUnicodeString(&szwStr,L"TEMP");
    4.      out_szwStr.Buffer = buffer;
    5.      out_szwStr.Length = 0x1FF;
    6.      out_szwStr.MaximumLength = sizeof(buffer);
    7.   NTSTATUS NtStatus = RtlQueryEnvironmentVariable_U(NULL,&szwStr,&out_szwStr);  
    8.   if(NT_SUCCESS(NtStatus))
    9.   {
    10.  
    11.   }
    интерует вопрос с GetTempFileName ?
    также на сколько я понимаю RtlQueryEnvironmentVariable_U это тоже надстройка есть более глубокое описание ?
     
  2. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    дизасм в руки, который быстро наведёт на PEB
     
  3. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    RET
    Код (Text):
    1. Peb->ProcessParameters->Environment_U
    По поводу RtlQueryEnvironmentVariable_U а если в среде нету темпа то она читает с реестра ???
     
  4. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Откуда загрузчик винды берёт - от туда и возьмет))
     
  5. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    извините но мне не совсем понятно ...
    вот исходник винды
    Код (Text):
    1. NTSTATUS
    2. RtlQueryEnvironmentVariable_U(
    3.     IN PVOID Environment OPTIONAL,
    4.     IN PUNICODE_STRING Name,
    5.     IN OUT PUNICODE_STRING Value
    6.     )
    7. {
    8.     NTSTATUS Status;
    9.     UNICODE_STRING CurrentName;
    10.     UNICODE_STRING CurrentValue;
    11.     PWSTR p;
    12.     PPEB Peb;
    13.  
    14.     Status = STATUS_VARIABLE_NOT_FOUND;
    15.     Peb = NtCurrentPeb();
    16.  
    17.     try {
    18.         if (ARGUMENT_PRESENT( Environment )) {
    19.             p = Environment;
    20.             if (*p == UNICODE_NULL) {
    21.                 leave;
    22.                 }
    23.             }
    24.         else {
    25.             //
    26.             // Acquire the Peb Lock for the duration while we munge the
    27.             // environment variable storage block.
    28.             //
    29.  
    30.             RtlAcquirePebLock();
    31.  
    32.             //
    33.             // Capture the pointer to the current process's environment variable
    34.             // block.
    35.             //
    36.  
    37.             p = Peb->ProcessParameters->Environment;
    38.  
    39.             }
    40. #if DBG
    41.         if (*p == UNICODE_NULL)
    42.             DbgPrint( "RTL: QEV - Empty Environment being searched: %08x\n", p);
    43.         else if ((UCHAR)((*p) >> 8) != '\0')
    44.             DbgPrint( "RTL: QEV - Possible ANSI Environment being searched: %08x\n", p);
    45. #endif
    46.  
    47.         if ( RtlpEnvironCacheValid && p == Peb->ProcessParameters->Environment ) {
    48.             if (RtlEqualUnicodeString( Name, &RtlpEnvironCacheName, TRUE )) {
    49.  
    50.                 //
    51.                 // Names are equal.  Always return the length of the
    52.                 // value string, excluding the terminating null.  If
    53.                 // there is room in the caller's buffer, return a copy
    54.                 // of the value string and success status.  Otherwise
    55.                 // return an error status.  In the latter case, the caller
    56.                 // can examine the length field of their value string
    57.                 // so they can determine much memory is needed.
    58.                 //
    59.  
    60.                 Value->Length = RtlpEnvironCacheValue.Length;
    61.                 if (Value->MaximumLength >= RtlpEnvironCacheValue.Length) {
    62.                     RtlMoveMemory( Value->Buffer,
    63.                                    RtlpEnvironCacheValue.Buffer,
    64.                                    RtlpEnvironCacheValue.Length
    65.                                  );
    66.                     //
    67.                     // Null terminate returned string if there is room.
    68.                     //
    69.  
    70.                     if (Value->MaximumLength > RtlpEnvironCacheValue.Length) {
    71.                         Value->Buffer[ RtlpEnvironCacheValue.Length/sizeof(WCHAR) ] = L'\0';
    72.                         }
    73.  
    74.                     Status = STATUS_SUCCESS;
    75.                     }
    76.                 else {
    77.                     Status = STATUS_BUFFER_TOO_SMALL;
    78.                     }
    79.                 goto environcachehit;
    80.                 }
    81.             }
    82.  
    83.         //
    84.         // The environment variable block consists of zero or more null
    85.         // terminated UNICODE strings.  Each string is of the form:
    86.         //
    87.         //      name=value
    88.         //
    89.         // where the null termination is after the value.
    90.         //
    91.  
    92.         if (p != NULL) while (*p) {
    93.             //
    94.             // Determine the size of the name and value portions of
    95.             // the current string of the environment variable block.
    96.             //
    97.  
    98.             CurrentName.Buffer = p;
    99.             CurrentName.Length = 0;
    100.             CurrentName.MaximumLength = 0;
    101.             while (*p) {
    102.                 //
    103.                 // If we see an equal sign, then compute the size of
    104.                 // the name portion and scan for the end of the value.
    105.                 //
    106.  
    107.                 if (*p == L'=' && p != CurrentName.Buffer) {
    108.                     CurrentName.Length = (USHORT)(p - CurrentName.Buffer)*sizeof(WCHAR);
    109.                     CurrentName.MaximumLength = (USHORT)(CurrentName.Length+sizeof(WCHAR));
    110.                     CurrentValue.Buffer = ++p;
    111.  
    112.                     while(*p) {
    113.                         p++;
    114.                         }
    115.                     CurrentValue.Length = (USHORT)(p - CurrentValue.Buffer)*sizeof(WCHAR);
    116.                     CurrentValue.MaximumLength = (USHORT)(CurrentValue.Length+sizeof(WCHAR));
    117.  
    118.                     //
    119.                     // At this point we have the length of both the name
    120.                     // and value portions, so exit the loop so we can
    121.                     // do the compare.
    122.                     //
    123.                     break;
    124.                     }
    125.                 else {
    126.                     p++;
    127.                     }
    128.                 }
    129.  
    130.             //
    131.             // Skip over the terminating null character for this name=value
    132.             // pair in preparation for the next iteration of the loop.
    133.             //
    134.  
    135.             p++;
    136.  
    137.             //
    138.             // Compare the current name with the one requested, ignore
    139.             // case.
    140.             //
    141.  
    142.             if (RtlEqualUnicodeString( Name, &CurrentName, TRUE )) {
    143.                 //
    144.                 // Names are equal.  Always return the length of the
    145.                 // value string, excluding the terminating null.  If
    146.                 // there is room in the caller's buffer, return a copy
    147.                 // of the value string and success status.  Otherwise
    148.                 // return an error status.  In the latter case, the caller
    149.                 // can examine the length field of their value string
    150.                 // so they can determine much memory is needed.
    151.                 //
    152.  
    153.                 Value->Length = CurrentValue.Length;
    154.                 if (Value->MaximumLength >= CurrentValue.Length) {
    155.                     RtlMoveMemory( Value->Buffer,
    156.                                    CurrentValue.Buffer,
    157.                                    CurrentValue.Length
    158.                                  );
    159.                     //
    160.                     // Null terminate returned string if there is room.
    161.                     //
    162.  
    163.                     if (Value->MaximumLength > CurrentValue.Length) {
    164.                         Value->Buffer[ CurrentValue.Length/sizeof(WCHAR) ] = L'\0';
    165.                         }
    166.  
    167.                     if ( !Environment || Environment == Peb->ProcessParameters->Environment) {
    168.                         RtlpEnvironCacheValid = TRUE;
    169.                         RtlpEnvironCacheName = CurrentName;
    170.                         RtlpEnvironCacheValue = CurrentValue;
    171.                         }
    172.  
    173.                     Status = STATUS_SUCCESS;
    174.                     }
    175.                 else {
    176.                     Status = STATUS_BUFFER_TOO_SMALL;
    177.                     }
    178.                 break;
    179.                 }
    180.             }
    181. environcachehit:;
    182.         }
    183.     finally {
    184.         //
    185.         // If abnormally terminating, assume access violation.
    186.         //
    187.  
    188.         if (AbnormalTermination()) {
    189.             Status = STATUS_ACCESS_VIOLATION;
    190.             }
    191.  
    192.         //
    193.         // Release the Peb lock.
    194.         //
    195.  
    196.         if (!ARGUMENT_PRESENT( Environment )) {
    197.             RtlReleasePebLock();
    198.             }
    199.         }
    200.  
    201.     //
    202.     // Return status.
    203.     //
    204.  
    205.     return( Status );
    206. }
     
  6. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Да ничего она не возьмет, она на входе получает блок окружения, и просто парсит его. О реестре она вообще ничего не знает. А GetTempFileName генерит имя файла и делает GetFileAttributes.
     
  7. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    о каком блоке окружения идет речь PEB ???
    вот мой PEB
    [​IMG]
     
  8. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    [​IMG]
     
  9. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    всем спасибо дошло )) тупанул.
    По поводу GetTempFileName она просто рандумно генериит названия файла ?
    или там может какая то ф-я есть промежуточная ?
     
  10. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    984259h открыть kernel32 в иде религия не позволяет?
     
  11. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    onSide
    позволяет )))
     
  12. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    написал такую простенькую ф-ю и не могу понять где ошибка когда отлаживаю все ОК когда просто запускаю экзешник функция слетает не могу понять где собака зарыта
    Код (Text):
    1. BOOL NtGetTempPath(PWCHAR szwInEnvironment, PWCHAR pBuff)
    2. {
    3.   BOOL bRet = FALSE;
    4.   PPEB pPeb;
    5.   __asm   {
    6.     push eax
    7.     mov eax, fs:[0x30]
    8.     mov [pPeb], eax
    9.     pop eax }
    10.   // pointer to process environment
    11.   int i = 0;
    12.   BOOL bChecked = FALSE;
    13.   //RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)pPeb->FastPebLock);
    14.   PWCHAR Environment = pPeb->ProcessParameters->Environment;
    15.   // allocate memory
    16.   PVOID pHeaps[1];
    17.   RtlGetProcessHeaps(1,(PVOID*)&pHeaps);
    18.   if (pHeaps[0] != NULL)
    19.   {
    20.      PWCHAR pMem = (PWCHAR)RtlAllocateHeap(pHeaps[0],HEAP_ZERO_MEMORY,0xFF);
    21.      if (pMem != NULL)
    22.      {
    23.         if (*Environment == L'=')
    24.         {  
    25.            while(*Environment)
    26.            {
    27.               while(*Environment && *Environment != L'=')
    28.               {
    29.                  pMem[i++] = *Environment++;
    30.               }
    31.               if (MyStrCmpW(szwInEnvironment,pMem) == 0 )
    32.               {
    33.                 Environment++;
    34.                 MyMemCpy(pBuff,Environment,MyStrLenW(Environment)*sizeof(WCHAR));
    35.                 bChecked = TRUE;
    36.                 bRet = TRUE;
    37.               }
    38.               i = 0;
    39.               if (bChecked == TRUE) break;
    40.               MyZeroMemory(pMem,MyStrLenW(pMem)*sizeof(WCHAR),0);
    41.               Environment++;
    42.            }
    43.          }
    44.          RtlFreeHeap(pHeaps[0],HEAP_NO_SERIALIZE,pMem);
    45.      }
    46.   }
    47.   //RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)pPeb->FastPebLock);
    48.   return bRet;
    49. }
    ну собственно вызов
    Код (Text):
    1.   WCHAR buffer[0xFF];
    2.   MyZeroMemory(buffer,sizeof(buffer),0);
    3.   NtGetTempPath(L"TEMP",buffer);
    4.   MessageBoxW(0x00,buffer,NULL,0x40);
     
  13. 984259h

    984259h New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2007
    Сообщения:
    194
    Делаю с RtlQueryEnvironmentVariable_U все срабатывает на ура )
    Код (Text):
    1.   WCHAR buffer[0xFF];
    2.   MyZeroMemory(buffer,sizeof(buffer),0);
    3.  
    4.   UNICODE_STRING InUnStr;
    5.   RtlInitUnicodeString(&InUnStr,L"TEMP");
    6.  
    7.   UNICODE_STRING OutUnStr;
    8.   OutUnStr.Buffer = buffer;
    9.   OutUnStr.Length = OutUnStr.MaximumLength = 0xFF;
    10.  
    11.   RtlQueryEnvironmentVariable_U(NULL,&InUnStr,&OutUnStr);
    12.  
    13.   MessageBoxW(0x00,buffer,NULL,0x40);