首页
社区
课程
招聘
[求助] call tss段描述符 切换任务失败
发表于: 2022-5-19 23:38 5210

[求助] call tss段描述符 切换任务失败

2022-5-19 23:38
5210

利用call进行tss段描述符 任务切换时失败

代码

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
#include "stdafx.h"
#include <windows.h>
 
DWORD dwOK;
DWORD dwESP;
DWORD dwCS;
 
__declspec(naked) func(){
    dwOK = 1;
    __asm {
        mov eax, esp
        mov dwESP, eax
        mov ax, cs
        mov word ptr [dwCS], ax
 
        iretd
    }
}
 
int main(int argc, char* argv[])
{
    DWORD CR3;
    printf("Input CR3:");
    scanf("%x", &CR3);
 
    char bu[0x1000] = {0};
 
    DWORD iTss[0x68] = {
        0x00000000, //link
        (DWORD)bu, // esp0
        0x00000010, // ss0
        0x00000000, // esp1
        0x00000000, // ss1
        0x00000000, // esp2
        0x00000000, // ss2
        (DWORD)CR3,
        (DWORD)func, // eip
        0x00000000, // eflags
        0x00000000, // eax
        0x00000000, // ecx
        0x00000000, // edx
        0x00000000, // ebx
        (DWORD)bu, // esp
        0x00000000, // ebp
        0x00000000, // esi
        0x00000000, // edi
        0x00000023, // es
        0x00000008, // cs
        0x00000010, // ss
        0x00000023, // ds
        0x00000030, // fs
        0x00000000, // gs
        0x00000000, // ldt
        0x20ac0000
    };
 
    printf("cr3:%x\n", CR3);
    printf("func addr:%p\n", (DWORD)func);
    printf("tss addr:%p\n", (DWORD)iTss);
 
    int pause;
    printf("input pause:\n");
    scanf("%x", &pause);
 
 
    char buff[6];
    *(DWORD*)&buff[0] = 0x12345678;
    *(WORD*)&buff[4] = 0x48;
 
    __asm {
        call fword ptr[buff]
    }
 
    printf("ok=%d ESP=%x cs=%x \n", dwOK, dwESP, dwCS);
    getchar();
    return 0;
}

操作过程

1.运行输入CR3
图片描述
图片描述
2.根据地址0x0012eddc修改GDT表对应段描述符
图片描述
3.随便输入数字1,放行程序
图片描述
4.程序退出
图片描述

 

实在看不出哪个细节出了问题,请大家不吝赐教,感谢感谢


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (7)
雪    币: 39
活跃值: (2871)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
*(WORD*)&buff[4] = 0x48;
改成
*(WORD*)&buff[4] = 0x4B;
试试
2022-5-20 13:56
0
雪    币: 39
活跃值: (2871)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
另外,tss里面的esp感觉不对,因为堆栈空间必须是ring0的,你ss=0x10, esp=&bu[0]有啥意义?
2022-5-20 14:04
0
雪    币: 227
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
NutCracker 另外,tss里面的esp感觉不对,因为堆栈空间必须是ring0的,你ss=0x10, esp=&bu[0]有啥意义?
我理解堆栈本质是内存,只要地址可以访问,其实都是可以设置的。利用tss进行task切换,如果我的RPL=00,那么切换任务(包括切换tss),esp和ss两个寄存器应该会从ESP0和SS0中取值;如果RPL==11,那么切换task,应该会从esp和ss取值
2022-5-20 17:28
0
雪    币: 39
活跃值: (2871)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
Kyro 我理解堆栈本质是内存,只要地址可以访问,其实都是可以设置的。利用tss进行task切换,如果我的RPL=00,那么切换任务(包括切换tss),esp和ss两个寄存器应该会从ESP0和SS0中取值;如果 ...
你的理解有偏差。当ring3通过call gate调用ring0的函数时,esp和ss才是从当前tss中的esp0及ss0中取值,注意是当前tss,并非目标tss;而通过tss或task gate从ring 3切换到ring 0时,esp和ss永远从目标tss的esp及ss中取值,并且目标tss中的ss必须与目标tss中的cs一样,都必须是ring 0的,否则会产生GPF。所以,你定义的目标tss中的ss:esp必须要保证指向合法的内存空间,但你的ss是ring0,而esp却是ring3的指针,即使ss=0x10碰巧与当前ring3的ss具有相同基址,那么esp也应该赋值为&bu[0]+0x1000,而不是&bu[0]。
2022-5-21 09:58
0
雪    币: 227
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
嗯,我那个理解是错的,当切换task时TSS设置的ss0和esp0应该也是没有意义的
“即使ss=0x10碰巧与当前ring3的ss具有相同基址,那么esp也应该赋值为&bu[0]+0x1000,而不是&bu[0]”,为什么要+0x1000?是为划出一段可用stack空间吗?
2022-5-21 15:43
0
雪    币: 39
活跃值: (2871)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
Kyro 嗯,我那个理解是错的,当切换task时TSS设置的ss0和esp0应该也是没有意义的[em_58]。 “即使ss=0x10碰巧与当前ring3的ss具有相同基址,那么esp也应该赋值为&bu ...
因为堆栈是倒着长的,你每push一下,esp会减4,要是你把esp赋值为&bu[0]的话,push的时候,esp就不在bu里面了。
2022-5-21 22:31
0
雪    币: 227
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
NutCracker 因为堆栈是倒着长的,你每push一下,esp会减4,要是你把esp赋值为&bu[0]的话,push的时候,esp就不在bu里面了。
懂了,感谢
2022-5-22 22:14
0
游客
登录 | 注册 方可回帖
返回
//