init
This commit is contained in:
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 64 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "headers.hpp"
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#pragma warning(push, 0)
|
||||
#pragma warning(disable: 4701 4706 26451)
|
||||
|
||||
#include "hde64.h"
|
||||
#include "table64.h"
|
||||
|
||||
unsigned int hde64_disasm(const void* code, hde64s* hs)
|
||||
{
|
||||
uint8_t x, c, * p = (uint8_t*)code, cflags, opcode, pref = 0;
|
||||
uint8_t* ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0;
|
||||
uint8_t op64 = 0;
|
||||
|
||||
// Avoid using memset to reduce the footprint.
|
||||
memset(hs, 0, sizeof(hde64s));
|
||||
|
||||
for (x = 16; x; x--)
|
||||
switch (c = *p++) {
|
||||
case 0xf3:
|
||||
hs->p_rep = c;
|
||||
pref |= PRE_F3;
|
||||
break;
|
||||
case 0xf2:
|
||||
hs->p_rep = c;
|
||||
pref |= PRE_F2;
|
||||
break;
|
||||
case 0xf0:
|
||||
hs->p_lock = c;
|
||||
pref |= PRE_LOCK;
|
||||
break;
|
||||
case 0x26: case 0x2e: case 0x36:
|
||||
case 0x3e: case 0x64: case 0x65:
|
||||
hs->p_seg = c;
|
||||
pref |= PRE_SEG;
|
||||
break;
|
||||
case 0x66:
|
||||
hs->p_66 = c;
|
||||
pref |= PRE_66;
|
||||
break;
|
||||
case 0x67:
|
||||
hs->p_67 = c;
|
||||
pref |= PRE_67;
|
||||
break;
|
||||
default:
|
||||
goto pref_done;
|
||||
}
|
||||
pref_done:
|
||||
|
||||
hs->flags = (uint32_t)pref << 23;
|
||||
|
||||
if (!pref)
|
||||
pref |= PRE_NONE;
|
||||
|
||||
if ((c & 0xf0) == 0x40) {
|
||||
hs->flags |= F_PREFIX_REX;
|
||||
if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
|
||||
op64++;
|
||||
hs->rex_r = (c & 7) >> 2;
|
||||
hs->rex_x = (c & 3) >> 1;
|
||||
hs->rex_b = c & 1;
|
||||
if (((c = *p++) & 0xf0) == 0x40) {
|
||||
opcode = c;
|
||||
goto error_opcode;
|
||||
}
|
||||
}
|
||||
|
||||
if ((hs->opcode = c) == 0x0f) {
|
||||
hs->opcode2 = c = *p++;
|
||||
ht += DELTA_OPCODES;
|
||||
}
|
||||
else if (c >= 0xa0 && c <= 0xa3) {
|
||||
op64++;
|
||||
if (pref & PRE_67)
|
||||
pref |= PRE_66;
|
||||
else
|
||||
pref &= ~PRE_66;
|
||||
}
|
||||
|
||||
opcode = c;
|
||||
cflags = ht[ht[opcode / 4] + (opcode % 4)];
|
||||
|
||||
if (cflags == C_ERROR) {
|
||||
error_opcode:
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
cflags = 0;
|
||||
if ((opcode & -3) == 0x24)
|
||||
cflags++;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
if (cflags & C_GROUP) {
|
||||
uint16_t t;
|
||||
t = *(uint16_t*)(ht + (cflags & 0x7f));
|
||||
cflags = (uint8_t)t;
|
||||
x = (uint8_t)(t >> 8);
|
||||
}
|
||||
|
||||
if (hs->opcode2) {
|
||||
ht = hde64_table + DELTA_PREFIXES;
|
||||
if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
}
|
||||
|
||||
if (cflags & C_MODRM) {
|
||||
hs->flags |= F_MODRM;
|
||||
hs->modrm = c = *p++;
|
||||
hs->modrm_mod = m_mod = c >> 6;
|
||||
hs->modrm_rm = m_rm = c & 7;
|
||||
hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
|
||||
|
||||
if (x && ((x << m_reg) & 0x80))
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
|
||||
if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
|
||||
uint8_t t = opcode - 0xd9;
|
||||
if (m_mod == 3) {
|
||||
ht = hde64_table + DELTA_FPU_MODRM + t * 8;
|
||||
t = ht[m_reg] << m_rm;
|
||||
}
|
||||
else {
|
||||
ht = hde64_table + DELTA_FPU_REG;
|
||||
t = ht[t] << m_reg;
|
||||
}
|
||||
if (t & 0x80)
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
}
|
||||
|
||||
if (pref & PRE_LOCK) {
|
||||
if (m_mod == 3) {
|
||||
hs->flags |= F_ERROR | F_ERROR_LOCK;
|
||||
}
|
||||
else {
|
||||
uint8_t* table_end, op = opcode;
|
||||
if (hs->opcode2) {
|
||||
ht = hde64_table + DELTA_OP2_LOCK_OK;
|
||||
table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
|
||||
}
|
||||
else {
|
||||
ht = hde64_table + DELTA_OP_LOCK_OK;
|
||||
table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
|
||||
op &= -2;
|
||||
}
|
||||
for (; ht != table_end; ht++)
|
||||
if (*ht++ == op) {
|
||||
if (!((*ht << m_reg) & 0x80))
|
||||
goto no_lock_error;
|
||||
else
|
||||
break;
|
||||
}
|
||||
hs->flags |= F_ERROR | F_ERROR_LOCK;
|
||||
no_lock_error:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (hs->opcode2) {
|
||||
switch (opcode) {
|
||||
case 0x20: case 0x22:
|
||||
m_mod = 3;
|
||||
if (m_reg > 4 || m_reg == 1)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
case 0x21: case 0x23:
|
||||
m_mod = 3;
|
||||
if (m_reg == 4 || m_reg == 5)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (opcode) {
|
||||
case 0x8c:
|
||||
if (m_reg > 5)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
case 0x8e:
|
||||
if (m_reg == 1 || m_reg > 5)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mod == 3) {
|
||||
uint8_t* table_end;
|
||||
if (hs->opcode2) {
|
||||
ht = hde64_table + DELTA_OP2_ONLY_MEM;
|
||||
table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM;
|
||||
}
|
||||
else {
|
||||
ht = hde64_table + DELTA_OP_ONLY_MEM;
|
||||
table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
|
||||
}
|
||||
for (; ht != table_end; ht += 2)
|
||||
if (*ht++ == opcode) {
|
||||
if (*ht++ & pref && !((*ht << m_reg) & 0x80))
|
||||
goto error_operand;
|
||||
else
|
||||
break;
|
||||
}
|
||||
goto no_error_operand;
|
||||
}
|
||||
else if (hs->opcode2) {
|
||||
switch (opcode) {
|
||||
case 0x50: case 0xd7: case 0xf7:
|
||||
if (pref & (PRE_NONE | PRE_66))
|
||||
goto error_operand;
|
||||
break;
|
||||
case 0xd6:
|
||||
if (pref & (PRE_F2 | PRE_F3))
|
||||
goto error_operand;
|
||||
break;
|
||||
case 0xc5:
|
||||
goto error_operand;
|
||||
}
|
||||
goto no_error_operand;
|
||||
}
|
||||
else
|
||||
goto no_error_operand;
|
||||
|
||||
error_operand:
|
||||
hs->flags |= F_ERROR | F_ERROR_OPERAND;
|
||||
no_error_operand:
|
||||
|
||||
c = *p++;
|
||||
if (m_reg <= 1) {
|
||||
if (opcode == 0xf6)
|
||||
cflags |= C_IMM8;
|
||||
else if (opcode == 0xf7)
|
||||
cflags |= C_IMM_P66;
|
||||
}
|
||||
|
||||
switch (m_mod) {
|
||||
case 0:
|
||||
if (pref & PRE_67) {
|
||||
if (m_rm == 6)
|
||||
disp_size = 2;
|
||||
}
|
||||
else
|
||||
if (m_rm == 5)
|
||||
disp_size = 4;
|
||||
break;
|
||||
case 1:
|
||||
disp_size = 1;
|
||||
break;
|
||||
case 2:
|
||||
disp_size = 2;
|
||||
if (!(pref & PRE_67))
|
||||
disp_size <<= 1;
|
||||
}
|
||||
|
||||
if (m_mod != 3 && m_rm == 4) {
|
||||
hs->flags |= F_SIB;
|
||||
p++;
|
||||
hs->sib = c;
|
||||
hs->sib_scale = c >> 6;
|
||||
hs->sib_index = (c & 0x3f) >> 3;
|
||||
if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
|
||||
disp_size = 4;
|
||||
}
|
||||
|
||||
p--;
|
||||
switch (disp_size) {
|
||||
case 1:
|
||||
hs->flags |= F_DISP8;
|
||||
hs->disp.disp8 = *p;
|
||||
break;
|
||||
case 2:
|
||||
hs->flags |= F_DISP16;
|
||||
hs->disp.disp16 = *(uint16_t*)p;
|
||||
break;
|
||||
case 4:
|
||||
hs->flags |= F_DISP32;
|
||||
hs->disp.disp32 = *(uint32_t*)p;
|
||||
}
|
||||
p += disp_size;
|
||||
}
|
||||
else if (pref & PRE_LOCK)
|
||||
hs->flags |= F_ERROR | F_ERROR_LOCK;
|
||||
|
||||
if (cflags & C_IMM_P66) {
|
||||
if (cflags & C_REL32) {
|
||||
if (pref & PRE_66) {
|
||||
hs->flags |= F_IMM16 | F_RELATIVE;
|
||||
hs->imm.imm16 = *(uint16_t*)p;
|
||||
p += 2;
|
||||
goto disasm_done;
|
||||
}
|
||||
goto rel32_ok;
|
||||
}
|
||||
if (op64) {
|
||||
hs->flags |= F_IMM64;
|
||||
hs->imm.imm64 = *(uint64_t*)p;
|
||||
p += 8;
|
||||
}
|
||||
else if (!(pref & PRE_66)) {
|
||||
hs->flags |= F_IMM32;
|
||||
hs->imm.imm32 = *(uint32_t*)p;
|
||||
p += 4;
|
||||
}
|
||||
else
|
||||
goto imm16_ok;
|
||||
}
|
||||
|
||||
if (cflags & C_IMM16) {
|
||||
imm16_ok:
|
||||
hs->flags |= F_IMM16;
|
||||
hs->imm.imm16 = *(uint16_t*)p;
|
||||
p += 2;
|
||||
}
|
||||
if (cflags & C_IMM8) {
|
||||
hs->flags |= F_IMM8;
|
||||
hs->imm.imm8 = *p++;
|
||||
}
|
||||
|
||||
if (cflags & C_REL32) {
|
||||
rel32_ok:
|
||||
hs->flags |= F_IMM32 | F_RELATIVE;
|
||||
hs->imm.imm32 = *(uint32_t*)p;
|
||||
p += 4;
|
||||
}
|
||||
else if (cflags & C_REL8) {
|
||||
hs->flags |= F_IMM8 | F_RELATIVE;
|
||||
hs->imm.imm8 = *p++;
|
||||
}
|
||||
|
||||
disasm_done:
|
||||
|
||||
if ((hs->len = (uint8_t)(p - (uint8_t*)code)) > 15) {
|
||||
hs->flags |= F_ERROR | F_ERROR_LENGTH;
|
||||
hs->len = 15;
|
||||
}
|
||||
|
||||
return (unsigned int)hs->len;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
#endif // defined(_M_X64) || defined(__x86_64__)
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 64
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
* hde64.h: C/C++ header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _HDE64_H_
|
||||
#define _HDE64_H_
|
||||
|
||||
/* stdint.h - C99 standard header
|
||||
* http://en.wikipedia.org/wiki/stdint.h
|
||||
*
|
||||
* if your compiler doesn't contain "stdint.h" header (for
|
||||
* example, Microsoft Visual C++), you can download file:
|
||||
* http://www.azillionmonkeys.com/qed/pstdint.h
|
||||
* and change next line to:
|
||||
* #include "pstdint.h"
|
||||
*/
|
||||
#include "pstdint.h"
|
||||
|
||||
#define F_MODRM 0x00000001
|
||||
#define F_SIB 0x00000002
|
||||
#define F_IMM8 0x00000004
|
||||
#define F_IMM16 0x00000008
|
||||
#define F_IMM32 0x00000010
|
||||
#define F_IMM64 0x00000020
|
||||
#define F_DISP8 0x00000040
|
||||
#define F_DISP16 0x00000080
|
||||
#define F_DISP32 0x00000100
|
||||
#define F_RELATIVE 0x00000200
|
||||
#define F_ERROR 0x00001000
|
||||
#define F_ERROR_OPCODE 0x00002000
|
||||
#define F_ERROR_LENGTH 0x00004000
|
||||
#define F_ERROR_LOCK 0x00008000
|
||||
#define F_ERROR_OPERAND 0x00010000
|
||||
#define F_PREFIX_REPNZ 0x01000000
|
||||
#define F_PREFIX_REPX 0x02000000
|
||||
#define F_PREFIX_REP 0x03000000
|
||||
#define F_PREFIX_66 0x04000000
|
||||
#define F_PREFIX_67 0x08000000
|
||||
#define F_PREFIX_LOCK 0x10000000
|
||||
#define F_PREFIX_SEG 0x20000000
|
||||
#define F_PREFIX_REX 0x40000000
|
||||
#define F_PREFIX_ANY 0x7f000000
|
||||
|
||||
#define PREFIX_SEGMENT_CS 0x2e
|
||||
#define PREFIX_SEGMENT_SS 0x36
|
||||
#define PREFIX_SEGMENT_DS 0x3e
|
||||
#define PREFIX_SEGMENT_ES 0x26
|
||||
#define PREFIX_SEGMENT_FS 0x64
|
||||
#define PREFIX_SEGMENT_GS 0x65
|
||||
#define PREFIX_LOCK 0xf0
|
||||
#define PREFIX_REPNZ 0xf2
|
||||
#define PREFIX_REPX 0xf3
|
||||
#define PREFIX_OPERAND_SIZE 0x66
|
||||
#define PREFIX_ADDRESS_SIZE 0x67
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct {
|
||||
uint8_t len;
|
||||
uint8_t p_rep;
|
||||
uint8_t p_lock;
|
||||
uint8_t p_seg;
|
||||
uint8_t p_66;
|
||||
uint8_t p_67;
|
||||
uint8_t rex;
|
||||
uint8_t rex_w;
|
||||
uint8_t rex_r;
|
||||
uint8_t rex_x;
|
||||
uint8_t rex_b;
|
||||
uint8_t opcode;
|
||||
uint8_t opcode2;
|
||||
uint8_t modrm;
|
||||
uint8_t modrm_mod;
|
||||
uint8_t modrm_reg;
|
||||
uint8_t modrm_rm;
|
||||
uint8_t sib;
|
||||
uint8_t sib_scale;
|
||||
uint8_t sib_index;
|
||||
uint8_t sib_base;
|
||||
union {
|
||||
uint8_t imm8;
|
||||
uint16_t imm16;
|
||||
uint32_t imm32;
|
||||
uint64_t imm64;
|
||||
} imm;
|
||||
union {
|
||||
uint8_t disp8;
|
||||
uint16_t disp16;
|
||||
uint32_t disp32;
|
||||
} disp;
|
||||
uint32_t flags;
|
||||
} hde64s;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* __cdecl */
|
||||
unsigned int hde64_disasm(const void *code, hde64s *hs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HDE64_H_ */
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <ntifs.h>
|
||||
#include <ntdef.h>
|
||||
#include <ntddk.h>
|
||||
#include <wdm.h>
|
||||
#include <ntstatus.h>
|
||||
#include <ntimage.h>
|
||||
#include <ntstrsafe.h>
|
||||
#include <intrin.h>
|
||||
#include <intsafe.h>
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Integer types for HDE.
|
||||
typedef INT8 int8_t;
|
||||
typedef INT16 int16_t;
|
||||
typedef INT32 int32_t;
|
||||
typedef INT64 int64_t;
|
||||
typedef UINT8 uint8_t;
|
||||
typedef UINT16 uint16_t;
|
||||
typedef UINT32 uint32_t;
|
||||
typedef UINT64 uint64_t;
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 64 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#define C_NONE 0x00
|
||||
#define C_MODRM 0x01
|
||||
#define C_IMM8 0x02
|
||||
#define C_IMM16 0x04
|
||||
#define C_IMM_P66 0x10
|
||||
#define C_REL8 0x20
|
||||
#define C_REL32 0x40
|
||||
#define C_GROUP 0x80
|
||||
#define C_ERROR 0xff
|
||||
|
||||
#define PRE_ANY 0x00
|
||||
#define PRE_NONE 0x01
|
||||
#define PRE_F2 0x02
|
||||
#define PRE_F3 0x04
|
||||
#define PRE_66 0x08
|
||||
#define PRE_67 0x10
|
||||
#define PRE_LOCK 0x20
|
||||
#define PRE_SEG 0x40
|
||||
#define PRE_ALL 0xff
|
||||
|
||||
#define DELTA_OPCODES 0x4a
|
||||
#define DELTA_FPU_REG 0xfd
|
||||
#define DELTA_FPU_MODRM 0x104
|
||||
#define DELTA_PREFIXES 0x13c
|
||||
#define DELTA_OP_LOCK_OK 0x1ae
|
||||
#define DELTA_OP2_LOCK_OK 0x1c6
|
||||
#define DELTA_OP_ONLY_MEM 0x1d8
|
||||
#define DELTA_OP2_ONLY_MEM 0x1e7
|
||||
|
||||
unsigned char hde64_table[] = {
|
||||
0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
|
||||
0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
|
||||
0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
|
||||
0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
|
||||
0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
|
||||
0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
|
||||
0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
|
||||
0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
|
||||
0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
|
||||
0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
|
||||
0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
|
||||
0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
|
||||
0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
|
||||
0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
|
||||
0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
|
||||
0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
|
||||
0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00,
|
||||
0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
|
||||
0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,
|
||||
0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
|
||||
0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
|
||||
0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
||||
0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
|
||||
0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
|
||||
0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
|
||||
0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
|
||||
0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10,
|
||||
0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00,
|
||||
0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb,
|
||||
0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff,
|
||||
0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09,
|
||||
0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff,
|
||||
0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08,
|
||||
0x00,0xf0,0x02,0x00
|
||||
};
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "inline_hooks.h"
|
||||
#include "kernel_function.h"
|
||||
#include "hde/hde64.h"
|
||||
|
||||
#pragma warning(disable : 4309 4838)
|
||||
|
||||
inline_hooks_manager* inline_hooks_manager::instance;
|
||||
|
||||
inline_hooks_manager* inline_hooks_manager::fn_get_instance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
{
|
||||
instance = (inline_hooks_manager*)ExAllocatePoolWithTag(NonPagedPool, sizeof(inline_hooks_manager), 'hook');
|
||||
|
||||
instance->m_cur_hook_count = 0;
|
||||
instance->m_trampo_line = (unsigned char*)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'line');
|
||||
RtlSecureZeroMemory(instance->m_Info, sizeof(HOOK_INFO) * HOOK_MAX_COUNT);
|
||||
RtlSecureZeroMemory(instance->m_trampo_line, PAGE_SIZE);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto inline_hooks_manager::inline_install_hook(void* target_func, void* my_function, void** origon_func) -> BOOL
|
||||
{
|
||||
if (m_cur_hook_count > HOOK_MAX_COUNT)
|
||||
return FALSE;
|
||||
|
||||
auto ori_func_addr = reinterpret_cast<unsigned char*>(target_func);
|
||||
|
||||
hde64s hde{ 0 };
|
||||
uint64_t break_byte_count = NULL;
|
||||
while (break_byte_count < 14)
|
||||
{
|
||||
hde64_disasm(ori_func_addr + break_byte_count, &hde);
|
||||
break_byte_count += hde.len;
|
||||
}
|
||||
|
||||
//保存原来的hook信息方便进行恢复
|
||||
m_Info[m_cur_hook_count].origon_func = target_func;
|
||||
memcpy(m_Info[m_cur_hook_count].destroy_code, target_func, 14);
|
||||
m_cur_hook_count++;
|
||||
|
||||
//开始hook
|
||||
//2D963190000 - FF25 00000000 A09AA40CFC7F0000 - jmp USER32.GetWindow
|
||||
char jmpcode[14] = { 0xFF,0x25,0,0,0,0,0xA0,0x9A,0xA4,0x0C,0xFC,0x7F,0x00,0x00 };
|
||||
*(uint64_t*)&jmpcode[6] = (uint64_t)my_function;
|
||||
|
||||
//蹦床构建
|
||||
*origon_func = bulid_trampo_line(ori_func_addr, break_byte_count);
|
||||
|
||||
auto status = kernel_function::MmMDLPagesCopy(ori_func_addr, &jmpcode, sizeof(jmpcode), 0x0000002, KernelMode);
|
||||
if (!NT_SUCCESS(status))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
auto inline_hooks_manager::inline_remov_hook(void** origon_func) -> BOOL
|
||||
{
|
||||
for (size_t i = 0; i < HOOK_MAX_COUNT; i++)
|
||||
{
|
||||
if (m_cur_hook_count <= i)
|
||||
break;
|
||||
|
||||
if (m_Info[i].origon_func)
|
||||
{
|
||||
if (m_Info[i].origon_func == origon_func)
|
||||
{
|
||||
kernel_function::MmMDLPagesCopy(m_Info[i].origon_func,
|
||||
&m_Info[i].destroy_code, 14, 0x0000002, KernelMode);
|
||||
}
|
||||
|
||||
if (origon_func == nullptr) {
|
||||
kernel_function::MmMDLPagesCopy(m_Info[i].origon_func,
|
||||
&m_Info[i].destroy_code, 14, 0x0000002, KernelMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
auto inline_hooks_manager::bulid_trampo_line(void* target_func, UINT64 break_byte_count) -> void*
|
||||
{
|
||||
//push 低32位
|
||||
//mov[rsp+4],高32位
|
||||
//ret
|
||||
|
||||
/*138DADF0000 - 68 A09AA40C - push 0CA49AA0
|
||||
138DADF0005 - C7 44 24 04 FC7F0000 - mov[rsp + 04], 00007FFC
|
||||
138DADF000D - C3 - ret*/
|
||||
|
||||
char push_mov_ret[] =
|
||||
{ 0x68, 0xA0, 0x9A, 0xA4, 0x0C,
|
||||
0xC7, 0x44, 0x24, 0x04, 0xFC, 0x7F, 0x00, 0x00,
|
||||
0xC3
|
||||
};
|
||||
|
||||
*(uint32_t*)&push_mov_ret[1] = (((uint64_t)target_func + break_byte_count) & 0xffffffff);
|
||||
*(uint32_t*)&push_mov_ret[9] = ((((uint64_t)target_func + break_byte_count) >> 32) & 0xffffffff);
|
||||
|
||||
memcpy(instance->m_trampo_line, target_func, break_byte_count);
|
||||
memcpy(instance->m_trampo_line + break_byte_count, &push_mov_ret, sizeof(push_mov_ret));
|
||||
|
||||
auto ret = reinterpret_cast<void*>(instance->m_trampo_line);
|
||||
|
||||
instance->m_trampo_line += break_byte_count + sizeof(push_mov_ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "Base.h"
|
||||
|
||||
#define HOOK_MAX_COUNT 0x100
|
||||
|
||||
typedef struct _HOOK_INFO
|
||||
{
|
||||
void* origon_func;
|
||||
|
||||
unsigned char* destroy_code[14];
|
||||
|
||||
unsigned char* m_trampo_line;
|
||||
|
||||
}HOOK_INFO, * PHOOK_INFO;
|
||||
|
||||
|
||||
class inline_hooks_manager
|
||||
{
|
||||
public:
|
||||
static inline_hooks_manager* fn_get_instance();
|
||||
|
||||
auto inline_install_hook(void* target_func,void* my_function, void** origon_func) -> BOOL;
|
||||
|
||||
auto inline_remov_hook(void** origon_func)->BOOL;
|
||||
|
||||
auto inline_remov_all_hook()->BOOL;
|
||||
|
||||
auto bulid_trampo_line(void* target_func, UINT64 break_byte_count) -> void*;
|
||||
|
||||
private:
|
||||
static inline_hooks_manager* instance;
|
||||
unsigned char* m_trampo_line;
|
||||
|
||||
UINT64 m_cur_hook_count;
|
||||
_HOOK_INFO m_Info[HOOK_MAX_COUNT];
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "mouse_key_win10.h"
|
||||
#include "mouse_keybord_hook.h"
|
||||
#include "inline_hooks.h"
|
||||
|
||||
|
||||
fnNtUserSendInput_win10 origon_NtUserSendInput_win10;
|
||||
|
||||
|
||||
|
||||
namespace mouse_key_win10
|
||||
{
|
||||
__int64 __fastcall hkNtUserSendInput(unsigned int a1, volatile void* a2, int a3, int a4)
|
||||
{
|
||||
|
||||
DbgPrintEx(77, 0, "%d\n", PsGetCurrentProcessId());
|
||||
|
||||
return origon_NtUserSendInput_win10(a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "Base.h"
|
||||
|
||||
typedef __int64(__fastcall* fnNtUserSendInput_win10)(unsigned int a1, volatile void* a2, int a3, int a4);
|
||||
extern fnNtUserSendInput_win10 origon_NtUserSendInput_win10;
|
||||
|
||||
namespace mouse_key_win10
|
||||
{
|
||||
__int64 __fastcall hkNtUserSendInput(unsigned int a1, volatile void* a2, int a3, int a4);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#pragma once
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "mouse_keybord_hook.h"
|
||||
#include "shadow_ssdt.h"
|
||||
#include "kernel_function.h"
|
||||
#include "utils.h"
|
||||
#include "inline_hooks.h"
|
||||
#include "mouse_key_win10.h"
|
||||
#include "mouse_key_win7.h"
|
||||
|
||||
|
||||
|
||||
namespace mouse_keybord_hook
|
||||
{
|
||||
unsigned char* _ntSendInput;
|
||||
|
||||
auto get_sendinput_hook_addr() -> unsigned char*
|
||||
{
|
||||
auto os = utils::GetVersion();
|
||||
if (os.dwBuildNumber == 7600 || os.dwBuildNumber == 7601)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if (os.dwBuildNumber >= 26100)
|
||||
{
|
||||
auto gSessionGlobalSlots = kernel_function::GetgSessionGlobalSlots();
|
||||
|
||||
auto W32GetSessionState = *(ULONG64*)(*(ULONG64*)((*(ULONG64*)gSessionGlobalSlots)) + 0x88);
|
||||
W32GetSessionState = *(ULONG64*)(W32GetSessionState + 0x150);
|
||||
auto NtUserSendInput = *(unsigned char**)(W32GetSessionState + 0xB18);
|
||||
|
||||
return NtUserSendInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto function = reinterpret_cast<unsigned char*>(ShadowSSDT::fn_get_shadowssdt_extport_func("NtUserSendInput"));
|
||||
if (!function)
|
||||
return NULL;
|
||||
|
||||
unsigned int break_byte_count = 0;
|
||||
unsigned int index = 0;
|
||||
while (break_byte_count < 2)
|
||||
{
|
||||
if (function[index++] == 0x48)
|
||||
break_byte_count++;
|
||||
}
|
||||
|
||||
return *(unsigned char**)((*(ULONG*)&function[index + 2]) + &function[index + 6]);
|
||||
}
|
||||
}
|
||||
|
||||
auto install_mouse_keybord_hook() -> BOOL
|
||||
{
|
||||
auto _eprocess_process = kernel_function::FindProcess("winlogon.exe");
|
||||
if (!_eprocess_process)
|
||||
return FALSE;
|
||||
|
||||
auto apc_state = kernel_function::ke_stack_attch_process(_eprocess_process);
|
||||
|
||||
_ntSendInput = get_sendinput_hook_addr();
|
||||
|
||||
auto os = utils::GetVersion();
|
||||
if (os.dwBuildNumber == 7600 || os.dwBuildNumber == 7601)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
inline_hooks_manager::fn_get_instance()->inline_install_hook(_ntSendInput, mouse_key_win10::hkNtUserSendInput, (void**)&origon_NtUserSendInput_win10);
|
||||
}
|
||||
|
||||
kernel_function::ke_unstack_detach_process(apc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto remove_mouse_keybord_hook() -> BOOL
|
||||
{
|
||||
auto _eprocess_process = kernel_function::FindProcess("winlogon.exe");
|
||||
if (!_eprocess_process)
|
||||
return FALSE;
|
||||
|
||||
auto apc_state = kernel_function::ke_stack_attch_process(_eprocess_process);
|
||||
|
||||
inline_hooks_manager::fn_get_instance()->inline_remov_hook((void**)_ntSendInput);
|
||||
|
||||
kernel_function::ke_unstack_detach_process(apc_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "Base.h"
|
||||
|
||||
namespace mouse_keybord_hook
|
||||
{
|
||||
auto get_sendinput_hook_addr() -> unsigned char*;
|
||||
|
||||
auto install_mouse_keybord_hook()->BOOL;
|
||||
|
||||
auto remove_mouse_keybord_hook()->BOOL;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "shadow_ssdt.h"
|
||||
#include "kernel_function.h"
|
||||
#include "kernel_api.h"
|
||||
#include "utils.h"
|
||||
|
||||
PULONG W32pServiceTable = nullptr;
|
||||
|
||||
|
||||
namespace ShadowSSDT
|
||||
{
|
||||
ULONG64 get_sssdt_func_addr(ULONG id) {
|
||||
LONG dwtmp = 0;
|
||||
PULONG ServiceTableBase = NULL;
|
||||
ServiceTableBase = W32pServiceTable;
|
||||
dwtmp = ServiceTableBase[id];
|
||||
dwtmp = dwtmp >> 4;
|
||||
return (LONGLONG)dwtmp + (ULONGLONG)ServiceTableBase;
|
||||
}
|
||||
|
||||
auto get_sssdt_extport_func_win10(const char* func_name)-> uintptr_t
|
||||
{
|
||||
uintptr_t fun_addrss = 0;
|
||||
|
||||
auto process = kernel_function::FindProcess("explorer.exe");
|
||||
if (!process)
|
||||
{
|
||||
DbgPrintEx(77, 0, "[+]get explorer fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto win32k_base = reinterpret_cast<PVOID>(kernel_function::GetKernelModule("win32k.sys"));
|
||||
if (!win32k_base)
|
||||
{
|
||||
ObDereferenceObject(process);
|
||||
DbgPrintEx(77, 0, "[+]get win32k_base fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
KAPC_STATE apc_state{ 0 };
|
||||
KeStackAttachProcess(process, &apc_state);
|
||||
W32pServiceTable = (PULONG)kernel_api::rtlfindexportedroutinebyname(win32k_base, "W32pServiceTable");
|
||||
if (!W32pServiceTable)
|
||||
{
|
||||
KeUnstackDetachProcess(&apc_state);
|
||||
ObDereferenceObject(process);
|
||||
DbgPrintEx(77, 0, "[+] getW32pServiceTable fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
auto pdos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(win32k_base);
|
||||
auto pNt_header = reinterpret_cast<PIMAGE_NT_HEADERS>((char*)win32k_base + pdos_header->e_lfanew);
|
||||
|
||||
|
||||
//±éÀúµ¼³ö±í
|
||||
const auto export_table = pNt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
const auto export_data = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>((char*)win32k_base + export_table.VirtualAddress);
|
||||
|
||||
const auto func_name_tab = reinterpret_cast<ULONG*>((char*)win32k_base + export_data->AddressOfNames);
|
||||
const auto func_index_tab = reinterpret_cast<SHORT*>((char*)win32k_base + export_data->AddressOfNameOrdinals);
|
||||
const auto func_addr_tab = reinterpret_cast<ULONG*>((char*)win32k_base + export_data->AddressOfFunctions);
|
||||
|
||||
|
||||
for (size_t i = 0; i < export_data->NumberOfNames; i++)
|
||||
{
|
||||
const char* func_names = reinterpret_cast<const char*>((char*)win32k_base + func_name_tab[i]);
|
||||
|
||||
if (strstr(func_names, "__win32kstub_"))
|
||||
{
|
||||
const auto lpFunc_addr = reinterpret_cast<PUCHAR>((char*)win32k_base + func_addr_tab[func_index_tab[i]]);
|
||||
char* FunctionName = strstr(func_names, "Nt");
|
||||
if (!strcmp(FunctionName, func_name))
|
||||
{
|
||||
auto func_index = *(ULONG*)((uintptr_t)lpFunc_addr + 1);
|
||||
fun_addrss = get_sssdt_func_addr(func_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeUnstackDetachProcess(&apc_state);
|
||||
ObDereferenceObject(process);
|
||||
return fun_addrss;
|
||||
}
|
||||
|
||||
//auto get_sssdt_extport_func_win7(const char* func_name)
|
||||
//{
|
||||
// UNREFERENCED_PARAMETER(func_name);
|
||||
|
||||
// auto process = kernel_function::FindProcess("explorer.exe");
|
||||
// if (!process)
|
||||
// {
|
||||
// DbgPrintEx(77, 0, "[+]get explorer fail\n");
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// KAPC_STATE apc_state{ 0 };
|
||||
// KeStackAttachProcess(process, &apc_state);
|
||||
|
||||
// do
|
||||
// {
|
||||
// auto dwPid = PsGetProcessId(process);
|
||||
|
||||
// UNICODE_STRING module_name{ 0 };
|
||||
// RtlInitUnicodeString(&module_name, L"user32.dll");
|
||||
|
||||
// unsigned char* moudle_buff = nullptr;
|
||||
// auto status = kernel_function::GetProcessModule(dwPid, module_name, &moudle_buff);
|
||||
// if (!NT_SUCCESS(status))
|
||||
// break;
|
||||
|
||||
// //char* FunctionName = strstr(func_name, "Nt");
|
||||
|
||||
// //DbgPrintEx(77,0,"")
|
||||
|
||||
// /*auto func_addr = utils::get_hmodule_expotr_func(moudle_buff, FunctionName);
|
||||
// if (!func_addr)
|
||||
// break;
|
||||
|
||||
// auto func_index = *(UINT32*)(func_addr + 4);
|
||||
|
||||
// DbgPrintEx(77, 0, "%p | %d\n", func_addr, func_index);*/
|
||||
|
||||
|
||||
|
||||
// } while (0);
|
||||
|
||||
|
||||
// KeUnstackDetachProcess(&apc_state);
|
||||
// ObDereferenceObject(process);
|
||||
//}
|
||||
|
||||
|
||||
auto fn_get_shadowssdt_extport_func(const char* func_name) -> uintptr_t
|
||||
{
|
||||
auto os = utils::GetVersion();
|
||||
if (os.dwBuildNumber == 7600 || os.dwBuildNumber == 7601)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_sssdt_extport_func_win10(func_name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "Base.h"
|
||||
|
||||
namespace ShadowSSDT
|
||||
{
|
||||
|
||||
auto fn_get_shadowssdt_extport_func(CONST char* func_name)->uintptr_t;
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user