根据Kernel32基地址调用函数

// 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;
}




来看一下效果图



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值