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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

快速恢复Safengine Protector的Shadow DLL

發布時間:2024/5/8 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 快速恢复Safengine Protector的Shadow DLL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文以Safengine Protector v2.3.x.0為例, 提供了一種C++代碼快速恢復Safengine的Shadow DLL的方法, 沒啥技術含量, 僅希望能給各位一點參考.


Shadow DLL是一種加密殼常見的反Hook/反下斷方案, 工作原理簡言之就是自行加載系統DLL, 并重定向受保護程序的API調用到相應處理過的Shadow DLL, 由此繞開了對原有系統DLL的調用, 阻止對系統DLL的下斷和攔截. 詳細請參閱半斤八兩前輩的文章【原創】Kill Safengine Shadow Dll(附源碼)

那如何恢復呢?上面那篇文章已經講得非常清楚了, 本文只是補充了一點, 即快速恢復.

有時候我們只對特定的API感興趣, 那么我們大可通過PE結構直接確定該API在物理文件中的位置(File Offset), HOOK NtReadFile攔截殼對系統DLL文件的讀取, 接著在特定位置使用0xFF25 jmp到系統DLL, 完成恢復.

攔截部分, 我的做法是HOOK NtCreateFile, NtReadFile, NtClose以確定殼正在加載那個DLL, 這種方法感覺最為簡單高效, 無須額外的API調用(僅僅HOOK NtReadFile你無法直接判斷打開的是什么文件), 然后可能你還要記錄讀取的位置, 因為SE殼會分多次, 而不是一次性讀入, 如果特定位置恰好在分塊位置, 你就需要特殊處理.

下面附上由Export Name確定對應File Offset的方法, 可算是本文的核心代碼:

static DWORD KiGetFileOffset(LPVOID lpBaseOfImage, LPCSTR lpTargetFuncName) {auto lpNtHeader = RtlImageNtHeader(lpBaseOfImage);auto sizeOfExpDir = 0UL; auto lpExportDir = static_cast<PIMAGE_EXPORT_DIRECTORY>(RtlImageDirectoryEntryToData(lpBaseOfImage, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &sizeOfExpDir));/*PIMAGE_DATA_DIRECTORY lpExportDirEntry = &lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];assert(lpExportDirEntry->Size != 0 && "no export table found!");auto lpExportDir = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(lpNtHeader->OptionalHeader.ImageBase + lpExportDirEntry->VirtualAddress);*/DWORD dwVirtualAddress = NULL;auto AddressOfNames = reinterpret_cast<PDWORD>(lpNtHeader->OptionalHeader.ImageBase + lpExportDir->AddressOfNames);auto AddressOfFunctions = reinterpret_cast<PDWORD>(lpNtHeader->OptionalHeader.ImageBase + lpExportDir->AddressOfFunctions);auto AddressOfNameOrdinals = reinterpret_cast<PUSHORT>(lpNtHeader->OptionalHeader.ImageBase + lpExportDir->AddressOfNameOrdinals);if (reinterpret_cast<DWORD>(lpTargetFuncName) & 0xFFFF0000) {long high = lpExportDir->NumberOfNames - 1;long low = 0;while (low <= high){auto mid = (high + low) >> 1;auto name = reinterpret_cast<PCHAR>(lpNtHeader->OptionalHeader.ImageBase) + AddressOfNames[mid];auto Idx = 0;while (name[Idx] && name[Idx] == lpTargetFuncName[Idx]) {++Idx;}auto ret = name[Idx] - lpTargetFuncName[Idx];if (ret == 0) {dwVirtualAddress = AddressOfFunctions[AddressOfNameOrdinals[mid]];break;} else if (ret > 0) {high = mid - 1;} else {low = mid + 1;} //if}} else {dwVirtualAddress = AddressOfFunctions[reinterpret_cast<DWORD>(lpTargetFuncName) & 0x0FFFF];} //ifif (!dwVirtualAddress) {return NULL;} //ifDWORD VRk = 0xffffffffUL;auto lpSection = IMAGE_FIRST_SECTION(lpNtHeader);for (register int i = 0; i < lpNtHeader->FileHeader.NumberOfSections; ++i, ++lpSection) {if (dwVirtualAddress > lpSection->VirtualAddress && dwVirtualAddress < (lpSection->VirtualAddress + lpSection->Misc.VirtualSize)){VRk = lpSection->VirtualAddress - lpSection->PointerToRawData;break;} //if} //forreturn VRk != 0xffffffffUL ? (dwVirtualAddress - VRk) : NULL; }




總結

以上是生活随笔為你收集整理的快速恢复Safengine Protector的Shadow DLL的全部內容,希望文章能夠幫你解決所遇到的問題。

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