TLS

Iniciado por dewolo, 16 Octubre 2011, 17:44 PM

0 Miembros y 1 Visitante están viendo este tema.

dewolo

amigoz, quisiera saber acerca de TLS cuando usarlo en que casos me conviene usarlo y como se usa. me han recomendado usarlo pero no se como, quisiera saber mas acerca de la utilidad y de como/cuando aplicarlo, un ejemplo algo, gracias


Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dewolo

#2
Cita de: Eternal Idol en 16 Octubre 2011, 17:49 PM
Thread Local Storage.

Using Thread Local Storage.

ta bueno el code

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

#define THREADCOUNT 4
DWORD dwTlsIndex;

VOID ErrorExit(LPSTR);

VOID CommonFunc(VOID)
{
  LPVOID lpvData;

// Retrieve a data pointer for the current thread.

  lpvData = TlsGetValue(dwTlsIndex);
  if ((lpvData == 0) && (GetLastError() != ERROR_SUCCESS))
     ErrorExit("TlsGetValue error");

// Use the data stored for the current thread.

  printf("common: thread %d: lpvData=%lx\n",
     GetCurrentThreadId(), lpvData);

  Sleep(5000);
}

DWORD WINAPI ThreadFunc(VOID)
{
  LPVOID lpvData;

// Initialize the TLS index for this thread.

  lpvData = (LPVOID) LocalAlloc(LPTR, 256);
  if (! TlsSetValue(dwTlsIndex, lpvData))
     ErrorExit("TlsSetValue error");

  printf("thread %d: lpvData=%lx\n", GetCurrentThreadId(), lpvData);

  CommonFunc();

// Release the dynamic memory before the thread returns.

  lpvData = TlsGetValue(dwTlsIndex);
  if (lpvData != 0)
     LocalFree((HLOCAL) lpvData);

  return 0;
}

int main(VOID)
{
  DWORD IDThread;
  HANDLE hThread[THREADCOUNT];
  int i;

// Allocate a TLS index.

  if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
     ErrorExit("TlsAlloc failed");

// Create multiple threads.

  for (i = 0; i < THREADCOUNT; i++)
  {
     hThread[i] = CreateThread(NULL, // default security attributes
        0,                           // use default stack size
        (LPTHREAD_START_ROUTINE) ThreadFunc, // thread function
        NULL,                    // no thread function argument
        0,                       // use default creation flags
        &IDThread);              // returns thread identifier

  // Check the return value for success.
     if (hThread[i] == NULL)
        ErrorExit("CreateThread error\n");
  }

  for (i = 0; i < THREADCOUNT; i++)
     WaitForSingleObject(hThread[i], INFINITE);

  TlsFree(dwTlsIndex);

  return 0;
}

VOID ErrorExit (LPSTR lpszMessage)
{
  fprintf(stderr, "%s\n", lpszMessage);
  ExitProcess(0);
}



http://msdn.microsoft.com/en-us/library/6yh4a9k1.aspx
CitarThread Local Storage (TLS) is the method by which each thread in a given multithreaded process can allocate locations in which to store thread-specific data. Dynamically bound (run-time) thread-specific data is supported by way of the TLS API ([TlsAlloc], [TlsGetValue], [TlsSetValue], and [TlsFree]). Win32 and the Visual C++ compiler now support statically bound (load-time) per-thread data in addition to the existing API implementation.

osea dado mi programa, un proceso multihilo, osea con capacidad para muchos hilos o que tenga muchos hilos, y con este truquin lo que puedo es crear uno o mas espacios en los cuales guardar datos especificos de/para un hilo de entre todos los del proceso. pero se hace dinamicamente con esas api provistas. osea quisiera saber la finalidad de usar esto, es para seguridad o me permite hacer algo especifico?


dewolo

aver aca he encontrado un code que usa tls, aver si puedo entender para que se usa..
Citar
Using detours for hooking writing text in notepad
Using detours for hooking writing text in notepad

Hi all.

I'm trying to use detours to hook text output for example in notepad.

I wrote the following code. I will not put here all code, but the most significant parts.

DLL part:

DLLEXPORT LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {

if (nCode < 0) {
    return CallNextHookEx(0, nCode, wParam, lParam);
}

if (nCode == HCBT_ACTIVATE)
{
    HWND hWnd = (HWND)wParam;

    TCHAR szTemp[255];
    GetWindowText(hWnd, szTemp, 255);

    DetourTransactionBegin();
    DetourUpdateThread(hWnd);
    DetourAttach(&(PVOID&)Real_DrawText, Mine_DrawText);
    DetourTransactionCommit();

    DetourTransactionBegin();
    DetourUpdateThread(hWnd);
    DetourAttach(&(PVOID&)Real_DrawTextEx, Mine_DrawTextEx);
    DetourTransactionCommit();

    DetourTransactionBegin();
    DetourUpdateThread(hWnd);
    DetourAttach(&(PVOID&)Real_TextOut, Mine_TextOut);
    DetourTransactionCommit();

    DetourTransactionBegin();
    DetourUpdateThread(hWnd);
    DetourAttach(&(PVOID&)Real_ExtTextOut, Mine_ExtTextOut);
    DetourTransactionCommit();
}

return 0;
}


Client part:

int main(int argc, char* argv[]) {
HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;

hinstDLL = LoadLibrary(TEXT("dllsample.dll"));

//cout << (hinstDLL == NULL);

hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "_CBTProc@12");
DWORD dw = GetLastError();

//cout << (hkprcSysMsg == NULL);
//cout << dw;

hhookSysMsg = SetWindowsHookEx(
                    WH_CBT,
                    hkprcSysMsg,
                    hinstDLL,
                    0);

//std::cout << (hhookSysMsg == NULL);

int i;

std::cin >> i;
}


Citar
The problem is that all 4 functions which draw text are not hooked. What do I do wrong. I'v started studing detours and didn't find answer for my question in docs.

If other parts of code are required, I'll put them here later.

The problem is that all 4 functions which draw text are not hooked. What do I do wrong. I'v started studing detours and didn't find answer for my question in docs.

If other parts of code are required, I'll put them here later.


/* t4.cpp
cl.exe /Zi /EHa /c /DUNICODE /D_UNICODE /I "c:/program files/Microsoft Research/Detours Express 2.1/include/" t4.cpp
link /DLL /DEBUG /LIBPATH:"c:/Program Files/Microsoft Visual Studio 10.0/VC/lib" /LIBPATH:"C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib" /LIBPATH:"c:/program files/Microsoft Research/Detours Express 2.1/lib" t4.obj user32.lib gdi32.lib
link /OUT:main.exe /DEBUG /LIBPATH:"c:/Program Files/Microsoft Visual Studio 10.0/VC/lib" /LIBPATH:"C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib" /LIBPATH:"c:/program files/Microsoft Research/Detours Express 2.1/lib" t4.obj user32.lib gdi32.lib
*/

#include <iostream>

#define NOMINMAX

#include <string.h>
#include <tchar.h>
#include <windows.h>
#include "detours.h"

#pragma comment(lib, "detours")
#pragma comment(lib, "detoured")

int (WINAPI *Real_DrawText)(HDC hDC, LPCTSTR lpchText, int, LPRECT, UINT) = DrawText;

BOOL (WINAPI *Real_TextOut)(
  __in  HDC hdc,
  __in  int nXStart,
  __in  int nYStart,
  __in  LPCTSTR lpString,
  __in  int cbString
  ) = TextOut;

int (WINAPI *Real_DrawTextEx)(
  __in     HDC hdc,
  __inout  LPTSTR lpchText,
  __in     int cchText,
  __inout  LPRECT lprc,
  __in     UINT dwDTFormat,
  __in     LPDRAWTEXTPARAMS lpDTParams
  ) = DrawTextEx;

BOOL (WINAPI *Real_ExtTextOut)(
  __in  HDC hdc,
  __in  int X,
  __in  int Y,
  __in  UINT fuOptions,
  __in  const RECT *lprc,
  __in  LPCTSTR lpString,
  __in  UINT cbCount,
  __in  const INT *lpDx
  ) = ExtTextOut;

int WINAPI Mine_DrawText(
  __in     HDC hDC,
  __inout  LPCTSTR lpchText,
  __in     int nCount,
  __inout  LPRECT lpRect,
  __in     UINT uFormat
  )
{
  OutputDebugString(TEXT("DrawText"));
  OutputDebugString(lpchText);
  return Real_DrawText(hDC, lpchText, nCount, lpRect, uFormat);
}

BOOL WINAPI Mine_TextOut(
  __in  HDC hdc,
  __in  int nXStart,
  __in  int nYStart,
  __in  LPCTSTR lpString,
  __in  int cbString
  )
{
  OutputDebugString(TEXT("TextOut"));
  OutputDebugString(lpString);
  return Real_TextOut(hdc, nXStart, nYStart, lpString, cbString);
}

int WINAPI Mine_DrawTextEx(
  __in     HDC hdc,
  __inout  LPTSTR lpchText,
  __in     int cchText,
  __inout  LPRECT lprc,
  __in     UINT dwDTFormat,
  __in     LPDRAWTEXTPARAMS lpDTParams
  )
{
  OutputDebugString(TEXT("DrawTextEx"));
  OutputDebugString(lpchText);
  return Real_DrawTextEx(hdc, lpchText, cchText, lprc, dwDTFormat, lpDTParams);
}

BOOL WINAPI Mine_ExtTextOut(
  __in  HDC hdc,
  __in  int X,
  __in  int Y,
  __in  UINT fuOptions,
  __in  const RECT *lprc,
  __in  LPCTSTR lpString,
  __in  UINT cbCount,
  __in  const INT *lpDx
  )
{
  OutputDebugString(TEXT("ExtTextOut"));
  OutputDebugString(lpString);
  return Real_ExtTextOut( hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx );
}

#define DLLEXPORT extern "C" __declspec(dllexport)

static DWORD dwTlsIndex; // address of shared memory

// Stores a DWORD in thread local storage
BOOL WINAPI StoreData(DWORD dw)
{
   LPVOID lpvData;
   DWORD * pData;  // The stored memory pointer

   lpvData = TlsGetValue(dwTlsIndex);
   if (lpvData == NULL)
   {
      lpvData = (LPVOID) LocalAlloc(LPTR, 256);
      if (lpvData == NULL)
         return FALSE;
      if (!TlsSetValue(dwTlsIndex, lpvData))
         return FALSE;
   }

   pData = (DWORD *) lpvData; // Cast to my data type.
   // In this example, it is only a pointer to a DWORD
   // but it can be a structure pointer to contain more complicated data.

   (*pData) = dw;
   return TRUE;
}

// Retrieve a DWORD from thread local storage
BOOL WINAPI GetData(DWORD *pdw)
{
   LPVOID lpvData;
   DWORD * pData;  // The stored memory pointer

   lpvData = TlsGetValue(dwTlsIndex);
   if (lpvData == NULL)
      return FALSE;

   pData = (DWORD *) lpvData;
   (*pdw) = (*pData);
   return TRUE;
}

DLLEXPORT LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
  if (nCode < 0) {
    return CallNextHookEx(0, nCode, wParam, lParam);
  }

  // Get a flag indicating if we're already detoured.
  DWORD detoured=false;
  GetData(&detoured);

  // If the window is activating and we're not detoured...
  if (nCode == HCBT_ACTIVATE && !detoured)
  {
    OutputDebugString(TEXT("CBTProc"));
    HWND hWnd = (HWND)wParam;

    // get window title
    TCHAR szTemp[256];
    int rc = GetWindowText(hWnd, szTemp, 255);

    if (rc != 0)
    {
      OutputDebugString(szTemp);

      // hook notepad functions.
      if (_tcsstr(szTemp, TEXT("Notepad"))!=0)
      {
        OutputDebugString(TEXT("Detouring"));
        HANDLE hThread = GetCurrentThread();

        DetourTransactionBegin();
        DetourUpdateThread(hThread);
        DetourAttach(&(PVOID&)Real_DrawText, Mine_DrawText);
        DetourAttach(&(PVOID&)Real_TextOut, Mine_TextOut);
        DetourAttach(&(PVOID&)Real_DrawTextEx, Mine_DrawTextEx);
        DetourAttach(&(PVOID&)Real_ExtTextOut, Mine_ExtTextOut);
        DetourTransactionCommit();
        StoreData(true);
      }
    }
  }

  return 0;
}


BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle
  DWORD fdwReason,                    // reason called
  LPVOID lpvReserved)                 // reserved
{
  LPVOID lpvData;
  BOOL fIgnore;

  switch (fdwReason)
  {
    // The DLL is loading due to process
    // initialization or a call to LoadLibrary.
  case DLL_PROCESS_ATTACH:
    OutputDebugString(TEXT("DLL_PROCESS_ATTACH"));
    // Allocate a TLS index.
    if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
      return FALSE;
    // No break: Initialize the index for first thread.
    // The attached process creates a new thread.
  case DLL_THREAD_ATTACH:
    OutputDebugString(TEXT("DLL_THREAD_ATTACH"));
    // Initialize the TLS index for this thread.
    lpvData = (LPVOID) LocalAlloc(LPTR, 256);
    if (lpvData != NULL)
      fIgnore = TlsSetValue(dwTlsIndex, lpvData);
    break;
    // The thread of the attached process terminates.
  case DLL_THREAD_DETACH:
    {
      OutputDebugString(TEXT("DLL_THREAD_DETACH"));
      DWORD detoured=false;
      GetData(&detoured);
      if(detoured)
      {
        OutputDebugString(TEXT("Un-Detouring"));
        HANDLE hThread = GetCurrentThread();

        DetourTransactionBegin();
        DetourUpdateThread(hThread);
        DetourDetach(&(PVOID&)Real_DrawText, Mine_DrawText);
        DetourDetach(&(PVOID&)Real_TextOut, Mine_TextOut);
        DetourDetach(&(PVOID&)Real_DrawTextEx, Mine_DrawTextEx);
        DetourDetach(&(PVOID&)Real_ExtTextOut, Mine_ExtTextOut);
        DetourTransactionCommit();
      }

      // Release the allocated memory for this thread.
      lpvData = TlsGetValue(dwTlsIndex);
      if (lpvData != NULL)
        LocalFree((HLOCAL) lpvData);
      break;
    }
    // DLL unload due to process termination or FreeLibrary.
  case DLL_PROCESS_DETACH:
    OutputDebugString(TEXT("DLL_PROCESS_DETACH"));
    // Release the allocated memory for this thread.
    lpvData = TlsGetValue(dwTlsIndex);
    if (lpvData != NULL)
      LocalFree((HLOCAL) lpvData);
    // Release the TLS index.
    TlsFree(dwTlsIndex);
    break;
  default:
    break;
  }

  return TRUE;
}

int main(int argc, char* argv[])
{
  HOOKPROC hkprcSysMsg;
  HHOOK hhookSysMsg;

  HINSTANCE dll = LoadLibrary(TEXT("t4.dll"));
  hkprcSysMsg = (HOOKPROC)GetProcAddress(dll, "_CBTProc@12");
  DWORD dw = GetLastError();

  hhookSysMsg = SetWindowsHookEx(
    WH_CBT,
    hkprcSysMsg,
    dll,
    0);

  int i;
  std::cin >> i;

  UnhookWindowsHookEx(hhookSysMsg);
}








Eternal Idol

No creo que te lo pueda explicar con mayor claridad que la documentacion, trata de leerla con atencion, inverti algunos minutos en ella y no busques ejemplos de gente que especificamente dice que tiene problemas con su codigo, el ejemplo de la MSDN si funciona.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dewolo

Cita de: Eternal Idol en 16 Octubre 2011, 18:57 PM
No creo que te lo pueda explicar con mayor claridad que la documentacion, trata de leerla con atencion, inverti algunos minutos en ella y no busques ejemplos de gente que especificamente dice que tiene problemas con su codigo, el ejemplo de la MSDN si funciona.

ta, igualmente buscando encontre otro concepto que responde un poco a lo que preguntaba antes de cuando implementarlo, encontre algo de informacion, un caso en el cual se quiera ejecutar codigo automaticamente ante determinado evento (callback), ejecutar algo antes del entrypoint precisamente. lei que el "loader" del sistema operativo se encarga de mapear en la memoria una DLL y comvertir los enlaces estaticos a punteros, si se necesitara ejecutar algo antes deberia ser dentro del loader mismo (osea al parecer inyectar codigo en el loader del sistema es la unica opcion para ejecutar algo antes del entrypoint), y para esto se usaria un callback TLS
osea al parecer se trata de algo que el loader del sistema va a reconocer en el momento de carga.


#include <windows.h>

char ollycrash[52] = "You are not allowed to debug this program!" "%04602x";

void __stdcall tls_callback(void * /*instance*/,
                        DWORD reason,
                        void * /*reserved*/)
{
  if ( reason == DLL_PROCESS_ATTACH )
  {
    MessageBox(NULL, "Debugger Owned!", "TLS Callback", MB_OK);
    OutputDebugStringA(ollycrash);
  }
}

DWORD _tls_index = 0;
PIMAGE_TLS_CALLBACK callback = tls_callback;
extern "C" IMAGE_TLS_DIRECTORY _tls_used = {0,0,&_tls_index,&callback,0,0};

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    MessageBox(NULL,"This is WinMain!","Boo!",MB_OK);
    return 0;
}


esta informacion me tome la molestia de leerla de aqui
http://www.hexblog.com/?p=9

Citar
In reality the mistery is explained easily: a TLS (thread-local-storage) callback is used by the application. Such a callback is called by the system before the application entry point

osea aparentemente esta seria una de las utilisaciones de TLS, aparte de las que explica en la msdn