零零散散花了一个月的时间初步学习了windows驱动编程,接着开始要制定2013年的学习计划,即将步入另外一个学习战场,于是就将最近学习记录下来,也好将来再返回学习时有点基础。
一、windows驱动安装
1、到官方下载DDK安装,ex : 3790.1830.DDK
2、目录简介
示例代码: 安装目录/src/general/event/sys
编译:build
基本文件:源文件,sources, makefile
二、VC6 驱动设置
1、 Tools->Options->Directories->Executable files->新建 ...\3790.1830\BIN\X86 移到最上边
Tools->Options->Directories->Include files->新建 ...\3790.1830\INC\CRT
Tools->Options->Directories->Include files->新建 ...\3790.1830\INC\DDK\WXP
Tools->Options->Directories->Include files->新建 ...\3790.1830\INC\WXP
Tools->Options->Directories->Include files->新建 ...\3790.1830\INC\DDK\WDM\WXP
Tools->Options->Directories->Library files->新建 ...\3790.1830\LIB\WXP\I386
2、编译设置:适用于NT驱动,WDM驱动
Project->Configurations->Add... 新建编译选项
Project->Setting->C/C++->Project Options
/nologo /Gz /MLd /WZ /WX /Z7 /Od /D WIN32=100 /D _X86_=1 /D WINVER=0x501 /D DBG=1 /Fo "ddk_check1" /Fd "ddk_check1" /FD /c
Project->Setting->Link->Project Options
wdm.lib ntoskrnl.lib /nologo /base:"0x10000" /stack:0x400000,0x1000
/entry:"DriverEntry" /subsystem:console /incremental=no
/pdb:"ddk_check/event.pdb" /debug /machine:I386
/nodefaultlib /out:"ddk_check/event.sys" /subsystem:native
/driver /SECTION:INIT,D /RELEASE /IGNORE:4078
三、VS2003设置
一、配置移到最上面
工具->选项-》项目-》VC++目录-》包含文件-》新建... 3790.1830\inc\crt
工具->选项-》项目-》VC++目录-》包含文件-》新建... 3790.1830\inc\ddk\wxp
工具->选项-》项目-》VC++目录-》包含文件-》新建... 3790.1830\inc\wxp
工具->选项-》项目-》VC++目录-》包含文件-》新建... 3790.1830\inc\ddk\wdm\wxp
工具->选项-》项目-》VC++目录-》库文件-》新建 ...3790.1830\Bin\x86
工具->选项-》项目-》VC++目录-》可执行文件-》新建 ...3790.1830\Bin\x86
项目-》event属性-》配置管理器-》项目上下文-》新建项目配置 + "check"
项目-》event属性-》配置属性-》C/C++-》常规-》调试信息格式@c7
项目-》event属性-》配置属性-》C/C++-》常规-》警告等级@wz
项目-》event属性-》配置属性-》C/C++-》预处理器: WIN32=100;_X86_=1, WINVER=0X501; DBG=1
项目-》event属性-》配置属性-》C/C++-》代码生成-》运行时库 @多线程
项目-》event属性-》配置属性-》C/C++-》代码生成-》缓冲区安全检查 @否
项目-》event属性-》配置属性-》C/C++-》高级-》调用约定 @__stdcall
项目-》event属性-》链接器-》常规-》输出文件 @.sys
项目-》event属性-》链接器-》输入-》附加依赖项@wdm.lib
项目-》event属性-》高级-》入口点 @DriverEntry
项目-》event属性-》高级-》基址@ 0x10000
#include <ntddk.h> #define INITCODE code_seg("INIT") #pragma INITCODE VOID DDK_Unload (IN PDRIVER_OBJECT pDriverObject); //前置说明 卸载例程 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING B) //TYPEDEF LONG NTSTATUS { KdPrint(("驱动成功被加载...OK++++++++")); pDriverObject->DriverUnload = DDK_Unload; return (1); } VOID DDK_Unload (IN PDRIVER_OBJECT pDriverObject) { KdPrint(("驱动成功被卸载...OK-----------")); //sprintf,printf DbgPrint("卸载成功"); }
五、原理介绍
windows API: user函数、gdi函数、kernel函数
user32.dll 管理窗口、菜单、对话框和控件
gdi32.dll 在物理设备上执行绘图操作
kernel32.dll 进程、线程、文件和同步服务
MFC库:在应用程序和win32子系统中间加了一层封装
SSDT: system service descriptor table 把ring3的win32 api 和ring0的内核api联系起来
应用层到内核层:
OpenProcess xx.dll->kernel32.OpenProcess->NtOpenProcess->ntdll.ZwOpenProcess->ntdll.KiFastSystemCall // eax参数+SSDT表
sysenter指令切换到内核
保护原理:inline hook这些API函数
内核:ntkrnlpa.ZwOpenProcess -> SSDT ->ntkrnlpa.NtOpenProcess
kernel32.dll -> SSDT
user32.dll gdi32.dll -> shadow SSDT -> win32k.sys
六、添加设备驱动例程
//_stdcall #include <ntddk.h> #define INITCODE code_seg("INIT") #define PAGECODE code_seg("PAGE") /*表示内存不足时,可以被置换到硬盘*/ #pragma INITCODE /*指的代码运行后 就从内存释放掉*/ NTSTATUS CreateMyDevice (IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status; PDEVICE_OBJECT pDevObj;/*用来返回创建设备*/ //创建设备名称 UNICODE_STRING devName; UNICODE_STRING symLinkName; // RtlInitUnicodeString(&devName, L"\\Device\\yjxDDK_Device"); /*对devName初始化字串为 "\\Device\\yjxDDK_Device"*/ //创建设备 status = IoCreateDevice( pDriverObject, \ 0, \ &devName, \ FILE_DEVICE_UNKNOWN, \ 0, TRUE, \ &pDevObj); if (!NT_SUCCESS(status)) { if (status == STATUS_INSUFFICIENT_RESOURCES) { KdPrint(("资源不足 STATUS_INSUFFICIENT_RESOURCES")); } if (status == STATUS_OBJECT_NAME_EXISTS ) { KdPrint(("指定对象名存在")); } if (status == STATUS_OBJECT_NAME_COLLISION) { KdPrint(("//对象名有冲突")); } KdPrint(("设备创建失败...++++++++")); return status; } KdPrint(("设备创建成功...++++++++")); pDevObj->Flags |= DO_BUFFERED_IO; //创建符号链接 RtlInitUnicodeString(&symLinkName, L"\\??\\yjx888"); status = IoCreateSymbolicLink( &symLinkName, &devName ); if (!NT_SUCCESS(status)) /*status等于0*/ { IoDeleteDevice( pDevObj ); return status; } return STATUS_SUCCESS; } #pragma INITCODE VOID DDK_Unload (IN PDRIVER_OBJECT pDriverObject); //前置说明 卸载例程 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING B) //TYPEDEF LONG NTSTATUS { KdPrint(("驱动成功被加载...OK++++++++")); //jmp指令 CreateMyDevice(pDriverObject); pDriverObject->DriverUnload = DDK_Unload; return (1); } VOID DDK_Unload (IN PDRIVER_OBJECT pDriverObject) { KdPrint(("驱动成功被卸载...OK-----------")); //sprintf,printf //删掉所有设备 DbgPrint("卸载成功"); }
七、WinDBG安装
1、在调试目标机上创建串口设备,创建命名管理 \\.\ipip\com_1
2、主机增加winddbg快捷方式,在windbg属性的目标里添加参数:-b -k com:pipe, port=\\.\pipe\com1, baud=115200, reconnect -y
3、被调试机boot.ini中添加一行: /fastdetect /debug /debugport=com1 /baudrate=115200
4、windgb调试命令
代码中断点加:__asm int 3;
命令:
G  
今天安装了vs2010,发现用“Win 32 控制台应用程序”编写程序时,cout语句不能显示在屏幕上就直接执行完毕,在网上找了一些方法解决了这些问题,此处为大家总结一下。
(声明:内容来自网上,已实验成功)
写的第一个程序自然是经典的“hello world”,用“启动调试 F5”调试,但屏幕一闪而过,提示信息是:
“HelloWorld.exe”: 已加载“C:\Windows\System32\ntdll.dll”,Cannot find or open the PDB file
“HelloWorld.exe”: 已加载“C:\Windows\System32\kernel32.dll”,Cannot find or open the PDB file
“HelloWorld.exe”: 已加载“C:\Windows\System32\KernelBase.dll”,Cannot find or open the PDB file
“HelloWorld.exe”: 已加载“C:\Windows\System32\msvcp100d.dll”,已加载符号。
“HelloWorld.exe”: 已加载“C:\Windows\System32\msvcr100d.dll”,已加载符号。
程序“[5272] HelloWorld.exe: 本机”已退出,返回值为 0 (0x0)。
原因:
程序输出的地方是系统而不是vs2010。你所点的按钮(或者按快捷键F5)的结果是启动调试。你所想要执行的命令是开始执行(不调试)。
我先用的是这个办法:
这是vs2010高级版的截图,熟悉吧,你随便写一个helloworld就会出现这个Cannot find or open the PDB file,就是找不到什么问题。
这样解决:工具--》选项--》》调试--》符号
接下来就是选择Microsoft,然后确认,重新编写一个程序,什么也可以,看看是不是好了?你没有发现编译很慢?
看到此目录下符号缓存了吗?找到这个目录拷贝出来,找个地方存放。接下来就是去掉Microsoft符号服务器,要是不去,每次都要从Microsoft下载很麻烦,已经缓存了,我们就可以利用好这些缓存,至此完美解决。
按照步骤操作完之后,虽然“Cannot find or open the PDB file”的问题解决了,但还是窗口一闪而过,于是找了下面的办法:
①目前为止最好的解决办法:(来自:CSDN论坛、新浪博客)
运行按:Ctrl+F5
(根本原因:程序输出的地方是系统而不是vs2010。你所点的按钮(或者按快捷键F5)的结果是启动调试。你所想要执行的命令是开始执行(不调试)。
解决办法1:直接按Ctrl + F5即可。
解决办法2:添加工具栏。步骤如下:
1). 双击工具栏上的空白区域,会跳出自定义工具栏窗口。到命令页找到工具栏->生成,查看里面的命令,至少包括“开始执行(不调试)”,“生成选定内容”,“生成解决方案”三项,如果缺少的话,点击右面的添加命令->调试里添加。
2). 在工具栏页勾选“生成”。以后直接点击工具栏上刚添加的“开始执行(不调试)”按钮就行了。)
②设置断点:在程序最后一个语句设置一个断点,那么运行到最后命令符就不会消失了。
package edu.cdut.robin;import java.lang.reflect.Field;import android.content.Context;import android.content.pm.PackageManager;import android.util.Log;public class TestPermission extends Thread{final Context context;final static String TAG="robin";TestPermission(Context context){super();this.context=context;}public void run(){/* 使用getDeclaredFields获取属性*/Class<android.Manifest.permission> classType=android.Manifest.permission.class;Field[] fields =classType.getFields();for (Field f : fields