使用 代码打印 进入 中断前后的 上下文,发现有 cs ss esp 改变了。中断门只用到了 TSS数据段中 cs ss esp 这几个东西;任务门 任务切换用到了更多的上下文 TSS 数据段的所有数据 。
TSS 数据格式:
2 代码:
// 3_中断现场分析.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
DWORD g_eax[2], g_ecx[2], g_edx[2], g_ebx[2];
DWORD g_esp[2], g_ebp[2], g_esi[2], g_edi[2];
WORD g_cs[2], g_ds[2], g_ss[2], g_es[2], g_fs[2], g_gs[2];
//WORD g_tr;
DWORD g_80042004;
// 0x401040
void __declspec(naked) IdtEntry()
{
_asm {
//pushad
mov[g_eax + 4],eax
mov[g_ecx + 4], ecx
mov[g_edx + 4], edx
mov[g_ebx + 4], ebx
mov[g_esp + 4], esp
mov[g_ebp + 4], ebp
mov[g_esi + 4], esi
mov[g_edi + 4], edi
push eax
mov ax, cs
mov[g_cs + 2], ax
mov ax, ds
mov[g_ds + 2], ax
mov ax, ss
mov[g_ss + 2], ax
mov ax, es
mov[g_es + 2], ax
mov ax, fs
mov[g_fs + 2], ax
mov ax, gs
mov[g_gs + 2], ax
pop eax
//popad
//int 3
iretd
}
}
void go()
{
__asm {
mov[g_eax],eax
mov [g_ecx],ecx
mov [g_edx],edx
mov [g_ebx], ebx
mov [g_esp], esp
mov [g_ebp], ebp
mov [g_esi], esi
mov [g_edi], edi
push eax
mov ax, CS
mov [g_cs], ax
mov ax, ds
mov [g_ds], ax
mov ax, ss
mov [g_ss] ,ax
mov ax, es
mov [g_es] ,ax
mov ax, fs
mov [g_fs],ax
mov ax, gs
mov [g_gs], ax
pop eax
}
// 最好不要在这里调用printf 先输出数据;因为调用了printf函数后可能哪里又会修改了。
__asm int 0x20
}
void main()
{
if ((DWORD)IdtEntry != 0x401040)
{
printf("wrong_addr: %p",IdtEntry);
exit(-1);
}
go();
printf("eax: %p, ecx: %p edx: %p ebx: %p
", g_eax[0], g_ecx[0], g_edx[0], g_ebx[0]);
printf("esp: %p, tebp: %p esi: %p edi: %p
", g_esp[0], g_ebp[0], g_esi[0], g_edi[0]);
printf("cs: %p, ds: %p ss:%p es: %p fs: %p gs: %p
", g_cs[0], g_ds[0], g_ss[0], g_es[0], g_fs[0], g_gs[0]);
printf("eax: %p,tecx: %p edx: %p ebx: %p
", g_eax[1], g_ecx[1], g_edx[1], g_ebx[1]);
printf("esp: %p, ebp: %p esi: %p edi: %p
", g_esp[1], g_ebp[1], g_esi[1], g_edi[1]);
printf("cs: %p, ds: %p ss: %p es: %p fs:%p gs: %p
", g_cs[1], g_ds[1], g_ss[1], g_es[1], g_fs[1], g_gs[1]);
//printf("tr:%p
", g_tr);
printf("%p
", g_80042004);
//printf("%p
",g_tmp);
system("pause");
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门提示:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件