日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C++寫殼詳細教程(上)

jf_78858299 ? 來源:看雪論壇九陽道人 ? 作者:看雪論壇九陽道人 ? 2023-03-17 14:49 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文基于Windows平臺對PE文件加殼的項目,經過一個月的緩沖,決定復習總結及分享下的我的心得。

主要工具: 010Editor、VS2017、x64dbg、LordPE、OD

實驗平臺:win10 64位

實現(xiàn)功能:加殼,壓縮,對代碼段加密。

一、加殼原理

要想弄明白怎么對PE文件加殼,首先需要對PE文件比較熟悉,而最快的熟悉PE文件的方法就是自己寫一個PE解析工具和寫殼了。

先只用工具010Editor完成一個手工加殼,那么就明白加殼的原理了。

首先進行手工加殼

先用VS隨便生成一個exe文件,我們使用它進行實驗。

可以先使用010Editor、LordPE、OD等工具查看節(jié)區(qū)個數(shù),我實驗程序的原始區(qū)段(節(jié)區(qū))個數(shù)是8個。

1. 給PE文件添加一個新區(qū)段

修改文件頭的NumberOfSection

使用010Editor打開測試程序,按alt+4出現(xiàn)一個模板菜單找到NumberOfSection把該數(shù)字加1,這里改為了9。

圖片

2. 設置新的區(qū)段頭

添加保存之后, 重新運行010Editor的模板(或者重啟010),區(qū)段就增加了一個。

圖片

設置整個新增加的區(qū)段的數(shù)據(jù),主要需要設置的字段如下:

圖片

① 區(qū)段名(可選)

② 區(qū)段數(shù)據(jù)的實際字節(jié)數(shù)Misc.VirtualSize

③ 區(qū)段的VirtualAddress(區(qū)段數(shù)據(jù)在內存中的RVA),此值必須是: 上一個區(qū)段的VirtualAddress + 上一個區(qū)段經內存對齊粒度對齊后的大?。▋却鎸R大小是0x1000的整數(shù)倍)

④ 區(qū)段以文件對齊粒度對齊后的大小SizeOfRawData(文件對齊大小是0x200的整數(shù)倍)

⑤ 區(qū)段的PointerToRawData(區(qū)段數(shù)據(jù)在文件中的偏移),此值必須是:上一個區(qū)段的PointerToRawData + 上一個區(qū)段的SizeOfRawData

⑥ 區(qū)段屬性主要設置區(qū)段為可讀可寫可執(zhí)行如下圖

圖片

對比上一個區(qū)段修改新添加的區(qū)段里的字段。

圖片

3. 添加區(qū)段數(shù)據(jù)

區(qū)段頭內容雖然設置好了,但真正重要的區(qū)段里的數(shù)據(jù)還需要插入到文件中,以擴充文件的大小,因為區(qū)段頭只是一個相當于目錄的存在,如果只有目錄而沒有內容,就會造成這個文件成為一個無效的PE文件。

把010Editor里的數(shù)據(jù)頁滾動到最下面按Ctrl+shift+i添加200h個(16進制)字節(jié)

圖片

圖片

4. 修改PE文件的擴展頭的SizeofImage

現(xiàn)在PE文件已經被擴充了大小,擴展頭中的映像大小必須更新,否則當PE文件加載到內存后,新區(qū)段的數(shù)據(jù)將無法得到正常加載。

這個字段的值記錄的是一個PE文件在內存中的大小,可以將之設置為: 最后一個區(qū)段在內存中的位置 + 最后一個區(qū)段在內存中的大小,即:

OptionalHeader.SizeofImage = 最后一個區(qū)段.VirtualAddress + 最后一個區(qū)段.SizeOfRawData按內存對齊粒度對齊的大小

圖片

保存之后,運行該程序,就能正常運行(中間某些環(huán)節(jié)操作錯了就會導致該文件無法正常運行)到此添加區(qū)段成功了。那么加殼也就成功了90%,這個新區(qū)段之后稱為殼代碼段。

5. 添加殼代碼

先找到擴展頭的DLL屬性字段,去掉隨機基址,把40 81改為 00 81后保存。

圖片

在這里為了方便,就使用LordPE來操作剩下的步驟了,先記錄原始的OEP入口點為11055,把他改為新區(qū)段的RVA 1F000然后點擊保存。

圖片

然后再使用OD打開,進入到入口點就是41F000,因為默認加載基址是0x400000, 發(fā)現(xiàn)全是00 00 00的字節(jié),沒用內容。把第一行代碼改為跳轉到原來的入口點jmp 0x411055,然后打一個補丁,程序就能正常運行了。

圖片

這就是一個完整的殼流程了,雖然這個殼的內容只有一條跳轉到原入口點的代碼,但萬丈高樓平地起。基礎的東西弄懂了后面才能少遇見一些坑!

二、為什么用C++寫殼?

我的答案是簡單、便捷、方便新手入門。

很多常見的殼都用匯編寫的,確實,匯編確實可以寫出很多短小精悍、騷操作的代碼,這是C++所沒有的,但是C++支持內聯(lián)匯編,在一定程度上彌補了它的不足。

使用DLL動態(tài)庫文件保存殼代碼,我們稱它為存根部分(stub),直接把這個文件里的內容移植到我們新添加的區(qū)段里面,因為PE文件涉及到重定位,而DLL也是一個PE文件,移植后里面的數(shù)據(jù)就變得很容易修復了。

三、C++加殼流程

1. 處理加殼程序

在加殼過程中,有一個加殼器程序和stub.dll兩個文件,加殼器程序會把原文件(要加殼的文件)以文件方式讀取到堆內存,它還是以文件對齊粒度(200h)對齊的,而stub.dll是以不處理的方式讀取到了內存中,它是以內存粒度(1000h)對齊的。

使用LoadLibraryExA加載DLL并且第三個參數(shù)使用DONT_RESOLVE_DLL_REFERENCES的時候,他就不會對這個文件進行重定位等操作,是以原始形態(tài)加載到內存。

//將DLL以不會執(zhí)行代碼的標志加載到進程中.
HMODULE hStubDll = LoadLibraryExA("Stub.dll", 0,
DONT_RESOLVE_DLL_REFERENCES);

再自定義一個共享頭文件share.h,這個文件保存一些加殼程序和stub.dll中都會用到的一些數(shù)據(jù),封裝的函數(shù),及共用的結構體!

流程如下:

① 使用加殼器給被加殼程序添加新區(qū)段。

② 加密/壓縮被加殼程序。

③ 將stub的代碼段移植到新區(qū)段。

④ 將被加殼程序的OEP記錄到share.h中。

⑤ 將被加殼程序的EP設置到新區(qū)段。

⑥ 去掉隨機基址。

⑦ 保存為新文件。

移植數(shù)據(jù)到新區(qū)段,把整個stub.dll的代碼段.text移植到目標文件新添加的區(qū)段中,這樣就完成了最簡單加殼操作。

圖片

當然事實上并沒有那么簡單,stub.dll里的.text段里面的數(shù)據(jù)需要先進行重定位修復,修復完成后再移植過去,這樣殼區(qū)段才能正常運行起來。

首先根據(jù)stub.dll的重定位表獲取出stub.dll中.text段需要重定位的數(shù)據(jù),然后把該數(shù)據(jù)

① 減去原始基址

② 減去原始代碼段Rva

③ 加上新基址(exe目標文件)

④ 加上新Rva (exe中新添加的區(qū)段RVA)

用C++寫代碼,首先封裝了很多常用的函數(shù),如獲取DOS頭和NT頭,區(qū)段頭等。這樣會節(jié)省后面大量敲代碼的時間。

//獲取DOS頭
PIMAGE_DOS_HEADER GetDosHeader(char* pBase)
{
return (PIMAGE_DOS_HEADER)pBase;
}

//獲取NT頭
PIMAGE_NT_HEADERS GetNtHeader(char* pBase)
{
return (PIMAGE_NT_HEADERS)
(GetDosHeader(pBase)->e_lfanew + (DWORD)pBase);
}

例如獲取NT頭:

auto pNt = (PIMAGE_NT_HEADERS)GetNtHeader(pBase);

C++里auto的功能是自動獲取后面數(shù)據(jù)類型,這也體現(xiàn)了C++的強大之處。

完整重定位代碼:

//修復stub的重定位
void FixStubReloc(char* pTarBuff, char*& hModule,DWORD dwNewBase,DWORD dwNewSecRva)
{
//獲取sutb.dll重定位va
auto pReloc = (PIMAGE_BASE_RELOCATION)
(GetOptHeader(hModule)->DataDirectory[5].VirtualAddress
+ hModule);
//獲取stub.dll的.text區(qū)段的Rva
DWORD dwTextRva = (DWORD)GetSecHeader(hModule, ".text")->VirtualAddress;

//修復重定位
while (pReloc->SizeOfBlock)
{
struct TypeOffset
{
WORD offset : 12;
WORD type : 4;
};
TypeOffset* pTyOf = (TypeOffset*)(pReloc + 1);
DWORD dwCount = (pReloc->SizeOfBlock - 8) / 2;
for (size_t i = 0; i < dwCount; i++)
{
if(pTyOf[i].type != 3)
continue;
//要修復的Rva
DWORD dwFixRva = pTyOf[i].offset + pReloc->VirtualAddress;
//要修復的地址
DWORD* pFixAddr = (DWORD*)(dwFixRva + (DWORD)hModule);
DWORD dwOldProc;
VirtualProtect(pFixAddr, 4, PAGE_READWRITE, &dwOldProc);
*pFixAddr -= (DWORD)hModule; //減去原始基址
*pFixAddr -= dwTextRva; //減去原始代碼段Rva
*pFixAddr += dwNewBase; //加上新基址
*pFixAddr += dwNewSecRva; //加上新Rva
VirtualProtect(pFixAddr, 4, dwOldProc, &dwOldProc);
}
//指向下一個重定位塊
pReloc = (PIMAGE_BASE_RELOCATION)
((DWORD)pReloc + pReloc->SizeOfBlock);
}
}

現(xiàn)在只是暫時搭建一個殼框架所以先不處理隨機基址的問題,所以要去掉隨機基址,后期再來解決隨機基址的問題。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • WINDOWS
    +關注

    關注

    4

    文章

    3707

    瀏覽量

    94355
  • C++
    C++
    +關注

    關注

    22

    文章

    2131

    瀏覽量

    77425
  • PE文件
    +關注

    關注

    0

    文章

    4

    瀏覽量

    5585
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    C++一個http服務器

    本篇文章不會涉及到很多復雜的概念,也沒有很難讀懂的模板函數(shù),代碼簡單可讀,本篇文章送給每一個想自己用C++一個http服務器的小伙伴!高手們、大佬們當然可以不用看的啦!
    發(fā)表于 09-30 10:47 ?2743次閱讀

    詳細講解C++串口的相關知識

    大家可以先參考一下這篇blog,C++串口通信里面詳細講解了C++串口的相關知識,以及一些函數(shù)的講解。下面我也會根據(jù)他的blog再講解。二、實現(xiàn)過程1、打開串口:使用函數(shù):HANDLE CreateFile();HANDLE C
    發(fā)表于 08-24 06:56

    詳述不用c++網(wǎng)頁的理由

    C++在web開發(fā)中地位如何,進來一探究竟吧。
    的頭像 發(fā)表于 12-22 10:07 ?6491次閱讀

    C++課程資料詳細資料合集包括了:面向對象程序設計與C++,算法,函數(shù)等

    本文檔的主要內容詳細介紹的是C++課程資料資料合集包括了:面向對象程序設計與C++,算法,函數(shù),概述, C++語言基礎,構造數(shù)據(jù)類型,數(shù)據(jù)類型,C+
    發(fā)表于 07-09 08:00 ?18次下載
    <b class='flag-5'>C++</b>課程資料<b class='flag-5'>詳細</b>資料合集包括了:面向對象程序設計與<b class='flag-5'>C++</b>,算法,函數(shù)等

    基于fpgrowth的c++實現(xiàn)詳細資料免費下載

    本文檔的主要內容詳細介紹的是基于fpgrowth的c++實現(xiàn)詳細資料免費下載
    發(fā)表于 08-02 08:00 ?1次下載

    如何提高cc++的安全編程能力?《CC++安全編碼》帶你詳細學習

    ,既詳細闡述了C/C++語言及其相關庫固有的安全問題和陷阱,系統(tǒng)總結了導致軟件漏洞的各種常見編碼錯誤,并給出了應對錯誤的解決方案;又對C/C++
    發(fā)表于 08-28 08:00 ?0次下載

    如何進行高質量的CC++編程?高質量C++C編程指南詳細資料免費下載

    本文檔的作用內容詳細介紹的是如何進行高質量的C、C++編程?高質量C++C編程指南詳細資料免費
    發(fā)表于 09-10 08:00 ?30次下載

    VISUAL C++教程之VISUAL C++的安裝和使用方法

    本文檔的主要內容詳細介紹的是VISUAL C++教程之VISUAL C++的安裝和使用方法資料免費下載。
    發(fā)表于 12-27 16:32 ?20次下載
    VISUAL <b class='flag-5'>C++</b>教程之VISUAL <b class='flag-5'>C++</b>的安裝和使用方法

    C++的cast最完整最詳細的解釋資料說明

    本文檔的主要內容詳細介紹的是C++的cast最完整最詳細的解釋資料說明。
    發(fā)表于 01-29 15:26 ?0次下載
    <b class='flag-5'>C++</b>的cast最完整最<b class='flag-5'>詳細</b>的解釋資料說明

    C++程序設計教程之C++的初步知識的詳細資料說明

    C++程序設計教程之C++的初步知識的詳細資料說明包括了:1. 從CC++,2 . 最簡單的C++
    發(fā)表于 03-14 14:48 ?31次下載
    <b class='flag-5'>C++</b>程序設計教程之<b class='flag-5'>C++</b>的初步知識的<b class='flag-5'>詳細</b>資料說明

    C++程序設計教程之C++工具的詳細資料說明

    本文檔的詳細介紹的是C++程序設計教程之C++工具的詳細資料說明主要內容包括了:1. 異常處理,2. 命名空間,3. 使用早期的函數(shù)庫
    發(fā)表于 03-14 16:39 ?4次下載
    <b class='flag-5'>C++</b>程序設計教程之<b class='flag-5'>C++</b>工具的<b class='flag-5'>詳細</b>資料說明

    C++語言編碼規(guī)范詳細說明

    本文檔的主要內容詳細介紹的是C++語言編碼規(guī)范詳細說明。
    發(fā)表于 01-07 16:19 ?18次下載
    <b class='flag-5'>C++</b>語言編碼規(guī)范<b class='flag-5'>詳細</b>說明

    C語言和C++的特點與用法詳細說明

    本文檔的主要內容詳細介紹的是C語言和C++的特點與用法詳細說明。
    的頭像 發(fā)表于 12-26 10:58 ?5649次閱讀

    qt用C++的2048小游戲源代碼

    qt用C++的2048小游戲源代碼
    發(fā)表于 09-27 11:48 ?3次下載

    C++詳細教程(下)

    本文基于Windows平臺對PE文件加的項目,經過一個月的緩沖,決定復習總結及分享下的我的心得。
    的頭像 發(fā)表于 03-17 14:49 ?1123次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>寫</b><b class='flag-5'>殼</b><b class='flag-5'>詳細</b>教程(下)
    汝州市| 镇安县| 昌宁县| 新竹县| 绍兴市| 驻马店市| 开封市| 焦作市| 农安县| 辽源市| 七台河市| 深水埗区| 洞头县| 关岭| 绥芬河市| 岳阳市| 民县| 陇西县| 张掖市| 元阳县| 阜城县| 凉城县| 恩平市| 陕西省| 青神县| 龙山县| 焦作市| 南通市| 柘城县| 莲花县| 兴隆县| 阿图什市| 洪雅县| 如皋市| 延长县| 都昌县| 蓬安县| 玛多县| 左权县| 虎林市| 双柏县|