||x s–切换系统
|x s–切换进程
~x s–切换线程
记录点滴
||x s–切换系统
|x s–切换进程
~x s–切换线程
修改注册表中 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Nls\Language,”InstallLanguage”的值
DWORD dwLanID = GetSystemDefaultLangID();
// Identifier Language
// 0×0000 Language Neutral
// 0×0400 Process Default Language
// 0×0401 Arabic (Saudi Arabia)
// 0×0801 Arabic (Iraq)
// 0x0c01 Arabic (Egypt)
// 0×1001 Arabic (Libya
1 .logopen logfile.log
该命令的作用是创建一个windbg的日志文件,从该文件创建开始直到.logclose调用,所有debug的过程都会log到logfile.log文件中。这对于调试过程的回忆和追踪是有用处的。
2 bp module!functionname(或者内存地址)
该命令的作用是创建在指定的地方插入一个断点。当程序运行到断点时,会产生中断等待用户处理(这个过程叫做中断命中breakpoint hit)。程序中可以加入多个中断。当我们在动态调试程序的时候,该命令较为常用,但是对于静态的dump文件不需要。
3 bl
该命令的作用是列出所有断电信息。
0:00
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #include <windows.h> #include <stdio.h> typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PVOID Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; // 申明ntdll中使用的函数 typedef DWORD (CALLBACK* RTLANSISTRINGTOUNICODESTRING)(PVOID, PVOID,DWORD); RTLANSISTRINGTOUNICODESTRING RtlAnsiStringToUnicodeString; typedef DWORD (CALLBACK* RTLFREEUNICODESTRING)(PVOID); RTLFREEUNICODESTRING RtlFreeUnicodeString; typedef DWORD (CALLBACK* ZWLOADDRIVER)(PVOID); ZWLOADDRIVER ZwLoadDriver; int LoadDriver(char * szDrvName, char * szDrvPath) { //修改注册表启动驱动程序 char szSubKey[200], szDrvFullPath[256]; LSA_UNICODE_STRING buf1; LSA_UNICODE_STRING buf2; int iBuffLen; HKEY hkResult; char Data[4]; DWORD dwOK; iBuffLen = sprintf(szSubKey,"System\\CurrentControlSet\\Services\\%s",szDrvName); szSubKey[iBuffLen]=0; dwOK = RegCreateKey(HKEY_LOCAL_MACHINE,szSubKey,&hkResult); if(dwOK!=ERROR_SUCCESS) return false; Data[0]=1; Data[1]=0; Data[2]=0; Data[3]=0; dwOK=RegSetValueEx(hkResult,"Type",0,4,(const unsigned char *)Data,4); dwOK=RegSetValueEx(hkResult,"ErrorControl",0,4,(const unsigned char *)Data,4); dwOK=RegSetValueEx(hkResult,"Start",0,4,(const unsigned char *)Data,4); GetFullPathName(szDrvPath, 256, szDrvFullPath, NULL); printf("Loading driver: %s\r\n", szDrvFullPath); iBuffLen = sprintf(szSubKey,"\\??\\%s",szDrvFullPath); szSubKey[iBuffLen]=0; dwOK=RegSetValueEx(hkResult,"ImagePath",0,1,(const unsigned char *)szSubKey,iBuffLen); RegCloseKey(hkResult); iBuffLen = sprintf(szSubKey,"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%s",szDrvName); szSubKey[iBuffLen]=0; buf2.Buffer = (PVOID)szSubKey; buf2.Length = iBuffLen; RtlAnsiStringToUnicodeString(&buf1,&buf2,1); //加载驱动程序 dwOK = ZwLoadDriver(&buf1); RtlFreeUnicodeString(&buf1); iBuffLen=sprintf(szSubKey,"%s%s\\Enum","System\\CurrentControlSet\\Services\\",szDrvName); szSubKey[iBuffLen]=0; //删除注册表项 RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf(szSubKey,"%s%s\\Security","System\\CurrentControlSet\\Services\\",szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf(szSubKey,"%s%s","System\\CurrentControlSet\\Services\\",szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf(szSubKey,"\\\\.\\%s",szDrvName); szSubKey[iBuffLen]=0; return true; } int main(int argc, char *argv[]) { printf("Load driver with ZwLoadDriver( )\r\n"); printf("Date: 8th May 2007\r\n"); printf("Modifed by: GaRY <wofeiwo_at_gmail_dot_com>\r\n\r\n"); if(argc != 3) { printf("Usage: %s <DriverFilename> <DriverPath>\r\n", argv[0]); exit(-1); } HMODULE hNtdll = NULL; hNtdll = LoadLibrary( "ntdll.dll" ); //从ntdll.dll里获取函数 if ( !hNtdll ) { printf( "LoadLibrary( NTDLL.DLL ) Error:%d\n", GetLastError() ); return false; } RtlAnsiStringToUnicodeString = (RTLANSISTRINGTOUNICODESTRING) GetProcAddress( hNtdll, "RtlAnsiStringToUnicodeString"); RtlFreeUnicodeString = (RTLFREEUNICODESTRING) GetProcAddress( hNtdll, "RtlFreeUnicodeString"); ZwLoadDriver = (ZWLOADDRIVER) GetProcAddress( hNtdll, "ZwLoadDriver"); //注册驱动程序 if(LoadDriver(argv[1], argv[2]) == false) return false; return true; } |
链表是一种常用结构,在驱动中也是如此。
双向链表中每个元素有两个指针:BLINK指向前一元素,FLINK指向后一元素。WDK提供链表的结构LIST_ENTRY,使用时插入已有的数据结构,把LIST_ENTRY作为一个成员便可。
1 2 3 4 5 | typed struct mystruct{ LIST_ENTRY ListEntry; ULONG a; ULONG b; }MYSTRUCT; |
每个双向链表都以一个链表头作为链表的第一个元素,使用前需要用IntializeListHead宏来初始化。通过判断链表头FLINK和BLINK是否指向自己来判断链表是否为空。或者使用IsListEmpty宏.
对链表的插入有两种方式,一种是在链表头部插入,一种是在尾部,两个函数insertHeadList(
Ida通过SIG文件来识别已知的函数信息,SIG制作如下:
(1)从LIB文件提取OBJ文件,用连接器如下:
link -lib /extract:[filename][libname].lib
(2)将OBJ文件制作成PAT文件:
pcf[Objname].obj
(3)多PAT文件联合编译SIG文件
sigmake[Pat name].pat [Sig name].sig
用Shift+F5将制作的SIG添加
批处理
md %1_objs
cd %1_objs
for /F %%i in (‘link -lib /list %1.lib’) do link -lib
Enter—跟进函数或跳转
Esc—–返回上次光标处
A——-解析光标处地址为字符串首地址
B——-解析光标处为二进制数
C——-解析光标处为指令
D——-解析光标处为数据(每按一次转换长度)
G——-快速跟进
H——-十进制与十六进制转换
K——-将数据解释为栈变量
;——-添加注释
M——-解释为枚举成员
N——-重命
作者:堕落天才
1,SSDT
SSDT即系统服务描述符表,它的结构如下(参考《Undocument Windows 2000 Secretes》第二章):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | typedef struct _SYSTEM_SERVICE_TABLE { PVOID ServiceTableBase; //这个指向系统服务函数地址表 PULONG ServiceCounterTableBase; ULONG NumberOfService; //服务函数的个数,NumberOfService*4 就是整个地址表的大小 ULONG ParamTableBase; }SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE; typedef struct _SERVICE_DESCRIPTOR_TABLE { SYSTEM_SERVICE_TABLE ntoskrnel; //ntoskrnl.exe的服务函数 SYSTEM_SERVICE_TABLE win32k; //win32k.sys的服务函数,(gdi.dll/user.dll的内核支持) SYSTEM_SERVICE_TABLE NotUsed1; SYSTEM_SERVICE_TABLE NotUsed2; }SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE; |
内核中有两个系统服务描述符表,一个是KeServiceDescriptorTable(由ntoskrnl.exe导出),一个是KeServieDescriptorTableShadow(没有导出)。两者的区别是,KeServiceDescriptorTable仅有ntoskrnel一项,KeServieDescriptorTableShadow包含了ntoskrn