青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

road420

導航

<2007年7月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

統計

常用鏈接

留言簿(2)

隨筆檔案

文章檔案

搜索

最新評論

閱讀排行榜

評論排行榜

DLL 線程本地存儲

DLL, 線程本地存儲

1.概覽
.構造DLL  
   (1)僅導出函數
      DLL可以導出全局變量和類,但我們不建議這么做,建議導出函數。
   (2).lib
      每個DLL都有與之相對應的.lib文件,該文件中列出了DLL中導出的函數和變量的符號名
   (3)指定要導出的函數名
       因為不同編譯器的Name mangle規則不同,這就導致DLL不能跨編譯器使用。
       有以下兩種方法可以解決這個問題:
            1..def文件中指定要導出的函數名
            2.在編譯指中指定要導出的函數名:
                #pragma comment(linker, "/export:MyFunc=_MyFunc@8")
.DLL加載路徑
    當需要加載一個DLL時,系統會依照下面的順序去尋找所需DLL直到找到為止,然后加載,否則加載失敗。
              (1)當前可執行文件路徑
              (2)GetWindowsDirectory返回的Windows系統路徑
              (3)16位系統的路徑 windows"system
              (4)GetSystemDirectory返回的Windows系統路徑
              (5)當前進程所在路徑
              (6)PATH環境中所指定的路徑
­
.創建\使用動態鏈接庫
首先必須創建一個包含需要導出的符號的頭文件,以便其他程序鏈接到該dll上:
// dllexample.h
#ifdef DLLEXAMPLE_EXPORTS // 在編譯命令中已定義,所以實際用的是 __declspec(dllexport)
#define DLLEXAMPLE_API __declspec(dllexport)
#else
#define DLLEXAMPLE_API __declspec(dllimport)
#endif
DLLEXAMPLE_API int fnDllexample(void);
當其他應用包含該頭文件,意圖使用該dll的導出符號時,因為沒有定義DLLEXAMPLE_EXPORTS,所以使用的是__declspec(dllimport),這樣編譯器編譯時便知道這是從外部引入的函數。在鏈接時,鏈接程序將生成導入表(ImportAddressTable),該表羅列了所有調用到的函數,以及一個空白的對應地址。在程序執行時,加載器將動態的填入每個函數符號在本進程中的地址,使得程序能正確的調用到dll中的函數上。
這種通過dll提供的.h和.lib文件進行鏈接dll的使用方式,稱為隱式鏈接。用vc開發程序時,幾乎所有的系統API調用都用了隱式鏈接。
.顯式鏈接
在exe創建時不引用.lib文件中的符號,當然也不必包含.h頭文件,而是由程序調用LoadLibrary(Ex)以及GetProcAddress函數來獲取每個需要使用的函數地址,從而進行dll中的函數調用,這種dll使用方法稱為顯式鏈接。顯式鏈接時不生成對應dll的IAT.
當決定不再使用該dll時,通過調用FreeLibrary來卸載。需要注意的是,同一個進程中共計調用LoadLibrary的次數要和調用FreeLibrary的次數相等,因為系統維護了一個使用計數,當計數為0時,才會真正的卸載該dll.
如果想確認一個dll是否已經被映射到進程空間中,盡量使用GetModuleHandle,最好不要冒然使用LoadLibrary(Ex).
GetProcAddress可以傳遞函數名或者序號(通過MAKEINTRESOURCE(2)來"制作"序號).
­
1.1動態加載DLL文件 LoadLibraryEx
HMODULE LoadLibraryEx( //返回DLL加載到進程空間原首地址。
PCTSTR pszDLLPathName,
HANDLE hFile,
DWORD dwFlags);
dwFlags 可以有以下幾個值
              (1) DONT_RESOLVE_DLL_REFERENCES
                                    建議永遠不要使有這個值,它的存在僅僅是為了向后兼容、
                  更多內容請訪問:http://blogs.msdn.com/oldnewthing/archive/2005/02/14/372266.aspx
              (2) LOAD_LIBRARY_AS_DATAFILE
                  把要加載的DLL文件以數據文件的形式加載到進程中。
                  GetModuleHandleGetProcAddress返回NULL
              (3) LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
                  與前者相同,不同的時獨占打開,禁止其它進程訪問和修改該DLL中的內容。
              (4) LOAD_LIBRARY_AS_IMAGE_RESOURCE
                  不修改DLL中的RVA,以image的形式加載到進程中。常與LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE一起使用。
              (5) LOAD_WITH_ALTERED_SEARCH_PATH
                   修改DLL的加載路徑
1.2 DLL的加載與卸載
    (1)加載
       不要在同一進程中,同時使用LoadLIbraryLoadLibraryEx加載同一DLL文件。
       DLL的引用計數是以進程為單位的。LoadLibrary會把DLL文件加載到內存,然后映射到進程空間中。
       多次加載同一DLL只會增加引用計數而不會多次映射。當所有進程對DLL的引用計數都為0時,系統會在內存中釋放該DLL
    (2)卸載
         FreeLibrary,FreeLibraryAndExitThread對當前進程的DLL的引用計數減1
    (3) GetProcAddress
         取得函數地址。它只接受ANSI字符串。
2.DLL的入口函數
      2.1 DllMain
              BOOL WINAPI DllMain(
              HINSTANCE hInstDll, ""加載后在進程中的虛擬地址
              DWORD fdwReason, ""系統因何而調用該函數
              PVOID fImpLoad ""查看是隱工還是動態加載該DLL
    DLLsDllMain方法來初始化他們自已。DllMain中的代碼應盡量簡單,只做一些簡單的初始化工作。
    不要在DllMain中調用LoadLibrary,FreeLibraryShell, ODBC, COM, RPC, socket 函數,從而避免不可預期的錯誤。
  2.2 fdwReason的值
    (1)DLL_PROCESS_ATTACH
      系統在為每個進程第一次加載該DLL時會,執行DLL_PROCESS_ATTACH后面的語句來初始化DLL,DllMain的返回值僅由它決定。
     系統會忽略DLL_THREAD_ATTACH等執行后DllMain的返回值。
     如果DllMain返回FALSE,系統會自動調用DLL_PROCESS_DETACH的代碼并解除DLL文件中進程中的內存映射。        
    (2)DLL_PROCESS_DETACH
        如果DLL是因進程終止而卸載其在進程中的映射,那么負責調用ExitProcess的線程會調用DllMainDLL_PROCESS_DETACH所對應的代碼。
        如果DLL是因FreeLibraryFreeLibraryAndExitThread,而卸載其在進程中的映射, 那么FreeLibraryFreeLibraryAndExitThread會負責調用DllMainDLL_PROCESS_DETACH所對應的代碼。
        如果DLL是因TerminateProcess而卸載其在進程中的映射,系統不會調用DllMainDLL_PROCESS_DETACH所對應的代碼。
    (3) DLL_THREAD_ATTACH
        若進程是先加載的DLL,后創建的線程
        那么在進程中創建新線程時(主線程除外),系統會執行該進程已載的所有DLLDllMainDLL_THREAD_ATTACH對應的代碼。
         若進程是先創建的線程,后加載的DLL
         那么系統不會調用DLLDllMain中的代碼。
     (4) DLL_THREAD_DETACH
         進程中的線程退出時,會先執行所有已加載DLLDllMainDLL_THREAD_DETACH所對應的代碼。若該代碼中有死循環,線程不會退出。              
2.3 同步化DllMain的調用
      同一時間只能有一個線程調用DllMain中的代碼,所以下面的代碼會導致死循環
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, PVOID fImpLoad) {
   HANDLE hThread;
   DWORD dwThreadId;
   switch (fdwReason) {
   case DLL_PROCESS_ATTACH:
      // The DLL is being mapped into the process' address space.
      // Create a thread to do some stuff.
      hThread = CreateThread(NULL, 0, SomeFunction, NULL,
         0, &dwThreadId);// CreateThreadDLL_THREAD_ATTACH中的代碼,但是由于當前線程并未執行完畢,
      //所以DLL_THREAD_ATTACH 中的代碼不會被執行,且CreateThread永無不會返回。
      // Suspend our thread until the new thread terminates.
      WaitForSingleObject(hThread, INFINITE);
­
      // We no longer need access to the new thread.
      CloseHandle(hThread);
      break;
­
   case DLL_THREAD_ATTACH:
      // A thread is being created.
      break;
­
   case DLL_THREAD_DETACH:
      // A thread is exiting cleanly.
      break;
­
   case DLL_PROCESS_DETACH:
      // The DLL is being unmapped from the process' address space.
      break;
   }
   return(TRUE);
}
­
3.延時加載DLL
(1)延時加載DLL的限制
         延遲加載的D L L是個隱含鏈接的D L L,它實際上要等到你的代碼試圖引用D L L中包含的一個符號時才進行加載,它與動態加載不同。
        http://msdn2.microsoft.com/en-us/library/yx1x886y(VS.80).aspx
4.已知的DLL (Known DLLs)
    位置:HKEY_LOCAL_MACHINE"SYSTEM"CurrentControlSet"Control"Session Manager"KnownDLLs
    LoadLibrary在查找DLL會先去該位置查找有無相應的鍵值與DLL要對應,若有則根據鏈值去%SystemRoot%"System32加載鍵值對應的DLL
    若無則根據默認規去尋找DLL
5.Bind and Rebase Module
    它可以程序啟動的速度。ReBaseImage
­
DLL 注入和API(DLL Injection and API Hooking)
1.概覽
  每個進程都有自已獨立的地址空間,一個進程不可能創建一個指向其它進程地址空間的指針。
   然而如果我們把自已的DLL注射到另一個進程的地址空間去,我們就可以在那個被注入的進程里為所欲為了。
   Subclass同一進程中的窗體:http://msdn2.microsoft.com/en-us/library/ms649784.aspx.
2.用注冊表注入DLL
     該方法適用于給GUI的程序注入DLL
     所有的GUI應用程序在啟動時都會加載User32.dll,而在User32.dllDLL_PROCESS_ATTACH代碼根據注冊表中的信息
來注入用戶指定的DLL
注冊表項 HKEY_LOCAL_MACHINE"Software"Microsoft"Windows NT"CurrentVersion"Windows"
中有兩個值:
    LoadAppInit_Dlls:鍵值中指定要注入的DLL 如:c:"inject.dll
AppInit_Dlls:若其鍵值為1,則注入LoadAppInit_Dlls中指定的DLL,否則若為0則不注入。
    :
(1)LoadAppInit_Dlls中的值是以空格或分號分隔的,所以DLL的路徑中最好不要有空格,最后不指定路徑,直接將DLL放到windows系統目錄中。
(2) 用注冊表注入DLL的方式有很大的局限性,Kernel32.dllNtdll.dll中有的函數才能調用
一.注入dll
1.通過注冊表項 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs 來指定你的dll的路徑,那么當一個GUI程序啟動時就要加載User32.dll,而User32.dll將會檢查這個值,如果有的話就LoadLibrary該Dll。這個方法不好,因為大多數情況我們只需要針對性的注入,并且沒辦法注入到不使用User32.dll的進程中;
­
2.用SetWindowsHookEx函數,并傳遞目標線程ID、需要掛載的Dll在本進程中的映射地址(hInstance)、替換函數在本進程中的地址。這樣,當被掛載進程的這個線程要執行相應的操作時(GETMESSAGE、鍵盤消息之類的),就會發現已經安裝了WH_XX,The system checks to see whether the DLL containing the GetMsgProc function is mapped into Process B's address space,如果還未映射該Dll,則強制LoadLibrary。然后系統調用hThisInstance + (GetMsgProc - hInstance),從而實現了事件的通知。這種方法的好處是可以針對某個進程安裝Hook,缺點是容易被目標進程發現、同樣只適用于GUI進程。如果不再想使用掛鉤了,那么需要調用UnhookWindowsHookEx,卸載Hook。
­
3.使用遠程線程注入Dll(Injecting a DLL Using Remote Threads)
這個方法比較好。流程是這樣的:
?調用VirtualAllocEx,在目標進程保留一塊內存,并提交,其長度是你要注入Dll的全路徑長度nLen + 1,返回地址pv;
?調用WriteProcessMemory,在目標進程的pv處寫入Dll的全路徑,注意要添加\0結束符;
?獲取本進程的LoadLibrary函數的地址,方法是調用pfn = GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA")——之所以獲取本進程的地址,是因為kernel32.dll在每個進程的映射地址都相同,倘若不同,那么此方法則無效;
?調用HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0,  pfn, pv, 0, NULL)來創建遠程線程,其實這個線程函數就是LoadLibrary函數,因此將執行映射Dll到目標進程的操作;
?調用VirtuallFreeEx(hProcessRemote, pv)釋放提交的內存;
這便完成了dll注入。
缺點是不能用在windows98上。但是對于xp都要被微軟拋棄的年代,windows98地影響不大了。
­
4.披著羊皮的狼:使用特洛伊Dll來注入Dll(Injecting a DLL with a Trojan DLL)
其實就是替換某個目標進程要加載的a.dll,并把a.dll的所有引出函數用函數轉發器在自己的dll引出。
­
5.用調試函數插入Dll
ReadProcessMemory和WriteProcessMemory是windows提供的調試函數。如果在方法3中調用WriteProcessMemory寫入的不是字串而是精心編排好的機器指令,并且寫在目標進程特定的地址空間,那么這段機器指令就有機會執行——而這段機器指令恰好完成了LoadLibrary功能;
­
6.其他方法(略)
­
二.掛接API(API Hooking)
其實,這是許多注入的Dll都愿意做的事情。
所謂掛接API就是在目標進程調用windows API之前,先執行我們的仿API函數,從而控制系統API的行為,達到特殊的目的。
我們的仿造函數必須與要替換的系統API有相同的型參表以及相同的返回值類型.
­
1.改寫系統API代碼的前幾個字節,通過寫入jmp指令來跳轉到我們的函數。在我們的函數里執行操作,可以直接返回一個值,也可以將系統API的前幾個字節復原,調用系統API,并返回系統API的值——隨便你想怎么做。
此方法的缺點是對于搶占式多線程的系統不太管用。
­
2.通過改寫目標進程IAT中要調用的函數地址來達到目的。具體操作見書中示例
­
­
­
線程本地存儲(Thread-Local Storage)
例子C / C + +運行期庫要使用線程本地存儲器( T L S)。由于運行期庫是在多線程應用程序出現前的許多年設計的,因此運行期庫中的大多數函數是用于單線程應用程序的。函數s t r t o k就是個很好的例子。
盡可能避免使用全局變量和靜態變量
1.動態TLS
圖21-1 用于管理T L S的內部數據結構
­
在創建線程時,進程會為當前創建的線程分配一個void *的數組作為TLS用。它用于存儲只限當前線程可見的全局變量。
從而使進程中的每個線程都可以有自已的(不能其它線程訪問的)全局變量。
TlsAlloc在返回時會先把槽中的值置為0。每個線程至少有64個槽。
2.靜態TLS
              __declspec(thread)關鍵字用于聲明,線程本地的全局變量。
              要求聲明的變量必須是全局變量或靜態變量。
3.Common API:
              TlsAlloc   TlsFree
              TlsSetValue   TlsGetValue
              __declspec(thread)

posted on 2009-10-26 18:33 深邃者 閱讀(1053) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美激情小视频| 精东粉嫩av免费一区二区三区| 一本色道婷婷久久欧美| 午夜激情综合网| 91久久在线播放| 国产欧美一区二区三区视频| 欧美成va人片在线观看| 久久国产精品毛片| 日韩视频在线免费观看| 免费视频一区| 欧美影视一区| 亚洲一区一卡| 亚洲午夜视频在线| 日韩视频一区二区三区| 在线观看亚洲精品视频| 国产一区二区丝袜高跟鞋图片| 国产精品久久久久久久午夜 | 久久免费99精品久久久久久| 一区二区三区视频在线| 91久久精品国产91久久| 一色屋精品视频免费看| 国语自产精品视频在线看一大j8 | 亚洲一区不卡| 一本久久综合| 亚洲美女在线视频| 亚洲日本精品国产第一区| 亚洲福利视频一区二区| 亚洲福利在线看| 影音先锋日韩有码| 亚洲电影专区| 最新中文字幕一区二区三区| 国产一区二区三区在线观看视频| 国产欧美日韩亚洲精品| 国产区亚洲区欧美区| 国产欧美一区二区三区久久 | 国产亚洲a∨片在线观看| 国产精品欧美风情| 国产精品国产三级欧美二区| 国产精品久久久久免费a∨| 国产精品老牛| 国产一区二区三区在线观看网站| 好看的av在线不卡观看| 伊人久久av导航| 在线观看成人av电影| 欧美亚洲尤物久久| 久久综合网络一区二区| 另类激情亚洲| 欧美黄在线观看| 亚洲国产婷婷香蕉久久久久久99| 久久久国产亚洲精品| 麻豆免费精品视频| 亚洲国产一区二区三区高清 | 欧美a级在线| 欧美日本视频在线| 国产精品亚洲欧美| 影院欧美亚洲| 在线亚洲电影| 久久精品视频免费播放| 欧美黄网免费在线观看| 中文精品一区二区三区| 欧美伊久线香蕉线新在线| 久久这里只精品最新地址| 欧美极品在线观看| 国产欧美1区2区3区| 在线观看亚洲一区| 亚洲素人一区二区| 久久久97精品| 亚洲电影网站| 亚洲手机视频| 久久亚洲精选| 欧美午夜精品久久久久久人妖| 国产欧美在线看| 亚洲乱码国产乱码精品精可以看| 亚洲欧美日韩国产综合在线| 久久综合网络一区二区| 日韩亚洲欧美综合| 久久精品亚洲一区二区| 欧美久久久久久久久久| 国产三级欧美三级日产三级99| 亚洲国产欧美在线人成| 亚洲欧美激情视频| 你懂的国产精品永久在线| 99精品久久免费看蜜臀剧情介绍| 欧美中文字幕视频| 欧美日韩国产小视频| 国内精品一区二区| 中国av一区| 嫩草伊人久久精品少妇av杨幂| 亚洲午夜在线观看| 欧美成人精品高清在线播放| 国产欧美精品日韩区二区麻豆天美| 亚洲国产精品久久久久秋霞蜜臀| 亚洲欧美国内爽妇网| 亚洲国产精品第一区二区| 亚洲一品av免费观看| 欧美激情视频一区二区三区不卡| 国产亚洲亚洲| 亚洲午夜在线观看视频在线| 免费观看成人鲁鲁鲁鲁鲁视频| 一区二区三区视频在线看| 蜜桃av久久久亚洲精品| 国产视频在线一区二区| 中文精品99久久国产香蕉| 免费中文字幕日韩欧美| 欧美亚洲一区三区| 国产精品久久激情| 一区二区三区久久| 欧美国产免费| 久久精品国产一区二区三区| 国产精品免费福利| 一区二区日韩精品| 亚洲第一福利视频| 久久久亚洲成人| 国产一区日韩一区| 欧美在线视频免费| 亚洲综合成人婷婷小说| 欧美午夜精品久久久久久孕妇| 日韩亚洲欧美一区| 亚洲福利视频网站| 久久青草福利网站| 红桃视频一区| 久久久久久久久久久久久9999 | 国产精品高清免费在线观看| 日韩午夜免费| 欧美激情一区二区三区蜜桃视频| 久久久久国产一区二区三区| 国产午夜精品福利| 午夜精品影院| 亚洲男女自偷自拍图片另类| 狠狠狠色丁香婷婷综合久久五月| 老司机一区二区三区| 性欧美长视频| 国产精品私人影院| 午夜视频一区在线观看| 一区二区三区成人精品| 欧美美女视频| 一区二区三区高清在线 | 亚洲国产精品美女| 免费成人高清在线视频| 亚洲国产成人高清精品| 欧美韩日精品| 欧美国产综合一区二区| 最新日韩欧美| 亚洲高清免费视频| 欧美国产视频在线观看| 亚洲麻豆av| 夜夜爽夜夜爽精品视频| 国产精品成人观看视频国产奇米| 亚洲欧美日韩一区在线| 亚洲午夜国产成人av电影男同| 国产精品激情电影| 欧美在线free| 久久狠狠一本精品综合网| 一区二区三区中文在线观看| 暖暖成人免费视频| 欧美精品日韩一本| 亚洲欧洲精品一区| 久久成人精品电影| 国产视频一区在线观看一区免费| 亚洲欧美日韩电影| 亚洲一区二区三区中文字幕| 国产精品视频免费在线观看| 欧美一区二区黄色| 欧美一级淫片aaaaaaa视频| 国产一区二区三区在线免费观看| 老司机一区二区三区| 欧美成va人片在线观看| 中文在线不卡视频| 午夜精品一区二区在线观看| 黄色日韩网站视频| 亚洲丁香婷深爱综合| 欧美日韩一卡| 久久国产精品久久久久久电车| 久久精品在线免费观看| 亚洲精品国精品久久99热| 99在线精品免费视频九九视| 国产日韩高清一区二区三区在线| 欧美成人精品h版在线观看| 欧美国产综合一区二区| 亚洲欧美综合另类中字| 久久亚洲一区二区三区四区| 99视频一区二区| 亚洲欧美一区二区激情| 91久久精品久久国产性色也91| 一本大道久久精品懂色aⅴ| 国产亚洲欧美中文| 亚洲片在线观看| 国产日韩欧美在线一区| 亚洲黄色成人| 国产视频欧美| 亚洲日本视频| 国产一区二区成人久久免费影院| 欧美福利一区二区三区| 国产精品久久久99| 老司机一区二区三区| 国产精品v片在线观看不卡| 另类图片综合电影| 国产精品v欧美精品v日本精品动漫| 美女主播视频一区| 国产精品黄视频|