专栏首页逆向技术x64下Hash获取Kernel32基地址

x64下Hash获取Kernel32基地址

x64下Hash获取Kernel32基地址

一丶 工程代码

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

1.主要代码

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 !='\0')
    {
        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('\0'))
    {
        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 != "\0")
        {
            //为其算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 \r\n", pBaseName->Buffer, (void*)ImageBase);
            InitFunctionHash(ImageBase);
        }

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

    } while (pCur);
}

2.ASM

x64Asm 如何编译64asm 参考之前博客 https://www.cnblogs.com/iBinary/p/10959448.html

.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 条评论
登录 后参与评论

相关文章

  • shellcode 开发

    r12 存储 kernel32 基址,通过 GetProcessAddress 将 LoadLibraryA 函数地址存储在 rax:

    CN_Simo
  • windows下获取dns地址

    Qt君
  • x64 gs寄存器的一点资料

    gs:[0x20] prcb gs:[0x30] TEB gs:[0x40] ...

    战神伽罗
  • 分析重装系统也无法清除的鬼影病毒

    声明:本文由【MS509 Team】成员expsky原创,仅用于技术交流分享,禁止将相关技术应用到不当途径。 整理电脑的时候找到自已以前分析的一个鬼影病毒的资料...

    FB客服
  • VanillaRat功能代码分析

    VanillaRat是一款由C#编写的remote administration tool,其github地址如下:https://github.com/...

    鸿鹄实验室
  • CS-Shellcode分析系列 第一课

    本文是CS的shellcode分析的第一篇文章,该系列文章旨在帮助具有一定二进制基础的朋友看懂cs的shellcode的生成方式,进而可以达到对shellcod...

    WgpSec
  • 汇编中FS寄存器的说明和使用

    用户2135432
  • iOS | 获取 App Store 中 App 下载地址

    感谢掘金各位大佬指点我这个小 Android,特意上来整理下,方便有需要的小伙伴。

    HLQ_Struggle
  • 内网渗透 | 横向移动中MSTSC的密码获取

    ④:For Every: cmd开3389 win08 win03 win7 win2012 winxp win08,三条命令即可:

    HACK学习
  • APT团伙(APT-C-01)新利用漏洞样本分析及关联挖掘

    APT-C-01组织是一个长期针对国内国防、政府、科技和教育领域的重要机构实施网络间谍攻击活动的APT团伙,其最早的攻击活动可以追溯到2007年,360威胁情报...

    FB客服
  • 跟Google学写代码--Chromium/base--windows_version源码学习及应用

    Chromium是一个伟大的、庞大的开源工程,很多值得我们学习的地方。 前面写道: 《跟Google学写代码–Chromium/base–stl_util源...

    程序员的酒和故事
  • java:多网卡环境下获取MAC地址

    JDK6以后 java.net.NetworkInterface提供了完整的方法用于获取网络设备信息。 调用 NetworkInterface.getNet...

    用户1148648
  • Windows下的代码注入

    木马和病毒的好坏很大程度上取决于它的隐蔽性,木马和病毒本质上也是在执行程序代码,如果采用独立进程的方式需要考虑隐藏进程否则很容易被发现,在编写这类程序的时候可以...

    Masimaro
  • C# 极限压缩 dotnet core 控制台发布文件

    每次发布 dotnet core 应用都会觉得发布文件太大,而如果使用极限压缩,用 CoreRT 能让发布的控制台文件到 5KB 左右,不需要带框架就能在其他设...

    林德熙
  • Windows 密码抓取方式总结

    渗透测试过程中我们经常需要获取管理员的账号密码,以便进行更进一步的操作,下面我将给大家总结几种 steal account 的手法!其中可能也会涉及到 apt ...

    信安之路
  • CoreHook:基于.NET Core运行时实现的Windows HOOK库

    今天为大家介绍一款基于.NET Core运行时实现的Windows HOOK库,CoreHook。

    FB客服
  • CVE-2015-1641 Word 利用样本分析

    00 引 子 本文我们将通过一个恶意文档的分析来理解漏洞 CVE-2015-1641(MS15-033)的具体利用过程,以此还原它在现实攻击中的应用。就目前来...

    Seebug漏洞平台
  • C++写壳之高级篇

    之前在写了写壳基础篇,现在就来完成写壳高级篇。没有基础篇的知识,那理解高级篇就比较困难。有了写壳基础后,才能在其基础上逐步实现高级功能,加壳的目的主要是防止别人...

    战神伽罗
  • 无文件执行:一切皆是shellcode (中)

    在上一篇文章中,介绍了PE_to_shellcode这个项目,并简单提了一句原理,本节就详细讲解一下PE是如何转化为shellcode的。

    七夜安全博客

扫码关注云+社区

领取腾讯云代金券