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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

移动导出表到新增节

發(fā)布時(shí)間:2025/3/21 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 移动导出表到新增节 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、為什么要移動(dòng)導(dǎo)出表

移動(dòng)導(dǎo)出表是指將導(dǎo)出表以及其內(nèi)部的三張子表移動(dòng)到新增節(jié),這個(gè)操作是軟件加密的第一步。因?yàn)檐浖用軙?huì)把節(jié)進(jìn)行加密,而數(shù)據(jù)目錄是在節(jié)里的,加密后操作系統(tǒng)不認(rèn)識(shí)了,因此我們要把數(shù)據(jù)目錄里面的東西移動(dòng)到一個(gè)新的節(jié)里。

二、怎么移動(dòng)

上圖是導(dǎo)出表的結(jié)構(gòu),移動(dòng)導(dǎo)出表的步驟,我個(gè)人的做法分為以下幾步:

  • 計(jì)算新增節(jié)的大小,必須能放下導(dǎo)出表,3張子表,所有按名字導(dǎo)出的函數(shù)名;
  • 新增一個(gè)節(jié),并設(shè)置其屬性為可讀,含已初始化數(shù)據(jù);
  • 原封不動(dòng)地拷貝3張子表到新增節(jié);
  • 遍歷 AddressOfNames,計(jì)算函數(shù)名的字節(jié)數(shù),然后依次添加到新增節(jié),添加同時(shí)更新 AddressOfNames 表里的RVA;
  • 拷貝導(dǎo)出表到新增節(jié),修改3張子表的RVA;
  • 修改目錄項(xiàng)中新導(dǎo)出表的RVA。
  • 三、代碼實(shí)現(xiàn)

    // 移動(dòng)導(dǎo)出表到新增節(jié) DWORD MoveExportTableToNewSection(LPVOID pFileBuffer, LPVOID *pNewFileBuffer, DWORD dwFileBufferSize) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pDosHeader + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + \RvaToFoa(pFileBuffer, pOptionHeader->DataDirectory[0].VirtualAddress));PDWORD pAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + RvaToFoa(pFileBuffer, pExportTable->AddressOfFunctions));PWORD pAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + RvaToFoa(pFileBuffer, pExportTable->AddressOfNameOrdinals));PDWORD pAddressOfNames = (PDWORD)((DWORD)pFileBuffer + RvaToFoa(pFileBuffer, pExportTable->AddressOfNames));// 計(jì)算新增節(jié)的大小// = NumberOfFunctions * 4 + NumberOfNames * (2 + 4) + 所有函數(shù)名的字節(jié) + sizeof(_IMAGE_EXPORT_DIRECTORY)// 然后文件對(duì)齊DWORD dwNewSectionSize = 0;dwNewSectionSize += pExportTable->NumberOfFunctions * 4; // AddressOfFunctions 的空間dwNewSectionSize += pExportTable->NumberOfNames * (2 + 4); // AddressOfNames + AddressOfNameOrdinals 的空間size_t i = 0;for (i = 0; i < pExportTable->NumberOfNames; i++){ LPCSTR lpszFuncName = (LPCSTR)((DWORD)pFileBuffer + RvaToFoa(pFileBuffer, pAddressOfNames[i]));dwNewSectionSize += strlen(lpszFuncName) + 1;}dwNewSectionSize += sizeof(_IMAGE_EXPORT_DIRECTORY);dwNewSectionSize = Align(dwNewSectionSize, pOptionHeader->FileAlignment);//printf("新增節(jié)的大小 = %x\n", dwNewSectionSize);DWORD dwNewBufferSize = AddSection(pFileBuffer, pNewFileBuffer, dwFileBufferSize, dwNewSectionSize);pDosHeader = (PIMAGE_DOS_HEADER)*pNewFileBuffer;pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pDosHeader + 4);pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);// 修改新增節(jié)屬性為可讀、含已初始化數(shù)據(jù)pSectionHeader[pPEHeader->NumberOfSections - 1].Characteristics = 0x40000040;pExportTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD)*pNewFileBuffer + \RvaToFoa(*pNewFileBuffer, pOptionHeader->DataDirectory[0].VirtualAddress));pAddressOfFunctions = (PDWORD)((DWORD)*pNewFileBuffer + RvaToFoa(*pNewFileBuffer, pExportTable->AddressOfFunctions));pAddressOfNameOrdinals = (PWORD)((DWORD)*pNewFileBuffer + RvaToFoa(*pNewFileBuffer, pExportTable->AddressOfNameOrdinals));pAddressOfNames = (PDWORD)((DWORD)*pNewFileBuffer + RvaToFoa(*pNewFileBuffer, pExportTable->AddressOfNames));// 把3張子表拷貝到新節(jié),更新指針LPVOID pInsert = (LPVOID)((DWORD)*pNewFileBuffer + pSectionHeader[pPEHeader->NumberOfSections - 1].PointerToRawData);memcpy(pInsert, pAddressOfFunctions, 4 * pExportTable->NumberOfFunctions);pAddressOfFunctions = (PDWORD)pInsert;pInsert = (LPVOID)((DWORD)pInsert + 4 * pExportTable->NumberOfFunctions);memcpy(pInsert, pAddressOfNameOrdinals, 2 * pExportTable->NumberOfNames);pAddressOfNameOrdinals = (PWORD)pInsert;pInsert = (LPVOID)((DWORD)pInsert + 2 * pExportTable->NumberOfNames);memcpy(pInsert, pAddressOfNames, 4 * pExportTable->NumberOfNames);pAddressOfNames = (PDWORD)pInsert;pInsert = (LPVOID)((DWORD)pInsert + 4 * pExportTable->NumberOfNames);// 拷貝函數(shù)名for (i = 0; i < pExportTable->NumberOfNames; i++){LPCSTR lpszFuncName = (LPCSTR)((DWORD)*pNewFileBuffer + RvaToFoa(*pNewFileBuffer, pAddressOfNames[i]));memcpy(pInsert, lpszFuncName, strlen(lpszFuncName) + 1);// 更新函數(shù)名的RVA地址pAddressOfNames[i] = FoaToRva(*pNewFileBuffer, (DWORD)pInsert - (DWORD)*pNewFileBuffer);pInsert = (LPVOID)((DWORD)pInsert + strlen(lpszFuncName) + 1);}// 拷貝導(dǎo)出表memcpy(pInsert, pExportTable, sizeof(_IMAGE_EXPORT_DIRECTORY));pExportTable = (PIMAGE_EXPORT_DIRECTORY)pInsert;pExportTable->AddressOfFunctions = FoaToRva(*pNewFileBuffer, (DWORD)pAddressOfFunctions - (DWORD)*pNewFileBuffer);pExportTable->AddressOfNameOrdinals = FoaToRva(*pNewFileBuffer, (DWORD)pAddressOfNameOrdinals - (DWORD)*pNewFileBuffer);pExportTable->AddressOfNames = FoaToRva(*pNewFileBuffer, (DWORD)pAddressOfNames - (DWORD)*pNewFileBuffer);// 修改目錄項(xiàng),指向新的導(dǎo)出表pOptionHeader->DataDirectory[0].VirtualAddress = FoaToRva(*pNewFileBuffer, (DWORD)pExportTable - (DWORD)*pNewFileBuffer);return dwNewBufferSize; }

    四、運(yùn)行結(jié)果

    depends walker 和 LordPE 識(shí)別正確


    調(diào)用新DLL的函數(shù),沒有問題。

    五、完整代碼

    https://blog.csdn.net/Kwansy/article/details/106234264

    總結(jié)

    以上是生活随笔為你收集整理的移动导出表到新增节的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。