首页
社区
课程
招聘
[原创]一点小技巧:利用Hook实现内存Dll(Dll数据重定向)
发表于: 2022-9-7 11:56 13073

[原创]一点小技巧:利用Hook实现内存Dll(Dll数据重定向)

2022-9-7 11:56
13073

MyHook.cpp里面仅仅是一个简单的APIHOOK,

Main.cpp:

#if _WIN64
NTSTATUS MyNtOpenFile(PHANDLE FileHandle,
    ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    PIO_STATUS_BLOCK IoStatusBlock,
    ULONG ShareAccess,
    ULONG OpenOptions)
\#elif _WIN32
NTSTATUS __stdcall MyNtOpenFile(PHANDLE FileHandle,
    ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    PIO_STATUS_BLOCK IoStatusBlock,
    ULONG ShareAccess,
    ULONG OpenOptions)
#endif
{
 
    g_MyNtOpenFileHook.Suspended();
    //先暂停Hook
    NTSTATUS result;
    result = ((MyNtOpenFileCall)g_MyNtOpenFileHook.GetOldFunction())(FileHandle,
        DesiredAccess,
        ObjectAttributes,
        IoStatusBlock,
        ShareAccess,
        OpenOptions);
    //调用原函数
    if (wcsstr(ObjectAttributes->ObjectName->Buffer, L"advapi32res.dll")) {
        //如果是加载的advapi32res.dll
        g_MyNtOpenFileHook.Stop();
        //取消Hook
        g_MyNtMapViewOfSectionHook.Start("ntdll.dll", "NtMapViewOfSection", (FARPROC)MyNtMapViewOfSection);
        return result;
    }
    g_MyNtOpenFileHook.Restore();
    //恢复Hook
    return result;
}
#if _WIN64
NTSTATUS MyNtOpenFile(PHANDLE FileHandle,
    ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    PIO_STATUS_BLOCK IoStatusBlock,
    ULONG ShareAccess,
    ULONG OpenOptions)
\#elif _WIN32
NTSTATUS __stdcall MyNtOpenFile(PHANDLE FileHandle,
    ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    PIO_STATUS_BLOCK IoStatusBlock,
    ULONG ShareAccess,
    ULONG OpenOptions)
#endif
{
 
    g_MyNtOpenFileHook.Suspended();
    //先暂停Hook
    NTSTATUS result;
    result = ((MyNtOpenFileCall)g_MyNtOpenFileHook.GetOldFunction())(FileHandle,
        DesiredAccess,
        ObjectAttributes,
        IoStatusBlock,
        ShareAccess,
        OpenOptions);
    //调用原函数
    if (wcsstr(ObjectAttributes->ObjectName->Buffer, L"advapi32res.dll")) {
        //如果是加载的advapi32res.dll
        g_MyNtOpenFileHook.Stop();
        //取消Hook
        g_MyNtMapViewOfSectionHook.Start("ntdll.dll", "NtMapViewOfSection", (FARPROC)MyNtMapViewOfSection);
        return result;
    }
    g_MyNtOpenFileHook.Restore();
    //恢复Hook
    return result;
}
void MyMapDll(byte* DllData,
PVOID* BaseAddress,
PSIZE_T ViewSize
) {
//获取基地址
__int64 DllMemoryBase = (__int64)&DllData[0];
PIMAGE_DOS_HEADER DOSHeader = (PIMAGE_DOS_HEADER)DllMemoryBase;
//读出文件DOS头
if (DOSHeader->e_magic == IMAGE_DOS_SIGNATURE) {
   //检测MZ头
   PIMAGE_NT_HEADERS NTHeader = (PIMAGE_NT_HEADERS)(DllMemoryBase + DOSHeader->e_lfanew);
   if (NTHeader->Signature == IMAGE_NT_SIGNATURE) {
       //检测PE头
       PVOID l_location, l_lpBaseAddress;
       PIMAGE_SECTION_HEADER Sectionheaders;
       __int64 SectionOffset;
       SectionOffset = DOSHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS);//IMAGE_SECTION_HEADER在内存中的偏移
       *BaseAddress = VirtualAlloc(NULL,
           NTHeader->OptionalHeader.SizeOfImage,
           MEM_COMMIT,
           PAGE_EXECUTE_READWRITE);
       //分配一块内存供给Dll使用
       *ViewSize = NTHeader->OptionalHeader.SizeOfImage;
       //下面开始根据SECTION信息将Dll数据逐步映射到内存
       int l_count = NTHeader->FileHeader.NumberOfSections;
       //拷贝DOS头
       RtlMoveMemory(*BaseAddress, &DllData[0], SectionOffset + sizeof(IMAGE_SECTION_HEADER) * l_count);
       //设置头部的保护
       VirtualProtect(&DllData[0], 0x1000, PAGE_READONLY, 0);
       for (int i = 0; i < l_count; i++) {
           Sectionheaders = (PIMAGE_SECTION_HEADER)(DllMemoryBase + SectionOffset);
           if (Sectionheaders->PointerToRawData != 0) {
               //如果Sectionheaders->PointerToRawData不为0,表示该段是有数据的,需要拷贝。
               l_location = (PVOID)(DllMemoryBase + Sectionheaders->PointerToRawData);
               l_lpBaseAddress = (PVOID)((__int64)*BaseAddress + Sectionheaders->VirtualAddress);
               //将段数据拷贝到分配的内存中
               RtlMoveMemory(l_lpBaseAddress, l_location, Sectionheaders->SizeOfRawData);
               //设置保护
               VirtualProtect(l_lpBaseAddress,
                   Sectionheaders->Misc.VirtualSize,
                   GetProtect(Sectionheaders->Characteristics),
                   0);
           }
           SectionOffset += sizeof(IMAGE_SECTION_HEADER);
           //读取下一个SECTION
       }
   }
}
}
void MyMapDll(byte* DllData,
PVOID* BaseAddress,
PSIZE_T ViewSize
) {
//获取基地址
__int64 DllMemoryBase = (__int64)&DllData[0];
PIMAGE_DOS_HEADER DOSHeader = (PIMAGE_DOS_HEADER)DllMemoryBase;
//读出文件DOS头
if (DOSHeader->e_magic == IMAGE_DOS_SIGNATURE) {
   //检测MZ头
   PIMAGE_NT_HEADERS NTHeader = (PIMAGE_NT_HEADERS)(DllMemoryBase + DOSHeader->e_lfanew);
   if (NTHeader->Signature == IMAGE_NT_SIGNATURE) {
       //检测PE头
       PVOID l_location, l_lpBaseAddress;
       PIMAGE_SECTION_HEADER Sectionheaders;
       __int64 SectionOffset;
       SectionOffset = DOSHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS);//IMAGE_SECTION_HEADER在内存中的偏移
       *BaseAddress = VirtualAlloc(NULL,
           NTHeader->OptionalHeader.SizeOfImage,
           MEM_COMMIT,
           PAGE_EXECUTE_READWRITE);
       //分配一块内存供给Dll使用
       *ViewSize = NTHeader->OptionalHeader.SizeOfImage;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (4)
雪    币: 3677
活跃值: (3268)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
牛啊牛啊 还以为只有易语言版 
2022-9-7 14:53
0
雪    币: 3892
活跃值: (3142)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
wonghouleong 牛啊牛啊 还以为只有易语言版 [em_13]
易语言版那个是我最早解析原理时写的一个例子。
后来用C++写才发现C++其实没必要用这么麻烦的方法,C++调用内存Dll可方便多了
2022-9-7 15:16
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2022-9-30 08:51
0
雪    币: 185
活跃值: (2397)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
是 win11 么? 这个圆角信息框好看多了
2022-9-30 09:02
0
游客
登录 | 注册 方可回帖
返回
//