-
-
[原创][win内核学习笔记]过写拷贝实现所有进程API HOOK----shellcode实现
-
发表于: 2022-11-7 16:42 16686
-
windows xp
wdk7600
2-9-9-12分页
替换MessageBoxA的第二个参数
1.在R0层申请一块内存,用来放置shellcode
2.R3修改shellcode的页属性+us、+rw,写入shellcode,shellcode末尾的代码需要还原MessageBoxA的指令
3.创建中断门,负责在调用shellcode之前提权修改shellcode页属性+us,-NX
4.R3修改MessageBoxA的页属性+us、+rw
5.R3对MessageBoxA进行inlineHook
替换4条指令(12个字节):
测试程序:
运行主程序:
运行测试程序:
调试测试程序看看指令:
其中 CD 20 是 int 20h
继续运行主程序,取消hook:
运行测试程序:
看到代码已还原:
R3
R0
__shellcode:
/
/
int
3
mov eax, __end
mov[esp
+
0xc
], eax
pop eax
/
*
.text:
77D507EA
8B
FF mov edi, edi
.text:
77D507EC
55
push ebp
.text:
77D507ED
8B
EC mov ebp, esp
.text:
77D507EF
83
3D
BC
14
D7
77
00
cmp
_gfEMIEnable,
0
*
/
_emit
0x8B
_emit
0xFF
_emit
0x55
_emit
0x8B
_emit
0xEC
_emit
0x83
_emit
0x3D
_emit
0xBC
_emit
0x14
_emit
0xD7
_emit
0x77
_emit
0x00
jmp eax
__end :
__shellcode:
/
/
int
3
mov eax, __end
mov[esp
+
0xc
], eax
pop eax
/
*
.text:
77D507EA
8B
FF mov edi, edi
.text:
77D507EC
55
push ebp
.text:
77D507ED
8B
EC mov ebp, esp
.text:
77D507EF
83
3D
BC
14
D7
77
00
cmp
_gfEMIEnable,
0
*
/
_emit
0x8B
_emit
0xFF
_emit
0x55
_emit
0x8B
_emit
0xEC
_emit
0x83
_emit
0x3D
_emit
0xBC
_emit
0x14
_emit
0xD7
_emit
0x77
_emit
0x00
jmp eax
__end :
int
0
/
/
0
替换成步骤
3
的中断门
nop
mov eax,
0DEADBEEFh
/
/
地址替换成shellcode的地址
call eax
nop
nop
int
0
/
/
0
替换成步骤
3
的中断门
nop
mov eax,
0DEADBEEFh
/
/
地址替换成shellcode的地址
call eax
nop
nop
int
main()
{
MessageBoxA(
0
,
"123"
,
"456"
,
0
);
return
0
;
}
int
main()
{
MessageBoxA(
0
,
"123"
,
"456"
,
0
);
return
0
;
}
/
/
main.cpp
#include "Driver.h"
#include <stdio.h>
#include <windows.h>
int
main(
int
argc, char
*
argv[])
{
Driver d;
if
(!d.loadDriver())
{
system(
"pause"
);
return
0
;
}
printf(
"loadDriver suc\n"
);
int
a
=
*
(
int
*
)MessageBoxA;
printf(
"MessageBoxA: %08x\n"
, a);
auto pShellCode
=
d.AllocMemory();
if
(NULL
=
=
pShellCode)
{
printf(
"AllocMemory error\n"
);
system(
"pause"
);
return
0
;
}
printf(
"pMem:0x%08x\n"
, pShellCode);
d.ChangeMemoryAttr(pShellCode);
printf(
"pMem: %s\n"
, pShellCode);
char
*
pShellCodeBegin
=
NULL;
char
*
pShellCodeEnd
=
NULL;
_asm
{
mov eax, __shellcode
mov pShellCodeBegin, eax
mov eax, __end
mov pShellCodeEnd, eax
jmp __end
__shellcode:
/
/
int
3
mov eax, __end
mov[esp
+
0xc
], eax
pop eax
/
*
.text:
77D507EA
8B
FF mov edi, edi
.text:
77D507EC
55
push ebp
.text:
77D507ED
8B
EC mov ebp, esp
.text:
77D507EF
83
3D
BC
14
D7
77
00
cmp
_gfEMIEnable,
0
*
/
_emit
0x8B
_emit
0xFF
_emit
0x55
_emit
0x8B
_emit
0xEC
_emit
0x83
_emit
0x3D
_emit
0xBC
_emit
0x14
_emit
0xD7
_emit
0x77
_emit
0x00
jmp eax
__end :
}
memcpy(pShellCode, pShellCodeBegin, pShellCodeEnd
-
pShellCodeBegin);
memcpy(pShellCode, pShellCodeBegin, pShellCodeEnd
-
pShellCodeBegin);
char
*
str_pos
=
pShellCode
+
(pShellCodeEnd
-
pShellCodeBegin);
memcpy(str_pos,
"hack"
,
5
);
memcpy(pShellCode
+
1
, &str_pos,
4
);
char intGate
=
d.CreateIntGate();
printf(
"intGate:%d\n"
, intGate);
d.ChangeMemoryAttr(MessageBoxA);
char hook[]
=
{
"\xCD\x00\x90\xB8\xEF\xBE\xAD\xDE\xFF\xD0\x90\x90"
};
hook[
1
]
=
intGate;
memcpy(MessageBoxA, hook,
12
);
memcpy((char
*
)MessageBoxA
+
4
, &pShellCode,
4
);
/
/
__debugbreak();
system(
"pause"
);
char MsgBox_old[]
=
{
"\x8B\xFF\x55\x8B\xEC\x83\x3D\xBC\x14\xD7\x77\x00"
};
memcpy(MessageBoxA, MsgBox_old,
12
);
printf(
"已还原\n"
);
system(
"pause"
);
return
0
;
}
/
/
main.cpp
#include "Driver.h"
#include <stdio.h>
#include <windows.h>
int
main(
int
argc, char
*
argv[])
{
Driver d;
if
(!d.loadDriver())
{
system(
"pause"
);
return
0
;
}
printf(
"loadDriver suc\n"
);
int
a
=
*
(
int
*
)MessageBoxA;
printf(
"MessageBoxA: %08x\n"
, a);
auto pShellCode
=
d.AllocMemory();
if
(NULL
=
=
pShellCode)
{
printf(
"AllocMemory error\n"
);
system(
"pause"
);
return
0
;
}
printf(
"pMem:0x%08x\n"
, pShellCode);
d.ChangeMemoryAttr(pShellCode);
printf(
"pMem: %s\n"
, pShellCode);
char
*
pShellCodeBegin
=
NULL;
char
*
pShellCodeEnd
=
NULL;
_asm
{
mov eax, __shellcode
mov pShellCodeBegin, eax
mov eax, __end
mov pShellCodeEnd, eax
jmp __end
__shellcode:
/
/
int
3
mov eax, __end
mov[esp
+
0xc
], eax
pop eax
/
*
.text:
77D507EA
8B
FF mov edi, edi
.text:
77D507EC
55
push ebp
.text:
77D507ED
8B
EC mov ebp, esp
.text:
77D507EF
83
3D
BC
14
D7
77
00
cmp
_gfEMIEnable,
0
*
/
_emit
0x8B
_emit
0xFF
_emit
0x55
_emit
0x8B
_emit
0xEC
_emit
0x83
_emit
0x3D
_emit
0xBC
_emit
0x14
_emit
0xD7
_emit
0x77
_emit
0x00
jmp eax
__end :
}
memcpy(pShellCode, pShellCodeBegin, pShellCodeEnd
-
pShellCodeBegin);
memcpy(pShellCode, pShellCodeBegin, pShellCodeEnd
-
pShellCodeBegin);
char
*
str_pos
=
pShellCode
+
(pShellCodeEnd
-
pShellCodeBegin);
memcpy(str_pos,
"hack"
,
5
);
memcpy(pShellCode
+
1
, &str_pos,
4
);
char intGate
=
d.CreateIntGate();
printf(
"intGate:%d\n"
, intGate);
d.ChangeMemoryAttr(MessageBoxA);
char hook[]
=
{
"\xCD\x00\x90\xB8\xEF\xBE\xAD\xDE\xFF\xD0\x90\x90"
};
hook[
1
]
=
intGate;
memcpy(MessageBoxA, hook,
12
);
memcpy((char
*
)MessageBoxA
+
4
, &pShellCode,
4
);
/
/
__debugbreak();
system(
"pause"
);
char MsgBox_old[]
=
{
"\x8B\xFF\x55\x8B\xEC\x83\x3D\xBC\x14\xD7\x77\x00"
};
memcpy(MessageBoxA, MsgBox_old,
12
);
printf(
"已还原\n"
);
system(
"pause"
);
return
0
;
}
/
/
Driver.h
#pragma once
#include "../xpDrv1/SysDefine.h"
class
Driver
{
public:
bool
loadDriver();
~Driver();
short CreateCallGate(CREATE_CALL_GATE
*
data);
char CreateIntGate();
char
*
AllocMemory();
bool
ChangeMemoryAttr(const void
*
data);
};
/
/
Driver.h
#pragma once
#include "../xpDrv1/SysDefine.h"
class
Driver
{
public:
bool
loadDriver();
~Driver();
short CreateCallGate(CREATE_CALL_GATE
*
data);
char CreateIntGate();
char
*
AllocMemory();
bool
ChangeMemoryAttr(const void
*
data);
};
/
/
Driver.cpp
#include "Driver.h"
#include <Windows.h>
#include <stdio.h>
bool
Driver::loadDriver()
{
auto h
=
OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if
(NULL
=
=
h)
{
printf(
"OpenSCManagerA error:%d\n"
, GetLastError());
return
false;
}
char path[
260
]
=
{
0
};
GetFullPathNameA(
"main.sys"
,
260
, path, NULL);
printf(
"sys path:%s\n"
, path);
auto service
=
CreateServiceA(
h,
"12345"
,
"678910"
, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE, path, NULL, NULL, NULL, NULL, NULL);
if
(NULL
=
=
service)
{
CloseServiceHandle(h);
DeleteService(service);
printf(
"CreateServiceA error:%d\n"
, GetLastError());
return
false;
}
if
(!StartService(service, NULL, NULL))
{
DWORD dwErr
=
GetLastError();
if
(dwErr !
=
ERROR_SERVICE_ALREADY_RUNNING)
{
printf(
"运行驱动服务失败, %d\n"
, dwErr);
return
false;
}
}
CloseServiceHandle(service);
CloseServiceHandle(h);
return
true;
}
Driver::~Driver()
{
SC_HANDLE hServiceMgr
=
OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hServiceDDK
=
OpenServiceA(hServiceMgr,
"12345"
, SERVICE_ALL_ACCESS);
SERVICE_STATUS SvrStatus;
ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrStatus);
DeleteService(hServiceDDK);
if
(hServiceDDK)
{
CloseServiceHandle(hServiceDDK);
}
if
(hServiceMgr)
{
CloseServiceHandle(hServiceMgr);
}
}
short Driver::CreateCallGate(CREATE_CALL_GATE
*
data)
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
0
;
}
USHORT CallGateDescriptor
=
0
;
/
/
调用门选择子
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_CREATE_CALL_GATE,
data,
sizeof(CREATE_CALL_GATE),
&CallGateDescriptor,
sizeof(USHORT),
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
}
CloseHandle(hDevice);
if
(dwRetBytes !
=
2
|| CallGateDescriptor
=
=
0
)
{
printf(
"构造调用门失败.\n"
);
return
0
;
}
return
CallGateDescriptor;
}
char Driver::CreateIntGate()
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
NULL;
}
char Ret
=
0
;
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_CREATE_INT_GATE,
NULL,
0
,
&Ret,
sizeof(Ret),
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
CloseHandle(hDevice);
return
NULL;
}
CloseHandle(hDevice);
return
Ret;
}
char
*
Driver::AllocMemory()
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
NULL;
}
char
*
pRet
=
NULL;
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_AllOC_SHELLCODE_MEMORY,
NULL,
0
,
&pRet,
sizeof(pRet),
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
CloseHandle(hDevice);
return
NULL;
}
CloseHandle(hDevice);
return
pRet;
}
bool
Driver::ChangeMemoryAttr(const void
*
data)
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
false;
}
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_CHANGE_MEMORY_ATTR,
&data,
sizeof(data),
NULL,
0
,
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
CloseHandle(hDevice);
return
false;
}
CloseHandle(hDevice);
return
true;
}
/
/
Driver.cpp
#include "Driver.h"
#include <Windows.h>
#include <stdio.h>
bool
Driver::loadDriver()
{
auto h
=
OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if
(NULL
=
=
h)
{
printf(
"OpenSCManagerA error:%d\n"
, GetLastError());
return
false;
}
char path[
260
]
=
{
0
};
GetFullPathNameA(
"main.sys"
,
260
, path, NULL);
printf(
"sys path:%s\n"
, path);
auto service
=
CreateServiceA(
h,
"12345"
,
"678910"
, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE, path, NULL, NULL, NULL, NULL, NULL);
if
(NULL
=
=
service)
{
CloseServiceHandle(h);
DeleteService(service);
printf(
"CreateServiceA error:%d\n"
, GetLastError());
return
false;
}
if
(!StartService(service, NULL, NULL))
{
DWORD dwErr
=
GetLastError();
if
(dwErr !
=
ERROR_SERVICE_ALREADY_RUNNING)
{
printf(
"运行驱动服务失败, %d\n"
, dwErr);
return
false;
}
}
CloseServiceHandle(service);
CloseServiceHandle(h);
return
true;
}
Driver::~Driver()
{
SC_HANDLE hServiceMgr
=
OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hServiceDDK
=
OpenServiceA(hServiceMgr,
"12345"
, SERVICE_ALL_ACCESS);
SERVICE_STATUS SvrStatus;
ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrStatus);
DeleteService(hServiceDDK);
if
(hServiceDDK)
{
CloseServiceHandle(hServiceDDK);
}
if
(hServiceMgr)
{
CloseServiceHandle(hServiceMgr);
}
}
short Driver::CreateCallGate(CREATE_CALL_GATE
*
data)
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
0
;
}
USHORT CallGateDescriptor
=
0
;
/
/
调用门选择子
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_CREATE_CALL_GATE,
data,
sizeof(CREATE_CALL_GATE),
&CallGateDescriptor,
sizeof(USHORT),
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
}
CloseHandle(hDevice);
if
(dwRetBytes !
=
2
|| CallGateDescriptor
=
=
0
)
{
printf(
"构造调用门失败.\n"
);
return
0
;
}
return
CallGateDescriptor;
}
char Driver::CreateIntGate()
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
NULL;
}
char Ret
=
0
;
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_CREATE_INT_GATE,
NULL,
0
,
&Ret,
sizeof(Ret),
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
CloseHandle(hDevice);
return
NULL;
}
CloseHandle(hDevice);
return
Ret;
}
char
*
Driver::AllocMemory()
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
NULL;
}
char
*
pRet
=
NULL;
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_AllOC_SHELLCODE_MEMORY,
NULL,
0
,
&pRet,
sizeof(pRet),
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
CloseHandle(hDevice);
return
NULL;
}
CloseHandle(hDevice);
return
pRet;
}
bool
Driver::ChangeMemoryAttr(const void
*
data)
{
HANDLE hDevice
=
CreateFileW(
DRIVER_LINK,
GENERIC_READ | GENERIC_WRITE,
0
,
0
,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if
(hDevice
=
=
INVALID_HANDLE_VALUE)
{
printf(
"CreateFileW error %d\n"
, GetLastError());
return
false;
}
DWORD dwRetBytes;
/
/
返回的字节数
if
(!DeviceIoControl(
hDevice,
IOCTL_CHANGE_MEMORY_ATTR,
&data,
sizeof(data),
NULL,
0
,
&dwRetBytes,
NULL))
{
printf(
"DeviceIoControl error %d\n"
, GetLastError());
CloseHandle(hDevice);
return
false;
}
CloseHandle(hDevice);
return
true;
}
/
/
driverMain.cpp
#include <ntddk.h>
#include "SysDefine.h"
#include "DriverDebugPrinter.h"
PDEVICE_OBJECT pDeviceObj
=
NULL;
/
/
设备对象指针
PVOID pShellCodeBuffer
=
NULL;
SHORT idt_index
=
0
;
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
UNREFERENCED_PARAMETER(pDriver);
DIRVER_PRINT_DEBUG_STRING(
"DriverUnload\n"
);
ExFreePool(pShellCodeBuffer);
UNICODE_STRING SymbolicLinkName;
/
/
符号链接名,
3
环用
RtlInitUnicodeString(&SymbolicLinkName, DRIVER_LINKD);
IoDeleteSymbolicLink(&SymbolicLinkName);
IoDeleteDevice(pDeviceObj);
}
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
LONG
SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
}LDR_DATA_TABLE_ENTRY,
*
PLDR_DATA_TABLE_ENTRY;
NTSTATUS OnCreateCallGate(char
*
data, ULONG inSize, ULONG_PTR
*
outSize)
{
CREATE_CALL_GATE arg;
RtlCopyMemory(&arg, data, inSize);
DIRVER_PRINT_DEBUG_STRING(
"OnCreateCallGate pFunc[0x%x], argc[%d]\n"
, arg.pFunc, arg.argc);
*
outSize
=
0
;
char gdt[
6
];
_asm
{
sgdt gdt
}
PLONG lpgdt
=
*
(PLONG
*
)(gdt
+
2
);
SHORT
len
=
*
(PSHORT)gdt;
DIRVER_PRINT_DEBUG_STRING(
"gdt addr[0x%x] limit[0x%x]\n"
, lpgdt,
len
);
if
(NULL
=
=
lpgdt)
{
return
-
1
;
}
for
(SHORT i
=
2
; i <
len
; i
+
=
2
)
{
if
(
0
=
=
(lpgdt[i
+
1
] &
0x8000
))
{
LONG
hData
=
(
LONG
)arg.pFunc &
0xffff0000
;
hData |
=
0xec00
| arg.argc;
LONG
lData
=
0x80000
| ((
LONG
)arg.pFunc &
0x0000ffff
);
lpgdt[i]
=
lData;
lpgdt[i
+
1
]
=
hData;
SHORT selector
=
(i
/
2
) <<
3
;
DIRVER_PRINT_DEBUG_STRING(
"创建门 gdt[%d] selector[%d] %08x`%08x\n"
, i
/
2
, selector, hData, lData);
RtlCopyMemory(data, &selector, inSize);
*
outSize
=
2
;
return
STATUS_SUCCESS;
}
}
return
-
2
;
}
void OnAddShellCodePage2()
{
ULONG p
=
(ULONG)pShellCodeBuffer &
0xfffff000
;
ULONG PDPTI
=
p >>
30
;
ULONG PDI
=
(p >>
21
) &
0x1ff
;
ULONG PTI
=
(p >>
12
) &
0x1ff
;
ULONG offset
=
p &
0xfff
;
DIRVER_PRINT_DEBUG_STRING(
"p = 0x%08x\n"
"PDPTI = 0x%x\n"
"PDI = 0x%x\n"
"PTI = 0x%x\n"
"offset = 0x%x\n"
,
p, PDPTI, PDI, PTI, offset
);
/
/
公式:
/
/
pPDE
=
0xc0600000
+
(PDPTI
*
4KB
)
+
(PDI
*
8
)
/
/
pPTE
=
0xc0000000
+
(PDPTI
*
2MB
)
+
(PDI
*
4KB
)
+
(PTI
*
8
)
/
/
更高效的公式(MmIsAddressValid是这么干的)
/
/
pPDE
=
0xc0600000
+
((addr >>
18
) &
0x3ff8
)
/
/
pPTE
=
0xc0000000
+
((addr >>
9
) &
0x7ffff8
)
PULONG pPDE
=
(PULONG)(
0xC0600000
+
PDPTI
*
0x1000
+
PDI
*
8
);
DIRVER_PRINT_DEBUG_STRING(
"PDE: %08x`%08x\n"
, pPDE[
1
], pPDE[
0
]);
pPDE[
1
]
=
pPDE[
1
] &
0x7fffffff
;
/
/
NX置
0
pPDE[
0
]
=
pPDE[
0
] &
0xfffffffb
;
pPDE[
0
]
=
pPDE[
0
] |
0x4
;
/
/
us位置
1
DIRVER_PRINT_DEBUG_STRING(
"PDE: %08x`%08x\n"
, pPDE[
1
], pPDE[
0
]);
if
(
0x80
=
=
(pPDE[
0
] &
0x80
))
{
DIRVER_PRINT_DEBUG_STRING(
"Large page\n"
);
}
else
{
PULONG pPTE
=
(PULONG)(
0xc0000000
+
PDPTI
*
0x200000
+
PDI
*
0x1000
+
PTI
*
8
);
DIRVER_PRINT_DEBUG_STRING(
"pPTE: %08x`%08x\n"
, pPTE[
1
], pPTE[
0
]);
pPTE[
1
]
=
pPTE[
1
] &
0x7fffffff
;
/
/
NX置
0
pPTE[
0
]
=
pPTE[
0
] &
0xfffffffb
;
pPTE[
0
]
=
pPTE[
0
] |
0x4
;
/
/
us位置
1
DIRVER_PRINT_DEBUG_STRING(
"pPTE: %08x`%08x\n"
, pPTE[
1
], pPTE[
0
]);
}
}
void __declspec(naked)OnAddShellCodePage()
{
__asm
{
pushad;
pushfd;
push fs;
}
OnAddShellCodePage2();
__asm
{
pop fs;
popfd;
popad;
iretd;
}
}
NTSTATUS OnCreateIntGate(char
*
data, ULONG inSize, ULONG_PTR
*
outSize)
{
*
outSize
=
0
;
if
(
0
!
=
idt_index)
{
*
outSize
=
1
;
RtlCopyMemory(data, &idt_index,
*
outSize);
return
STATUS_SUCCESS;
}
char idt[
6
];
_asm
{
sidt idt
}
PLONG lpidt
=
*
(PLONG
*
)(idt
+
2
);
SHORT
len
=
*
(PSHORT)idt;
DIRVER_PRINT_DEBUG_STRING(
"gdt addr[0x%x] limit[0x%x]\n"
, lpidt,
len
);
if
(NULL
=
=
lpidt)
{
return
-
1
;
}
LONG
hData
=
(
LONG
)OnAddShellCodePage &
0xffff0000
;
hData |
=
0xee00
;
LONG
lData
=
0x80000
| ((
LONG
)OnAddShellCodePage &
0x0000ffff
);
lpidt[
32
*
2
]
=
lData;
lpidt[
32
*
2
+
1
]
=
hData;
idt_index
=
32
;
DIRVER_PRINT_DEBUG_STRING(
"创建中断门 index[%d] %08x`%08x\n"
, idt_index, hData, lData);
*
outSize
=
1
;
RtlCopyMemory(data, &idt_index,
*
outSize);
return
STATUS_SUCCESS;
}
NTSTATUS OnAllocShellCodeMemory(char
*
data, ULONG inSize, ULONG_PTR
*
outSize)
{
DIRVER_PRINT_DEBUG_STRING(
"OnAllocMemory\n"
);
*
outSize
=
0
;
if
(NULL
=
=
pShellCodeBuffer)
{
pShellCodeBuffer
=
ExAllocatePoolWithTag(NonPagedPool,
0x1000
,
'ABCD'
);
if
(NULL
=
=
pShellCodeBuffer)
{
DIRVER_PRINT_DEBUG_STRING(
"ExAllocatePoolWithTag error\n"
);
return
-
1
;
}
RtlCopyMemory(pShellCodeBuffer,
"1234deadbeef"
,
13
);
}
*
outSize
=
sizeof(pShellCodeBuffer);
RtlCopyMemory(data, &pShellCodeBuffer,
*
outSize);
DIRVER_PRINT_DEBUG_STRING(
"pbuffer:0x%08x data:%08x\n"
, pShellCodeBuffer, data);
return
STATUS_SUCCESS;
}
NTSTATUS OnChangeMemoryAttr(char
*
data, ULONG inSize, ULONG_PTR
*
outSize)
{
*
outSize
=
0
;
ULONG p
=
NULL;
RtlCopyMemory(&p, data, sizeof(p));
if
(NULL
=
=
p)
{
DIRVER_PRINT_DEBUG_STRING(
"NULL == p\n"
);
return
-
1
;
}
p &
=
0xfffff000
;
ULONG PDPTI
=
p >>
30
;
ULONG PDI
=
(p >>
21
) &
0x1ff
;
ULONG PTI
=
(p >>
12
) &
0x1ff
;
ULONG offset
=
p &
0xfff
;
DIRVER_PRINT_DEBUG_STRING(
"p = 0x%08x\n"
"PDPTI = 0x%x\n"
"PDI = 0x%x\n"
"PTI = 0x%x\n"
"offset = 0x%x\n"
,
p, PDPTI, PDI, PTI, offset
);
/
/
公式:
/
/
pPDE
=
0xc0600000
+
(PDPTI
*
4KB
)
+
(PDI
*
8
)
/
/
pPTE
=
0xc0000000
+
(PDPTI
*
2MB
)
+
(PDI
*
4KB
)
+
(PTI
*
8
)
/
/
更高效的公式(MmIsAddressValid是这么干的)
/
/
pPDE
=
0xc0600000
+
((addr >>
18
) &
0x3ff8
)
/
/
pPTE
=
0xc0000000
+
((addr >>
9
) &
0x7ffff8
)
PULONG pPDE
=
(PULONG)(
0xC0600000
+
PDPTI
*
0x1000
+
PDI
*
8
);
DIRVER_PRINT_DEBUG_STRING(
"PDE: %08x`%08x\n"
, pPDE[
1
], pPDE[
0
]);
pPDE[
1
]
=
pPDE[
1
] &
0x7fffffff
;
/
/
NX置
0
pPDE[
0
]
=
pPDE[
0
] &
0xfffffffb
;
pPDE[
0
]
=
pPDE[
0
] |
0x6
;
/
/
us,rw位置
1
DIRVER_PRINT_DEBUG_STRING(
"PDE: %08x`%08x\n"
, pPDE[
1
], pPDE[
0
]);
if
(
0x80
=
=
(pPDE[
0
] &
0x80
))
{
DIRVER_PRINT_DEBUG_STRING(
"Large page\n"
);
}
else
{
PULONG pPTE
=
(PULONG)(
0xc0000000
+
PDPTI
*
0x200000
+
PDI
*
0x1000
+
PTI
*
8
);
DIRVER_PRINT_DEBUG_STRING(
"pPTE: %08x`%08x\n"
, pPTE[
1
], pPTE[
0
]);
pPTE[
1
]
=
pPTE[
1
] &
0x7fffffff
;
pPTE[
0
]
=
pPTE[
0
] &
0xfffffffb
;
pPTE[
0
]
=
pPTE[
0
] |
0x6
;
/
/
us,rw位置
1
DIRVER_PRINT_DEBUG_STRING(
"pPTE: %08x`%08x\n"
, pPTE[
1
], pPTE[
0
]);
}
return
STATUS_SUCCESS;
}
NTSTATUS OnMessage(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack
=
IoGetCurrentIrpStackLocation(Irp);
if
(IRP_MJ_DEVICE_CONTROL
=
=
irpStack
-
>MajorFunction)
{
static struct
{
ULONG
id
;
NTSTATUS(
*
callback)(char
*
pData, ULONG lenth, ULONG_PTR
*
);
}CallBackMap[]
=
{
{IOCTL_CREATE_CALL_GATE, OnCreateCallGate},
{IOCTL_AllOC_SHELLCODE_MEMORY, OnAllocShellCodeMemory},
{IOCTL_CHANGE_MEMORY_ATTR, OnChangeMemoryAttr},
{IOCTL_CREATE_INT_GATE, OnCreateIntGate},
};
for
(
int
i
=
0
; i < sizeof(CallBackMap)
/
sizeof(CallBackMap[
0
]);
+
+
i)
{
if
(CallBackMap[i].
id
=
=
irpStack
-
>Parameters.DeviceIoControl.IoControlCode)
{
Irp
-
>IoStatus.Status
=
CallBackMap[i].callback(
(char
*
)Irp
-
>AssociatedIrp.SystemBuffer,
irpStack
-
>Parameters.DeviceIoControl.InputBufferLength,
&Irp
-
>IoStatus.Information);
break
;
}
}
}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_SUCCESS;
}
/
/
IRP_MJ_CREATE 处理函数
NTSTATUS IrpCreateProc(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
/
/
DbgPrint(
"应用层连接设备.\n"
);
/
/
返回状态如果不设置,Ring3返回值是失败
pIrp
-
>IoStatus.Status
=
STATUS_SUCCESS;
pIrp
-
>IoStatus.Information
=
0
;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return
STATUS_SUCCESS;
}
/
/
IRP_MJ_CLOSE 处理函数
NTSTATUS IrpCloseProc(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
/
/
DbgPrint(
"应用层断开连接设备.\n"
);
/
/
返回状态如果不设置,Ring3返回值是失败
pIrp
-
>IoStatus.Status
=
STATUS_SUCCESS;
pIrp
-
>IoStatus.Information
=
0
;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return
STATUS_SUCCESS;
}
extern
"C"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath)
{
UNREFERENCED_PARAMETER(pRegPath);
pDriver
-
>DriverUnload
=
DriverUnload;
pDriver
-
>MajorFunction[IRP_MJ_DEVICE_CONTROL]
=
OnMessage;
pDriver
-
>MajorFunction[IRP_MJ_CREATE]
=
IrpCreateProc;
pDriver
-
>MajorFunction[IRP_MJ_CLOSE]
=
IrpCloseProc;
DIRVER_PRINT_DEBUG_STRING(
"pDriver: 0x%08x\n"
, pDriver);
UNICODE_STRING DeviceName;
/
/
设备名,
0
环用
RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
auto status
=
IoCreateDevice(pDriver,
0
, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObj);
if
(status !
=
STATUS_SUCCESS)
{
IoDeleteDevice(pDeviceObj);
DIRVER_PRINT_DEBUG_STRING(
"创建设备失败 0x%08x.\n"
, status);
return
status;
}
UNICODE_STRING SymbolicLinkName;
/
/
符号链接名,
3
环用
RtlInitUnicodeString(&SymbolicLinkName, DRIVER_LINKD);
status
=
IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
if
(!NT_SUCCESS(status))
{
DIRVER_PRINT_DEBUG_STRING(
"创建符号失败 0x%08x.\n"
, status);
}
return
STATUS_SUCCESS;
}
/
/
driverMain.cpp
#include <ntddk.h>
#include "SysDefine.h"
#include "DriverDebugPrinter.h"
PDEVICE_OBJECT pDeviceObj
=
NULL;
/
/
设备对象指针
PVOID pShellCodeBuffer
=
NULL;
SHORT idt_index
=
0
;
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2022-11-8 14:33
被洋洋不得意编辑
,原因: 过写拷贝
赞赏记录
参与人
雪币
留言
时间
伟叔叔
为你点赞~
2023-3-18 00:43
一笑人间万事
为你点赞~
2023-1-11 11:24
shishichen
为你点赞~
2023-1-1 15:22
赞赏
他的文章
看原图
赞赏
雪币:
留言: