1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | DWORD dwOK;
DWORD dwESP;
DWORD dwCS;
DWORD dwEFLG;
DWORD dwSS;
void __declspec(naked) Func()
{
dwOK = 1 ;
__asm
{
/ / int 3
/ / 实验会发现当前eip的eflgs中的nt位为 1 ,看截图
/ / 返回地址从tss中的ptl中拿出
/ / PTL为自动填补的上一个tss连接
push eax
pushfd
pop eax
mov dwEFLG,eax
or eax, 0x4000
push eax
popfd
mov eax, 0
mov dwESP,esp
mov ax,ss
mov dwSS,eax
mov ax,cs
mov dwCS,eax
pop eax
iretd
}
}
/ / 过去当前eip,通过函数调用堆栈中的返回地址获取
void __declspec(naked) GetEIP()
{
__asm
{
mov eax,dword ptr ss:[esp]
ret
}
}
int main()
{
/ / 查看函数地址
printf( "Function addr:[%x]\n" , &Func);
char bu[ 0x10 ]; / / 12ff70
int iCr3;
printf( "input CR:\n" );
scanf( "%x" ,&iCr3); / / 通过windbg工具, !process 0 0 指令获取
/ / 写入寄存器的值,我们刚刚设定好的段选择子
DWORD ITss[ 0x68 ] =
{
0x00000000 , / / link
0x00000000 , / / esp0
0x00000000 , / / ss0
0x00000000 , / / esp1
0x000000a9 , / / ss1
0x00000000 , / / esp2
0x00000000 , / / ss2
(DWORD)iCr3,
(DWORD)&Func, / / eip
0x00000000 , / / eflags
0x00000000 , / / eax
0x00000000 , / / ecx
0x00000000 , / / edx
0x00000000 , / / ebx
(DWORD)bu, / / esp
0x00000000 , / / ebp
0x00000000 , / / esi
0x00000000 , / / edi
0x00000023 , / / es
0x00000099 , / / cs
0x000000a9 , / / ss
0x00000023 , / / ds
0x000000a9 , / / fs 这里不管改不改都能跑,问题不大
0x00000000 , / / gs
0x00000000 , / / ldt
0x20ac0000
};
printf( "tss adress:[%x]\n" , &ITss);
system( "pause" );
char buff[ 6 ];
* (DWORD * )&buff[ 4 ] = 0x91 ;
__asm
{
call fword ptr[buff]
}
/ / 查看当前的 eip
DWORD eipp;
GetEIP();
__asm
{
mov eipp,eax
}
/ / 打印输出值
printf( "current eip:%x\n" , eipp);
printf( "TSS:[%x]\n" ,(DWORD)(ITss[ 0 ]));
printf( "ESP = %x CS = %x SS = %x Eflgs = %x\n" , dwESP,dwCS,dwSS,dwEFLG);
if (dwOK = = 1 )
{
printf( "Ring1 success!\n" );
}
else
{
printf( "Ring1 failed!\n" );
}
system( "pause" );
return 0 ;
}
|