ISCC 2012 内核关的一些蛋疼想法

内核关是最蛋疼的一关,需要配置DDK VM 之类的一些东西,调试过程中还很有可能各种蓝屏,而且我的机器也不给力,巨卡无比,所以调试过程中·也是各种阻碍各种死机。


内核关一:

题目给一个内核文件,要求调用此内核文件一个函数来读出密码的长度,其实用笔记本打开后可以看到密码,发现代码很短,挨个试一下,水水的解决了。

内核关二:

这题我纠结了很久,题目要求实现一个windows API HOOK,来隐藏进程。想要详细了解同学可以看这篇文章http://www.cnblogs.com/BoyXiao/archive/2011/09/05/2168115.html

先说一下原理,HOOK 分为 用户态也就是ring3 HOOK与内核态HOOK也就是Ring0 HOOK,这次要用到得是Ring0 HOOK中的SSDK HOOK,

SSDK 全程叫做 System Services Descriptor Table.俗称系统服务描述表,linux中也有一个类似的表叫做system_call_table,SSDK的作用是把Ring3的Win32 API和Ring0

的内核API联系起来。我们只需要修改SSDK数组中的函数地址使它指向我们自己定义的函数,便完成了HOOK。


先来说一下编程过程中用到的知识,

#pragma pack(1)

#pragma pack()

这两句是为了修改数据在内存中的对齐方式,不加也可以。

__declspec(dllimport) 声明了函数为导入函数,是ms自定义的宏,一般在dll文件中使用__declspec(dllexmport),在exe文件中使用__declspec(dllimport)

NTSYSAPI  的定义在winnt.h 中如下,NTSYSAPI这个宏最终还是归结到 __declspec(dllimport)这个宏上

#if (defined(_M_IX86) || defined(_M_IA64) || defined(_M_AMD64)) && !defined(MIDL_PASS)
#define DECLSPEC_IMPORT __declspec(dllimport)
#else
#define DECLSPEC_IMPORT
#endif
#if !defined(_NTSYSTEM_)
#define NTSYSAPI     DECLSPEC_IMPORT
#define NTSYSCALLAPI DECLSPEC_IMPORT
#else
#if (defined(_M_IX86) || defined(_M_IA64) || defined(_M_AMD64)) && !defined(MIDL_PASS)
#define DECLSPEC_IMPORT __declspec(dllimport)
#else
#define DECLSPEC_IMPORT
#endif

NTAPI 的定义在winnt.h中

#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define NTAPI __stdcall
#else
#define _cdecl
#define __cdecl
#define NTAPI
#endif

__stdcall是函数调用约定的一种,主要规定了参数入栈顺序,和堆栈由谁清理。

具体可以看百度百科http://baike.baidu.com/view/1276580.htm

NTSTATUS 在头文件NTSTATUS.h中,一般被定义成long型,用来返回函数执行中的状态。

在修改SSDT之前,需要去除SSDT的写保护,不然会出现访问无效内存之类的蓝屏,去除写保护只要修改控制寄存器CR0就可以了

CR0的16位是WP位,把它置0可以关闭写保护。代码很简单,只可以在RING0权限下运行。

__asm
{
    cli ;    //关中断
    mov eax, cr0
    and  eax, ~0x10000  //and eax,0xfffeffff 
    mov cr0, eax
}

// 恢复写保护
__asm
{
    mov  eax, cr0
    or     eax, 0x10000
    mov  cr0, eax
    sti ;  //开中断
}


获取ZwQuerySystemInformation在SSDT中的方法是这样

PULONG与PUCHAR的定义如下,应该也是微软弄得蛋疼东西

UCHAR == unsigned char,
PUCHAR == unsigned char *,

因为ZwQuerySysteminformation的汇编代码第一句是吧SSDT索引值传入寄存器,

mov eax,0xxxxxxxxxh 其中的立即数便是索引值

这段代码的机器码是5个字节,立即数占了4字节

所以先把函数地址转为char型,后移一个字节,再转成long型,便读取到索引值了·

  *(PULONG)((PUCHAR)ZwQuerySystemInformation+1));


SystemInformClass等于5时,表示请求process信息,之后对process链表的处理很常规,就不再多说了。

#include "ntddk.h"
#pragma pack(1)    //修改数据在内存中的对齐方式
typedef struct ServiceDescriptorEntry {
        unsigned int *ServiceTableBase;
        unsigned int *ServiceCounterTableBase;
        unsigned int NumberOfServices;
        unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t;
#pragma pack()   //还原数据在内存中的对齐方式
unsigned long OldCr0;
__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

typedef struct _SYSTEM_PROCESSES
{
        ULONG                   NextEntryDelta;
        ULONG                   ThreadCount;
        ULONG                   Reserved[6];
        LARGE_INTEGER           CreateTime;
        LARGE_INTEGER           UserTime;
        LARGE_INTEGER           KernelTime;
        UNICODE_STRING          ProcessName;
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;

NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN ULONG SystemInformationClass,
                                  IN PVOID SystemInformation,
                                  IN ULONG SystemInformationLength,
                                  OUT PULONG ReturnLength);

typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(ULONG SystemInformationCLass,
                                             PVOID SystemInformation,
                                             ULONG SystemInformationLength,
                                             PULONG ReturnLength);

ZWQUERYSYSTEMINFORMATION OrgZwQuerySystemInformation;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值