在windows平台做逆向、外挂等,经常需要调用很多未导出的内核函数,怎么方便、快速查找了?可以先用IDA等工具查看硬编码,再根据硬编码定位到需要调用的函数。整个思路大致如下:

1、先查找目标模块

   遍历模块的方式有多种。既然通过驱动在内核编程,这里选择遍历driverObject的DriverSection字段来遍历内核所有模块,核心代码如下:

 /*
  可以用来动态查找内核模块的基址,后续用于:
  1、PTE\PDE等base计算
  2、其他函数、变量精确位置的计算(IDA静态分析只能查到偏移)
*/
PVOID FindMould(PDRIVER_OBJECT pDriverObject, PWCHAR moudName, PULONG pSize)
{
// 从PDRIVER_OBJECT获取DriverSection,便可获得驱动模块链表
PLDR_DATA_TABLE_ENTRY pDriverData = (PLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
// 开始遍历双向链表
PLDR_DATA_TABLE_ENTRY pFirstDriverData = pDriverData;
do
{
if (( < pDriverData->BaseDllName.Length) ||
( < pDriverData->FullDllName.Length))
{
// 显示
DbgPrint("BaseDllName=%ws,\tDllBase=0x%p,\tSizeOfImage=0x%X,\tFullDllName=%ws\n",
pDriverData->BaseDllName.Buffer, pDriverData->DllBase,
pDriverData->SizeOfImage, pDriverData->FullDllName.Buffer);
//BaseDllName.Buffer是PWCH,也就是宽字符串,所以自己定义的moudName也要是PWCHAR类型
if (!_stricmp(moudName, (PCHAR)pDriverData->BaseDllName.Buffer))
{
DbgPrint("find target : BaseDllName=%ws,\tDllBase=0x%p,\tSizeOfImage=0x%X,\tFullDllName=%ws\n",
pDriverData->BaseDllName.Buffer, pDriverData->DllBase,
pDriverData->SizeOfImage, pDriverData->FullDllName.Buffer);
*pSize = pDriverData->SizeOfImage;
return pDriverData->DllBase;
} }
// 下一个
pDriverData = (PLDR_DATA_TABLE_ENTRY)pDriverData->InLoadOrderLinks.Flink; } while (pFirstDriverData != pDriverData); return NULL;
}

  传入driverObject、模块名称,得到模块基址(返回值)和模块长度(参数);

2、得到模块基址后,再进一步根据特征码查找目标函数:

 PVOID FindFun(PVOID pSearchBeginAddr, ULONG ulSearchLength, PUCHAR pSpecialCode, ULONG ulSpecialCodeLength)
{
PVOID pDestAddr = NULL;
PUCHAR pBeginAddr = (PUCHAR)pSearchBeginAddr;
PUCHAR pEndAddr = pBeginAddr + ulSearchLength;
PUCHAR i = NULL;
ULONG j = ; for (i = pBeginAddr; i <= pEndAddr; i++)
{
// 遍历特征码
for (j = ; j < ulSpecialCodeLength; j++)
{
// 判断地址是否有效 ntoskrnl.exe有时地址无效,蓝屏报错:PAGE FAULED IN NONPAGED AREA
if (FALSE == MmIsAddressValid((PVOID)(i + j)))
{
break;
}
// 匹配特征码
if (*(PUCHAR)(i + j) != pSpecialCode[j])
{
break;
}
}
// 匹配成功
if (j >= ulSpecialCodeLength)
{
pDestAddr = (PVOID)i;
break;
}
} return pDestAddr;
}

  这里特征码搜索可以继续改进,比如用正则做模糊匹配~~~

3、用法举例:强行杀死线程时,需要调用 PspTerminateThreadByPointer 函数,但此函数并未导出,可以通过IDA查看汇编代码,也可以在windbg通过U PspTerminateThreadByPointer,如下:

kd> u nt!PspTerminateThreadByPointer

nt!PspTerminateThreadByPointer:

fffff803`d01c6210 48895c2408      mov     qword ptr [rsp+8],rbx

fffff803`d01c6215 48896c2410      mov     qword ptr [rsp+10h],rbp

fffff803`d01c621a 4889742418      mov     qword ptr [rsp+18h],rsi

fffff803`d01c621f 57              push    rdi

fffff803`d01c6220 4883ec30        sub     rsp,30h

fffff803`d01c6224 8b81d0060000    mov     eax,dword ptr [rcx+6D0h]

fffff803`d01c622a 418ae8          mov     bpl,r8b

fffff803`d01c622d 488bb920020000  mov     rdi,qword ptr [rcx+220h]

由于大多数函数刚开始都是初始化堆栈代码,这里特征码重合度较高,为了避免找到其他函数,建议从稍微靠后几行代码处提取特征码,比如这里从第7行开始提取 418ae8488bb920020000 10个字节,找到后再减去26字节就回到了PspTerminateThreadByPointer入口;

 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
DbgPrint("Enter DriverEntry\n"); NTSTATUS status = STATUS_SUCCESS;
pDriverObject->DriverUnload = DriverUnload;
for (ULONG i = ; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
pDriverObject->MajorFunction[i] = DriverDefaultHandle;
} ULONG mouldSize = ;
PWCHAR mouldName = L"ntkrnlmp.exe";
PVOID mouldBase = FindMould(pDriverObject, mouldName, &mouldSize); DbgPrint("mould name = %ws ; mould base = 0x%p; mould size = 0x%X\n", mouldName, mouldBase, mouldSize); UCHAR pSpecialCode[] = { };
/*418ae8488bb920020000*/
pSpecialCode[] = 0x41;
pSpecialCode[] = 0x8a;
pSpecialCode[] = 0xe8;
pSpecialCode[] = 0x48;
pSpecialCode[] = 0x8b;
pSpecialCode[] = 0xb9;
pSpecialCode[] = 0x20;
pSpecialCode[] = 0x02;
pSpecialCode[] = 0x00;
pSpecialCode[] = 0x00; PVOID FunAddress = FindFun(mouldBase, mouldSize, pSpecialCode, );
DbgPrint("Finally function address = 0x%p;\n", FunAddress-); return status;
}

windows:根据特征码查找内核任意函数的更多相关文章

  1. [原创]使用GCC创建 Windows NT 下的内核DLL

    原文链接:使用GCC创建 Windows NT 下的内核DLL 在温习<<Windows 2000 Driving>>分层驱动程序一章的时候,看到了关于紧耦合驱动连接方式,这种 ...

  2. 【Windows下DLL查找顺序 】

    一.写作初衷 在Windows下单个DLL可能存在多个不同的版本,若不特别指定DLL的绝对路径或使用其他手段指定,在应用程序加载DLL时可能会查找到错误的版本,进而引出各种莫名其妙的问题.本文主要考虑 ...

  3. Delphi For Android 开发笔记-附:如何Delphi中同时实现Windows、Android版的GetModuleFileName函数

    在Windows中开发DLL时,经常会需要获取当前DLL所在目录以便读取同目录下的其他文件,而目前Delphi在开发android时,其实没多大必要获取,因为整个工程只有一个so文件,而这个so文件也 ...

  4. 在windows下解压缩Linux内核源代码出现重复文件原因

    在windows下解压缩Linux内核源代码出现重复文件原因 2009年06月30日 13:35 来源:ChinaUnix博客 作者:embededgood 编辑:周荣茂     原因一.因为在Lin ...

  5. Qt Windows下链接子系统与入口函数(终结版)(可同时存在main和WinMain函数)

    Qt Windows下链接子系统与入口函数(终结版) 转载自:http://blog.csdn.net/dbzhang800/article/details/6358996 能力所限,本讨论仅局限于M ...

  6. linux2.6内核compat_ioctl函数

    一.内核原型(linux2.6.28-7) long (*compat_ioctl)(struct tty_struct *tty, struct file * file,               ...

  7. Windows下DLL查找顺序

    目录 第1章说明    2 1.1 查找顺序    2 1.1.1 检查DllCharacteristics字段    3 1.1.2 读取manifset资源    3 1.1.3 读取manifs ...

  8. Linux内核d_path函数应用的经验总结

    问题背景 一个内核模块中,需要通过d_path接口获取文件的路径,然后与目标文件白名单做匹配. 在生产环境中,获取的文件是存在的,但是与文件白名单中的文件总是匹配失败. 问题定位: 通过打印d_pat ...

  9. 内核开发知识第一讲.内核中的数据类型.重要数据结构.常用内核API函数.

    一丶内核中的数据类型 在内核中.程序的编写不能简单的用基本数据类型了. 因为操作系统不同.很有可能造成数据类型的长度不一.而产生重大问题.所以在内核中. 数据类型都一定重定义了. 数据类型 重定义数据 ...

随机推荐

  1. 微软全球资深副总裁对 VS Code 黑宝书的推荐序!VS Code 月活用户已达 1200 万!

    前不久,首本 VS Code 中文书终于问世了! 在本书出版之前,我很高兴能邀请到微软全球资深副总裁 Julia Liuson 为本书写推荐序!下面,我们就来看一下 Julia 所写的推荐序的完整内容 ...

  2. 07 . Jenkins忘记root密码

    重置Jenkins用户名密码 忘记用户名密码(如图)不管是忘记用户名密码还是误删jenkins目录下的users文件都可以使用下面的方式找回密码,我的版本是Jenkins 2.134 配置config ...

  3. [Mybatis]Mybatis常用操作

    Mybatis是目前国内比较流行的ORM框架,特点是可以写灵活的SQL语句,非常适合中小企业的面向数据库开发. 本文总结自己开发过程中常用的Mybatis操作. 一.插入操作 主键自增插入单条 < ...

  4. 数据库周刊31丨openGauss 正式开源;7月数据库排行榜发布;浙江移动国产数据库AntDB迁移;oracle ADG跨版本搭建;PG解决社保问题;mysqlbinlog解析……

    摘要:墨天轮数据库周刊第31期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.openGauss 正式开源,华为公开发布源代码[摘要]6月1日,华为正式宣布开源数据库能 ...

  5. day35 作业

    服务端 import subprocess import struct import json from socket import * server = socket(AF_INET, SOCK_S ...

  6. java 面向对象(六):类结构 方法(三) java的值传递机制

    java的值传递机制 1.针对于方法内变量的赋值举例: System.out.println("***********基本数据类型:****************"); int ...

  7. How to install chinese input method

    在Ubuntu中安装中文输入法确实比较麻烦,特别是英文版的Ubuntu系统   Ubuntu上的输入法主要有小小输入平台(支持拼音/二笔/五笔等),Fcitx,Ibus,Scim等.其中Scim和Ib ...

  8. js dom演示

    <body> <div id="div1"> <p name="p1">p1内容</p> <p name= ...

  9. 从Excel(CSV)文件导入数据到Oracle

    步骤: 1.准备数据:在excel中构造出需要的数据2.将excel中的数据另存为文本文件(有制表符分隔的)3.将新保存到文本文件中的数据导入到pl*sql中在pl*sql中选择tools--text ...

  10. JavaWeb基础(day15)( http + tomcat + servlet + 响应)

    HTTP+Tomcat+Servlet+响应 HTTP HTTP  超文本传输协议(Hyper Text  Transfer  Protocol  ),一种网络协议. 协议的组成和过程 HTTP协议由 ...