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

road420

導航

<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

統計

常用鏈接

留言簿(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>
            国产精品免费在线| 日韩一区二区久久| 亚洲国产精品精华液网站| 国产精品免费区二区三区观看| 欧美日韩国产成人| 欧美色大人视频| 国产麻豆精品久久一二三| 国产亚洲一区二区精品| 曰韩精品一区二区| 亚洲国产欧美另类丝袜| 亚洲精品免费一区二区三区| 久久精品官网| 久热精品视频在线免费观看| 欧美成人性网| 欧美日在线观看| 国产一区二区三区在线免费观看| 国内久久精品视频| 在线播放国产一区中文字幕剧情欧美 | 亚洲一区二区三区在线视频| 亚洲免费在线视频| 久久精品理论片| 免费观看成人www动漫视频| 欧美高清在线观看| avtt综合网| 欧美在线观看视频| 欧美成人网在线| 欧美三级在线| 激情另类综合| 亚洲视频网在线直播| 久久精品视频导航| 亚洲毛片视频| 久久性色av| 国产精品久久久久久av下载红粉| 一区二区在线免费观看| 中文网丁香综合网| 欧美成人激情视频免费观看| 亚洲香蕉视频| 欧美激情第10页| 狠狠色伊人亚洲综合网站色| 亚洲午夜视频| 欧美激情在线观看| 欧美一区二区三区在| 欧美日韩一区在线观看| 亚洲第一区在线观看| 欧美一区二区三区久久精品 | 欧美一级播放| 国产精品高潮呻吟久久av无限 | 国产精品视频一区二区三区 | 米奇777在线欧美播放| 亚洲小说欧美另类婷婷| 蜜桃av一区二区在线观看| 国产日韩欧美二区| 亚洲欧美日韩一区在线观看| 亚洲欧洲精品一区| 欧美一级网站| 国产欧美在线| 久久gogo国模裸体人体| 亚洲综合色婷婷| 国产精品久久久久久亚洲调教 | 伊人久久成人| 久久精品99| 午夜视频一区二区| 欧美一区2区视频在线观看 | 亚洲激情小视频| 免费不卡在线观看av| 久久精品男女| 在线欧美日韩国产| 欧美顶级大胆免费视频| 美女黄色成人网| 91久久久亚洲精品| 91久久久在线| 欧美日韩免费一区二区三区| 亚洲美女尤物影院| 日韩视频一区二区三区| 欧美色图天堂网| 亚洲欧美日韩人成在线播放| 亚洲午夜精品一区二区三区他趣| 国产精品国产亚洲精品看不卡15 | 亚洲片在线观看| 欧美日韩ab片| 亚洲一区三区电影在线观看| 亚洲素人一区二区| 国产欧美一区二区三区沐欲| 久久久久久久91| 免费观看一区| 亚洲一区亚洲二区| 欧美中文字幕精品| 亚洲精品乱码久久久久久蜜桃91 | 在线视频日韩| 亚洲欧美国内爽妇网| 一区二区视频免费在线观看| 亚洲激情国产| 国产一区二区| 亚洲成在人线av| 国产精品v一区二区三区| 久久精品亚洲| 欧美日韩不卡| 久久最新视频| 国产精品theporn88| 美腿丝袜亚洲色图| 国产精品多人| 亚洲国产精品久久久久婷婷884| 欧美午夜免费电影| 欧美成人影音| 国产日韩亚洲欧美精品| 亚洲国产aⅴ天堂久久| 国产欧美日韩视频一区二区三区 | 久久综合九色综合网站 | 欧美韩日一区二区三区| 欧美日韩中文在线观看| 久久精品官网| 欧美视频在线观看一区| 免费欧美在线视频| 国产精品一区二区在线观看网站 | 久久一区欧美| 欧美一级在线播放| 日韩一级黄色av| 久久久久久久综合狠狠综合| 午夜久久久久久久久久一区二区| 欧美搞黄网站| 你懂的国产精品永久在线| 国产情侣久久| 亚洲视频免费| 亚洲视频在线观看一区| 欧美国产日本| 亚洲福利在线看| 亚洲国产成人精品女人久久久 | 亚洲激情视频| 亚洲电影第三页| 久久国产精品黑丝| 久久精品视频播放| 国产一区二区福利| 亚洲午夜久久久| 亚洲在线中文字幕| 欧美亚洲不卡| 在线亚洲一区| 亚洲欧美一级二级三级| 欧美视频你懂的| 一区二区三区国产盗摄| 亚洲天堂久久| 欧美视频三区在线播放| 一区二区91| 午夜精品久久久久久久男人的天堂 | 久久精品亚洲国产奇米99| 国产亚洲电影| 欧美一区日本一区韩国一区| 久久久亚洲高清| 韩国av一区二区三区四区| 久久精品国产一区二区电影 | 亚洲大胆人体视频| 亚洲激情女人| 欧美日韩在线精品一区二区三区| 一本大道久久a久久精品综合 | 亚洲美女毛片| 亚洲综合首页| 国产偷久久久精品专区| 久久国产精品亚洲va麻豆| 欧美成人福利视频| 99av国产精品欲麻豆| 欧美私人啪啪vps| 亚洲一区二区三区在线播放| 久久久久久一区二区三区| 亚洲第一在线综合在线| 欧美激情四色| 亚洲免费影视第一页| 能在线观看的日韩av| 一区二区三区欧美在线| 国产精品综合网站| 麻豆精品在线视频| 一本久道综合久久精品| 久久精品夜色噜噜亚洲a∨| 亚洲国产成人在线视频| 欧美视频不卡| 久久在线91| 亚洲视频 欧洲视频| 免费成人在线观看视频| 亚洲免费大片| 国产精品久久久久7777婷婷| 欧美在线高清视频| 亚洲精品乱码久久久久久按摩观| 亚洲制服丝袜在线| 亚洲国产精品福利| 国产精品久久久免费| 久久综合九色九九| 亚洲一区影音先锋| 亚洲国产日韩一区二区| 欧美中文字幕视频在线观看| 亚洲久久在线| 永久免费精品影视网站| 国产精品每日更新在线播放网址| 免费看亚洲片| 久久精品99| 亚洲一本视频| 99xxxx成人网| 亚洲国产一区二区三区青草影视| 久久久久久久久久久一区| 在线亚洲精品| 亚洲免费黄色| 亚洲国内自拍| 亚洲成人在线视频播放|