成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

網絡安全編程:PE編程實例之添加節區

安全
添加節區在很多場合都會用到,比如在加殼中、在免殺中都會經常用到對PE文件添加一個節區。

[[397152]]

添加節區在很多場合都會用到,比如在加殼中、在免殺中都會經常用到對PE文件添加一個節區。添加一個節區的方法有4步,第1步是在節表的最后面添加一個IMAGE_SECTI ON_HEADER,第2步是更新IMAGE_FILE_HEADER中的NumberOfSections字段,第3步是更新IMAGE_OPTIONAL_HEADER中的SizeOfImage字段,最后一步則是添加文件的數據。當然,前3步是沒有先后順序的,但是最后一步一定要明確如何改變。

某些情況下,在添加新的節區項以后會向新節區項的數據部分添加一些代碼,而這些代碼可能要求在程序執行之前就被執行,那么這時還需要更新IMAGE_OPTIONAL_HEADER中的AddressOfEntryPoint字段。

1. 手動添加一個節區

先來進行一次手動添加節區的操作,這個過程是個熟悉上述步驟的過程。網上有很多現成的添加節區的工具。這里自己編寫工具的目的是掌握和了解其實現方法,鍛煉編程能力;手動添加節區是為了鞏固所學的知識,熟悉添加節區的步驟。

使用C32Asm用十六進制編輯方式打開測試程序,并定位到其節表處,如圖1所示。

圖1  節表位置信息

從圖1中可以看到,該PE文件有3個節表。直接看十六進制信息可能很不方便,為了直觀方便地查看節表中IMAGE_SECTION_HEADER的信息,那么使用LordPE進行查看,如圖2所示。

圖2  使用LordPE查看該節表信息

用LordPE工具查看的確直觀多了。對照LordPE顯示的節表信息來添加一個節區。IMAGE_SECTION_HEADER結構體定義如下: 

  1. typedef struct _IMAGE_SECTION_HEADER {  
  2.  BYTE Name[IMAGE_SIZEOF_SHORT_NAME];  
  3.  union {  
  4.  DWORD PhysicalAddress;  
  5.  DWORD VirtualSize;  
  6.  } Misc;  
  7.  DWORD VirtualAddress;  
  8.  DWORD SizeOfRawData;  
  9.  DWORD PointerToRawData;  
  10.  DWORD PointerToRelocations;  
  11.  DWORD PointerToLinenumbers;  
  12.  WORD NumberOfRelocations;  
  13.  WORD NumberOfLinenumbers;  
  14.  DWORD Characteristics;  
  15. } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 

IMAGE_SECTION_HEADER 結構體的成員很多,但是真正要使用的只有 6 個,分別是Name、VirtualSize、VritualAddress、SizeOfRawData、PointerToRawData 和 Characteristics。這 6 項剛好與 LordPE 顯示的 6 項相同。其實 IMAGE_SECTION_HEADER 結構體中其余的成員幾乎不被使用。下面介紹如何添加這些內容。

IMAGE_SECTION_HEADER 的長度為 40 字節,是十六進制的 0x28,在 C32Asm 中占用 2 行半的內容,這里一次把這兩行半的內容手動添加進去。回到 C32Asm 中,在最后一個節表的位置處開始添加內容,首先把光標放到右邊的 ASCII 字符中,輸入“.test”,如圖3所示。

圖3  添加“.test”節名

接下來在00000240位置處添加節的大小,該大小直接是對齊后的大小即可。由于文件對齊是0x1000字節,也就是4096字節,那么采用最小值即可,使該值為0x1000。在C32Asm中添加時,正確的添加應當是“00 10 00 00”,以后添加時也要注意字節順序。在添加后面幾個成員時,不再提示注意字節順序,應時刻清楚這點。在添加該值時,應當將光標定位在十六進制編輯處,而不是剛才所在的ASCII字符處。順便要把VirutalAddress也添加上,VirtualAddress的值是前一個節區的起始位置加上上一個節對齊后的長度的值,上一個節區的起始位置為0x6000,上一個節區對齊后的長度為0x3000,因此新節區的起始位置為0x9000。添加VirtualSize和VirtualAddress后如圖4所示。

圖4  添加VirtualSize和VirtualAddress的值

接下來的兩個字段分別是SizeOfRawData和PointerToRawData,其添加方法類似前面兩個字段的添加方法,這里就不細說了。分別添加“0x9000”和“0x1000”兩個值,如圖5所示。

圖5  添加SizeOfRawData和PointerToRawData

PointerToRawData后面的12字節都可以為0,只要修改最后4字節的內容,也就是Characteristics的值即可。這個值直接使用上一個節區的值即可,實際添加時應根據所要節的屬性給值。這里為了省事而直接使用上一個節區的屬性,如圖6所示。

圖6  添加Characteristics屬性 

整個節表需要添加的地方就添加完成了,接下來需要修改該PE文件的節區數量。當前節區數量是3,這里要修改為4。雖然可以通過LordPE等修改工具完成,但是這里仍然使用手動修改。對于修改的位置,請大家自行定位找到,修改如圖7所示。

圖7  修改節區個數為4

除了節區數量以外,還要修改文件映像的大小,也就是SizeOfImage的值。由于新添加了節區,那么應該把該節區的大小加上SizeOfImage的大小,即為新的SizeOfImage的大小。現在的SizeOfImage的大小為0x9000,加上新添加節區的大小為0xa000。SizeOfImage的位置請大家自行查找,修改如圖8所示。

圖8  修改SizeOfImage的值為0xa000

修改PE結構字段的內容都已經做完了,最后一步就是添加真實的數據。由于這個節區不使用,因此填充0值就可以了,文件的起始位置為0x9000,長度為0x1000。把光標移到文件的末尾,單擊“編輯”→“插入數據”命令,在“插入數據大小”文本框中輸入十進制的4096,也就是十六進制的0x1000,如圖9所示。

圖9  “插入數據”對話框的設置

單擊“確定”按鈕,可以看到在剛才的光標處插入了很多0值,這樣工作也完成了。單擊“保存”按鈕進行保存,提示是否備份,選擇“是”。然后用LordPE查看添加節區的情況,如圖10所示。

圖10  添加新的節區信息

對比前后兩個文件的大小,如圖11所示。

圖11  添加節區前后文件的大小

從圖11中可以看出,添加節區后的文件比原來的文件大了4KB,這是由于添加了4096字節的0值。也許大家最關心的不是大小問題,而是軟件添加了大小后是否真的可以運行。其實試運行一下,是可以運行的。

上面的整個過程就是手動添加一個新節區的全部過程,除了特有的幾個步驟以外,要注意新節區的內存起始位置和文件起始位置的值。相信通過上面手動添加節區,大家對此已經非常熟悉了。下面就開始通過編程來完成添加節區的任務。

在C32Asm軟件中可以快速定位PE結構的各個結構體和字段的位置,在菜單欄單擊“查看(V)”->“PE信息(P)”即可在C32Asm工作區的左側打開一個PE結構字段的解析面板,在面板上雙擊PE結構的每個字段則可在C32Asm工作區中定位到十六進制形式的PE結構字段的數據。

2. 通過編程添加節區

通過編程添加一個新的節區無非就是文件相關的操作,只是多了一個對PE文件的解析和操作而已。添加節區的步驟和手動添加節區的步驟是一樣的,只要一步一步按照上面的步驟寫代碼就可以了。在開始寫代碼前,首先修改FileCreate()函數中的部分代碼,具體如下: 

  1. m_hMap = CreateFileMapping(m_hFile, NULL,  
  2.   PAGE_READWRITE /*| SEC_IMAGE*/,0, 0, 0);  
  3. if ( m_hMap == NULL )  
  4.  
  5.   CloseHandle(m_hFile); 
  6.   return bRet;  
  7. }  

這里要把SEC_IMAGE宏注釋掉。因為要修改內存文件映射,有這個值會使添加節區失敗,因此要將其注釋掉或者直接刪除掉。

程序的界面如圖12所示。

圖12  添加節區界面

首先編寫“添加”按鈕響應事件,代碼如下: 

  1. void CPeParseDlg::OnBtnAddSection()  
  2.  
  3.   // 在這里添加驅動程序  
  4.   // 節名  
  5.   char szSecName[8] = { 0 };  
  6.   // 節大小  
  7.   int nSecSize = 0 
  8.   GetDlgItemText(IDC_EDIT_SECNAME, szSecName, 8);  
  9.   nSecSize = GetDlgItemInt(IDC_EDIT_SEC_SIZE, FALSE, TRUE);  
  10.   AddSec(szSecName, nSecSize);  

按鈕事件中最關鍵的地方是AddSec()函數。該函數有兩個參數,分別是添加節的名稱與添加節的大小。這個大小無論輸入多大,最后都會按照對齊方式進行向上對齊。看一下AddSec()函數的代碼,具體如下: 

  1. VOID CPeParseDlg::AddSec(char *szSecName, int nSecSize)  
  2.  
  3.   int nSecNum = m_pNtHdr->FileHeader.NumberOfSections;  
  4.   DWORD dwFileAlignment = m_pNtHdr->OptionalHeader.FileAlignment;  
  5.   DWORD dwSecAlignment = m_pNtHdr->OptionalHeader.SectionAlignment;  
  6.   PIMAGE_SECTION_HEADER pTmpSec = m_pSecHdr + nSecNum;  
  7.   // 復制節名  
  8.   strncpy((char *)pTmpSec->Name, szSecName, 7);  
  9.   // 節的內存大小  
  10.   pTmpSec->Misc.VirtualSize = AlignSize(nSecSize, dwSecAlignment);  
  11.   // 節的內存起始位置  
  12.   pTmpSec->VirtualAddress=m_pSecHdr[nSecNum-1].VirtualAddress+AlignSize(m_pSecHdr [nSecNum - 1].Misc.VirtualSize, dwSecAlignment);  
  13.   // 節的文件大小  
  14.   pTmpSec->SizeOfRawData = AlignSize(nSecSize, dwFileAlignment);  
  15.   // 節的文件起始位置 
  16.   pTmpSec->PointerToRawData=m_pSecHdr[nSecNum-1].PointerToRawData+AlignSize(m_pSecHdr[nSecNum - 1].SizeOfRawData, dwSecAlignment);  
  17.   // 修正節數量  
  18.   m_pNtHdr->FileHeader.NumberOfSections ++;  
  19.   // 修正映像大小  
  20.   m_pNtHdr->OptionalHeader.SizeOfImage += pTmpSec->Misc.VirtualSize;  
  21.   FlushViewOfFile(m_lpBase, 0);  
  22.   // 添加節數據  
  23.   AddSecData(pTmpSec->SizeOfRawData);  
  24.   EnumSections();  

代碼中每一步都按照相應的步驟來完成,其中用到的兩個函數分別是 AlignSize()和AddSecData()。前者是用來進行對齊的,后者是用來在文件中添加實際的數據內容的。這兩個函數非常簡單,代碼如下: 

  1. DWORD CPeParseDlg::AlignSize(int nSecSize, DWORD Alignment)  
  2.  
  3.   int nSize = nSecSize 
  4.   if ( nSize % Alignment != 0 )  
  5.   {  
  6.     nSecSize = (nSize / Alignment + 1) * Alignment;  
  7.   }  
  8.   return nSecSize;  
  9.  
  10. VOID CPeParseDlg::AddSecData(int nSecSize)  
  11.   PBYTE pByte = NULL 
  12.   pByte = (PBYTE)malloc(nSecSize);  
  13.   ZeroMemory(pByte, nSecSize);  
  14.   DWORD dwNum = 0 
  15.   SetFilePointer(m_hFile, 0, 0, FILE_END);  
  16.   WriteFile(m_hFile, pByte, nSecSize, &dwNum, NULL);  
  17.   FlushFileBuffers(m_hFile);  
  18.   free(pByte);  

整個添加節區的代碼就完成了,仍然使用最開始的那個簡單程序進行測試,看是否可以添加一個節區,如圖13所示。

圖13  添加節區

從圖13中可以看出,添加節區是成功的。試著運行一下添加節區后的文件,可以正常運行,而且添加節區的文件比原文件大了4KB,和前面手動添加的效果是一樣的。 

 

責任編輯:龐桂玉 來源: 計算機與網絡安全
相關推薦

2021-04-25 21:25:09

網絡安全網絡安全編程PE編程

2021-04-26 10:32:38

網絡安全PE編程工具

2021-04-28 14:35:48

網絡安全PE編程代碼

2021-04-19 10:26:41

網絡安全PE文件

2021-03-03 12:20:42

網絡安全DLL編程

2016-10-10 00:18:27

2021-01-18 10:35:18

網絡安全Windows代碼

2021-03-05 13:46:56

網絡安全遠程線程

2021-01-26 13:45:03

網絡安全Winsock編程

2021-04-22 09:35:23

網絡安全PE地址

2021-02-19 09:30:52

網絡安全服務控制管理器代碼

2021-02-21 18:19:43

網絡安全網絡安全編程創建進程

2021-02-23 10:20:07

網絡安全進程代碼

2021-05-08 11:50:59

網絡安全API函數代碼

2021-03-31 11:35:00

網絡安全OllyDbg分析工具

2021-04-14 15:53:58

網絡安全C語言wcslen

2021-03-01 11:20:13

網絡安全多線程代碼

2021-06-18 09:55:09

網絡安全目錄監控

2021-04-06 11:04:54

網絡安全C語言代碼

2021-04-13 11:15:54

網絡安全C語言循環結構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国产91久久久久久密臀 | 国产欧美日韩在线一区 | www.黄网 | 国产一区二区三区在线观看免费 | 国产午夜精品视频 | 日韩久久久久久 | 视频在线一区二区 | 中文字幕精品视频 | 爱爱免费视频 | 欧美精品91| 精品乱人伦一区二区三区 | 超黄毛片 | 国产精品综合色区在线观看 | 欧美精品一区二区三区在线播放 | 欧美不卡| 亚洲高清免费视频 | 午夜爱爱毛片xxxx视频免费看 | 精品九九| 天天舔天天 | 国产精品中文字幕在线观看 | 久久久久91 | 欧美日韩视频网站 | 国产精品毛片av | 黄色免费在线网址 | 亚洲欧美中文日韩在线v日本 | 亚洲久久久 | 亚洲午夜电影 | 91视频在线 | 中文字幕亚洲一区二区三区 | 一区二区国产精品 | 成人在线视频观看 | 亚洲一区欧美一区 | 日韩看片 | 色黄爽 | 日韩欧美国产精品 | 粉嫩一区二区三区国产精品 | 亚洲电影一区二区三区 | 成人在线观看免费 | av一区二区三区四区 | 亚洲免费网址 | www.色综合|