📄 asm.c
字号:
/*****************************************************************
*
* Reversed By yykingking (yykingking@126.com)
* 仅供学习交流使用
*****************************************************************/
#include "header.h"
extern BOOL g_IsMulProcesser;
extern DWORD g_KBIntEntry,g_KBIntEntry1,g_KBIntEntry2;//双核CPU键盘中断入口处...保存用来恢复..
extern PSTRUCT_17H g_Buffer17H;
extern PSTRUCT_12H g_Buffer12H;
extern DWORD g_DUnKnown1;
extern DWORD g_IntVector;
extern KIRQL g_Kirql;
extern bool g_IsNT4;
extern KDPC g_Kdpc;
bool g_bAsm1,g_bAsm2,g_bAsm3,g_bAsm4;
BYTE g_r60LastRead,g_r60Last2Read,g_byteAsm3;
DWORD g_DR7;
DWORD g_DAsm1;
// **** Copy From SoBeIt ****//
// 在HAL里虽然HalBeginSystemInterrupt仍然是IRQL机制的发动引擎,但是因为有APIC的支持,
// 它和其它共同实现IRQL的函数要比PIC HAL里对应的函数功能简单得多。
// HalBeginSystemInterrupt通过用IRQL做索引在HalpIRQLtoTPR数组中获取该IRQL对应
// 的任务优先级,用该优先级设置任务优先级寄存器TPR,并把TPR中原先的任务优先级/16做
// 为索引在HalpVectorToIRQL数组中获取对应的原先的IRQL然后返回。
// 若IRQL是从低于DISPATCH_LEVEL提升到高于DISPATCH_LEVEL,
// 还需要设置KPCR+0x95(0xffdff095)为DISPATCH_LEVEL(0x2),
// 表示是从DISPATCH_LEVEL以下的级别提升IRQL。
// HalEndSystemInterrupt向本地APIC的EOI寄存发送0,表示中断结束,
// 可以接收新中断。并还要判断要降到的IRQL是否小于DISPATCH_LEVEL,
// 若小于则进一步判断KPCR+0x96(0xffdff096)是否置位,若置位则表示
// 有DPC中断在等待(在IRQL高于DISPATCH_LEVEL被引发,然后等待直到IRQL降到
// 低于DISPATCH_LEVEL),则将KPCR+0x95和KPCR+0x96清0后调用KiDispatchInterrupt响
// 应DPC软中断。否则做的工作就是和HalBeginSystemInterrupt一样的过程:把要降到
// 的IRQL转换成任务优先级设置TRP,并把久的任务优先级转成IRQL返回。
// KfRaiseIrql、KfLowerIrql之类的函数也是这么一回事,把当前IRQL转成任务优先
// 级修改TPR,并把原先TPR的值转成原先的IRQL并返回。而现在软中断的产生也有
// 了APIC支持,APIC通过产生一个发向自己的处理器间中断,就可以产生一个软中断,
// 因为可以指定该中断的向量,所以软中断就可以区分优先级别,如APC_LEVEL、
// DISPATCH_LEVEL。产生软中断的函数一样还是HalRequestSoftwareInterrupt,
// 该函数会先判断KPCR+0x95是否和要产生的软中断IRQL一样,若是的话则
// 置位KPCR+0x96并返回,表示现在IRQL大于DISPATCH_LEVEL所以不处理DPC中断。
// 否则以要产生的软中断的IRQL为索引从HalpIRQLtoTPRHAL取出对应任务优先级,
// 并或上0x4000,表示是发向自身的固定处理间中断,并用该值设置中断命令
// 寄存器ICW的低32位,然后读取中断命令寄存器ICW的低32位是否为0x1000,确定
// 中断消息已经发送后就返回,这时候软中断已经产生。值得注意的是APIC HAL里
// 没有HalEndSoftwareInterrupt这个函数。
__declspec(dllimport) HalBeginSystemInterrupt( DWORD, KIRQL, PKIRQL);
__declspec(dllimport) HalEndSystemInterrupt( KIRQL, DWORD);
#define RET_BEGIN_END_INT if ( g_IntVector != 0x31) \
{ HalBeginSystemInterrupt( 9, g_Kirql, &NewIrql); \
HalEndSystemInterrupt( NewIrql, 0); \
return 0; \
}
__declspec (naked) Write64Port( BYTE code)
{
__asm
{
mov al,code
out 0x64,al
retn
}
}
__declspec (naked) Write60Port( BYTE code)
{
__asm
{
mov al,code
out 0x60,al
retn
}
}
BYTE Read64Port()
{
BYTE code;
__asm
{
in al,0x64
mov code,al
}
return code;
}
BYTE Read60Port()
{
BYTE code;
__asm
{
in al,0x60
mov code,al
}
return code;
}
void TestKBCIdl() //测试KBC输入寄存器已空,无限延时.如果不空就循环等待..
{
int i=0;
__asm
{
LoopIfBusy:
xor al, al
in al, 0x64
add i, 1
and al, 2
jnz LoopIfBusy
}
}
void TestKBCOut() //测试KBC输出寄存器非空
{
BYTE result;
int delay1=0x2710;
int delay2=0;
__asm
{
LoopNotNuLL:
xor al, al
in al, 0x64 //; AT Keyboard controller 8042.
add delay2, 1
sub delay1, 1
cmp delay1, 0
jz Over
test al, 1
loope LoopNotNuLL
Over:
mov result, al
}
}
void TestKBCIdlWithNumber() ////测试KBC输入寄存器已空,在一定次数内测试...如果空就退出..
{
BYTE result;
int delay1=0xea60;
int delay2=0;
__asm
{
LoopIfBusy:
xor al, al
in al, 0x64 //; AT Keyboard controller 8042.
add delay2, 1
sub delay1, 1
cmp delay1, 0
jz Over
test al, 2
loopne LoopIfBusy
Over:
mov result, al
}
}
__declspec (naked) SaveDR7()
{
_asm
{
mov eax,dr7
mov g_DR7,eax
retn
}
}
__declspec (naked) WriteDR7_400H()
{
_asm
{
mov eax, 400h
mov dr7, eax
retn
}
}
__declspec (naked) ReLoadDR7()
{
_asm
{
mov eax, g_DR7
mov dr7, eax
retn
}
}
typedef struct _CODE_STRUCT_
{
char Ascii; //0x0
char r60; //0x1
char Reserved1; //0x2
char Reserved2; //0x3
}STRUCTCODE,*PSTRUCTCODE;
DWORD DispatchNewInt( DWORD param)
{
KIRQL NewIrql;
DWORD Number1,Number2,Number3,Number4,Number5,Number6,Number7,Number8,Number9,Number10;
DWORD Number11,Number12,Number13,Number14,Number15,Number16,Number17,Number18,Number19;
DWORD Dr7Tmp;
DWORD Var_2C,Var_34,Var_24;
STRUCTCODE Var_Code;
bool NotDr7_400H=false;
bool Input;
BYTE r64Port,r60Port;
if( g_IsMulProcesser)
{
// fs偏移51H处为当前运行的CPU??
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number1, eax;
if ( Number1 == 0)
{
g_bAsm1 = true;
if ( g_bAsm2)
return g_KBIntEntry1;
}
else
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number2, eax;
if ( Number2 == 1)
if( g_bAsm3)
return g_KBIntEntry2;
}
}
NewIrql = KfRaiseIrql( HIGH_LEVEL);
__asm mov eax, dr7;
__asm mov Dr7Tmp, eax;
if ( Dr7Tmp != 0x400)
NotDr7_400H = true;
if ( g_Buffer17H->Reserved3 == false)
g_Buffer17H->Reserved3 = NotDr7_400H;
if ( g_IsMulProcesser)
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number3, eax;
if ( Number2 != 0)
if ( g_bAsm1)
{
KfLowerIrql( NewIrql);
return g_KBIntEntry2;
}
}
if ( g_bAsm1)
g_bAsm1 = false;
SaveDR7();
// 清除调试标记,清除全局断点
WriteDR7_400H();
if ( !g_Buffer17H->Reserved6 && ! g_Buffer17H->Reserved11)
{
if ( g_Buffer17H->Reserved11)
{
TestKBCIdlWithNumber();
r64Port = Read64Port();
//最后一位为1表示输出寄存器非空,?第5位为0表示数据源为键盘?
if ( ( r64Port&1 ) != 1 || ( r64Port&0x20 ) == 0x20)
{
// 输出寄存器空 或者 数据源不为键盘
Var_2C = 0;
r60Port = Read60Port();
r64Port = Read64Port();
ReLoadDR7();
KfLowerIrql( NewIrql);
if( g_IsMulProcesser)
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number4, eax;
if( Number4 == 0)
return g_KBIntEntry1;
else
return g_KBIntEntry2;
}
else
return g_KBIntEntry;
}
// else if( ( r64Port&1 ) == 1 && ( r64Port&0x20 ) == 0x20)
// {
// Var_34 = 0;
// r60Port = Read60Port();
// r64Port = Read64Port();
// ReLoadDR7();
// if( g_IsMulProcesser)
// {
// __asm movzx eax, byte ptr fs:0x51;
// __asm mov Number10, eax;
// }
// RET_BEGIN_END_INT;
// }
// 输出寄存器非空 并且 数据源为键盘
r60Port = Read60Port();
if ( ( r60Port==0 ) || ( r60Port==0xfe ) )
{
// 为不处理的数据
ReLoadDR7();
KfLowerIrql( NewIrql);
if( g_IsMulProcesser)
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number5, eax;
if( Number5 == 0)
return g_KBIntEntry1;
else
return g_KBIntEntry2;
}
else
return g_KBIntEntry;
}
// 到了这里直接跳出整个if语句,到达 g_IsNt4的比较
}
else
{
if ( g_DUnKnown1 == 0)
{
ReLoadDR7();
KfLowerIrql( NewIrql);
if( g_IsMulProcesser)
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number6, eax;
if( Number6 == 0)
return g_KBIntEntry1;
else
return g_KBIntEntry2;
}
else
return g_KBIntEntry;
}
if ( g_Buffer12H->Reserved6 || g_Buffer12H->Reserved7)
{
ReLoadDR7();
KfLowerIrql( NewIrql);
if( g_IsMulProcesser)
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number7, eax;
if( Number7 == 0)
return g_KBIntEntry1;
else
return g_KBIntEntry2;
}
else
return g_KBIntEntry;
}
if ( g_Buffer12H->bDoletter && g_Buffer12H->Reserved10 )
{
ReLoadDR7();
KfLowerIrql( NewIrql);
if( g_IsMulProcesser)
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number8, eax;
if( Number8 == 0)
return g_KBIntEntry1;
else
return g_KBIntEntry2;
}
else
return g_KBIntEntry;
}
if ( g_Buffer12H->Reserved11)
{
ReLoadDR7();
KfLowerIrql( NewIrql);
if( g_IsMulProcesser)
{
__asm movzx eax, byte ptr fs:0x51;
__asm mov Number9, eax;
if( Number9 == 0)
return g_KBIntEntry1;
else
return g_KBIntEntry2;
}
else
return g_KBIntEntry;
}
TestKBCIdlWithNumber();
r64Port = Read64Port();
//最后一位为1表示输出寄存器非空,?第5位为0表示数据源为键盘?
if ( ( r64Port&1 ) != 1 || ( r64Port&0x20 ) == 0x20 )
{
// 不空或者不是键盘
Var_34 = 0;
r60Port = Read60Port();
r64Port = Read64Port();
ReLoadDR7();
if( g_IsMulProcesser)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -