为什么一个句柄加上(BYTE*)后就可以变成指针了.解决思路

为什么一个句柄加上(BYTE*)后就可以变成指针了....
句柄跟指针怎么能因为一个(BYTE*)就转换了呢...
比如:
C/C++ code

#include <stdio.h>
#include <windows.h>

void main()    
{
    HMODULE hMod = ::GetModuleHandle(NULL);//这个是取得模块的句柄.............

    IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod;//突然间 这么轻易就被转换成其他结构的地址了...
    IMAGE_OPTIONAL_HEADER * pOptHeader =
        (IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24);//这个也是  直接用BYTE*就取得这个模块内存地址的首地址  这么简单??为什么能这样呢!!

    IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)
        ((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

    while(pImportDesc->FirstThunk)
    {
        char* pszDllName = (char*)((BYTE*)hMod +pImportDesc->Name);
        printf("\n模块名称:%s \n", pszDllName);
    
        
        
        IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)
            ((BYTE*)hMod + pImportDesc->OriginalFirstThunk);
        int n = 0;
        while(pThunk->u1.Function)
        {
            
            char* pszFunName = (char*)
                ((BYTE*)hMod + (DWORD)pThunk->u1.AddressOfData + 2);
            
            PDWORD lpAddr = (DWORD*)((BYTE*)hMod + pImportDesc->FirstThunk) + n;

            
            printf("  从此模块导入的函数:%-25s,", pszFunName);
            printf("函数地址:%X \n", lpAddr);
            n++; pThunk++;
        }
        
        pImportDesc++;
    }
}



------解决方案--------------------
LoadLibraryEx得到的句柄是基地址加上一些标志位