freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

計算機科學與技術(shù)專業(yè)畢業(yè)設(shè)計-pe格式程序加殼軟件-資料下載頁

2024-11-07 22:48本頁面

【導讀】包含本人或其他用途使用過的成果。相關(guān)文獻的引用已在論文中作了明確的說明。學位論文與資料若有不實之處,本人承擔一切相關(guān)責任。加殼過的程序可以直接運行,但是不能查看源代碼.要經(jīng)過脫殼才可以查。加殼的另一種常用的方式是在二進制的程序中植入一段代碼,在運行的時候。優(yōu)先取得程序的控制權(quán),做一些額外的工作。大多數(shù)病毒就是基于此原理。這種技術(shù)也常用來保護軟件版權(quán),防止被軟件破解。

  

【正文】 入的外殼能更有效地組織,需要增加兩個節(jié)。 一個節(jié)用來寫入 shellcode,即在被加殼文件中首先運行的外殼 代碼。另一個節(jié)是外殼所用到的數(shù)據(jù)節(jié)。把外殼需要用到的數(shù)據(jù)寫進被加殼文件中,如原程序真正的程序入口點,外殼所用的輸入表等。 先要在 PE 頭增加兩個節(jié)頭。 23 (圖 ) 增加了兩個節(jié)后,用一些 PE 查看工具即可查看到所增加的兩個節(jié)。名叫 .mypack和 .mpdata (圖 ) 24 寫入 shellcode 代碼 把節(jié)的存儲空間準備好后,就可以寫入 shellcode。至于 shellcode 的編寫,論文后面會作詳細介紹。 (圖 ) 寫入外殼所需數(shù)據(jù) 這里的數(shù)據(jù)是外殼所用到,包括 OEP,外殼所用輸入表,等。以下是該數(shù)據(jù)結(jié)構(gòu): (圖 ) 接這個數(shù)據(jù)結(jié)構(gòu)后面的,是原程序的原始輸入表,用自定義的格式,寫入到文件里。 25 (圖 ) 26 7 shellcode 的編寫 什么是外殼 外殼實際上是一段 shellcode,被存放到某段內(nèi)存中。 CPU 可以執(zhí)行這段 shellcode。加殼后的程序,外殼會先于原程序取得控制權(quán),在進行了外殼的解密等操作后,會將把控制權(quán)還給原程序。對于用戶來講,外殼好像什么都沒有做一樣,對用戶是 完全透明的。但對想要破解軟件者來講,就是一道必須面對的坑。 ShellCode 可以在內(nèi)存中任何一個位置獨立運行,他不需要外界對其進行任何操作,不需要裝載器對其進行裝載、重定位、填充 IAT 這樣操作。 因此很多工作都需要自己去做。所以,在編寫時需要一定的前置知識: .高級語言源代碼是怎么變成 Opcode 的,如何處理局部 或 全局變量,文件作用域內(nèi)代碼是如何排布的 文件結(jié)構(gòu)的知識 .尤其是 EAT 方面的,因為在 ShellCode 執(zhí)行過程中調(diào)用的 API 都需要你自己獲取到 。 Shellcode 是一段高技巧的軟件代碼,為了小而精,一般直接寫為 16 進制的操作碼,當然編寫者一般采用 C 或匯編編寫,然后通過匯編程序成為 16進制的操作碼。 Shellcode能完成特殊任務的自包含的二進制代碼,根據(jù)不同的任務可能是發(fā)出一條系統(tǒng)調(diào)用或建立一個高權(quán)限, Shellcode 還可用于 漏洞入侵,通過把一段二進制碼送入后并執(zhí)行,就可以獲得目標機器的控制權(quán),之后的事情是屬于愛好者學習技術(shù),還是黑客的行為,就看攻擊者的一念之差。 但這里,本程序的 shellcode 只是完成外殼應該要做的事情:取得所需 API,還原輸入表,重定位 程序,跳轉(zhuǎn)程序原始 OEP。這些都是一般外殼要做的事。 27 (圖 ) 內(nèi)聯(lián)匯編 簡介 內(nèi)聯(lián)匯編,就是在 C/C++語言的代碼中插入?yún)R編語言編寫程序。這種編程方式更加高效,更加底層。 一個內(nèi)聯(lián)匯編在 C 和 C++ 可以嵌入?yún)R編語言指令源程序,而無需額外的程序集和鏈接步驟。 一個內(nèi)聯(lián)匯編編譯為編譯器 — 您不需要一個單獨的匯編程序 (如 Microsoft Macro Assembler (masm)。 由于這個內(nèi)聯(lián)匯編不需要單獨的程序集和鏈接步驟,與一個單獨的匯編方便。 內(nèi)聯(lián)程序集 代碼可以使用任何 C 或 C++ 變量或中的函數(shù)名,因此,其集成的程序的 C 和 C++ 代碼非常容易。 并且,由于程序集代碼可以與 C 和 C++ 語句組合,可以執(zhí)行會相當麻煩或不可以在一個 C 或 C++ 的任務。 __asm 關(guān)鍵字調(diào)用一個內(nèi)聯(lián)匯編,并且可以顯示,每當 c. 或 C++ 語句合法。 它不能單獨出現(xiàn)。 必須由程序集指令執(zhí)行它,請在大括號中 的命令的一組,或者,至少, null 對大括號。 該術(shù)語 “ __asm 塊是”此處稱為命令的說明或組,在大括號。 下面的代碼是簡單的 __asm 塊對大括號。 (代碼是一個自定義 prolog 序列。 ) // // processor: x86 void __declspec(naked) main() 28 { // Naked functions must provide their own prolog... __asm { push ebp mov ebp, esp sub esp, __LOCAL_SIZE } // ... and epilog __asm { pop ebp ret } } 或者,可以放置在每個程序集指令前面的 __asm : __asm push ebp __asm mov ebp, esp __asm sub esp, __LOCAL_SIZE 外殼與內(nèi)聯(lián)匯編 由于外殼的特殊性,外殼 的編寫使用匯編比較方便。高級語言如 C/C++等對一些比較底層的操作做不到匯編那么靈活,自如。但使用內(nèi)聯(lián)匯編也要注意更多問題,如返回值,棧平衡等。 內(nèi)聯(lián)匯編可以幫助我們充分利用計算能力。然而,大多數(shù)程序員很少有機會實際使用該特性。事實上,內(nèi)聯(lián)匯編只為特定的要求提供服務,在涉及先進的高層編程語言時尤其如此。 由于 shellcode 所需的操作比較特別,所以本加殼程序還是采用內(nèi)聯(lián)匯編作為shellcode 編寫方法。雖然也可以用別的編譯器如 microsoft 的 masn。但這對 shellcode的提取和整合到程序都比 較麻煩。所以還是采用內(nèi)聯(lián)匯編。 如圖為本程序所寫的 shellcode。 29 (圖 ) shellcode 中變量存儲 局部變量與全局變量 從物理上講,堆棧是就是一段連續(xù)分配的內(nèi)存空間。在一個程序中,會聲明各種變量。靜態(tài)全局變量是位于數(shù)據(jù)段并且在程序開始運行的時候被加載。而程序的動態(tài)的局部變量則分配在堆棧里面。 從操作上來講,堆棧是一個先入后出的隊列。他的生長方向與內(nèi)存的生長方向正好相反。我們規(guī)定內(nèi)存的生長方向為向上,則棧的生長方向為向下。壓棧的操作 push=ESP4,出棧的操作是 pop=ESP+,堆棧中老的值,其內(nèi)存地址,反而比新的值要大。請牢牢記住這一點,因為這是堆棧溢出的基本理論依據(jù)。 30 在一次函數(shù)調(diào)用中,堆棧中將被依次壓入:參數(shù),返回地址, EBP。如果函數(shù)有局部變量,接下來,就在堆棧中開辟相應的空間以構(gòu)造變量。函數(shù)執(zhí)行結(jié)束,這些局部變量的內(nèi)容將被丟失。但是不被清除。在函數(shù)返回的時候,彈出 EBP,恢復堆棧到函數(shù)調(diào)用的地址 ,彈出返回地址到 EIP 以繼續(xù)執(zhí)行程序。這就是正常 C函數(shù)調(diào)用所用到的變量與棧的關(guān)系。 (圖 ) 在 shellcode 中,不能使用全局變量。正常通過編譯器編寫的程序,可以有全局變量,全局變量都是存儲在數(shù)據(jù)段中,全局變量的地址在鏈接完成后就已經(jīng)是確定的了。但是shellcode 執(zhí)行的地址卻是不確定的,他無法使用全局變量。 31 shellcode 中的變量 在 shellcode 中不可能使用全局變量,因為在不同的被加殼 PE文件內(nèi)部,是不可能知道或者存在全局變量的地址。在這里可以使用局部變量的方式,使用 EBP 指針來定位局部變量。 Shellcode 使用 C語言對局部變量的處理方式,來使用變量。 (圖 ) 通過這種方式,就可以在 shellcode 中利用棧使用變量。 在 shellcode 寫義變量: 32 (圖 ) Shellcode 以 EBP 為基址,對于不同的變量,只要 EBP增加或減少相應的值,就可以取得棧中相應的變量的值。 shellcode 重定位 什么是重定位?在 shellcode 里通俗地講就是代碼要知道自已現(xiàn)在運行的地址,在哪里運行的。最簡單也是用得最多的方法是 call/pop 大法: call label1 label1: pop eax 通過這 個簡單的操作, eax 里的值就是當前的地址了。 可以一句一句地分析上面的語句 1,當執(zhí)行完 call label1 時, EIP 指向 POP EAX 這指令,同時反回地址即 label1 的地址壓入棧 pop eax 后,些時會把棧頂?shù)闹蒂x給 eax。 通過這兩條指令就能拿到當前地址了。這小技巧對于加殼程序的字符串處起到十分重要的作用。 33 字符串處理 雖然內(nèi)聯(lián)匯編可以訪問 C\C++中的數(shù)據(jù)變量以及類對象,但它不可能通過 MASM 指令和操作符來定義數(shù)據(jù)及對象。尤其你還不能使用 DB, DW, DD, DQ, DT 和 DF 等定義指令以及 DUP和 This操作符。匯編中的結(jié)構(gòu)記錄也不是可用的。內(nèi)聯(lián)匯編也不支持 directives STRUC, RECORD, WIDTH, 和 MASK 指令。不過,在內(nèi)聯(lián)匯編可以使用到一個 _emit 宏指令,它類似于 MASM 中的 DB 指令,它可以在本區(qū)域內(nèi)定義出一個字節(jié)型,雖然它每次只能定義一個字節(jié)出來,但還是可以用它來定義出一個字符串,請看示例 : ? define randasm __asm _emit 0x4A __asm _emit 0x43 __asm _emit 0x4B ? ? ? __asm ? { ? randasm ? } 所以,內(nèi)聯(lián)匯編寫義一些自定義的數(shù)據(jù)(即在 shellcode 里存放數(shù)據(jù))是很麻煩的。只能用一個內(nèi)聯(lián)匯編的宏指令 _emit 來定義,而且只能一個一個定義。 但對于本程序的 shellcode,有一個必須要使用的是字符串,比如一些特殊的 API 函數(shù)的名稱如” GetProcAddress” \0, “ LoadLibraryA” \0 等。必須利用宏指令 _emit 來實現(xiàn)字符串的處理。 這里我使用了一種方法。代碼如下: 34 (圖 ) 如上圖,字符 串的定義都是在 shellcode 代碼里面的,即這段外殼即有代碼,也有數(shù)據(jù)。對于字符串 GetModuleHandleA\0,我要取得這個串的首地址,把它壓入棧,以供程序其他函數(shù)調(diào)用。 但要怎么取得字符串的首地址,這個就需要用到特別的方法。 在內(nèi)聯(lián)匯編,對于如下例子: label: _emit 0x45 _emit 0x46 _emit 0x0 要取得字符串地址 , 可以 push label。 但這個 push label 操作,所入棧的地址卻不是 35 被加殼程序的該字符串在 shellcode 的地址,而是該字符串在 本加殼程序里的地址! 兩個不同的程序,引用相同的地址,在加殼程序里該地址是正確的,但這段 shellcode 是要運行在別的被加殼程序里,所以這個 push label 的地址肯定是錯誤的。 要取得正確的地址,可以用如下方法: Push_GetModuleHandleA: call Push_GetModuleHandleA1 Push_GetModuleHandleA1: push ecx mov eax,[esp + 8] mov ecx,[esp + 4] add ecx,22 //22這個值是經(jīng)過 OD測試,使 ecx剛好到達字符串 mov [esp + 8] , ecx pop ecx add esp,4 jmp eax 當程序要使用字符串時,可以 call Push_GetModuleHandleA, 因為這里所使用的 call是 0xE8 指令類弄的 call,所調(diào)用的函數(shù)是通過相對偏移來找到地址的,所以當運行在別處時,可以正確地去到 Push_GetModuleHandleA 這個標號處所在地址。 然后利用一些重定位技術(shù),棧平衡的手段,就可以得到字符串的地址,并且把它 的值入棧。 即當 call Push_GetModuleHandleA 后,相當于字符串“ GetModuleHandleA\0”的地址壓棧了。這時就可以供 shellcode 使用了。 36 函數(shù)調(diào)用約定 函數(shù)調(diào)用 如何定義函數(shù)、調(diào)用函數(shù),是每個程序員學習編程的入門課。調(diào)用函數(shù) (caller)向被調(diào)函數(shù) (callee)傳入?yún)?shù),被調(diào)函數(shù)返回結(jié)果,看似簡單的過程,其實 CPU 和系統(tǒng)內(nèi)核在背后做了很多工作。 下面看一個函數(shù)調(diào)用實例: int foo(int a, int b){ return a+b。 } int main(void){ Foo(2, 5)。 return 0。 } 該程序很簡單, mainfoo。 一個函數(shù)被調(diào)用,首先默認要完成以下動作:
點擊復制文檔內(nèi)容
高考資料相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1