diff --git a/LoaderDemoExe/LoaderDemoExe.cpp b/LoaderDemoExe/LoaderDemoExe.cpp index 8f57712..61e36d2 100644 --- a/LoaderDemoExe/LoaderDemoExe.cpp +++ b/LoaderDemoExe/LoaderDemoExe.cpp @@ -30,6 +30,7 @@ int _tmain(int argc, _TCHAR* argv[]) sNtFuncPtrsTable.pfnGetProcAddress = GetProcAddress; sNtFuncPtrsTable.pfnVirtualAlloc = VirtualAlloc; sNtFuncPtrsTable.pfnVirtualFree = VirtualFree; + sNtFuncPtrsTable.pfnVirtualProtect = VirtualProtect; sMemModule.pNtFuncptrsTable = &sNtFuncPtrsTable; diff --git a/mmLoader/mmLoader.cpp b/mmLoader/mmLoader.cpp index 3c3372c..9bc3f79 100644 --- a/mmLoader/mmLoader.cpp +++ b/mmLoader/mmLoader.cpp @@ -20,6 +20,7 @@ EXTERN_C BOOL ReleaseRawFileResource(PMEM_MODULE pMemModule); BOOL RelocateMemModule(PMEM_MODULE pMemModule); BOOL ResolveImports(PMEM_MODULE pMemModule); + BOOL SetMemProtectStatus(PMEM_MODULE pMemModule); BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason); FARPROC GetExportedProcAddress(PMEM_MODULE pMemModule, LPCSTR lpName); VOID UnmapMemModule(PMEM_MODULE pMemModule); @@ -126,6 +127,12 @@ BOOL __stdcall LoadMemModule(PMEM_MODULE pMemModule, LPCTSTR lpName, BOOL bCallE return FALSE; } + if (FALSE == SetMemProtectStatus(pMemModule)) + { + UnmapMemModule(pMemModule); + return FALSE; + } + if (bCallEntry) { // 调用失败,这次Load视为失败,清理所有资源 @@ -360,8 +367,6 @@ BOOL MapMemModuleSections(PMEM_MODULE pMemModule) Type_VirtualAlloc pfnVirtualAlloc = (Type_VirtualAlloc)(pMemModule->pNtFuncptrsTable->pfnVirtualAlloc); Type_VirtualFree pfnVirtualFree = (Type_VirtualFree)(pMemModule->pNtFuncptrsTable->pfnVirtualFree); - BOOL br = FALSE; - PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(pMemModule->RawFile.pBuffer); PIMAGE_NT_HEADERS pImageNtHeader = MakePointer( @@ -382,19 +387,14 @@ BOOL MapMemModuleSections(PMEM_MODULE pMemModule) pImageNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - } - - // 仍然失败,说明内存无法满足要求 - IfFalseGoExit(NULL != lpBase); - LPVOID lpNtHeaderBase = pfnVirtualAlloc( - lpBase, - pImageNtHeader->OptionalHeader.SizeOfHeaders, - MEM_COMMIT, - PAGE_READWRITE); - IfFalseGoExit(NULL != lpNtHeaderBase); + if (NULL == lpBase) + { + return FALSE; + } + } - // 把PE头部拷贝到目标位置 + // 把PE头部拷贝到目标位置 Dw_memmove( lpBase, pMemModule->RawFile.pBuffer, @@ -410,24 +410,7 @@ BOOL MapMemModuleSections(PMEM_MODULE pMemModule) { if (0 != pImageSectionHeader[i].VirtualAddress && 0 != pImageSectionHeader[i].SizeOfRawData) { - DWORD dwSectionMemProtect = PAGE_READWRITE; - // 计算该Section的内存保护属性 - DWORD dwSectionCharacteristics = pImageSectionHeader[i].Characteristics; - if (dwSectionCharacteristics & IMAGE_SCN_MEM_EXECUTE) - { - dwSectionMemProtect = PAGE_EXECUTE_READWRITE; - } - dwSectionBase = pImageSectionHeader[i].VirtualAddress + (DWORD)lpBase; - - // 提交内存 - LPVOID lpSectionBase = NULL; - lpSectionBase = pfnVirtualAlloc( - (LPVOID)dwSectionBase, - pImageSectionHeader[i].SizeOfRawData, - MEM_COMMIT, - dwSectionMemProtect); - IfFalseGoExit(dwSectionBase == (DWORD)lpSectionBase); // 拷贝一个Section到指定位置 Dw_memmove( @@ -442,12 +425,7 @@ BOOL MapMemModuleSections(PMEM_MODULE pMemModule) pMemModule->dwSizeOfImage = pImageNtHeader->OptionalHeader.SizeOfImage; pMemModule->bLoadOk = TRUE; -_Exit: - if (FALSE == br && NULL != lpBase) - { - pfnVirtualFree(lpBase, 0, MEM_RELEASE); - } - return br; + return TRUE; } /* @@ -606,6 +584,65 @@ BOOL ResolveImports(PMEM_MODULE pMemModule) } +BOOL SetMemProtectStatus(PMEM_MODULE pMemModule) +{ + if (NULL == pMemModule + || NULL == pMemModule->pNtFuncptrsTable) + { + return FALSE; + } + + typedef BOOL (WINAPI * Type_VirtualProtect)(LPVOID, SIZE_T, DWORD, PDWORD); + + Type_VirtualProtect pfnVirtualProtect = (Type_VirtualProtect)(pMemModule->pNtFuncptrsTable->pfnVirtualProtect); + + BOOL br = FALSE; + + PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(pMemModule->lpBase); + + PIMAGE_NT_HEADERS pImageNtHeader = MakePointer( + PIMAGE_NT_HEADERS32, pImageDosHeader, pImageDosHeader->e_lfanew); + + int nNumberOfSections = pImageNtHeader->FileHeader.NumberOfSections; + PIMAGE_SECTION_HEADER pImageSectionHeader = MakePointer( + PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS32)); + + DWORD dwSectionBase = NULL; + + for (int i = 0; i < nNumberOfSections; ++i) + { + if (0 != pImageSectionHeader[i].VirtualAddress && 0 != pImageSectionHeader[i].SizeOfRawData) + { + DWORD dwOldMemProtect = 0; + DWORD dwSectionMemProtect = 0; + //// 计算该Section的内存保护属性 + // not all conditions are considerd + DWORD dwSectionCharacteristics = pImageSectionHeader[i].Characteristics; + if (dwSectionCharacteristics & IMAGE_SCN_MEM_EXECUTE) + { + dwSectionMemProtect = PAGE_EXECUTE_READWRITE; + } + + dwSectionBase = pImageSectionHeader[i].VirtualAddress + (DWORD)pMemModule->lpBase; + + //// 提交内存 + LPVOID lpSectionBase = NULL; + br = pfnVirtualProtect( + (LPVOID)dwSectionBase, + pImageSectionHeader[i].SizeOfRawData, + dwSectionMemProtect, + &dwOldMemProtect); + + if (!br) + { + return FALSE; + } + } + } + + return TRUE; +} + BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason) { if (NULL == pMemModule diff --git a/mmLoader/mmLoader.h b/mmLoader/mmLoader.h index db9bd1c..a97eb3c 100644 --- a/mmLoader/mmLoader.h +++ b/mmLoader/mmLoader.h @@ -17,7 +17,7 @@ typedef struct __NTFUNCPTRS LPVOID pfnCreateFileW; //CreateFileW LPVOID pfnGetFileSize; //GetFileSize LPVOID pfnCreateFileMappingW; //CreateFileMappingW - LPVOID pfnMapViewOfFile; //MapViewOfFile + LPVOID pfnMapViewOfFile; //MapViewOfFile LPVOID pfnUnmapViewOfFile; //UnmapViewOfFile LPVOID pfnCloseHandle; //CloseHandle LPVOID pfnGetModuleHandleA; //GetModuleHandleA @@ -25,6 +25,7 @@ typedef struct __NTFUNCPTRS LPVOID pfnGetProcAddress; //GetProcAddress LPVOID pfnVirtualAlloc; //VirtualAlloc LPVOID pfnVirtualFree; //VirtualFree + LPVOID pfnVirtualProtect; //VirtualProtect LPVOID pfnReversed_0; LPVOID pfnReversed_1; LPVOID pfnReversed_2;