x64下Hash获取Kernel32基地址

2021-02-05 14:54:59 浏览数 (1)

x64下Hash获取Kernel32基地址

一丶 工程代码

代码中包含x64Asm 其中函数也是可以算hash的.自己写asm遍历导出表即可.

1.主要代码

代码语言:javascript复制
extern "C" long long  _readgsqword(long long ReadValue);
extern "C" void * _GetLdrDataTableEntry();
map<DWORD, char*> m_HashProcMap;  //记录导出表名字以及Hash值
vector<DWORD> m_ProcHash;         //记录函数的Hash值

typedef struct _UNICODE_STRING {
    unsigned short length;
    unsigned short Maximumlength;
    wchar_t* Buffer;
}UNICODE_STRING,*PUNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    WORD LoadCount;
    WORD TlsIndex;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

DWORD _ROR32(unsigned int Value, unsigned int shift)
{
    //0X12345678  << 24  LOW >> 24 = HIGHT
    shift &= 31;
    unsigned int LowByte = (Value << 24) & 0xFF000000;
    unsigned int HighByte = (Value >> (shift));
    unsigned int Result = LowByte | HighByte;
    return Result;
}

long long GetProcHashValue(char* Names)
{
    if (Names == nullptr)
        return 0;
    auto HashValue = 0u;

    while (*Names !='')
    {
        HashValue = ((*Names)   _ROR32(HashValue, 8)) ^ 0x7c35d9a3;
        Names  ;
    }
    return HashValue;
}
//通过DLL名字生成Hash值
long long GetHashValue(TCHAR *DllName)
{
    //DLLName转为小写计算
    if (DllName == nullptr)
        return 0;
    auto NameSize = wcslen(DllName);
    wstring wstr = DllName;
    transform(wstr.begin(), wstr.end(), wstr.begin(), ::tolower);
   
    auto  len = wstr.length();
    auto* Names = new TCHAR[len*2]();
    shared_ptr<TCHAR> p1(Names);
    wcscpy_s(Names,len * 2, wstr.c_str());
    auto HashValue = 0u;
    while (*Names != TEXT(''))
    {
        HashValue = ((*Names | 0x20)   _ROR32(HashValue, 8)) ^ 0x7c35d9a3;
        Names  ;
    }
    return HashValue;
}

void FindProcNameFromHash(DWORD HashValue)
{
    
    m_ProcHash.push_back(0xBDA26FE6);
    m_ProcHash.push_back(0xA16DC157);
    m_ProcHash.push_back(0xF339F5E3);
    m_ProcHash.push_back(0x95D9FE52);
    m_ProcHash.push_back(0xB8D629F8);
    m_ProcHash.push_back(0x991AB7EE);
   
    for (auto i = 0l; i < m_ProcHash.size(); i  )
    {
        auto it = m_HashProcMap.find(m_ProcHash[i]);
        if (it != m_HashProcMap.end())
        {
            cout << std::setiosflags(ios::uppercase) 
                << "Hash t" << hex <<"0x" <<it->first 
                << "tProcName t" << it->second << endl;
        }
    }

   
}
void InitFunctionHash(PVOID KernelBase)
{
    /*
    1.遍历Kernel32.dll的导出表
    2.获取其函数名称表
    3.将其函数名称表中的所有函数做一次Hash计算
    4.对比Hash值 如果相等 就得出是那个函数
    */
   
    PIMAGE_DOS_HEADER pDos = reinterpret_cast<PIMAGE_DOS_HEADER>(KernelBase);
    PIMAGE_NT_HEADERS pNtHead = reinterpret_cast<PIMAGE_NT_HEADERS>((char *)pDos   pDos->e_lfanew);
    PIMAGE_OPTIONAL_HEADER pOptHead = &pNtHead->OptionalHeader;
  
 
    PIMAGE_EXPORT_DIRECTORY pExport = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>((char*)KernelBase   pOptHead->DataDirectory[0].VirtualAddress );
    auto ExportFunctionNameCount = pExport->NumberOfNames;
    PVOID ProcName = (char*)(KernelBase) pExport->Name;

    for (auto i = 0; i < ExportFunctionNameCount;i  )
    {
        if (ProcName != "")
        {
            //为其算Hash
            DWORD ProcHashValue = GetProcHashValue((char *)ProcName);
            m_HashProcMap.insert(std::pair<DWORD, char*>(ProcHashValue,(char *)ProcName));
            ProcName = (char*)ProcName   strlen((char*)ProcName)   1;
        }
    }
    FindProcNameFromHash(0);
    //auto HashValue = GetProcHashValue((char*)"LocalAlloc");
    //cout << hex << HashValue << endl;
}
void Hash()
{
    PUNICODE_STRING pBaseName = NULL;
    PLIST_ENTRY pStartList = nullptr;
    PLIST_ENTRY pCur = nullptr;
    PLDR_DATA_TABLE_ENTRY Teb = (PLDR_DATA_TABLE_ENTRY)_GetLdrDataTableEntry();
    pStartList = (PLIST_ENTRY)(Teb->InMemoryOrderLinks.Flink);
    pCur = pStartList;
    auto Value = GetHashValue((wchar_t*)L"KERNEL32.dll");
    PVOID ImageBase = 0;
    do
    {
        PLDR_DATA_TABLE_ENTRY pTempLdr = (PLDR_DATA_TABLE_ENTRY)pCur;
        pBaseName = (PUNICODE_STRING)(&((pTempLdr)->BaseDllName));

        //对名字做Hash计算得出Hash
        auto HashValue = GetHashValue(pBaseName->Buffer);
        HashValue = HashValue ^ 0x12345678;
        if (HashValue == 0xEF6F4419)
        {
            ImageBase = pTempLdr->DllBase;
            printf("%ls  0X%p rn", pBaseName->Buffer, (void*)ImageBase);
            InitFunctionHash(ImageBase);
        }

        pCur = pCur->Flink;
        if (pCur == pStartList)
            break;

    } while (pCur);
}

2.ASM

x64Asm 如何编译64asm 参考之前博客 https://cloud.tencent.com/developer/article/1444068

代码语言:javascript复制
.DATA

.CODE

_readgsqword PROC
   mov rax,rcx
   mov rax,gs:[rax]
   ret 
_readgsqword endp

_GetLdrDataTableEntry PROC
   mov rax,gs:[60h]
   mov rax,[rax   18h]
   ret
_GetLdrDataTableEntry endp

_ROR4 PROC
	
_ROR4 ENDP

end

3.输出结果

0 人点赞