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

road420

導航

<2009年10月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

統計

常用鏈接

留言簿(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 深邃者 閱讀(1057) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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成人激情| 亚洲日本欧美| 亚洲一级免费视频| 久久夜色精品亚洲噜噜国产mv| 久久综合九色| 久久人体大胆视频| 国产精品久久久久77777| 在线播放日韩专区| 亚洲综合激情| 亚洲欧洲一区二区在线播放| aa日韩免费精品视频一| 亚洲国产天堂网精品网站| 久久se精品一区精品二区| 一区在线观看视频| 久久国产精品久久w女人spa| 日韩亚洲视频在线| 毛片一区二区三区| 黄色在线成人| 亚洲国产精品久久91精品| 欧美日韩国产欧美日美国产精品| 亚洲二区视频在线| 久久久激情视频| 亚洲欧美网站| 国产精品一区二区三区免费观看 | 亚洲欧美日韩国产另类专区| 国产视频一区二区在线观看 | 亚洲综合视频一区| 欧美一级久久久| 国产情人综合久久777777| 亚洲愉拍自拍另类高清精品| 欧美在线观看日本一区| 99精品国产高清一区二区 | 夜夜嗨av一区二区三区四区| 在线亚洲成人| 国产精品福利久久久| 久久久久在线| 久久国产精品99精品国产| 国产欧美日韩精品在线| 欧美黄在线观看| 麻豆成人在线播放| 欧美亚洲在线播放| 久久成人免费网| 中文在线不卡视频| 一区二区国产精品| 国产精品视频xxxx| 久久国产精品99久久久久久老狼| 美女精品一区| 久久午夜激情| 国产精品人成在线观看免费 | 亚洲一区免费看| 蜜臀久久久99精品久久久久久| 小黄鸭精品aⅴ导航网站入口| 欧美精品激情在线| 午夜精品福利在线观看| 香蕉久久夜色精品国产使用方法| 国产一区亚洲一区| 欧美成人在线免费视频| 欧美成人高清| 亚洲欧美日韩天堂一区二区| 欧美一区二区三区免费观看视频 | 国产精品日本一区二区| 亚洲欧洲视频在线| 亚洲第一色在线| 亚洲国产日韩欧美在线99| 国产综合自拍| 亚洲一区激情| 亚洲国产成人久久| 久久欧美肥婆一二区| 久久九九热re6这里有精品| 国产精品免费久久久久久| 久久9热精品视频| 国产精品一区二区在线观看不卡| 亚洲蜜桃精久久久久久久| 99精品国产福利在线观看免费| 欧美**字幕| 欧美在线播放| 欧美精品亚洲精品| 亚洲肉体裸体xxxx137| 国产一区二区三区高清 | 欧美亚洲视频在线观看| 国产精品丝袜久久久久久app| 正在播放亚洲| 久久激情网站| 欧美精品在线视频| 久久一区二区三区四区五区| 国产自产高清不卡| 久久综合色播五月| 久久av在线看| 在线免费高清一区二区三区| 免费在线视频一区| 亚洲视频在线观看网站| 亚洲免费观看高清完整版在线观看熊 | 亚洲一区二区三区色| 欧美一区二区视频在线观看2020| 国产香蕉97碰碰久久人人| 久久久久久电影| 欧美一区二区精品久久911| 国产亚洲欧美中文| 鲁鲁狠狠狠7777一区二区| 亚洲精品系列| 日韩视频―中文字幕| 国产精品盗摄久久久| 欧美在线视频一区二区三区| 欧美激情2020午夜免费观看| 亚洲午夜免费福利视频| 国模私拍视频一区| 欧美精品日韩精品| 午夜精品久久久久久久99樱桃 | 欧美一站二站| 亚洲国产精品久久精品怡红院| 欧美日韩高清在线播放| 欧美一区二区视频在线| 91久久精品日日躁夜夜躁国产| 欧美在线亚洲| 日韩视频免费观看高清在线视频| 国产美女在线精品免费观看| 嫩草国产精品入口| 欧美在线免费观看| 一区二区毛片| 亚洲国产精品久久| 久久亚洲春色中文字幕久久久| 亚洲视频综合| 91久久中文字幕| 欧美福利一区二区| 亚洲激情电影中文字幕| 久久久国产91| 亚洲欧洲av一区二区| 日韩午夜av电影| 1204国产成人精品视频| 国产欧美日韩一区二区三区在线| 欧美黄色精品| 浪潮色综合久久天堂| 久久久99免费视频| 亚洲国产日韩美| 欧美成人一区二免费视频软件| 欧美一级电影久久| 亚洲欧美日本国产专区一区| 一区二区三区日韩欧美精品| 国产精品久久国产精品99gif | 欧美日韩亚洲综合一区| 亚洲自拍偷拍网址| 蜜臀av性久久久久蜜臀aⅴ四虎 | 国产精品久久毛片a| 欧美激情亚洲精品| 欧美成人一区二区三区| 欧美gay视频激情| 久久亚洲影音av资源网| 久久久最新网址| 久久一区二区精品| 乱中年女人伦av一区二区| 久久精品国产亚洲aⅴ| 欧美专区亚洲专区| 久久国产婷婷国产香蕉| 久久国产精品99国产| 久久久一区二区| 免费久久99精品国产| 欧美高清在线一区二区| 欧美日韩精品免费看 | 午夜视频久久久久久| 亚洲免费婷婷| 久久国产精品久久久久久| 久久激情婷婷| 男女精品网站| 欧美精品97| 国产精品v一区二区三区| 快射av在线播放一区| 免费在线观看成人av| 欧美日韩成人一区| 国产欧美日韩视频| 国产专区综合网| 亚洲经典一区| 伊人精品成人久久综合软件| 亚洲国产成人av好男人在线观看| 亚洲久色影视| 午夜在线视频一区二区区别| 久久亚洲精品网站| 欧美激情1区2区| 亚洲视频在线视频| 久久五月天婷婷| 欧美理论电影在线观看| 国产毛片一区| 亚洲精品久久久久| 性色av一区二区三区| 美女亚洲精品| 一区二区三区|亚洲午夜| 久久riav二区三区| 欧美日韩国产天堂| 国产在线观看一区| 日韩一区二区免费看| 午夜欧美精品| 亚洲激情视频在线播放| 午夜国产精品视频| 欧美成人中文| 国产一区二区三区无遮挡| 99这里只有精品| 男男成人高潮片免费网站| 老司机成人网| 欧美a级一区二区| 中日韩高清电影网|