自用 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;
}
相關文章
- 自用筆記筆記
- 自用 docker-composeDocker
- 預設源(自用)
- Linux: 命令速查(自用)Linux
- idea 自用外掛Idea
- 自用ssh命令總結
- TensorFlow 入門 上(自用)
- TensorFlow 入門 下(自用)
- Js方法整理自用(未完)JS
- C# NLog 自用配置C#
- 常用命令(自用)
- MongoDB命令--自用記錄MongoDB
- MongoDB和pymongo自用手冊MongoDB
- java web學習 日常自用JavaWeb
- 自用驗證類封裝封裝
- Tensorflow 深度學習簡介(自用)深度學習
- Where the top of the stack is on x86
- CSRF&SSRF練習(自用筆記)筆記
- 【自用】彙編初學筆記 #1筆記
- 部落格園自用主題美化 - Light
- Linux常用命令(自用記錄)Linux
- ARM和X86架構架構
- Linux之x86架構Linux架構
- 分享一個自用的 go-toolkit 包Go
- 一道小程式設計題(自用)程式設計
- 自用的一個API快速構建元件API元件
- 線段樹模板重製(自寫自用)
- 高速介面自用筆記:GT基礎(二)筆記
- 最短路模板(堆最佳化Dijkstra)(自用
- js基礎函式(下)(小白自用5)JS函式
- Centos 7 x86 安裝JDKCentOSJDK
- 常用的x86彙編指令
- 解析x86指令格式
- MongoDB 資料遷移 備份 匯入(自用)MongoDB
- 資料庫日常遇到的需求筆記(自用)資料庫筆記
- Conda常用命令記錄(自用記錄)
- Java多執行緒學習筆記(自用)Java執行緒筆記
- X86中斷/異常與APICAPI