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

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>
            欧美成人免费视频| 欧美一级久久| 欧美一级网站| 一区二区三区在线高清| 欧美视频在线观看一区二区| 久久久国产成人精品| 亚洲午夜激情在线| 欧美高清视频在线| 欧美一区二区视频在线观看2020 | 欧美午夜免费影院| 久久一区二区视频| 欧美一区二区啪啪| 亚洲图片欧美一区| 9人人澡人人爽人人精品| 亚洲第一成人在线| 久久国产一区| 香蕉av福利精品导航| 亚洲视频网在线直播| 亚洲理伦在线| 免费看av成人| 欧美日韩亚洲一区二区三区在线 | 亚洲成色精品| 久久精品盗摄| 午夜免费在线观看精品视频| 制服丝袜亚洲播放| 99精品热6080yy久久| 亚洲日本久久| 亚洲开发第一视频在线播放| 亚洲第一精品夜夜躁人人躁| 国产自产精品| 韩国一区电影| 狠狠爱www人成狠狠爱综合网| 国产区欧美区日韩区| 国产精品日韩欧美综合| 国产乱码精品1区2区3区| 国产精品在线看| 欧美日韩国产成人在线91| 欧美精品偷拍| 欧美日韩国产色站一区二区三区| 欧美va亚洲va香蕉在线| 欧美福利一区| 欧美日韩你懂的| 欧美日韩亚洲免费| 欧美日韩一区免费| 国产精品久久久久久久久婷婷 | 国产精品扒开腿做爽爽爽软件| 欧美日韩视频第一区| 欧美午夜一区| 国产精品午夜电影| 国产精品自拍在线| 国产午夜亚洲精品羞羞网站| 国模精品娜娜一二三区| 狠狠色狠狠色综合| 亚洲国产三级网| 日韩一级欧洲| 亚洲欧美一级二级三级| 久久久一二三| 欧美激情亚洲自拍| 亚洲日本激情| 亚洲直播在线一区| 久久精品国产亚洲5555| 裸体素人女欧美日韩| 国产精品久久网| 国产精品自拍三区| 亚洲国产一区二区三区高清| 99视频精品全部免费在线| 午夜精品视频网站| 老色鬼久久亚洲一区二区| 亚洲国产精品一区二区www在线| 亚洲美女黄网| 欧美专区在线观看| 欧美寡妇偷汉性猛交| 国产精品日韩专区| 亚洲电影免费观看高清完整版在线观看| 亚洲久久一区| 欧美在线综合| 欧美国产1区2区| 亚洲影音一区| 牛牛国产精品| 国产日韩一区二区| 亚洲精品日韩在线观看| 欧美在线free| 亚洲国产欧美一区二区三区丁香婷| 亚洲日本一区二区三区| 最新国产の精品合集bt伙计| 性伦欧美刺激片在线观看| 欧美电影免费观看网站| 国产精品丝袜白浆摸在线| 亚洲国产免费| 久久精品最新地址| 日韩一级裸体免费视频| 久久久97精品| 国产精品亚洲网站| 日韩网站在线观看| 久久久青草婷婷精品综合日韩| 亚洲精品日韩在线| 久久婷婷成人综合色| 国产精品劲爆视频| 亚洲精品中文字幕在线观看| 久久综合国产精品台湾中文娱乐网| 日韩一级视频免费观看在线| 理论片一区二区在线| 国产精品视频一区二区高潮| 日韩一级黄色大片| 美国十次成人| 午夜国产精品视频免费体验区| 欧美aa国产视频| 国产夜色精品一区二区av| 99riav国产精品| 另类图片国产| 午夜精品久久久久久久蜜桃app| 欧美电影资源| 亚洲国产一区在线观看| 久久夜色精品国产亚洲aⅴ| 亚洲影视综合| 欧美成人在线免费观看| 亚洲一二三级电影| 欧美gay视频| 欧美一区二区日韩一区二区| 欧美午夜欧美| 一本一本久久a久久精品牛牛影视| 欧美电影打屁股sp| 老鸭窝亚洲一区二区三区| 一区二区在线看| 欧美在线视频免费| 一区二区三欧美| 欧美激情91| 亚洲精品视频免费在线观看| 亚洲国产精品久久久久婷婷老年| 久久综合电影一区| 黄色成人在线| 免费欧美日韩| 免费亚洲网站| 亚洲国产三级网| 最新国产乱人伦偷精品免费网站| 久久久亚洲精品一区二区三区| 国产午夜精品一区二区三区欧美| 欧美在线啊v| 欧美一进一出视频| 国产一区自拍视频| 麻豆成人在线观看| 久久成人精品一区二区三区| 国产亚洲免费的视频看| 久久福利视频导航| 久久久国产精彩视频美女艺术照福利| 激情欧美一区二区三区| 久久综合给合久久狠狠狠97色69| 久久久久久久久久久成人| 1204国产成人精品视频| 欧美激情视频在线播放| 欧美理论视频| 亚洲综合视频网| 亚洲女人天堂成人av在线| 国产视频在线观看一区 | 亚洲桃色在线一区| 国产麻豆日韩欧美久久| 久久婷婷久久| 欧美福利电影网| 亚洲一区免费视频| 久久黄色网页| 亚洲另类在线一区| 在线中文字幕一区| 国产亚洲二区| 美乳少妇欧美精品| 欧美金8天国| 亚洲一区二区三区中文字幕在线| 亚洲欧美日本精品| 亚洲国产精品一区| 一区二区三区精密机械公司| 国产啪精品视频| 亚洲国产成人精品久久久国产成人一区 | 巨乳诱惑日韩免费av| 亚洲美女区一区| 亚洲欧美日韩一区二区在线| 国产欧美精品久久| 亚洲国产成人久久综合一区| 欧美视频四区| 久久精品视频va| 欧美啪啪一区| 久久久噜噜噜久久中文字幕色伊伊| 美女在线一区二区| 亚洲欧美在线高清| 久久精品视频在线看| 一本一本a久久| 看欧美日韩国产| 欧美一区二区三区视频在线| 久久久综合网站| 销魂美女一区二区三区视频在线| 久久亚洲精品中文字幕冲田杏梨 | 亚洲男人的天堂在线观看| 欧美一区二区三区视频| 99re66热这里只有精品3直播| 午夜欧美大尺度福利影院在线看| 亚洲精品免费在线观看| 亚洲已满18点击进入久久| 日韩午夜av| 久久久国产精彩视频美女艺术照福利| 亚洲自拍16p| 欧美激情一区二区三区在线视频观看 | 在线成人av网站|