最近一段时间都在解决ring0调用ring3函数的问题
因为想在驱动中间实现启动一个应用程序,这个应用程序有可能是exe也有可能是dll,但是在核心层没有像WinExec或者LoadLibrary这样的API可供我们调用,并且驱动程序和应用程序的地址空间不同,一个是在高地址空间,一个在低地址空间,如何才能实现ring0调用ring3的函数呢,肯定是不能直接在驱动的地址空间中间执行,因为这些函数在高地址空间中间根本无法解析,或者在编译的时候就无法通过
因此必须要把用户态的函数或者代码放在应用程序的地址空间中间执行
ring0调用ring3函数有3种方法:
http://hi.baidu.com/%CE%F7%B7%E7%B9%AB%C9%E7/blog/item/0febbd355d0904bfd1a2d320.html
我用的是插入APC的方法
在使用的过程中间还是出现了很多问题,需要插入的汇编代码主要部分为
mov eax,0x7c86114d
push 1
nop
push 0xabcd
call eax
jmp end
nop
nop
0x7c86114d为winexec函数在系统中间的地址,这个地址不同的系统还不同
最开始运行的时候没有反应,原来要把地址变为当前系统里面winexec函数的地址,但是这也带来了一个问题,没有通用性,如果换到其它的系统上还要手动修改这个值,如果动态获得就是最好的了
接下来的工作就是动态获得winexec函数的地址
获取函数的地址是通过PEB(进程环境块)获取加载的模块基址,winexec在kernel32.dll里面,因此先获得kernel32.dll的内存基地址,之后再遍历获得winexec函数的地址
问题1:如何获得PEB的地址?
PsGetCurrentProcess函数可以获得EPROCESS的地址,+0x088获取进程列表头 ActiveProcessLinks ,遍历找到explorer.exe进程,再explorer.exe进程的EPROCESS结构+0x1b0里面获得PEB的地址
问题2:如何由PEB获得Kernel32.dll的内存基地址?
一般应用程序最先加载的是NTDLL。dll和kernel32.dll,peb+0x0c获得PEB_LDR_DATA的地址,PEB_LDR_DATA + 0X1C处存放着指向模块初始化链表InInitializationOrderModuleList的头指针,第一个链表节点是ntdll.dll,第二个链表的节点就是Kernel32.dll,+0x08获得kernel32的内存基地址
问题3:如何通过内存基地址获得函数地址?
内存基地址实际上就是PE结构的DOS头结构的地址,+ 0x3c获取PE文件头的地址,0x78获取输出表的地址,输出表中就保存着输出函数的相关信息,通过遍历就可以得到Winexec函数的地址
问题4:获取动态地址之后如何把地址传给用户代码
mov eax,fun_addr;这个操作是绝对不行的,因为这行代码已经在用户空间中运行,而fun_addr是内核中间的变量,用户空间可以无法访问内核空间中的变量,这里需要做的就是应该自己计算机mov eax,fun_adr这条指令的偏移...在驱动里copy下..替换下就OK
实际中需要注意的地方:
1.因为都是用地址来操作的,所以都用ULONG来表示地址,并且查找一个值的时候也是用基址+偏移地址的形式而不是用结构,若涉及到结构,则编程的时候就需要定义结构,而结构又是相互嵌套,这就带来了很大的工作量
2.在内核空间不可以直接访问进程的地址空间,需要切换下,需要用到的函数是KeStackAttachProcess ( (ULONG *)pSystemProcess,&ApcState);pSystemProcess为进程的EPROCESS地址,否则就会产生系统错误,并且不用的时候要用KeUnstackDetachProcess (&ApcState);
3.最后在获取函数地址的时候,因为都是用32位的变量来保存数据,但是序号只是2个字节中存放,所以就存在如何获取32位数据的高16位或者说是低16位,自然而然应该用与操作,NumberOfNames&0x00001111获取低16位的数据,咋看之下是对的,其实错了,应该是NumberOfNames&0x0000ffff
OK,其中涉及到的资料链接如下:
http://bbs.pediy.com/showthread.php?t=46068
http://topic.csdn.net/u/20090630/14/d04aae5d-14f3-42c3-9c4b-9b4ae37fe01c.html
http://www.debugman.com/read.php?tid=3983
http://www.101d1.cn/read.php?87
1.PE结构信息(可以在winnt.h中获得所有PE结构信息)
https://forum.eviloctal.com/thread-32393-1-7.html
http://blog.csdn.net/strongxu/archive/2009/11/04/4766062.aspx
http://hi.baidu.com/hnxyy/blog/item/c2bfec24400be5014d088d47.html
2.WinDbg调试命令
http://www.zhizihua.com/blog/post/248.html
http://bbs.pediy.com/showthread.php?t=98183
3.EPROCESS结构信息(这个在windbg工具中也可以看到)
http://hi.baidu.com/id404notfound/blog/item/375b8c478c87400e6a63e556.html
http://bbs.driverdevelop.com/read.php?tid=112877
4.获取api地址
http://blog.csdn.net/syf442/archive/2009/07/27/4383254.aspx