• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            TLS隱藏的入口點

            轉載自:http://bbs.pediy.com/showthread.php?p=442958



            TLS簡介
            1. 什么是TLS?
             
            TLS是Thread Local Storage(線程局部存儲)的簡稱,是一項解決多線程內部變量使用問題的技術。用于將某些數據和一特定線程關聯起來,即,這些數據為關聯線程所獨有(私有)。在多線程編程中, 同一個變量, 如果要讓多個線程共享訪問, 那么這個變量可以使用關鍵字volatile進行聲明; 而如果一個變量不想被多個線程共享訪問, 那么就應該使用TLS。
             
            2. 如何使用TLS編程?

            TLS使用非常簡單, 只要對變量聲明時使用__declspec(thread)修飾就可以了。例如:
            _declspec(thread) int g_nData = 0;

            3. 一個使用TLS的例子
            //--------------------------------------------------------------------------------------------------------
            #include <windows.h> 
            #include 
            <stdio.h> 
             
            #define THREADCOUNT 4 
            DWORD dwTlsIndex; 
             
            int iNUM_OF_CALL_COMMON=0;
            int iNUM_OF_CALL_THREAD=0;
             
            VOID ErrorExit(LPSTR); 
             
            VOID CommonFunc(VOID) 

               LPVOID lpvData; 
             
            // Retrieve a data pointer for the current thread. 
             iNUM_OF_CALL_COMMON++;
             
               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. 
             iNUM_OF_CALL_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"); 
               }
             
             
              
            // printf("All threads were created.\n");
               for (i = 0; i < THREADCOUNT; i++
                  WaitForSingleObject(hThread[i], INFINITE); 
             
               TlsFree(dwTlsIndex);
             
               printf(
            "The nums of thread is: %d\n",iNUM_OF_CALL_THREAD);
               printf(
            "The nums of call is: %d\n",iNUM_OF_CALL_COMMON);
             
               
            return 0
            }
             
             
            VOID ErrorExit (LPSTR lpszMessage) 
            {  
               fprintf(stderr, 
            "%s\n", lpszMessage); 
               ExitProcess(
            0); 
            }
              
            //--------------------------------------------------------------------------------------------------------

            4. T L S的內部數據結構
             
            1.jpg
            圖1 用于管理T L S的內部數據結構
             
             
            每個標志均可設置為FREE或者INUSE,表示TLS槽( s l o t )是否正在使用。Microsoft保證至少TLS_MINIMUM_AVAILABLE位標志是可供使用的。
             
            5. 相關API
             
            Windows TLS的API: TlsAlloc, TlsFree, TlsSetValue, TlsGetValue。
             
            ● DWORD TlsAlloc(); //(若要使用動態T L S,首先必須調用TlsAlloc函數)
             
            這個函數命令系統對進程中的位標志進行掃描,并找出一個FREE標志。然后系統將該標志從FREE改為INUSE,并且TlsAlloc返回位數組中的標志的索引。DLL(或APP)通常將該索引保存在一個全局變量中,因為它的值是每個進程而不是每個線程使用的值。
             
            ● BOOL TlsSetValue( //將一個值放入線程的數組中
             
            DWORD dwTlsIndex,
             
            PVOID pvTlsValue);
             
            ● PVOID TlsGetValue(DWORD dwTlsIndex); //要從線程的數組中檢索一個值
             
            ● BOOL TlsFree(DWORD dwTlsIndex); //當在所有線程中不再需要保留TLS槽時
             
             
             
            參考資料:Jeffrey Richter《《Programming Applications for Microsoft Windows (4th Ed.)》》Chapter 21
             
            6. TLS目錄
             
            7.JPG
            TLS Callback Functions
            這是線程建立和退出時的回調函數, 包括主線程和其他線程.AddressOfCallBacks 是指向函數指針數組的指針, 以 0 結束.
            typedef struct _TEB {
            NT_TIB Tib;
            PVOID EnvironmentPointer;
            CLIENT_ID Cid;
            PVOID ActiveRpcInfo;
            PVOID ThreadLocalStoragePointer; ; 2ch
            PPEB Peb; ; 30h
            ULONG LastErrorValue; ; 34h
            …}


            TLS目錄 #define IMAGE_DIRECTORY_ENTRY_TLS 9 (第十個目錄)
             
             
             
            Tls隱藏的入口點利用
             
             
            就是利用Address of Callbacks字段,寫入要執行的代碼的地址就可以了.
             
             
            測試對象:test.exe
             
            程序類型:delphi編寫
             
             
             
            PeEditor檢測Tls信息(文件偏移59400H處)如下:
            2.jpg
             
            TLS信息
             
            ------------------------------------------
             
             
             
            目錄表: 0045D000
             
            TLS數據: 0045D010
             
            索引變量: 004570A0
             
            調用返回地址: 0045E010 (調用返回地址)
             
            ------------------------------------------
             
             
             
            我們打算讓系統在0045E010處執行我們的代碼,就需要在這個地方對應的文件偏移處寫入我們的代碼。
             
             
             
            觀察節表信息
             
            VA=0045E010,按照文件不需要重定位去計算則RVA=0005E010
             
            觀察節表信息,這個值處于.rdata節內。
             
            .rdata節起始RVA=0005E000,起始Offset為00059400
             
            則callback地址對應的Offset=(0005E010 - 0005E000)+ 00059400 =00059410
             
            注意在這里(00059410H)應該寫入一個函數地址。

            打造一個簡單的代碼:

            ----------------------------------------------------------------
             
            .386
             
            .model flat,stdcall
             
            option casemap
            :none
             
             
             
            include windows
            .inc
             
            include user32
            .inc
             
             
             
            includelib user32
            .lib
             
             
             
            .code
             
            start
            :
             
            jmp 
            @F
             
             
             
            db 
            'Run thru Tls entry point.',0
             
            @@
            : 
             
            mov eax
            ,$
             
            sub eax,26
             
            call 
            @delta
             
            @delta:
             
            pop ebp
             
            sub ebp,offset @delta
             
            add eax
            ,ebp
             
            invoke MessageBox
            ,NULL,eax,NULL,0
             
            ret
             
            end start
             
            ----------------------------------------------------------------

            編譯生成可執行文件,這只是一個簡單的彈出對話框的程序。
            3.jpg
             
            打開16進制工具,載入msgbox.exe,復制代碼:
            4.jpg
             
            注意00402000H處存放的是MessageBox的入口地址,我把它固化下來,動態跟蹤發現是8A05D577H。(當然在編程時可以動態搜尋我們需要的API,為簡單起見這里Hard-code一下。)
             
            打開16進制工具,載入藝術字體2.exe,定位到00059410。
            5.jpg
             
            我們把代碼復制在偏移00059410處,對應的VA=0045E030H,則把0045E030存入偏移00059410。
             
            還要注意最后的 MessageBox的入口地址我們使用硬編碼的方式,我們把這個地址寫入在00059480處了。保存修改,然后運行程序。程序首先彈出兩個對話框(一個是TLS模板,一個是主線程創建),結束程序運行還會彈出一個對話框,不過這個對話框太丑了:
             
            6.jpg
             
             
            說明:我在看一本介紹病毒知識的書籍時看到作者提及到這么一句話,大概意思是說他們公司某人發現了這個秘密,一直沒有公布,不過后來由于rgb利用此技術制造了病毒,也就無所謂秘密可言了。由于Tls入口要比OEP先執行,所以在加殼與脫殼中都有利用的價值。

            posted on 2008-04-29 14:16 楊粼波 閱讀(537) 評論(0)  編輯 收藏 引用

            久久精品国产99久久丝袜| 热综合一本伊人久久精品| 久久精品一区二区三区中文字幕 | 国产精品久久毛片完整版| 18岁日韩内射颜射午夜久久成人| 亚洲欧美日韩精品久久亚洲区 | 久久福利青草精品资源站| 国产成人无码精品久久久免费| 国产精品丝袜久久久久久不卡 | 久久精品国产精品亚洲毛片| 色综合色天天久久婷婷基地| 亚洲欧美另类日本久久国产真实乱对白| 国产成人久久777777| 欧美激情精品久久久久久| 欧美丰满熟妇BBB久久久| 97久久国产亚洲精品超碰热| 精品久久久久久亚洲| 国产精品伦理久久久久久| 久久亚洲色一区二区三区| 四虎国产精品成人免费久久| 久久午夜无码鲁丝片秋霞| 国产精品视频久久| 久久99精品九九九久久婷婷| 久久青青草原精品国产| 成人国内精品久久久久影院| 国产成人精品久久| 无码人妻精品一区二区三区久久久| 精品久久久久久久久久久久久久久| 热RE99久久精品国产66热| 伊人久久五月天| 久久天天躁狠狠躁夜夜2020老熟妇| 亚洲精品午夜国产va久久| aaa级精品久久久国产片| 久久久久成人精品无码| 久久亚洲AV成人无码国产| 久久国产午夜精品一区二区三区| 国产精品美女久久福利网站| 色综合合久久天天综合绕视看| 18禁黄久久久AAA片| 国内精品久久久久久久亚洲| 久久综合九色综合网站|