x64下Hash获取Kernel32基地址
地址 获取 HASH X64
2023-09-27 14:21:04 时间
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.输出结果
相关文章
- 【视频开发】ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)
- 【VS开发】【DSP开发】地址对齐
- java根据本地Ip获取mac地址
- ShellCode之寻找Debug下真实函数地址
- nslookup获取域名对应的的ip地址
- 微信小程序 wx.chooseLocation定位获取地址,并解析省市区
- 25.Django大型电商项目之地址管理——如何使用三级联动菜单数据加载地址、保存数据、动态获取数据、设置默认值
- jeecms v9修改后台访问地址
- 打开google 新地址
- mybatis大于号,小于号,去地址符,单引号,双引号转义说明
- js获取input file路径改变图像地址
- Ubuntu18.04修改主机名和网卡地址
- delphi 获取本机IP地址和MAC地址
- csdn获取自己所有博客的地址,包含分页
- [download]-软件下载地址-百度网盘
- java对象的内存布局(二):利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值
- C++ 获取计算机系统的mac地址
- C++基础入门:利用C++轻松获取ip定位地址!
- python3 根据注册表获取百度云软件的安装地址
- 用函数SendARP()获取局域网计算机的MAC地址
- [LeetCode] 929. Unique Email Addresses 唯一的电邮地址
- asp dotnet core 从 Frp 获取用户真实 IP 地址
- asp dotnet core 从 Frp 获取用户真实 IP 地址