内核交互函数调用和函数地址动态寻找

OpenProcess这个内核交互函数为例

Windwos需要进行内核交互的函数调用进内核的3种方式:
					1.int 2E	
					2.sysenter
					3.syscall	

win7 x32 以OpenProcess为例
exe(OpenProcess) -> kernel32.dll(openProcess)
kernel32.dll(openProcess) -> kernelbase.dll(NTOpenProcess)
kernelbase.dll(NTOpenProcess) -> ntdll.dll(KiFastSystemCall)
ntdll.dll(KiFastSystemCall) -> ntdll.dll(sysenter) -> 内核(nt!KiFastSystemEntry)

X86OS
	x32.debug.exe:
		1.主模块->kernel32.dll
		2.kernel32.dll->kernelBase.dll(ntopenprocess)
		3.kernelbase.dll(ntopenprocess)->ntdll.dll(zwopenprocess)
		4.ntdll.dll(zwopenprocess)->sysenter(内核)
	x32.release.exe:
		1.主模块->kernel32.dll
		2.kernel32.dll->kernelBase.dll(ntopenprocess)
		3.kernelbase.dll(ntopenprocess)->ntdll.dll(zwopenprocess)
		4.ntdll.dll(zwopenprocess)->sysenter(内核)	

X64OS
	x32.debug.exe:
		1.主模块->kernel32.dll
		2.kernel32.dll->kernelBase.dll(ntopenprocess)
		3.kernelbase.dll(ntopenprocess)->ntdll.dll
		4.ntdll.dll->Wow64(为64OS,模拟32OS,转发进内核)
	x32.relesae.exe:
		1.主模块->kernel32.dll
		2.kernel32.dll->kernelBase.dll(ntopenprocess)
		3.kernelbase.dll(ntopenprocess)->ntdll.dll
		4.ntdll.dll->Wow64(为64OS,模拟32OS,转发进内核)
	x64.debug.exe:
		1.主模块->kernel32.dll
		2.kernel32.dll->kernelBase.dll(ntopenprocess)
		3.kernelbase.dll(ntopenprocess)->ntdll.dll(ntopenprocess)
		4.ntdll.dll(ntopenprocess)->syscall(内核)
	x64.relesae.exe:
		1.主模块->kernel32.dll
		2.kernel32.dll->kernelBase.dll(ntopenprocess)
		3.kernelbase.dll(ntopenprocess)->ntdll.dll(ntopenprocess)
		4.ntdll.dll(ntopenprocess)->syscall(内核)
#include <iostream>
#include <windows.h>

//WINAPI,这个宏不能少,不然会报错
EXTERN_C typedef FARPROC(WINAPI* MyGetProcAddress)(_In_ HMODULE hModule, _In_ LPCSTR lpProcName);

EXTERN_C typedef HMODULE(WINAPI* MyLoadLibrary)(_In_ LPCWSTR lpLibFileName);

EXTERN_C typedef int(WINAPI* MyMessageBox)(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType);

EXTERN_C typedef  VOID(WINAPI* MyExitProcess)(_In_ UINT uExitCode);

DWORD Getkerlen32adders()
{
	_TEB* pTeb = NtCurrentTeb();
    //pTeb里面是指针,把它转成PBYTE(字节为单位)+0x30,定位到了指向PEB的指针的位置,
      又因为指向PEB的是指针,指针在x86OS站4字节,
      所以把定位到的那个位置转成4字节的指针即  (PUINT/PDWORD),
      然后在“*”取值即:把定位到的那个位置往后数4给字节里面的值取出来,
      在对值进行取值,就得到了PEB结构体,又因为后面需要用PEB结构体,
      所以又把PEB结构体的首地址转成PBYTE。

    PBYTE pPeb = (PBYTE) * (PUINT)((PBYTE)pTeb + 0x30);
	PBYTE pLdr = (PBYTE) * (PUINT)(pPeb + 0x0C);
	PUINT InloadorderrmoudleList = (PUINT)(pLdr + 0xc);
	PUINT pExe = (PUINT)*InloadorderrmoudleList;
	PUINT pNtdll = (PUINT)*pExe;    //因为_LIST_ENTRY嵌在_LDR_DATA_TABLE_ENTRY的首位,所以可以*pExe、*pNtdll一直取到Kernel32.dll的位置
	PBYTE pKernel32dll = (PBYTE)*pNtdll;
	UINT Kernel32DllBase = *(PUINT)(pKernel32dll + 0x18);
	return Kernel32DllBase;
}

DWORD GetProcAddressFun()
{
	DWORD DllBase = Getkerlen32adders();
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)Getkerlen32adders();
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((PBYTE)pDos + pDos->e_lfanew);
	PIMAGE_EXPORT_DIRECTORY pEm = (PIMAGE_EXPORT_DIRECTORY)(pNt->OptionalHeader.DataDirectory[0].VirtualAddress + DllBase);
	PDWORD NameTable = (PDWORD)(DllBase + pEm->AddressOfNames);
	for (size_t i = 0; i < pEm->NumberOfNames; i++)
	{
		if (!NameTable[i])
		{
			continue;
		}
		PCHAR szFuncName = (PCHAR)(NameTable[i] + DllBase);
		if (!strcmp(szFuncName,"GetProcAddress"))
		{
			DWORD index = ((PWORD)(pEm->AddressOfNameOrdinals + DllBase))[i];
			DWORD Funcaddrs= ((PDWORD)(pEm->AddressOfFunctions + DllBase))[index];
			return Funcaddrs + DllBase;
		}
	}
}

int main()
{
	MyGetProcAddress pMyGetProcAddress = (MyGetProcAddress)GetProcAddressFun();
	HMODULE kernelHandle = (HMODULE)Getkerlen32adders();
	MyLoadLibrary pMyLoadLibrary = (MyLoadLibrary)pMyGetProcAddress(kernelHandle, "LoadLibraryW");
	HMODULE hUser32 = pMyLoadLibrary(L"User32.dll");
	MyMessageBox pMyMessageBox = (MyMessageBox)pMyGetProcAddress(hUser32, "MessageBoxA");
	MyExitProcess pMyExitProcess = (MyExitProcess)pMyGetProcAddress(kernelHandle, "ExitProcess");

	pMyMessageBox(NULL, "0.0", "Meg", MB_OK);
	pMyExitProcess(0);
}

双机调试步骤:

双机调试步骤:  (注意空格)
1 windbg断下来
2 ! process 0 0 (查看当前所有进程信息)
3 . process /i 地址 (切换到指定进程上下文)
4 windbg按F5执行断下
5 !process (查看指定的进程信息)
6 dt _teb 地址 (查看这个地址,按_TEB结构解析)
7 dt _peb 地址
8 dt _peb_ldr_data 地址
9 dt _ldr_data_table_entry 地址  (是主模块的)
10 dt _ldr_data_table_entry 地址  (一般是ntdll.dll)
11 dt _ldr_data_table_entry 地址  (一般是kernel32.dll)


dt _list_entry   (查看_list_entry结构的)


!peb    (查看打开进程的PEB地址)
!teb    (查看打开进程的TEB地址)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值