00000000`8003f120
8003f120 00000000`80aaa1aa 00000000`8003f130
8003f130 00000000`8003f138 00000000`8003f140
8003f140 00000000`8003f148 00000000`8003f150
8003f150 00000000`8003f158 00000000`8003f160
目标0x8053E545
写入目标是0x8003f120
#include <iostream>
#include<Windows.h>
char* p;
int i;
void JmpTarget();
void __declspec(naked) IdtEntry() {
p = (char*)0x8003f120;
for (int i = 0; i < 64; i++) {
*p = ((char*)JmpTarget)[i];
p++;
}
__asm {
iretd
}
}
void __declspec(naked) JmpTarget() {
__asm {
mov ecx, 0x23
push 0x30
pop fs
mov ds, cx
mov es, cx
mov ecx, 0x8053E54D
jmp ecx
}
}
void go() {
__asm {
mov eax, 1
int 0x20
}
}
int main()
{
if ((DWORD)IdtEntry != 0x401040) {
printf("wrong addr:%p", IdtEntry);
exit(-1);
}
go();
system("pause");
}
运行之后验证写入成功:
关闭CPU写保护
PTE
可读不可写可执行
mov eax, cr0
and eax, not 10000h
mov cr0, eax
开启CPU写保护
mov eax, cr0
or eax, 10000h
mov cr0, eax
#include <iostream>
#include<Windows.h>
DWORD g_num;
void __declspec(naked) IdtEntry() {
__asm {
mov eax, cr0
and eax, not 10000h
mov cr0, eax
mov al, 0xe9
mov ds : [0x8053E540] , al
mov eax, 0xFFB00BDB
mov ds : [0x8053E541] , eax
mov eax, cr0
or eax, 10000h
mov cr0, eax
test eax, eax
jnz L
mov ds : [0x8003f3f0] , eax
mov g_num, eax
jmp End
L :
mov eax, ds : [0x8003f3f0]
mov g_num, eax
End :
iretd
}
}
void reset() {
__asm {
xor eax.eax
int 0x20
}
}
void go() {
__asm {
mov eax, 1
int 0x20
}
}
int main()
{
if ((DWORD)IdtEntry != 0x401000) {
printf("wrong addr:%p", IdtEntry);
exit(-1);
}
reset();
printf("%d\n", g_num);
while (1) {
go();
Sleep(1000);
printf("%d\n", g_num);
}
system("pause");
}
Hook1:
#include <iostream>
#include<Windows.h>
DWORD g_num;
void __declspec(naked) IdtEntry() {
__asm {
mov eax, cr0
and eax, not 10000h
mov cr0, eax
mov al, 0xe9
mov ds : [0x8053E540] , al
mov eax, 0xFFB00BDB
mov ds : [0x8053E541] , eax
mov eax, cr0
or eax, 10000h
mov cr0, eax
iretd
}
}
void go() {
__asm {
int 0x20
}
}
int main()
{
if ((DWORD)IdtEntry != 0x401040) {
printf("wrong addr:%p", IdtEntry);
exit(-1);
}
printf("%d\n", g_num);
go();
system("pause");
}
查看入口调用次数
在0x8003f3f0地址处查看调用次数
#include <iostream>
#include<Windows.h>
char* p;
int i;
void JmpTarget();
void __declspec(naked) IdtEntry() {
p = (char*)0x8003f120;
for (int i = 0; i < 64; i++) {
*p = ((char*)JmpTarget)[i];
p++;
}
__asm {
iretd
}
}
void __declspec(naked) JmpTarget() {
__asm {
pushad
pushfd
mov eax,ds:[0x8003f3f0]
inc eax
mov ds:[0x8003f3f0],eax
popfd
popad
mov ecx, 0x23
push 0x30
pop fs
mov ds, cx
mov es, cx
mov ecx, 0x8053E54D
jmp ecx
}
}
void go() {
__asm {
mov eax, 1
int 0x20
}
}
int main()
{
if ((DWORD)IdtEntry != 0x401040) {
printf("wrong addr:%p", IdtEntry);
exit(-1);
}
go();
system("pause");
}
利用程序将其次数打印出来
#include <iostream>
#include<Windows.h>
DWORD g_num;
void __declspec(naked) IdtEntry() {
__asm {
test eax, eax
jnz L
mov ds : [0x8003f3f0] , eax
mov g_num, eax
jmp End
L :
mov eax, ds : [0x8003f3f0]
mov g_num, eax
End :
iretd
}
}
void reset() {
__asm {
xor eax,eax
int 0x20
}
}
void go() {
__asm {
mov eax, 1
int 0x20
}
}
int main()
{
if ((DWORD)IdtEntry != 0x401040) {
printf("wrong addr:%p", IdtEntry);
exit(-1);
}
reset();
printf("%d\n", g_num);
while (1) {
go();
Sleep(1000);
printf("%d\n", g_num);
}
system("pause");
}