隐藏你程序的窗体,让其他程序不能枚举
一、LDasm.h#ifndef _LDASM_
#define _LDASM_
#ifdef __cplusplus
extern "C" {
#endif
unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode);
unsigned long __fastcall SizeOfProc(void *Proc);
char __fastcall IsRelativeCmd(unsigned char *pOpcode);
#ifdef __cplusplus
}
#endif
#endif
#define OP_NONE 0x00
#define OP_MODRM 0x01
#define OP_DATA_I8 0x02
#define OP_DATA_I16 0x04
#define OP_DATA_I32 0x08
#define OP_DATA_PRE66_670x10
#define OP_WORD 0x20
#define OP_REL32 0x40
#define UCHAR unsigned char
#define ULONG unsigned long
#define PVOID void*
#define PUCHAR unsigned char*
#define BOOLEAN char
#define FALSE 0
#define TRUE1
UCHAR OpcodeFlags =
{
OP_MODRM, // 00
OP_MODRM, // 01
OP_MODRM, // 02
OP_MODRM, // 03
OP_DATA_I8, // 04
OP_DATA_PRE66_67, // 05
OP_NONE, // 06
OP_NONE, // 07
OP_MODRM, // 08
OP_MODRM, // 09
OP_MODRM, // 0A
OP_MODRM, // 0B
OP_DATA_I8, // 0C
OP_DATA_PRE66_67, // 0D
OP_NONE, // 0E
OP_NONE, // 0F
OP_MODRM, // 10
OP_MODRM, // 11
OP_MODRM, // 12
OP_MODRM, // 13
OP_DATA_I8, // 14
OP_DATA_PRE66_67, // 15
OP_NONE, // 16
OP_NONE, // 17
OP_MODRM, // 18
OP_MODRM, // 19
OP_MODRM, // 1A
OP_MODRM, // 1B
OP_DATA_I8, // 1C
OP_DATA_PRE66_67, // 1D
OP_NONE, // 1E
OP_NONE, // 1F
OP_MODRM, // 20
OP_MODRM, // 21
OP_MODRM, // 22
OP_MODRM, // 23
OP_DATA_I8, // 24
OP_DATA_PRE66_67, // 25
OP_NONE, // 26
OP_NONE, // 27
OP_MODRM, // 28
OP_MODRM, // 29
OP_MODRM, // 2A
OP_MODRM, // 2B
OP_DATA_I8, // 2C
OP_DATA_PRE66_67, // 2D
OP_NONE, // 2E
OP_NONE, // 2F
OP_MODRM, // 30
OP_MODRM, // 31
OP_MODRM, // 32
OP_MODRM, // 33
OP_DATA_I8, // 34
OP_DATA_PRE66_67, // 35
OP_NONE, // 36
OP_NONE, // 37
OP_MODRM, // 38
OP_MODRM, // 39
OP_MODRM, // 3A
OP_MODRM, // 3B
OP_DATA_I8, // 3C
OP_DATA_PRE66_67, // 3D
OP_NONE, // 3E
OP_NONE, // 3F
OP_NONE, // 40
OP_NONE, // 41
OP_NONE, // 42
OP_NONE, // 43
OP_NONE, // 44
OP_NONE, // 45
OP_NONE, // 46
OP_NONE, // 47
OP_NONE, // 48
OP_NONE, // 49
OP_NONE, // 4A
OP_NONE, // 4B
OP_NONE, // 4C
OP_NONE, // 4D
OP_NONE, // 4E
OP_NONE, // 4F
OP_NONE, // 50
OP_NONE, // 51
OP_NONE, // 52
OP_NONE, // 53
OP_NONE, // 54
OP_NONE, // 55
OP_NONE, // 56
OP_NONE, // 57
OP_NONE, // 58
OP_NONE, // 59
OP_NONE, // 5A
OP_NONE, // 5B
OP_NONE, // 5C
OP_NONE, // 5D
OP_NONE, // 5E
OP_NONE, // 5F
OP_NONE, // 60
OP_NONE, // 61
OP_MODRM, // 62
OP_MODRM, // 63
OP_NONE, // 64
OP_NONE, // 65
OP_NONE, // 66
OP_NONE, // 67
OP_DATA_PRE66_67, // 68
OP_MODRM | OP_DATA_PRE66_67, // 69
OP_DATA_I8, // 6A
OP_MODRM | OP_DATA_I8, // 6B
OP_NONE, // 6C
OP_NONE, // 6D
OP_NONE, // 6E
OP_NONE, // 6F
OP_DATA_I8, // 70
OP_DATA_I8, // 71
OP_DATA_I8, // 72
OP_DATA_I8, // 73
OP_DATA_I8, // 74
OP_DATA_I8, // 75
OP_DATA_I8, // 76
OP_DATA_I8, // 77
OP_DATA_I8, // 78
OP_DATA_I8, // 79
OP_DATA_I8, // 7A
OP_DATA_I8, // 7B
OP_DATA_I8, // 7C
OP_DATA_I8, // 7D
OP_DATA_I8, // 7E
OP_DATA_I8, // 7F
OP_MODRM | OP_DATA_I8, // 80
OP_MODRM | OP_DATA_PRE66_67, // 81
OP_MODRM | OP_DATA_I8, // 82
OP_MODRM | OP_DATA_I8, // 83
OP_MODRM, // 84
OP_MODRM, // 85
OP_MODRM, // 86
OP_MODRM, // 87
OP_MODRM, // 88
OP_MODRM, // 89
OP_MODRM, // 8A
OP_MODRM, // 8B
OP_MODRM, // 8C
OP_MODRM, // 8D
OP_MODRM, // 8E
OP_MODRM, // 8F
OP_NONE, // 90
OP_NONE, // 91
OP_NONE, // 92
OP_NONE, // 93
OP_NONE, // 94
OP_NONE, // 95
OP_NONE, // 96
OP_NONE, // 97
OP_NONE, // 98
OP_NONE, // 99
OP_DATA_I16 | OP_DATA_PRE66_67,// 9A
OP_NONE, // 9B
OP_NONE, // 9C
OP_NONE, // 9D
OP_NONE, // 9E
OP_NONE, // 9F
OP_DATA_PRE66_67, // A0
OP_DATA_PRE66_67, // A1
OP_DATA_PRE66_67, // A2
OP_DATA_PRE66_67, // A3
OP_NONE, // A4
OP_NONE, // A5
OP_NONE, // A6
OP_NONE, // A7
OP_DATA_I8, // A8
OP_DATA_PRE66_67, // A9
OP_NONE, // AA
OP_NONE, // AB
OP_NONE, // AC
OP_NONE, // AD
OP_NONE, // AE
OP_NONE, // AF
OP_DATA_I8, // B0
OP_DATA_I8, // B1
OP_DATA_I8, // B2
OP_DATA_I8, // B3
OP_DATA_I8, // B4
OP_DATA_I8, // B5
OP_DATA_I8, // B6
OP_DATA_I8, // B7
OP_DATA_PRE66_67, // B8
OP_DATA_PRE66_67, // B9
OP_DATA_PRE66_67, // BA
OP_DATA_PRE66_67, // BB
OP_DATA_PRE66_67, // BC
OP_DATA_PRE66_67, // BD
OP_DATA_PRE66_67, // BE
OP_DATA_PRE66_67, // BF
OP_MODRM | OP_DATA_I8, // C0
OP_MODRM | OP_DATA_I8, // C1
OP_DATA_I16, // C2
OP_NONE, // C3
OP_MODRM, // C4
OP_MODRM, // C5
OP_MODRM | OP_DATA_I8, // C6
OP_MODRM | OP_DATA_PRE66_67, // C7
OP_DATA_I8 | OP_DATA_I16, // C8
OP_NONE, // C9
OP_DATA_I16, // CA
OP_NONE, // CB
OP_NONE, // CC
OP_DATA_I8, // CD
OP_NONE, // CE
OP_NONE, // XF
OP_MODRM, // D0
OP_MODRM, // D1
OP_MODRM, // D2
OP_MODRM, // D3
OP_DATA_I8, // D4
OP_DATA_I8, // D5
OP_NONE, // D6
OP_NONE, // D7
OP_WORD, // D8
OP_WORD, // D9
OP_WORD, // DA
OP_WORD, // DB
OP_WORD, // DC
OP_WORD, // DD
OP_WORD, // DE
OP_WORD, // DF
OP_DATA_I8, // E0
OP_DATA_I8, // E1
OP_DATA_I8, // E2
OP_DATA_I8, // E3
OP_DATA_I8, // E4
OP_DATA_I8, // E5
OP_DATA_I8, // E6
OP_DATA_I8, // E7
OP_DATA_PRE66_67 | OP_REL32, // E8
OP_DATA_PRE66_67 | OP_REL32, // E9
OP_DATA_I16 | OP_DATA_PRE66_67,// EA
OP_DATA_I8, // EB
OP_NONE, // EC
OP_NONE, // ED
OP_NONE, // EE
OP_NONE, // EF
OP_NONE, // F0
OP_NONE, // F1
OP_NONE, // F2
OP_NONE, // F3
OP_NONE, // F4
OP_NONE, // F5
OP_MODRM, // F6
OP_MODRM, // F7
OP_NONE, // F8
OP_NONE, // F9
OP_NONE, // FA
OP_NONE, // FB
OP_NONE, // FC
OP_NONE, // FD
OP_MODRM, // FE
OP_MODRM | OP_REL32 // FF
};
UCHAR OpcodeFlagsExt =
{
OP_MODRM, // 00
OP_MODRM, // 01
OP_MODRM, // 02
OP_MODRM, // 03
OP_NONE, // 04
OP_NONE, // 05
OP_NONE, // 06
OP_NONE, // 07
OP_NONE, // 08
OP_NONE, // 09
OP_NONE, // 0A
OP_NONE, // 0B
OP_NONE, // 0C
OP_MODRM, // 0D
OP_NONE, // 0E
OP_MODRM | OP_DATA_I8, // 0F
OP_MODRM, // 10
OP_MODRM, // 11
OP_MODRM, // 12
OP_MODRM, // 13
OP_MODRM, // 14
OP_MODRM, // 15
OP_MODRM, // 16
OP_MODRM, // 17
OP_MODRM, // 18
OP_NONE, // 19
OP_NONE, // 1A
OP_NONE, // 1B
OP_NONE, // 1C
OP_NONE, // 1D
OP_NONE, // 1E
OP_NONE, // 1F
OP_MODRM, // 20
OP_MODRM, // 21
OP_MODRM, // 22
OP_MODRM, // 23
OP_MODRM, // 24
OP_NONE, // 25
OP_MODRM, // 26
OP_NONE, // 27
OP_MODRM, // 28
OP_MODRM, // 29
OP_MODRM, // 2A
OP_MODRM, // 2B
OP_MODRM, // 2C
OP_MODRM, // 2D
OP_MODRM, // 2E
OP_MODRM, // 2F
OP_NONE, // 30
OP_NONE, // 31
OP_NONE, // 32
OP_NONE, // 33
OP_NONE, // 34
OP_NONE, // 35
OP_NONE, // 36
OP_NONE, // 37
OP_NONE, // 38
OP_NONE, // 39
OP_NONE, // 3A
OP_NONE, // 3B
OP_NONE, // 3C
OP_NONE, // 3D
OP_NONE, // 3E
OP_NONE, // 3F
OP_MODRM, // 40
OP_MODRM, // 41
OP_MODRM, // 42
OP_MODRM, // 43
OP_MODRM, // 44
OP_MODRM, // 45
OP_MODRM, // 46
OP_MODRM, // 47
OP_MODRM, // 48
OP_MODRM, // 49
OP_MODRM, // 4A
OP_MODRM, // 4B
OP_MODRM, // 4C
OP_MODRM, // 4D
OP_MODRM, // 4E
OP_MODRM, // 4F
OP_MODRM, // 50
OP_MODRM, // 51
OP_MODRM, // 52
OP_MODRM, // 53
OP_MODRM, // 54
OP_MODRM, // 55
OP_MODRM, // 56
OP_MODRM, // 57
OP_MODRM, // 58
OP_MODRM, // 59
OP_MODRM, // 5A
OP_MODRM, // 5B
OP_MODRM, // 5C
OP_MODRM, // 5D
OP_MODRM, // 5E
OP_MODRM, // 5F
OP_MODRM, // 60
OP_MODRM, // 61
OP_MODRM, // 62
OP_MODRM, // 63
OP_MODRM, // 64
OP_MODRM, // 65
OP_MODRM, // 66
OP_MODRM, // 67
OP_MODRM, // 68
OP_MODRM, // 69
OP_MODRM, // 6A
OP_MODRM, // 6B
OP_MODRM, // 6C
OP_MODRM, // 6D
OP_MODRM, // 6E
OP_MODRM, // 6F
OP_MODRM | OP_DATA_I8, // 70
OP_MODRM | OP_DATA_I8, // 71
OP_MODRM | OP_DATA_I8, // 72
OP_MODRM | OP_DATA_I8, // 73
OP_MODRM, // 74
OP_MODRM, // 75
OP_MODRM, // 76
OP_NONE, // 77
OP_NONE, // 78
OP_NONE, // 79
OP_NONE, // 7A
OP_NONE, // 7B
OP_MODRM, // 7C
OP_MODRM, // 7D
OP_MODRM, // 7E
OP_MODRM, // 7F
OP_DATA_PRE66_67 | OP_REL32, // 80
OP_DATA_PRE66_67 | OP_REL32, // 81
OP_DATA_PRE66_67 | OP_REL32, // 82
OP_DATA_PRE66_67 | OP_REL32, // 83
OP_DATA_PRE66_67 | OP_REL32, // 84
OP_DATA_PRE66_67 | OP_REL32, // 85
OP_DATA_PRE66_67 | OP_REL32, // 86
OP_DATA_PRE66_67 | OP_REL32, // 87
OP_DATA_PRE66_67 | OP_REL32, // 88
OP_DATA_PRE66_67 | OP_REL32, // 89
OP_DATA_PRE66_67 | OP_REL32, // 8A
OP_DATA_PRE66_67 | OP_REL32, // 8B
OP_DATA_PRE66_67 | OP_REL32, // 8C
OP_DATA_PRE66_67 | OP_REL32, // 8D
OP_DATA_PRE66_67 | OP_REL32, // 8E
OP_DATA_PRE66_67 | OP_REL32, // 8F
OP_MODRM, // 90
OP_MODRM, // 91
OP_MODRM, // 92
OP_MODRM, // 93
OP_MODRM, // 94
OP_MODRM, // 95
OP_MODRM, // 96
OP_MODRM, // 97
OP_MODRM, // 98
OP_MODRM, // 99
OP_MODRM, // 9A
OP_MODRM, // 9B
OP_MODRM, // 9C
OP_MODRM, // 9D
OP_MODRM, // 9E
OP_MODRM, // 9F
OP_NONE, // A0
OP_NONE, // A1
OP_NONE, // A2
OP_MODRM, // A3
OP_MODRM | OP_DATA_I8, // A4
OP_MODRM, // A5
OP_NONE, // A6
OP_NONE, // A7
OP_NONE, // A8
OP_NONE, // A9
OP_NONE, // AA
OP_MODRM, // AB
OP_MODRM | OP_DATA_I8, // AC
OP_MODRM, // AD
OP_MODRM, // AE
OP_MODRM, // AF
OP_MODRM, // B0
OP_MODRM, // B1
OP_MODRM, // B2
OP_MODRM, // B3
OP_MODRM, // B4
OP_MODRM, // B5
OP_MODRM, // B6
OP_MODRM, // B7
OP_NONE, // B8
OP_NONE, // B9
OP_MODRM | OP_DATA_I8, // BA
OP_MODRM, // BB
OP_MODRM, // BC
OP_MODRM, // BD
OP_MODRM, // BE
OP_MODRM, // BF
OP_MODRM, // C0
OP_MODRM, // C1
OP_MODRM | OP_DATA_I8, // C2
OP_MODRM, // C3
OP_MODRM | OP_DATA_I8, // C4
OP_MODRM | OP_DATA_I8, // C5
OP_MODRM | OP_DATA_I8, // C6
OP_MODRM, // C7
OP_NONE, // C8
OP_NONE, // C9
OP_NONE, // CA
OP_NONE, // CB
OP_NONE, // CC
OP_NONE, // CD
OP_NONE, // CE
OP_NONE, // XF
OP_MODRM, // D0
OP_MODRM, // D1
OP_MODRM, // D2
OP_MODRM, // D3
OP_MODRM, // D4
OP_MODRM, // D5
OP_MODRM, // D6
OP_MODRM, // D7
OP_MODRM, // D8
OP_MODRM, // D9
OP_MODRM, // DA
OP_MODRM, // DB
OP_MODRM, // DC
OP_MODRM, // DD
OP_MODRM, // DE
OP_MODRM, // DF
OP_MODRM, // E0
OP_MODRM, // E1
OP_MODRM, // E2
OP_MODRM, // E3
OP_MODRM, // E4
OP_MODRM, // E5
OP_MODRM, // E6
OP_MODRM, // E7
OP_MODRM, // E8
OP_MODRM, // E9
OP_MODRM, // EA
OP_MODRM, // EB
OP_MODRM, // EC
OP_MODRM, // ED
OP_MODRM, // EE
OP_MODRM, // EF
OP_MODRM, // F0
OP_MODRM, // F1
OP_MODRM, // F2
OP_MODRM, // F3
OP_MODRM, // F4
OP_MODRM, // F5
OP_MODRM, // F6
OP_MODRM, // F7
OP_MODRM, // F8
OP_MODRM, // F9
OP_MODRM, // FA
OP_MODRM, // FB
OP_MODRM, // FC
OP_MODRM, // FD
OP_MODRM, // FE
OP_NONE // FF
};
unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode)
{
PUCHAR cPtr;
UCHAR Flags;
BOOLEAN PFX66, PFX67;
BOOLEAN SibPresent;
UCHAR iMod, iRM, iReg;
UCHAR OffsetSize, Add;
UCHAR Opcode;
OffsetSize = 0;
PFX66 = FALSE;
PFX67 = FALSE;
cPtr = (PUCHAR)Code;
while ( (*cPtr == 0x2E) || (*cPtr == 0x3E) || (*cPtr == 0x36) ||
(*cPtr == 0x26) || (*cPtr == 0x64) || (*cPtr == 0x65) ||
(*cPtr == 0xF0) || (*cPtr == 0xF2) || (*cPtr == 0xF3) ||
(*cPtr == 0x66) || (*cPtr == 0x67) )
{
if (*cPtr == 0x66) PFX66 = TRUE;
if (*cPtr == 0x67) PFX67 = TRUE;
cPtr++;
if (cPtr > (PUCHAR)Code + 16) return 0;
}
Opcode = *cPtr;
if (pOpcode) *pOpcode = cPtr;
if (*cPtr == 0x0F)
{
cPtr++;
Flags = OpcodeFlagsExt[*cPtr];
} else
{
Flags = OpcodeFlags;
if (Opcode >= 0xA0 && Opcode <= 0xA3) PFX66 = PFX67;
}
cPtr++;
if (Flags & OP_WORD) cPtr++;
if (Flags & OP_MODRM)
{
iMod = *cPtr >> 6;
iReg = (*cPtr & 0x38) >> 3;
iRM= *cPtr &7;
cPtr++;
if ((Opcode == 0xF6) && !iReg) Flags |= OP_DATA_I8;
if ((Opcode == 0xF7) && !iReg) Flags |= OP_DATA_PRE66_67;
SibPresent = !PFX67 & (iRM == 4);
switch (iMod)
{
case 0:
if ( PFX67 && (iRM == 6)) OffsetSize = 2;
if (!PFX67 && (iRM == 5)) OffsetSize = 4;
break;
case 1: OffsetSize = 1;
break;
case 2: if (PFX67) OffsetSize = 2; else OffsetSize = 4;
break;
case 3: SibPresent = FALSE;
}
if (SibPresent)
{
if (((*cPtr & 7) == 5) && ( (!iMod) || (iMod == 2) )) OffsetSize = 4;
cPtr++;
}
cPtr = (PUCHAR)(ULONG)cPtr + OffsetSize;
}
if (Flags & OP_DATA_I8)cPtr++;
if (Flags & OP_DATA_I16) cPtr += 2;
if (Flags & OP_DATA_I32) cPtr += 4;
if (PFX66) Add = 2; else Add = 4;
if (Flags & OP_DATA_PRE66_67) cPtr += Add;
return (ULONG)cPtr - (ULONG)Code;
}
unsigned long __fastcall SizeOfProc(void *Proc)
{
ULONGLength;
PUCHAR pOpcode;
ULONGResult = 0;
do
{
Length = SizeOfCode(Proc, &pOpcode);
Result += Length;
if ((Length == 1) && (*pOpcode == 0xC3)) break;
Proc = (PVOID)((ULONG)Proc + Length);
} while (Length);
return Result;
}
char __fastcall IsRelativeCmd(unsigned char *pOpcode)
{
UCHAR Flags;
if (*pOpcode == 0x0F) Flags = OpcodeFlagsExt[*(PUCHAR)((ULONG)pOpcode + 1)];
else Flags = OpcodeFlags[*pOpcode];
return (Flags & OP_REL32);
}
unsigned long GetPatchSize(void* Proc,unsigned long dwNeedSize)
{
ULONG Length;
PUCHAR pOpcode;
ULONG PatchSize = 0;
do
{
Length = SizeOfCode(Proc, &pOpcode);
if ((Length == 1) && (*pOpcode == 0xC3)) break;
if ((Length == 3) && (*pOpcode == 0xC2)) break;
Proc = (PVOID)((ULONG)Proc + Length);
PatchSize += Length;
if (PatchSize >= dwNeedSize)
{
break;
}
} while (Length);
return PatchSize;
}
二、SSDTSHADOW.h
#include <NTDDK.H>
typedef struct _System_Service_Table{
PVOIDServiceTableBase;
PVOIDServiceCounterTableBase;
ULONGNumberOfServices;
PVOIDParamTableBase;
} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
typedef struct _SERVICE_DESCRIPTOR_TABLE{
SYSTEM_SERVICE_TABLE ntoskrnl;// ntoskrnl.exe (native api)
SYSTEM_SERVICE_TABLE win32k; // win32k.sys (gdi/user)
SYSTEM_SERVICE_TABLE Table3; // not used
SYSTEM_SERVICE_TABLE Table4; // not used
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
//----------------------------------------------------------------------------------
typedef ULONG (*NTUSERWINDOWFROMPOINT)( LONG, LONG );
typedef UINT_PTR (*NTUSERQUERYWINDOW)
(
IN ULONG WindowHandle,
IN ULONG TypeInformation
);
typedef ULONG (*NTUSERFINDWINDOWEX)
(
IN HWND hwndParent,
IN HWND hwndChild,
IN PUNICODE_STRING pstrClassName OPTIONAL,
IN PUNICODE_STRING pstrWindowName OPTIONAL,
IN DWORD dwType
);
typedef NTSTATUS (*NTUSERBUILDHWNDLIST)
(
IN HDESK hdesk,
IN HWND hwndNext,
IN ULONG fEnumChildren,
IN DWORD idThread,
IN UINT cHwndMax,
OUT HWND *phwndFirst,
OUT ULONG *pcHwndNeeded
);
typedef NTSTATUS (*NTDUPLICATEOBJECT)
(
IN HANDLE SourceProcessHandle,
IN HANDLE SourceHandle,
IN HANDLE TargetProcessHandle,
OUT PHANDLE TargetHandle OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes,
IN ULONG Options
);
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess
(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
typedef NTSTATUS(*OBOPENOBJECTBYPOINTER)
(
IN PVOIDObject,
IN ULONGHandleAttributes,
IN PACCESS_STATEPassedAccessStateOPTIONAL,
IN ACCESS_MASKDesiredAccessOPTIONAL,
IN POBJECT_TYPEObjectTypeOPTIONAL,
IN KPROCESSOR_MODEAccessMode,
OUT PHANDLEHandle
);
NTKERNELAPI HANDLE PsGetProcessId( PEPROCESS Process );
NTKERNELAPI KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);
NTKERNELAPI PEPROCESS IoThreadToProcess ( IN PETHREAD Thread);
externPSYSTEM_SERVICE_TABLE KeServiceDescriptorTable;
PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow;
externNtBuildNumber;// 该项会被填充当前系统的BuildNumber
KSPIN_LOCK spinLock;
NTUSERQUERYWINDOW NtUserQueryWindow=NULL,Old_NtUserQueryWindow=NULL;
NTUSERFINDWINDOWEX NtUserFindWindowEx=NULL,Old_NtUserFindWindowEx=NULL;
NTUSERBUILDHWNDLIST NtUserBuildHwndList=NULL,Old_NtUserBuildHwndList=NULL;
NTUSERWINDOWFROMPOINT NtUserWindowFromPoint=NULL,Old_NtUserWindowFromPoint=NULL;
NTDUPLICATEOBJECT NtDuplicateObject=NULL,Old_NtDuplicateObject=NULL;
OBOPENOBJECTBYPOINTER ObOpenObjectByPointer=NULL,Old_ObOpenObjectByPointer=NULL;
//判断当前系统自行编号//下面是XP 的调用号
ULONG NtUserQueryWindow_Index=483;
ULONG NtUserFindWindowEx_Index=378;
ULONG NtUserBuildHwndList_Index=312;
ULONG NtUserWindowFromPoint_Index=592;
ULONG NtDuplicateObject_Index=68;
//主要保护对象 1进程 和1线程
PEPROCESS ProtectedProcess=NULL;
PETHREAD ProtectedThread=NULL;
//下面函数实现都很简单 较为依赖NtUserQueryWindow 函数 关联窗口和进程ID
NTSTATUS fake_NtUserFindWindowEx(
IN HWND hwndParent,
IN HWND hwndChild,
IN PUNICODE_STRING pstrClassName OPTIONAL,
IN PUNICODE_STRING pstrWindowName OPTIONAL,
IN DWORD dwType)
{
ULONGhWnd;
hWnd = Old_NtUserFindWindowEx(hwndParent, hwndChild, pstrClassName, pstrWindowName, dwType);//执行原函数
DbgPrint("当前被调用程序的进程ID: %d\n",PsGetCurrentProcessId());
if (PsGetCurrentProcess()!= ProtectedProcess)//操作进程不是自身则
{
ULONG ProcessID = Old_NtUserQueryWindow(hWnd, 0);//查询返回窗口的进程ID
if (ProcessID == (ULONG)PsGetProcessId(ProtectedProcess))//是保护进程 则返回0
{
return FALSE;
}
}
return hWnd;
}
NTSTATUS fake_NtUserBuildHwndList(
IN HDESK hdesk,
IN HWND hwndNext,
IN ULONG fEnumChildren,
IN DWORD idThread,
IN UINT cHwndMax,
OUT HWND *phwndFirst,
OUT ULONG* pcHwndNeeded)
{
NTSTATUS ntStatus;
ULONG i=0;
DbgPrint("当前被调用程序的进程ID: %d\n",PsGetCurrentProcessId());
if (PsGetCurrentProcess()!= ProtectedProcess)
{
if (fEnumChildren==1)//是否是枚举子窗口
{ //如果是枚举本程序子窗体 返回失败
if (Old_NtUserQueryWindow((ULONG)hwndNext, 0) == (ULONG)PsGetProcessId(ProtectedProcess))
{
return STATUS_UNSUCCESSFUL;
}
}
//枚举顶层窗口
ntStatus = Old_NtUserBuildHwndList(hdesk, hwndNext, fEnumChildren, idThread, cHwndMax, phwndFirst, pcHwndNeeded);
if (NT_SUCCESS(ntStatus))
{
while (i<*pcHwndNeeded)//循环查询是否为本程序窗体从数组中擦掉
{
if (Old_NtUserQueryWindow((ULONG)phwndFirst,0) == (ULONG)PsGetProcessId(ProtectedProcess))
{ //直接置0就好了前面代码有问题
phwndFirst=0;
}
i++;
}
}
return ntStatus;
}
return Old_NtUserBuildHwndList(hdesk, hwndNext, fEnumChildren, idThread, cHwndMax, phwndFirst, pcHwndNeeded);
}
UINT_PTR__stdcall fake_NtUserQueryWindow(IN ULONG WindowHandle,IN ULONG TypeInformation)
{DbgPrint("当前被调用程序的进程ID: %d\n",PsGetCurrentProcessId());
if( PsGetCurrentProcess() != ProtectedProcess )
{
if (Old_NtUserQueryWindow(WindowHandle, TypeInformation) == (ULONG)PsGetProcessId(ProtectedProcess))
{//试图关联保护的PID 返回0
return FALSE;
}
}
return Old_NtUserQueryWindow(WindowHandle, TypeInformation);
}
ULONG fake_NtUserWindowFromPoint(LONG x, LONG y)
{
ULONG hWnd;
hWnd=Old_NtUserWindowFromPoint(x,y);
DbgPrint("当前被调用程序的进程ID: %d\n",PsGetCurrentProcessId());
if (PsGetCurrentProcess() != ProtectedProcess)
{
if (Old_NtUserQueryWindow(hWnd, 0) == (ULONG)PsGetProcessId(ProtectedProcess))
{
return FALSE;
}
}
return hWnd;
}
//思路很简单 执行原函数后直接判断输出句柄 如果是我们的 直接close掉然后返回失败
//还好NtDuplicateObject 系统调用不是很频繁如果是调用频繁的系统函数 不建议这样乱来.^_^
NTSTATUS fake_NtDuplicateObject(
IN HANDLE SourceProcessHandle,
IN HANDLE SourceHandle,
IN HANDLE TargetProcessHandle,
OUT PHANDLE TargetHandle OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes,
IN ULONG Options)
{
NTSTATUS ntStatus,Tmp;
//PVOID pObj=NULL;
PROCESS_BASIC_INFORMATION PBI;
ntStatus=Old_NtDuplicateObject(SourceProcessHandle,SourceHandle,TargetProcessHandle,
TargetHandle,DesiredAccess,Attributes,Options);
if (NT_SUCCESS(ntStatus) )
{ //在当前进程上下文直接查询输出句柄所属ID是我们的直接CLOSE掉
//这里 用内核提供的查询句柄函数似乎更精确 可以直接获取对象 然后对比是否是我们的进线程对象.
Tmp=ZwQueryInformationProcess(*TargetHandle,ProcessBasicInformation,&PBI,sizeof(PBI),NULL);
//Tmp=ObReferenceObjectByHandle(*TargetHandle, 0, NULL, KernelMode, &pObj, NULL );
if (NT_SUCCESS(Tmp))
{ /*//需要自己替换 可防止COPY 进线程句柄
if (pObj==(PVOID)ProtectedProcess|pObj==(PVOID)ProtectedThread)
{
ZwClose(*TargetHandle);
*TargetHandle=0;
ntStatus= STATUS_UNSUCCESSFUL;
}*/
if (PBI.UniqueProcessId ==(ULONG)PsGetProcessId(ProtectedProcess))
{
ZwClose(*TargetHandle);
*TargetHandle=0;
ntStatus= STATUS_UNSUCCESSFUL;
}
}
}
return ntStatus;
}
NTSTATUS fake_ObOpenObjectByPointer(
IN PVOIDObject,
IN ULONGHandleAttributes,
IN PACCESS_STATEPassedAccessStateOPTIONAL,
IN ACCESS_MASKDesiredAccessOPTIONAL,
IN POBJECT_TYPEObjectTypeOPTIONAL,
IN KPROCESSOR_MODEAccessMode,
OUT PHANDLEHandle)
{
if ((Object != NULL) && (MmIsAddressValid(Object)))
{
if ((ProtectedThread !=PsGetCurrentThread())) //当前操作者不是本程序自身的线程
{
if (Object == IoThreadToProcess(ProtectedThread)|| Object==ProtectedThread)
{//目标是否为我们保护的对象
return STATUS_ACCESS_DENIED;// 是则拒绝访问
}
}
}
return Old_ObOpenObjectByPointer (Object, HandleAttributes,PassedAccessState,
DesiredAccess,ObjectType,AccessMode,Handle);
}
//该函数是网上COPY来的 做法很标准什么时候自己写的也有这么标准就好了 ^_^
ULONG GetShadowTableAddress()
{
ULONG dwordatbyte,i;
PUCHAR p = (PUCHAR) KeAddSystemServiceTable;
for(i = 0; i < PAGE_SIZE; i++, p++)//往下找一页 指针递增1
{
__try
{
dwordatbyte = *(PULONG)p;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return FALSE;
}
if(MmIsAddressValid((PVOID)dwordatbyte))
{
if(memcmp((PVOID)dwordatbyte, KeServiceDescriptorTable, 16) == 0)//对比前16字节 相同则找到
{
if((PVOID)dwordatbyte == KeServiceDescriptorTable)//排除自己
{
continue;
}
return dwordatbyte;
}
}
}
return FALSE;
}
ULONG GetSSDTCurAddr(IN ULONG Index,BOOL IsShadow)
{
ULONG ServiceCount,BaseAddr;
if (KeServiceDescriptorTableShadow!=NULL)
{
ServiceCount=KeServiceDescriptorTableShadow.NumberOfServices;
BaseAddr = (ULONG)KeServiceDescriptorTableShadow.ServiceTableBase;
if (Index>=ServiceCount) return FALSE;
return *(PULONG)(BaseAddr+Index * 4);
}
return FALSE;
}
三、Xacker.h
#include <NTDDK.H>
#include <windef.h>
#include "LDasm.h"
#include "SSDTSHADOW.h"
#define NT_DEVICE_NAME L"\\Device\\Hook"
#define DOS_DEVICE_NAME L"\\DosDevices\\Hook"
#define IOCTL_Hook CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_UnHook CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2, METHOD_BUFFERED, FILE_ANY_ACCESS)
void MemOpen()
{
__asm {
cli
moveax,cr0
andeax,not 10000h
movcr0,eax
}
}
void MemClose()
{
__asm {
moveax,cr0
or eax,10000h
movcr0,eax
sti
}
}
// 不做任何异常处理需要自行处理环境偏移
void Hook (PVOID Func,PVOID New_Func,PVOID Proxy_Func)
{
ULONG PatchSize;
BYTE g_HookCode = { 0xE9, 0, 0, 0, 0 };//相对跳转
BYTE Jmp_Orig_Code = { 0xEA, 0, 0, 0, 0, 0x08, 0x00 }; //绝对地址跳转
PatchSize=GetPatchSize(Func,5);//获得要Patch的字节数
//构造Proxy_Func
memcpy( (PBYTE)Proxy_Func,(PBYTE)Func,PatchSize);//实现原函数头
*( (PULONG)(Jmp_Orig_Code + 1) ) = (ULONG) ( (PBYTE)Func + PatchSize );//原函数+N 地址
memcpy( (PBYTE)Proxy_Func+ PatchSize, Jmp_Orig_Code, 7);//绝对地址跳转
*( (ULONG*)(g_HookCode + 1) ) = (ULONG)New_Func - (ULONG)Func - 5;//计算JMP 地址
MemOpen();
memcpy(Func, g_HookCode, 5);
MemClose();
}
void UnHook (PVOID Func,PVOID Proxy_Func)
{
MemOpen();
memcpy(Func,Proxy_Func,5);
MemClose();
}
//方便起见不做任何判断需要的自己加强
//不喜欢硬编码自行解决SSDTSHADOW 表的其他系统服务号硬编码
//其实在SSDTSHADOW中HOOK 一个函数即可达到保护窗体的目的
//ICY的PSNULL3里好 像就是这样的 因为窗体名称是随机的 所以 只要防止窗体与进程关联 就可以达到保护窗体的效果了
VOID StartHook ()
{
UNICODE_STRING uniFuncName;
RtlInitUnicodeString(&uniFuncName,L"ObOpenObjectByPointer");
ObOpenObjectByPointer = MmGetSystemRoutineAddress(&uniFuncName);
//当前SSDTSHADOW 函数指针需要的自己加
NtUserQueryWindow=(PVOID)GetSSDTCurAddr(NtUserQueryWindow_Index,TRUE);
NtUserFindWindowEx=(PVOID)GetSSDTCurAddr(NtUserFindWindowEx_Index,TRUE);
NtUserBuildHwndList=(PVOID)GetSSDTCurAddr(NtUserBuildHwndList_Index,TRUE);
NtUserWindowFromPoint=(PVOID)GetSSDTCurAddr(NtUserWindowFromPoint_Index,TRUE);
NtDuplicateObject=(PVOID)GetSSDTCurAddr(NtDuplicateObject_Index,FALSE);
//代理函数指针
Old_ObOpenObjectByPointer=ExAllocatePool(NonPagedPool, 20);
Old_NtUserQueryWindow=ExAllocatePool(NonPagedPool, 20);
Old_NtUserFindWindowEx=ExAllocatePool(NonPagedPool, 20);
Old_NtUserBuildHwndList=ExAllocatePool(NonPagedPool, 20);
Old_NtUserWindowFromPoint=ExAllocatePool(NonPagedPool, 20);
Old_NtDuplicateObject=ExAllocatePool(NonPagedPool, 20);
memset(Old_ObOpenObjectByPointer,0x90,20);
memset(Old_NtUserQueryWindow,0x90,20);//NOP一下
memset(Old_NtUserFindWindowEx,0x90,20);
memset(Old_NtUserBuildHwndList,0x90,20);
memset(Old_NtUserWindowFromPoint,0x90,20);
memset(Old_NtDuplicateObject,0x90,20);
//HOOK
Hook(ObOpenObjectByPointer,fake_ObOpenObjectByPointer,Old_ObOpenObjectByPointer);
Hook(NtUserQueryWindow,fake_NtUserQueryWindow,Old_NtUserQueryWindow);
Hook(NtUserFindWindowEx,fake_NtUserFindWindowEx,Old_NtUserFindWindowEx);
Hook(NtUserBuildHwndList,fake_NtUserBuildHwndList,Old_NtUserBuildHwndList);
Hook(NtUserWindowFromPoint,fake_NtUserWindowFromPoint,Old_NtUserWindowFromPoint);
Hook(NtDuplicateObject,fake_NtDuplicateObject,Old_NtDuplicateObject);
}
VOID StopHook()
{
UnHook(ObOpenObjectByPointer,Old_ObOpenObjectByPointer);
UnHook(NtUserQueryWindow,Old_NtUserQueryWindow);
UnHook(NtUserFindWindowEx,Old_NtUserFindWindowEx);
UnHook(NtUserBuildHwndList,Old_NtUserBuildHwndList);
UnHook(NtUserWindowFromPoint,Old_NtUserWindowFromPoint);
UnHook(NtDuplicateObject,Old_NtDuplicateObject);
ExFreePool(Old_ObOpenObjectByPointer);
ExFreePool(Old_NtUserQueryWindow);
ExFreePool(Old_NtUserFindWindowEx);
ExFreePool(Old_NtUserBuildHwndList);
ExFreePool(Old_NtUserWindowFromPoint);
ExFreePool(Old_NtDuplicateObject);
}
四、Xacker.c
//本代码 只在XP SP2下测试通过其他系统 除去SSDTSHADOW 编号问题 应该都可以正常运行
//需要的自行测试代码需要放在系统SYSTEM32目录下
#include <NTDDK.H>
#include "Xacker.h"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject );
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING uniDeviceName;
UNICODE_STRING uniSymLink;
NTSTATUS ntStatus;
PDEVICE_OBJECT deviceObject = NULL;
DbgPrint("当前被调用程序的进程ID: %d\n",PsGetCurrentProcessId());
DbgPrint("Hello I am Loading.....\n");
RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME);
RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);
DriverObject->MajorFunction =
DriverObject->MajorFunction = DispatchCreateClose;
DriverObject->MajorFunction = DispatchIoctl;
DriverObject->DriverUnload = UnloadDriver;
ntStatus = IoCreateDevice(DriverObject, 0,&uniDeviceName,FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN, FALSE,&deviceObject);
if (!NT_SUCCESS(ntStatus)) return ntStatus;
ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName);
if (!NT_SUCCESS(ntStatus))
{
IoDeleteDevice(deviceObject);
return ntStatus;
}
KeInitializeSpinLock(&spinLock);
KeServiceDescriptorTableShadow=(PSYSTEM_SERVICE_TABLE)GetShadowTableAddress();
if (!KeServiceDescriptorTableShadow)
{
return STATUS_UNSUCCESSFUL;
}
DbgPrint("%d",NtBuildNumber);
//DbgPrint("driver loaded!\n");
return STATUS_SUCCESS;
}
NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT pDevObj,INPIRP pIrp)
{
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;//STATUS_UNSUCCESSFUL;//
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
ULONG inBufLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG outBufLength =pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
PVOID OutputBuffer = pIrp->UserBuffer;
PVOID InputBuffer= pIrp->AssociatedIrp.SystemBuffer;
switch(uIoControlCode)
{
case IOCTL_Hook:
{ //不要输入任何信息 直接取IO线程的信息
if (!ProtectedProcess&&!ProtectedThread)
{
ProtectedProcess=PsGetCurrentProcess();
ProtectedThread=PsGetCurrentThread();
StartHook();
ntStatus=STATUS_SUCCESS;
}
break;
}
case IOCTL_UnHook:
{
if (ProtectedProcess&&ProtectedThread)
{
StopHook();
ProtectedProcess=NULL;
ProtectedThread=NULL;
ntStatus=STATUS_SUCCESS;
}
break;
}
}
pIrp->IoStatus.Status = ntStatus;
//pIrp->IoStatus.Information = outBufLength;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return ntStatus;
}
//卸载驱动前一定要先通过IO线程把钩子卸载了 否则必蓝.
VOID UnloadDriver( IN PDRIVER_OBJECT DriverObject )
{
PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
UNICODE_STRING uniSymLink;
RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);
//DbgPrint("driver unloaded.\n");
IoDeleteSymbolicLink(&uniSymLink);
IoDeleteDevice(deviceObject);
}
路过 看帖是一种习惯,不过我回帖也是一种习惯 更是一种美德 打酱油的啦,飘过赚点海币而已。 穿自己的鞋,走别人的路,让他们找去说吧,
页:
[1]