根据Kernel32基地址调用函数

    xiaoxiao2025-08-29  6

    // KernelTest.cpp : 定义控制台应用程序的入口点。 // /* 调用函数一般过程 1:一般来说调用一个函数习惯是导入所需要的头文件 2:调用具体的函数 不导入头文件如何调用函数 1:通过动态调用的方法LoadLibaryW() 2: 调用GetProcAddress() 3:根据获取的函数指针调用具体的函数 今天所说的是通过Kernel32.dll基地址调用函数 1:根据fs:[30]通过一系列步骤查找到kernel32.dll的基地址 ps这里需要有关于PE导出表的知识需要自行观看相关书籍推荐PE权威指南 2:根据基地址查找这两个函数的地址LoadLibary GetProcAddress 3:步骤跟上面的一样了,只需要调用函数即可 */ #include "stdafx.h" #include <stdio.h> #include <tchar.h> #include <windows.h> //添加windows.h是为了定义的方便 //MessageBoxW()函数类型 typedef int (WINAPI *MsgBox)(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); //LoadLibaryW()函数类型 typedef HMODULE (WINAPI *LQLoadLibrary)( _In_ LPCTSTR lpFileName); //GetProcAddress()函数类型 typedef FARPROC (WINAPI *LQGetProcAddress)(HMODULE hModule,LPCSTR lpProcName ); int _tmain(int argc, _TCHAR* argv[]) { char*GetProcAddress="GetProcAddress"; char*MyLoadLibrary="LoadLibraryW"; HMODULE lib=NULL; //申明三个函数指针 LQLoadLibrary ld; LQGetProcAddress addr; MsgBox mb; DWORD hModule=0; //获取kernel32.dll基地址,网上有详细解释 __asm { push eax mov eax, fs:[30h] //PEB 址, mov eax, fs:[18h] 这个获得TEB地址 mov eax, [eax + 0Ch] mov eax, [eax + 1Ch] mov eax, [eax] mov eax, [eax] mov eax, [eax + 8] mov hModule, eax pop eax } printf("%x\n",hModule); //根据导出表获取具体函数地址,具体的可以参考市面上众多的PE文件解析书籍 IMAGE_DOS_HEADER *pIDH=(IMAGE_DOS_HEADER*)(hModule); IMAGE_NT_HEADERS *pINH=(IMAGE_NT_HEADERS*)(hModule+pIDH->e_lfanew); //偏移78是导出表地址rva IMAGE_DATA_DIRECTORY *pIDD=(IMAGE_DATA_DIRECTORY*)((DWORD)pINH+0x78); //导出表 IMAGE_EXPORT_DIRECTORY *pIED=(IMAGE_EXPORT_DIRECTORY*)(hModule+pIDD->VirtualAddress); //AddressOfNameOrdinals的起始地址 USHORT * AddressOfNameOrdinals=(USHORT*)(hModule+pIED->AddressOfNameOrdinals); //函数地址 DWORD *arrayAdress=(DWORD*)(pIED->AddressOfFunctions+hModule); PVOID getProcAddress=NULL; //函数名称地址 DWORD Name=pIED->AddressOfNames+hModule; //AddressOfNameOrdinals的起始地址 SHORT *ordinals=(SHORT*)(pIED->AddressOfNameOrdinals+hModule); //计数器 int count=-1; //是否找到函数 bool isfound=false; //便利所有的有名称的函数 for(int i=0;i<pIED->NumberOfNames;i++){ //这个比下面的后执行经过我的测试 if(!isfound&&strcmp((char*)(*(DWORD*)Name+hModule),MyLoadLibrary)==0){ printf("%s",(char*)(*(DWORD*)Name+hModule)); //复制函数指针 ld=(LQLoadLibrary)(hModule+arrayAdress[ordinals[i]]); //调用函数 lib=ld(_T("user32.dll")); //跳出循环 break; isfound=true; } if(strcmp((char*)(*(DWORD*)Name+hModule),GetProcAddress)==0){ printf("%s\n",(char*)(*(DWORD*)Name+hModule)); //赋值函数指针 addr=(LQGetProcAddress)(arrayAdress[ordinals[i]]+hModule); printf("finished Get %x\n",addr); } //名字指针往后走 Name+=4; } if(lib!=INVALID_HANDLE_VALUE&&lib!=NULL){ //调用函数 mb=(MsgBox)addr(lib,"MessageBoxW"); mb(NULL,_T("ff"),_T("ff"),0); printf("finished Load %x\n",lib); }else{ printf(" Load error "); } //这里还有一个FreeLibary函数就不写了,可以根据上面的写下来了 system("pause"); return 0; }

    来看一下效果图

    转载请注明原文地址: https://ju.6miu.com/read-1302097.html
    最新回复(0)