久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2560|回復: 0
打印 上一主題 下一主題
收起左側(cè)

內(nèi)核編程練習作品->UnSSDTHOOK

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:71922 發(fā)表于 2015-1-10 23:24 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
       前段時間在研究51單片機,花了兩個月的時間,總算是摸熟了單片機的工作方式以及程序設計的方法以及焊接技術的提升。寫程序,時序圖很重要啊...可惜因為資金不足,想做很多實驗都沒法...例如自己想整個語音控制程序,實現(xiàn)通過以說話的方式控制單片機執(zhí)行。也想整個GPS+GPRS,實現(xiàn)追蹤器,也沒錢買相應的硬件。想整個遙控車+攝像頭,實現(xiàn)移動監(jiān)控。也想整個自動導航飛機,實現(xiàn)高空巡邏。.... 錢錢錢...真讓人糾結.....

        所以在沒有穩(wěn)定的工作前,就先暫時放下單片機,復習一下編程知識。這個編程作品,也是在復習的時候,蔣哥想在需要的時候結束幾個隱藏的進程。隱藏進程的實現(xiàn)方法通常都是通過DLL遠程注入的方式,也有RING3 下HOOK相關API。而蔣哥的增值程序采用的是 SSDT HOOK技術(具體請看我的另外一篇《學習筆記 -> HOOK SSDT表的理解(1) 》http://www.zg4o1577.cn/bbs/dpj-30383-1.html  )。那個增值程序僅僅只是HOOK了 NtQuerySystemInformation,修改里它的返回值,所以普通的任務管理器自然就看不到該進程。就幫他整了一個簡單的程序。后來想想,他在網(wǎng)吧工作,所以可能會有別的需要,所以索性就改進成通用版的,可以恢復指定被HOOK 的NtAPI。方便他用批處理器調(diào)用,也算是自己的第一個內(nèi)核驅(qū)動編程作品吧。

      恢復比HOOK要簡單多。只需要把被修改的地址改回原來的即可。留下驅(qū)動代碼供日后自己復習用:

GetAPI_Addr.h :用來獲取原始API地址和被修改的API地址
======================================================================================================
typedef struct _ServiceDescriptorTable
{
PVOID ServiceTableBase;// SSDT 基地址
PVOID ServiceCounterTable;// 包含SSDT中每個服務被調(diào)用次數(shù)的計數(shù)器,一般由sysenter更新
unsigned int NumberOfServices;// 由ServiceTableBase 描述的服務的數(shù)目
PVOID ParamTableBase;// 包含每個系統(tǒng)服務參數(shù)字節(jié)數(shù)表的基地址-系統(tǒng)服務參數(shù)表
}*PServiceDescriptorTable;

extern PServiceDescriptorTable KeServiceDescriptorTable;        // 導出

#pragma PAGECODE
// 獲取當前Nt函數(shù)的地址
ULONG GetNt_DQ_Addr(int PianYi_Addr)
{
LONG SSDT_Addr, NtAPI_Addr, *t_addr;

// 讀取SSDT基地址
SSDT_Addr = (LONG)KeServiceDescriptorTable->ServiceTableBase;

// 根據(jù)SSDT基址確定存放指定Nt函數(shù)的地址位置
t_addr = (PLONG)(SSDT_Addr+PianYi_Addr*4);

// 取出Nt函數(shù)的地址
NtAPI_Addr = *t_addr;

return NtAPI_Addr;
}
#pragma PAGECODE
// 獲取原來的Nt函數(shù)的地址
ULONG GetNt_YL_Addr(WCHAR NtAPIName[])
{
UNICODE_STRING YL_NtAPI;
ULONG YL_NtAPI_Addr;

RtlInitUnicodeString(&YL_NtAPI, NtAPIName);

// 讀取原來的地址
YL_NtAPI_Addr = (ULONG)MmGetSystemRoutineAddress(&YL_NtAPI);

return YL_NtAPI_Addr;

}

//UnHook函數(shù)構建
//////////////////////////////////////////////////////
#pragma PAGECODE
VOID UnHook(int PianYi_Addr, ULONG YL_Nt_Addr)
{
ULONG  SSDT_Nt_Addr;
SSDT_Nt_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + PianYi_Addr * 4;

/*修改 cr0 寄存器,關閉寫保護*/
__asm
{
cli
mov     eax, cr0
and     eax, not 10000h
mov     cr0, eax
}

// 還原SSDT
*((ULONG*)SSDT_Nt_Addr) = YL_Nt_Addr;

/*恢復寫保護*/
__asm
{
mov     eax, cr0
or     eax, 10000h
mov     cr0, eax
sti
}

return;
}

main.h
======================================================================================================
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>         //這里包含需要用C方式編譯的頭文件
        #include "GetAPI_Addr.h"
#ifdef __cplusplus
}
#endif

#include <windef.h>

#define INITCODE code_seg("INIT")
#define PAGECODE code_seg("PAGE") /*表示內(nèi)存不足時,可以被置換到硬盤*/

// 定義宏,用來判斷應用程序傳遞下來的數(shù)據(jù)。應用程序也需要相應的宏定義
#define UHook CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED,FILE_ANY_ACCESS)

VOID DDK_Unload (IN PDRIVER_OBJECT pDriverObject); //前置說明 卸載例程
NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp);//派遣函數(shù)

// 創(chuàng)建設備
#pragma INITCODE /*指的代碼運行后 就從內(nèi)存釋放掉*/
NTSTATUS CreateMyDevice (IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;/*用來返回創(chuàng)建設備*/

//創(chuàng)建設備名稱
UNICODE_STRING devName;
UNICODE_STRING symLinkName; //
RtlInitUnicodeString(&devName,L"\\Device\\L_Device");/*對devName初始化字串為 "\\Device\\L_Device"*/

//創(chuàng)建設備
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(("設備創(chuàng)建失敗...++++++++"));
return status;
}
KdPrint(("設備創(chuàng)建成功...++++++++"));

pDevObj->Flags |= DO_BUFFERED_IO;


RtlInitUnicodeString(&symLinkName,L"\\??\\LoveMengx_UnSSDTHOOK_Driver");// 初始化
status = IoCreateSymbolicLink( &symLinkName,&devName );// 創(chuàng)建符號鏈接
if (!NT_SUCCESS(status)) /*status等于0*/
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}

main.cpp
======================================================================================================#include "main.h"
#pragma  INITCODE

// 此函數(shù)形同應用程序的main()函數(shù)
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING B) //TYPEDEF LONG NTSTATUS
{  

//注冊派遣函數(shù)
pDriverObject->MajorFunction[IRP_MJ_CREATE]=DispatchRoutine; //IRP_MJ_CREATE相關IRP處理函數(shù)
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=DispatchRoutine; //IRP_MJ_CREATE相關IRP處理函數(shù)
pDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRoutine; //IRP_MJ_CREATE相關IRP處理函數(shù)
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=DispatchRoutine; //IRP_MJ_CREATE相關IRP處理函數(shù)
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchRoutine; //IRP_MJ_CREATE相關IRP處理函數(shù)

CreateMyDevice(pDriverObject);//創(chuàng)建相應的設備

pDriverObject->DriverUnload=DDK_Unload;        // 指定卸載驅(qū)動的時候要執(zhí)行的函數(shù) 如果未指定則無法卸載

return (1);
}

// 卸載驅(qū)動的時候必須提供,否則無法卸載
#pragma PAGECODE
VOID DDK_Unload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pDev;//用來取得要刪除設備對象
UNICODE_STRING symLinkName; //

pDev=pDriverObject->DeviceObject;
IoDeleteDevice(pDev); //刪除設備

//取符號鏈接名字
RtlInitUnicodeString(&symLinkName,L"\\??\\LoveMengx_UnSSDTHOOK_Driver");
//刪除符號鏈接
IoDeleteSymbolicLink(&symLinkName);
KdPrint(("驅(qū)動成功被卸載...OK-----------")); //sprintf,printf

}

/* 不知道為什么 atoi 在驅(qū)動中無法使用 就只能用這個替代 */
int my_atoi(const char* p)
{
bool neg_flag = false;// 符號標記
int res = 0;// 結果
if(p[0] == '+' || p[0] == '-')
neg_flag = (*p++ != '+');
while(isdigit(*p)) res = res*10 + (*p++ - '0');
return neg_flag ?0 -res : res;
}


#pragma PAGECODE
NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp)
{   //
ULONG info = 0;

//得到當前棧指針
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

ULONG mf=stack->MajorFunction;        //區(qū)分IRP
switch (mf)
{
case IRP_MJ_DEVICE_CONTROL:
{
KdPrint(("Enter myDriver_DeviceIOControl\n"));
NTSTATUS status = STATUS_SUCCESS;

//得到輸入緩沖區(qū)大小
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
//得到輸出緩沖區(qū)大小
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
//得到IOCTL碼
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;

switch (code)                // 通過 code分析
{
case UHook:        // 如果是自己的定義的消息
{  
char NtAPIName[100] = {0};
char Tmp[100] = {0};
int Index = 0;


                                                        // 取得應用程序傳遞下來的數(shù)據(jù)

char* InputBuffer = (char*)pIrp->AssociatedIrp.SystemBuffer;
char* OutputBuffer = (char*)pIrp->AssociatedIrp.SystemBuffer;

strcpy(NtAPIName, InputBuffer);        
                           
                                                        // 檢查格式。如果格式不對,容易導致藍屏
if (strstr(NtAPIName,"-") && strstr(NtAPIName, "+"))
{

KdPrint(("從應用程序中得到的數(shù)據(jù):%s\n", NtAPIName));

*(strstr(NtAPIName,"-")) = '\0';
Index = my_atoi(NtAPIName);// 分析得到第一個參數(shù) NtAPI 的序號
if(Index >= 0 && Index <=295)
                                {
        strcpy(Tmp, InputBuffer);

        char *Tou = strstr(Tmp, "-")+1;
        Tou = strstr(Tmp, "-") +1;
        *(strstr(Tou,"+")) = '\0';// 分析得到第二個參數(shù) NtAPI 的名字
        
                    KdPrint(("Tou:%s\n", Tou));
                    
        UNICODE_STRING wText;

        ANSI_STRING Name;
        
        RtlInitString(&Name, Tou);// 初始化 Name
        
        RtlAnsiStringToUnicodeString(&wText,&Name, TRUE);// 轉(zhuǎn)換為UNICODE_STRING
        
        ULONG YL_NtAPI = (ULONG)MmGetSystemRoutineAddress(&wText);// 獲取指定的 NtAPI 原始的地址

                                        KdPrint(("YL_NtAPI:0x%X\n", YL_NtAPI));

                                        if(YL_NtAPI > 0x80000000 && YL_NtAPI < 0x90000000)
                                        {
                                                    UnHook(Index, YL_NtAPI);// 恢復 SSDT
                                                    strcpy(Tmp, "OK...");                                                
                                         }
                                         else
                                                    strcpy(Tmp, "獲取NtAPI地址失敗,請檢查NtAPI名。");                                         
                                }
                                else
                                     strcpy(Tmp, "NtAPI的序號超出大小限制。WinXP:0-283 Win2003:0-295");


}
else
strcpy(Tmp, "參數(shù)格式不對。");

KdPrint(("處理結果:%s\n", Tmp));
                            strcpy(OutputBuffer, Tmp);                            // 將數(shù)據(jù)返回至應用層。
info = strlen(Tmp);
break;
}
}
break;
}
case IRP_MJ_CREATE:
break;

case IRP_MJ_CLOSE:
break;

case IRP_MJ_READ:
break;
}

//對相應的IPR進行處理
pIrp->IoStatus.Information=info;//設置操作的字節(jié)數(shù)為0,這里無實際意義
pIrp->IoStatus.Status=STATUS_SUCCESS;//返回成功

IoCompleteRequest(pIrp,IO_NO_INCREMENT);//指示完成此IRP

//KdPrint(("離開派遣函數(shù)\n"));//調(diào)試信息

return STATUS_SUCCESS; //返回成功
}

==========================================================================================
程序下載地址: SSDT_UnHOOK.rar (19.35 KB, 下載次數(shù): 4)

調(diào)用方法:

UnSSDTHOOK [ID]-[NtAPI]+

ID:SSDT表中函數(shù)服務號

NtAPI:函數(shù)名字

通過XueTr可以知道有那些API被HOOK,ID就是
里面的序號。NtAPI就是函數(shù)的名字。

例如:UnSSDTHOOK 122-NtOpenProcess+

注意,在執(zhí)行前需要確定序號與函數(shù)名是相對應的。

可以通過批處理(.bat),循環(huán)調(diào)用,也可以自己寫程
序調(diào)用。

UnSSDTHOOK 執(zhí)行后會加載驅(qū)動,所以驅(qū)動名字不得修改。
恢復指定的函數(shù)地址后,會自動卸載驅(qū)動。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产高清视频一区 | 国产成人av一区二区三区 | 台湾佬久久 | 美女天天操 | 中文二区 | 亚洲精品一区二区 | 亚洲精品久久久9婷婷中文字幕 | 北条麻妃99精品青青久久主播 | 在线观看av免费 | 综合另类 | 色一阁| 夜夜操天天操 | 国产伦精品一区二区三区精品视频 | 欧美精品久久 | 国产成人久久av免费高清密臂 | 欧美精品一级 | 久久aⅴ乱码一区二区三区 91综合网 | 国产h视频| 男女激情网 | 久久久久久久久久久久久久久久久久久久 | 久久一区二区三区四区五区 | 亚洲一区二区在线电影 | 一区二区三区视频在线观看 | 久久伊人精品 | 美日韩免费 | 国产在线播 | 伊人二区 | 欧美一级二级在线观看 | 91久久精品国产91久久 | 在线国产一区二区 | 欧美中文视频 | 日本精品一区 | 亚洲精品99 | 夜夜草视频 | 国产ts一区| 99精品免费视频 | 国产精品高清一区二区三区 | 97久久久久久久久 | 久久久久国产 | 国产综合网站 | 久草青青草|