相关文章推荐
大力的椰子  ·  Android ...·  5 月前    · 
礼貌的木瓜  ·  layui ...·  1 年前    · 


最近在看《windows图形编程》,其中提到一些比较实用的windows系统的文件特性,总结一下,把代码也贴出来作参考。

原文参考P27,在这里只把代码写出来,代码经过我的初步修改,可以直接运行。

要求要了解PE文件结构,熟悉基本的windowsAPI。下面程序把原来需要调用user32.dll中的MessageBoxA函数用自己实现的MyMessageBox代替,也就是一个重定向的功能。

// NormalProject.cpp : Defines the entry point for the application.
#include "stdafx.h"
#include <windows.h>
#include "NormalProject.h"
#include "KPEFile.h"
int WINAPI MyMessageA(HWND hWnd, LPCSTR pText, LPCSTR pCaption,
					  UINT uType);
int APIENTRY _tWinMain(HINSTANCE hInstance,
					   HINSTANCE hPrevInstance,
					   LPTSTR    lpCmdLine,
					   int       nCmdShow)
	KPEFile pe(hInstance);
	pe.SetImportAddress("user32.dll","MessageBoxA",
		(FARPROC)MyMessageA);
	MessageBoxA(NULL,"Test","SetImportAddress",MB_OK);
int WINAPI MyMessageA(HWND hWnd, LPCSTR pText, LPCSTR pCaption,
					  UINT uType)
	WCHAR wText[MAX_PATH];
	WCHAR wCaption[MAX_PATH];
	MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,pText,-1,wText,MAX_PATH);
	wcscat(wText,L"-intercepted");
	MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,pCaption,-1,wCaption,MAX_PATH);
	wcscat(wCaption,L"-intercepted");
	return MessageBoxW(hWnd,wText,wCaption,uType);


      接下来是KPEFile.h

#pragma once
class KPEFile
	const char * m_pModule;
	PIMAGE_DOS_HEADER m_pDOSHeader;
	PIMAGE_NT_HEADERS m_pNTHeader;
public:
	KPEFile(HMODULE hModule);
	~KPEFile(void);
	const char * RVA2Ptr(unsigned rva) 
		if ((m_pModule!=NULL)&&rva)
			return m_pModule+rva;
			return NULL;
	const void * GetDirectory(int id);
	PIMAGE_IMPORT_DESCRIPTOR GetImportDescriptor(LPCSTR pDllName);
	const unsigned * GetFunctionPtr(PIMAGE_IMPORT_DESCRIPTOR pImport,
		LPCSTR pProcName);
	FARPROC SetImportAddress(LPCSTR pDllName, LPCSTR pProcName, FARPROC pNewProc);

以及实现代码:

#include "StdAfx.h"
#include "KPEFile.h"
KPEFile::KPEFile(HMODULE hModule)
	m_pModule = (const char *)hModule;
	if (IsBadReadPtr(m_pModule, sizeof(IMAGE_DOS_HEADER)))
		m_pDOSHeader = NULL;
		m_pNTHeader = NULL;
		m_pDOSHeader = (PIMAGE_DOS_HEADER)m_pModule;
		if (IsBadReadPtr(RVA2Ptr(m_pDOSHeader->e_lfanew),sizeof(IMAGE_NT_HEADERS)))
			m_pNTHeader = NULL;
			m_pNTHeader = (PIMAGE_NT_HEADERS)RVA2Ptr(m_pDOSHeader->e_lfanew);
KPEFile::~KPEFile(void)
const void * KPEFile::GetDirectory(int id)
	return RVA2Ptr(m_pNTHeader->OptionalHeader.DataDirectory[id].VirtualAddress);
PIMAGE_IMPORT_DESCRIPTOR KPEFile::GetImportDescriptor(LPCSTR pDllName)
	PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)GetDirectory(IMAGE_DIRECTORY_ENTRY_IMPORT);
	if ( pImport == NULL)
		return NULL;
	while(pImport->FirstThunk)
		if (stricmp(pDllName,RVA2Ptr(pImport->Name))==0)
			return pImport;
		pImport++;
	return NULL;
const unsigned * KPEFile::GetFunctionPtr(PIMAGE_IMPORT_DESCRIPTOR pImport, LPCSTR pProcName)
	PIMAGE_THUNK_DATA pThunk;
	pThunk = (PIMAGE_THUNK_DATA)RVA2Ptr(pImport->OriginalFirstThunk);
	for (int i =0; pThunk->u1.Function; i++)
		bool match;
		if (pThunk->u1.Ordinal & 0x80000000)
			match = (pThunk->u1.Ordinal&0xFFFF) == ((DWORD)pProcName);
			match = stricmp(pProcName,RVA2Ptr((unsigned)pThunk->u1.AddressOfData)+2) == 0;
		if (match)
			return (unsigned*)RVA2Ptr(pImport->FirstThunk)+i;
		pThunk++;
	return NULL;
FARPROC KPEFile::SetImportAddress(LPCSTR pDllName, LPCSTR pProcName, FARPROC pNewProc)
	PIMAGE_IMPORT_DESCRIPTOR pImport = GetImportDescriptor(pDllName);
	if (pImport)
		const unsigned * pfn = GetFunctionPtr(pImport,pProcName);
		if (IsBadReadPtr(pfn, sizeof(DWORD)))
			return NULL;
		FARPROC oldproc = (FARPROC) * pfn;
		DWORD dwWritten;
		WriteProcessMemory(GetCurrentProcess(),(void *)pfn,
			&pNewProc, sizeof(DWORD), &dwWritten);  //改变符号指向的地址,实现钩子目的。
		return oldproc;
		return NULL;


没有太多时间,代码中没有一一注释。

在一些木马以及防木马的技术中,这个技术应该是可以应用的。

一、概述: 了解windows程序设计的人都知道,Windows系统程序的运行是建立在消息传递机制的基础之上的,几乎所有的程序活动都由消息来驱动。钩子机制可以看作是一个消息的中转站,控制系统发出消息的处理和传递。利用钩子,我们可以截获系统发给应用程序的消息,并且在经过处理后决定是否将消息再发给下一个应用程序。利用钩子的这一特性,我们可以创建一个监控程序,收集和控制系统发出的消息。 二、Windows钩子程序的编制 编制Windows钩子程序,需要用到几个SDK中的API函数。下面列出这几个函数的原型及说明: HHOOK SetWindowsHookEx( int idHook, HOOK_
我们知道Windows中的窗口程序是基于消息,由事件驱动的,在某些情况下可能需要捕获或者修改消息,从而完成一些特殊的功能(MFC框架就利用Windows钩子对消息进行引导)。对于捕获消息而言,无法使用IAT或Inline Hook之类的方式去进行捕获,这就要用到接下来要介绍的Windows提供的专门用于处理消息的钩子函数。 1. 挂钩原理 Windows下的应用程序大部分都是基于消息机
1,钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息, 而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许 应用程序截获处理window消息或特定事件。 2,钩子程序是windows上监控软件的基础之一,例如杀毒软件对下载文件的监控,当下载完之后对其进行杀毒, 对运行程序的监控,当这个...
如果一张表中有一个非主键的字段指向了另一张表中的主键,就将该字段叫做外键。一张表中外键可以有多个,也就是不同字段指向了不同表中的主键。需要注意数据表的存储引擎必须为InnoDB,因为InnoDB提供事务支持以及外部键等高级数据库功能,相反的MyISAM不支持。 外键的作用是保持数据一致性、完整性,主要体现在下面两个方面: 从表插入新行,其外键值不是主表的主键值便阻止插入; 从表修改外键值,新值不是主表的主键值便阻止修改; 主表删除行,其主键值在从表里存在便阻止删除(要想删除,必须先删除从表的
WINDOWS钩子函数可以认为是WINDOWS的主要特性之一。利用它们,您可以捕捉您自己进程或其它进程发生的事件。通过“钩挂”,您可以给WINDOWS一个处理或过滤事件的回调函数,该函数也叫做“钩子函数”,当每次发生您感兴趣的事件时,WINDOWS都将调用该函数。一共有两种类型的钩子:局部的和远程的。   局部钩子仅钩挂您自己进程的事件。   远程的钩子还可以将钩挂其它进程发生的事件。远程的钩子又有两种:   基于线程的 它将捕获其它进程中某一特定线程的事件。简言之,就是可以用来观察其它进程中的某.
一、前 言 众所周知,Windows程式的运行是依靠发生的事件来驱动。换句话说,程式不断等待一个消息的发生,然后对这个消息的类型进行判断,再做适当的处理。处理完此次消息后又回到等待状态。从上面对Windows程式运行机制的分析不难发现,消息在用户与程式之间进行交流时起了一种中间“语言”的作用。在程式中接收和处理消息的主角是窗口,它通过消息泵接收消息,再通过一个窗口过程对消息进行相应的处理。 消息拦截的实现是在窗口过程处理消息之前拦截到消息并做相关处理后再传送给原窗口过程。通常情况下,程序员可以在窗口过程
Windows HooK钩子技术是指基于Windows中窗口的程序的消息处理里机制,对系统或者进程中的消息进行截获和处理,并将截获和处理的消息在重新处理和发送,使其可以实现不同的功能。 钩子技术分为系统钩子技术和线程钩子技术 系统钩子:是用于监视真个系统中的消息的钩子技术,因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL) 中。做好之后使用其他程序将钩子挂载到系统的进程中。 线程钩子:指的是对指定线程进行监视。 钩子原理 在使用钩子技术的时候,WINDOWS会先在内存中创