自用 x86 GetProcAddress + GetModuleHandle
寫專案時自己實現了這兩個函式,記錄下來以後方便複習。
// 從PEB的_PEB_LDR_DATA裡獲取已載入模組的控制程式碼
HMODULE GetLoadedModuleW(LPCWSTR lpModuleName)
{
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA
{
DWORD Length;
bool Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
UINT32 SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
UINT32 Flags;
USHORT LoadCount;
USHORT TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
UINT32 CheckSum;
UINT32 TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
PPEB_LDR_DATA pLDR = NULL;
PLDR_DATA_TABLE_ENTRY pLdteHead;
PLDR_DATA_TABLE_ENTRY pLdteCur;
BOOL bEqual = FALSE;
DWORD StringMinLen = 0;
HMODULE hModule = NULL;
//pLDR = (PPEB_LDR_DATA)(__readfsdword(0x30) + 0x0C);
__asm
{
mov eax, fs: [0x30] ; // PEB
mov eax, [eax + 0x0C]; // PEB->LDR
mov pLDR, eax;
}
// 如果是NULL,直接返回主模組控制程式碼(第一個模組)
if (lpModuleName == NULL)
{
__asm
{
mov eax, fs: [0x30] ;
mov eax, [eax + 0x08];
mov hModule, eax;
}
return hModule;
}
pLdteHead = (PLDR_DATA_TABLE_ENTRY)(&pLDR->InLoadOrderModuleList);
pLdteCur = (PLDR_DATA_TABLE_ENTRY)(pLdteHead->InLoadOrderLinks.Flink);
// 遍歷模組
do
{
PLDR_DATA_TABLE_ENTRY pLdte = CONTAINING_RECORD(pLdteCur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
// 字串對比
bEqual = TRUE;
StringMinLen = min(wcslen(lpModuleName), pLdteCur->BaseDllName.Length);
for (size_t i = 0; i < StringMinLen; i++)
{
if (towupper(lpModuleName[i]) != towupper(pLdteCur->BaseDllName.Buffer[i]))
{
bEqual = FALSE;
break;
}
}
if (bEqual)
{
hModule = (HMODULE)pLdteCur->DllBase;
break;
}
pLdteCur = (PLDR_DATA_TABLE_ENTRY)pLdteCur->InLoadOrderLinks.Flink;
} while (pLdteHead != pLdteCur);
return hModule;
}
// 重寫的 GetProcAddress
LPVOID GetFunctionByName(LPVOID pDllImageBuffer, LPCSTR lpszFunc)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pDllImageBuffer;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)pDllImageBuffer +
pNtHeader->OptionalHeader.DataDirectory[0].VirtualAddress);
PDWORD AddressOfFunctions = (PDWORD)((PBYTE)pDllImageBuffer + pExport->AddressOfFunctions);
PDWORD AddressOfNames = (PDWORD)((PBYTE)pDllImageBuffer + pExport->AddressOfNames);
PUSHORT AddressOfNameOrdinals = (PUSHORT)((PBYTE)pDllImageBuffer + pExport->AddressOfNameOrdinals);
for (size_t i = 0; i < pExport->NumberOfNames; i++)
{
if (0 == strcmp(lpszFunc, (char *)pDllImageBuffer + AddressOfNames[i]))
{
return AddressOfFunctions[AddressOfNameOrdinals[i]] + (PBYTE)pDllImageBuffer;
}
}
return NULL;
}
相關文章
- GetProcAddress
- 自用,httpsHTTP
- 自用筆記筆記
- 預設源(自用)
- 自用 docker-composeDocker
- MongoDB命令--自用記錄MongoDB
- Js方法整理自用(未完)JS
- 常用命令(自用)
- 自用ssh命令總結
- Kafka 叢集搭建 (自用)Kafka
- Linux: 命令速查(自用)Linux
- idea 自用外掛Idea
- MongoDB和pymongo自用手冊MongoDB
- TensorFlow 入門 上(自用)
- TensorFlow 入門 下(自用)
- 自用驗證類封裝封裝
- java web學習 日常自用JavaWeb
- C# NLog 自用配置C#
- MongoDB分片叢集新增分片(自用)MongoDB
- [轉]根據PE檔案格式獲取LoadLibraryA()/GetProcAddress()地址
- Tensorflow 深度學習簡介(自用)深度學習
- 【自用】彙編初學筆記 #1筆記
- 【自用】有上下界的網路流
- CSRF&SSRF練習(自用筆記)筆記
- Where the top of the stack is on x86
- virtualization tech of x86 platformPlatform
- 部落格園自用主題美化 - Light
- 自用的一個API快速構建元件API元件
- 一道小程式設計題(自用)程式設計
- 分享一個自用的 go-toolkit 包Go
- js基礎函式(下)(小白自用5)JS函式
- Python 自用程式碼(調整日期格式)Python
- Python 自用程式碼(拆分txt檔案)Python
- MTNET 自用ios網路庫開源iOS
- Linux常用命令(自用記錄)Linux
- 線段樹模板重製(自寫自用)
- 高速介面自用筆記:GT基礎(二)筆記
- Build gdbserver for x86 AndroidUIServerAndroid