Skip to content

Commit

Permalink
upd: modify the section page protect attributes at last
Browse files Browse the repository at this point in the history
  • Loading branch information
tians committed Oct 5, 2015
1 parent 50a93ba commit a170b68
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 37 deletions.
1 change: 1 addition & 0 deletions LoaderDemoExe/LoaderDemoExe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
109 changes: 73 additions & 36 deletions mmLoader/mmLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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视为失败,清理所有资源
Expand Down Expand Up @@ -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(
Expand All @@ -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,
Expand All @@ -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(
Expand All @@ -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;
}

/*
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion mmLoader/mmLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ 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
LPVOID pfnLoadLibraryA; //LoadLibraryA
LPVOID pfnGetProcAddress; //GetProcAddress
LPVOID pfnVirtualAlloc; //VirtualAlloc
LPVOID pfnVirtualFree; //VirtualFree
LPVOID pfnVirtualProtect; //VirtualProtect
LPVOID pfnReversed_0;
LPVOID pfnReversed_1;
LPVOID pfnReversed_2;
Expand Down

0 comments on commit a170b68

Please sign in to comment.