无法成功跳转,麻烦帮忙看下问题。
代码:
/*
当使用JMP FAR来实现任务切换时,TSS结构体中的Previous Task Link的值在任务切换完成之后为0,CPU不会为其赋值;如果使用CALL FAR来实现任务切换,Previous Task Link的值在任务切换完成之后会CPU会将其填充为原来的TSS段选择子
当使用JMP FAR来实现任务切换时,EFLAGS寄存器中的NT位不变;当使用CALL FAR来实现任务切换时,EFLAGS寄存器中的NT位就会被置1(NT位会对iret指令产生影响 NT位如果为0,iret的值从堆栈中取(中断返回);如果NT位为1,会找TSS中的Previous Task Link进行返回)
*/
// 实现的主要代码
#include "windows.h"
#include "stdio.h"
DWORD eaxV;
DWORD fsV;
DWORD temp;
**//一个完整的TSS结构**
typedef struct TSS {
DWORD link; // 保存前一个 TSS 段选择子,使用 call 指令切换寄存器的时候由CPU填写。
// 这 6 个值是固定不变的,用于提权,CPU 切换栈的时候用
DWORD esp0; // 保存 0 环栈指针
DWORD ss0; // 保存 0 环栈段选择子
DWORD esp1; // 保存 1 环栈指针
DWORD ss1; // 保存 1 环栈段选择子
DWORD esp2; // 保存 2 环栈指针
DWORD ss2; // 保存 2 环栈段选择子
// 下面这些都是用来做切换寄存器值用的,切换寄存器的时候由CPU自动填写。
DWORD cr3;
DWORD eip;
DWORD eflags;
DWORD eax;
DWORD ecx;
DWORD edx;
DWORD ebx;
DWORD esp;
DWORD ebp;
DWORD esi;
DWORD edi;
DWORD es;
DWORD cs;
DWORD ss;
DWORD ds;
DWORD fs;
DWORD gs;
DWORD ldt;
// 这个暂时忽略
DWORD io_map;
} TSS;
TSS tss={0};
DWORD cr3V=0;
BYTE byteArrayR0[0x10]={0};
BYTE byteArrayR3[0x10]={0};
BYTE jmpAddr[]={0,0,0,0,0x4B,0};
BYTE retAddr[]={0x35,0x15,0x41,0x0,0x1B,0x0};
**//通过调用门调用的函数
**void _declspec(naked) tssFun()
{
__asm{
//----------------代码
//断点,中断查看栈
/*
*/
push fs
pushfd
int 3
popfd
pop fs
//读取高g内存
mov eax,0xf82B140C
mov ebx,[eax]
mov temp,ebx
** //返回
** //jmp far retAddr
iretd;
}
}
/*
---获取真实地址
*/
VOID getRealAddr(OUT PDWORD addrPtr,IN DWORD fun){
PBYTE jmpArray=(PBYTE)fun;
*addrPtr=fun+0x5+*(PDWORD)(jmpArray+1);
}
int main()
{
//DWORD tssFunAddress=(DWORD)tssFun;
DWORD tssFunAddress=(DWORD)tssFun;
getRealAddr(&tssFunAddress,(DWORD)tssFun);
PWORD tssFunPtr=(PWORD)(&tssFunAddress);
PDWORD tssPtr=(PDWORD)(&tss);
PBYTE tssSecondPtr=(PBYTE)(&tssPtr);
** //tss赋值
** tss.esp0=(DWORD)(byteArrayR0);//esp0
tss.ss0=0x00000010;//ss0
tss.eip=tssFunAddress;//函数地址
tss.esp=(DWORD)(byteArrayR0);//esp
tss.es=0x00000023;//es
tss.cs= 0x00000008;//cs
tss.ss= 0x00000010;//ss
tss.ds= 0x00000023;//ds
tss.fs= 0x00000030;//fs
tss.io_map= 0x20ac0000; //IO
printf( "tss地址:%08X\n" , tssPtr );
printf( "调用门函数tssFun地址:%08X\n" ,((DWORD)tssFun) );
printf("请在windbg中执行如下命令:eq 8003f048 %02X00e9%02X`%04X0068, tss\n",*(tssSecondPtr+3),*(tssSecondPtr+2),*(PWORD)tssSecondPtr);
system( "pause" );
printf("!process 0 0 tssDescriptior.exe查看cr3 ,请input cr3:");
scanf_s("%x",&cr3V);
tss.cr3 = cr3V;
_asm {
** //jmp到任务段,任务段保存的指向
** call far jmpAddr
}
printf( "提权后读取的高g内容::%08X\n" , temp );
system( "pause" );
}