#
# Coded by @RceNinja 2019
#

import collections
import logging
import os
import idaapi
import idautils
import idc

msr_list = {

#
# Hyper-V MSRs
#
0x40000000 : 'HV_X64_MSR_GUEST_OS_ID',
0x40000001 : 'HV_X64_MSR_HYPERCALL',
0x40000002 : 'HV_X64_MSR_VP_INDEX',
0x40000003 : 'HV_X64_MSR_RESET',
0x40000010 : 'HV_X64_MSR_VP_RUNTIME',
0x40000020 : 'HV_X64_MSR_TIME_REF_COUNT',
0x40000021 : 'HV_X64_MSR_REFERENCE_TSC',
0x40000022 : 'HV_X64_MSR_TSC_FREQUENCY',
0x40000023 : 'HV_X64_MSR_APIC_FREQUENCY',
0x40000070 : 'HV_X64_MSR_EOI',
0x40000071 : 'HV_X64_MSR_ICR',
0x40000072 : 'HV_X64_MSR_TPR',
0x40000073 : 'HV_X64_MSR_VP_ASSIST_PAGE',
0x40000080 : 'HV_X64_MSR_SCONTROL',
0x40000081 : 'HV_X64_MSR_SVERSION',
0x40000082 : 'HV_X64_MSR_SIEFP',
0x40000083 : 'HV_X64_MSR_SIMP',
0x40000084 : 'HV_X64_MSR_EOM',
0x40000090 : 'HV_X64_MSR_SINT0',
0x40000091 : 'HV_X64_MSR_SINT1',
0x40000092 : 'HV_X64_MSR_SINT2',
0x40000093 : 'HV_X64_MSR_SINT3',
0x40000094 : 'HV_X64_MSR_SINT4',
0x40000095 : 'HV_X64_MSR_SINT5',
0x40000096 : 'HV_X64_MSR_SINT6',
0x40000097 : 'HV_X64_MSR_SINT7',
0x40000098 : 'HV_X64_MSR_SINT8',
0x40000099 : 'HV_X64_MSR_SINT9',
0x4000009A : 'HV_X64_MSR_SINT10',
0x4000009B : 'HV_X64_MSR_SINT11',
0x4000009C : 'HV_X64_MSR_SINT12',
0x4000009D : 'HV_X64_MSR_SINT13',
0x4000009E : 'HV_X64_MSR_SINT14',
0x4000009F : 'HV_X64_MSR_SINT15',
0x400000B0 : 'HV_X64_MSR_STIMER0_CONFIG',
0x400000B1 : 'HV_X64_MSR_STIMER0_COUNT',
0x400000B2 : 'HV_X64_MSR_STIMER1_CONFIG',
0x400000B3 : 'HV_X64_MSR_STIMER1_COUNT',
0x400000B4 : 'HV_X64_MSR_STIMER2_CONFIG',
0x400000B5 : 'HV_X64_MSR_STIMER2_COUNT',
0x400000B6 : 'HV_X64_MSR_STIMER3_CONFIG',
0x400000B7 : 'HV_X64_MSR_STIMER3_COUNT',
0x400000C1 : 'HV_X64_MSR_POWER_STATE_TRIGGER_C1',
0x400000C2 : 'HV_X64_MSR_POWER_STATE_TRIGGER_C2',
0x400000C3 : 'HV_X64_MSR_POWER_STATE_TRIGGER_C3',
0x400000D1 : 'HV_X64_MSR_POWER_STATE_CONFIG_C1',
0x400000D2 : 'HV_X64_MSR_POWER_STATE_CONFIG_C2',
0x400000D3 : 'HV_X64_MSR_POWER_STATE_CONFIG_C3',
0x400000E0 : 'HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE',
0x400000E1 : 'HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE',
0x400000E2 : 'HV_X64_MSR_STATS_VP_RETAIL_PAGE',
0x400000E3 : 'HV_X64_MSR_STATS_VP_INTERNAL_PAGE',
0x400000F0 : 'HV_X64_MSR_GUEST_IDLE',
0x400000F1 : 'HV_X64_MSR_SYNTH_DEBUG_CONTROL',
0x400000F2 : 'HV_X64_MSR_SYNTH_DEBUG_STATUS',
0x400000F3 : 'HV_X64_MSR_SYNTH_DEBUG_SEND_BUFFER',
0x400000F4 : 'HV_X64_MSR_SYNTH_DEBUG_RECEIVE_BUFFER',
0x400000F5 : 'HV_X64_MSR_SYNTH_DEBUG_PENDING_BUFFER',
0x40000100 : 'HV_X64_MSR_CRASH_P0',
0x40000101 : 'HV_X64_MSR_CRASH_P1',
0x40000102 : 'HV_X64_MSR_CRASH_P2',
0x40000103 : 'HV_X64_MSR_CRASH_P3',
0x40000104 : 'HV_X64_MSR_CRASH_P4',
0x40000105 : 'HV_X64_MSR_CRASH_CTL',

0x40000106 : 'HV_X64_MSR_REENLIGHTENMENT_CONTROL',
0x40000107 : 'HV_X64_MSR_TSC_EMULATION_CONTROL',
0x40000108 : 'HV_X64_MSR_TSC_EMULATION_STATUS',


#
# XEON MSRs
#
0x0000004E : 'MSR_XEON_D_PPIN_CTL',
0x0000004F : 'MSR_XEON_D_PPIN',
0x000000CE : 'MSR_XEON_D_PLATFORM_INFO',
0x000000E2 : 'MSR_XEON_D_PKG_CST_CONFIG_CONTROL',
0x00000179 : 'MSR_XEON_D_IA32_MCG_CAP',
0x0000017D : 'MSR_XEON_D_SMM_MCA_CAP',
0x000001A2 : 'MSR_XEON_D_TEMPERATURE_TARGET',
0x000001AD : 'MSR_XEON_D_TURBO_RATIO_LIMIT',
0x000001AE : 'MSR_XEON_D_TURBO_RATIO_LIMIT1',
0x00000606 : 'MSR_XEON_D_RAPL_POWER_UNIT',
0x00000618 : 'MSR_XEON_D_DRAM_POWER_LIMIT',
0x00000619 : 'MSR_XEON_D_DRAM_ENERGY_STATUS',
0x0000061B : 'MSR_XEON_D_DRAM_PERF_STATUS',
0x0000061C : 'MSR_XEON_D_DRAM_POWER_INFO',
0x00000620 : 'MSR_XEON_D_MSRUNCORE_RATIO_LIMIT',
0x00000639 : 'MSR_XEON_D_PP0_ENERGY_STATUS',
0x00000690 : 'MSR_XEON_D_CORE_PERF_LIMIT_REASONS',
0x00000C8D : 'MSR_XEON_D_IA32_QM_EVTSEL',
0x00000C8F : 'MSR_XEON_D_IA32_PQR_ASSOC',
0x000001AC : 'MSR_XEON_D_TURBO_RATIO_LIMIT3',
0x00000C81 : 'MSR_XEON_D_IA32_L3_QOS_CFG',
0x00000C90 : 'MSR_XEON_D_IA32_L3_QOS_MASK_0',
0x00000C91 : 'MSR_XEON_D_IA32_L3_QOS_MASK_1',
0x00000C92 : 'MSR_XEON_D_IA32_L3_QOS_MASK_2',
0x00000C93 : 'MSR_XEON_D_IA32_L3_QOS_MASK_3',
0x00000C94 : 'MSR_XEON_D_IA32_L3_QOS_MASK_4',
0x00000C95 : 'MSR_XEON_D_IA32_L3_QOS_MASK_5',
0x00000C96 : 'MSR_XEON_D_IA32_L3_QOS_MASK_6',
0x00000C97 : 'MSR_XEON_D_IA32_L3_QOS_MASK_7',
0x00000C98 : 'MSR_XEON_D_IA32_L3_QOS_MASK_8',
0x00000C99 : 'MSR_XEON_D_IA32_L3_QOS_MASK_9',
0x00000C9A : 'MSR_XEON_D_IA32_L3_QOS_MASK_10',
0x00000C9B : 'MSR_XEON_D_IA32_L3_QOS_MASK_11',
0x00000C9C : 'MSR_XEON_D_IA32_L3_QOS_MASK_12',
0x00000C9D : 'MSR_XEON_D_IA32_L3_QOS_MASK_13',
0x00000C9E : 'MSR_XEON_D_IA32_L3_QOS_MASK_14',
0x00000C9F : 'MSR_XEON_D_IA32_L3_QOS_MASK_15',



# 
# QQQQQQQQQQ
#

0x00000048 : 'MSR_SPEC_CTRL',
0x00000049 : 'MSR_PRED_CMD',

0x000001C8 : 'MSR_LBR_SELECT',
0x000001C9 : 'MSR_LBR_TOS',
0x00000680 : 'MSR_LBR_NHM_FROM',
0x000006C0 : 'MSR_LBR_NHM_TO',
0x00000040 : 'MSR_LBR_CORE_FROM',
0x00000060 : 'MSR_LBR_CORE_TO',


0x000001DB : 'MSR_IA32_LASTBRANCHFROMIP',
0x000001DC : 'MSR_IA32_LASTBRANCHTOIP',
0x000001DD : 'MSR_IA32_LASTINTFROMIP',
0x000001DE : 'MSR_IA32_LASTINTTOIP',

# https://github.com/collectd/collectd/blob/master/src/msr-index.h
#
# C-state Residency Counters
#
0x000003F8 : 'MSR_PKG_C3_RESIDENCY',
0x000003F9 : 'MSR_PKG_C6_RESIDENCY',
0x000003FA : 'MSR_ATOM_PKG_C6_RESIDENCY',
0x000003FA : 'MSR_PKG_C7_RESIDENCY',
0x000003FC : 'MSR_CORE_C3_RESIDENCY',
0x000003FD : 'MSR_CORE_C6_RESIDENCY',
0x000003FE : 'MSR_CORE_C7_RESIDENCY',
0x000003FF : 'MSR_KNL_CORE_C6_RESIDENCY',
0x0000060D : 'MSR_PKG_C2_RESIDENCY',
0x00000630 : 'MSR_PKG_C8_RESIDENCY',
0x00000631 : 'MSR_PKG_C9_RESIDENCY',
0x00000632 : 'MSR_PKG_C10_RESIDENCY',


# https://sites.uclouvain.be/SystInfo/usr/include/asm/msr-index.h.html

#
# Centaur-Hauls/IDT defined MSRs.
#
0x00000107 : 'MSR_IDT_FCR1',
0x00000108 : 'MSR_IDT_FCR2',
0x00000109 : 'MSR_IDT_FCR3',
0x0000010A : 'MSR_IDT_FCR4',
0x00000110 : 'MSR_IDT_MCR0',
0x00000111 : 'MSR_IDT_MCR1',
0x00000112 : 'MSR_IDT_MCR2',
0x00000113 : 'MSR_IDT_MCR3',
0x00000114 : 'MSR_IDT_MCR4',
0x00000115 : 'MSR_IDT_MCR5',
0x00000116 : 'MSR_IDT_MCR6',
0x00000117 : 'MSR_IDT_MCR7',
0x00000120 : 'MSR_IDT_MCR_CTRL',


0x000000CD : 'MSR_FSB_FREQ',
0x00000119 : 'MSR_IA32_BBL_CR_CTL',

# 
# QQQQQQQQQQ
#

# AMD-V MSRs
0xC0010114 : 'MSR_VM_CR',
0xC0010115 : 'MSR_VM_IGNNE',
0xC0010117 : 'MSR_VM_HSAVE_PA',



###########################################################
# start https://github.com/wbenny/ia32-doc

# @defgroup intel_manual \
#           Intel Manual
# BEGIN
# @defgroup model_specific_registers \
#           Model Specific Registers
# BEGIN
# @defgroup ia32_p5_mc \
#           IA32_P5_MC_(x)
# BEGIN
0x00000000 : 'IA32_P5_MC_ADDR',
0x00000001 : 'IA32_P5_MC_TYPE',
# END

0x00000006 : 'IA32_MONITOR_FILTER_SIZE',
0x00000010 : 'IA32_TIME_STAMP_COUNTER',
0x00000017 : 'IA32_PLATFORM_ID',
0x0000001B : 'IA32_APIC_BASE',
0x0000003A : 'IA32_FEATURE_CONTROL',
0x0000003B : 'IA32_TSC_ADJUST',
0x00000079 : 'IA32_BIOS_UPDT_TRIG',
0x0000008B : 'IA32_BIOS_SIGN_ID',
# @defgroup ia32_sgxlepubkeyhash \
#           IA32_SGXLEPUBKEYHASH[(64*n+63):(64*n)]
# BEGIN
0x0000008C : 'IA32_SGXLEPUBKEYHASH0',
0x0000008D : 'IA32_SGXLEPUBKEYHASH1',
0x0000008E : 'IA32_SGXLEPUBKEYHASH2',
0x0000008F : 'IA32_SGXLEPUBKEYHASH3',
# END

0x0000009B : 'IA32_SMM_MONITOR_CTL',
0x0000009E : 'IA32_SMBASE',
# @defgroup ia32_pmc \
#           IA32_PMC(n)
# BEGIN
0x000000C1 : 'IA32_PMC0',
0x000000C2 : 'IA32_PMC1',
0x000000C3 : 'IA32_PMC2',
0x000000C4 : 'IA32_PMC3',
0x000000C5 : 'IA32_PMC4',
0x000000C6 : 'IA32_PMC5',
0x000000C7 : 'IA32_PMC6',
0x000000C8 : 'IA32_PMC7',
# END

0x000000E7 : 'IA32_MPERF',
0x000000E8 : 'IA32_APERF',
0x000000FE : 'IA32_MTRRCAP',
0x00000174 : 'IA32_SYSENTER_CS',
0x00000175 : 'IA32_SYSENTER_ESP',
0x00000176 : 'IA32_SYSENTER_EIP',
0x00000179 : 'IA32_MCG_CAP',
0x0000017A : 'IA32_MCG_STATUS',
0x0000017B : 'IA32_MCG_CTL',
# @defgroup ia32_perfevtsel \
#           IA32_PERFEVTSEL(n)
# BEGIN
0x00000186 : 'IA32_PERFEVTSEL0',
0x00000187 : 'IA32_PERFEVTSEL1',
0x00000188 : 'IA32_PERFEVTSEL2',
0x00000189 : 'IA32_PERFEVTSEL3',
# END

0x00000198 : 'IA32_PERF_STATUS',
0x00000199 : 'IA32_PERF_CTL',
0x0000019A : 'IA32_CLOCK_MODULATION',
0x0000019B : 'IA32_THERM_INTERRUPT',
0x0000019C : 'IA32_THERM_STATUS',
0x000001A0 : 'IA32_MISC_ENABLE',
0x000001B0 : 'IA32_ENERGY_PERF_BIAS',
0x000001B1 : 'IA32_PACKAGE_THERM_STATUS',
0x000001B2 : 'IA32_PACKAGE_THERM_INTERRUPT',
0x000001D9 : 'IA32_DEBUGCTL',
0x000001F2 : 'IA32_SMRR_PHYSBASE',
0x000001F3 : 'IA32_SMRR_PHYSMASK',
0x000001F8 : 'IA32_PLATFORM_DCA_CAP',
0x000001F9 : 'IA32_CPU_DCA_CAP',
0x000001FA : 'IA32_DCA_0_CAP',
# @defgroup ia32_mtrr_physbase \
#           IA32_MTRR_PHYSBASE(n)
# BEGIN
0x00000200 : 'IA32_MTRR_PHYSBASE0',
0x00000202 : 'IA32_MTRR_PHYSBASE1',
0x00000204 : 'IA32_MTRR_PHYSBASE2',
0x00000206 : 'IA32_MTRR_PHYSBASE3',
0x00000208 : 'IA32_MTRR_PHYSBASE4',
0x0000020A : 'IA32_MTRR_PHYSBASE5',
0x0000020C : 'IA32_MTRR_PHYSBASE6',
0x0000020E : 'IA32_MTRR_PHYSBASE7',
0x00000210 : 'IA32_MTRR_PHYSBASE8',
0x00000212 : 'IA32_MTRR_PHYSBASE9',
# END

# @defgroup ia32_mtrr_physmask \
#           IA32_MTRR_PHYSMASK(n)
# BEGIN
0x00000201 : 'IA32_MTRR_PHYSMASK0',
0x00000203 : 'IA32_MTRR_PHYSMASK1',
0x00000205 : 'IA32_MTRR_PHYSMASK2',
0x00000207 : 'IA32_MTRR_PHYSMASK3',
0x00000209 : 'IA32_MTRR_PHYSMASK4',
0x0000020B : 'IA32_MTRR_PHYSMASK5',
0x0000020D : 'IA32_MTRR_PHYSMASK6',
0x0000020F : 'IA32_MTRR_PHYSMASK7',
0x00000211 : 'IA32_MTRR_PHYSMASK8',
0x00000213 : 'IA32_MTRR_PHYSMASK9',
# END

# @defgroup ia32_mtrr_fix \
#           IA32_MTRR_FIX(x)
# BEGIN
# @defgroup ia32_mtrr_fix64k \
#           IA32_MTRR_FIX64K(x)
# BEGIN
0x00000000 : 'IA32_MTRR_FIX64K_BASE',
0x00010000 : 'IA32_MTRR_FIX64K_SIZE',
0x00000250 : 'IA32_MTRR_FIX64K_00000',
# END

# @defgroup ia32_mtrr_fix16k \
#           IA32_MTRR_FIX16K(x)
# BEGIN
0x00080000 : 'IA32_MTRR_FIX16K_BASE',
0x00004000 : 'IA32_MTRR_FIX16K_SIZE',
0x00000258 : 'IA32_MTRR_FIX16K_80000',
0x00000259 : 'IA32_MTRR_FIX16K_A0000',
# END

# @defgroup ia32_mtrr_fix4k \
#           IA32_MTRR_FIX4K(x)
# BEGIN
0x000C0000 : 'IA32_MTRR_FIX4K_BASE',
0x00001000 : 'IA32_MTRR_FIX4K_SIZE',
0x00000268 : 'IA32_MTRR_FIX4K_C0000',
0x00000269 : 'IA32_MTRR_FIX4K_C8000',
0x0000026A : 'IA32_MTRR_FIX4K_D0000',
0x0000026B : 'IA32_MTRR_FIX4K_D8000',
0x0000026C : 'IA32_MTRR_FIX4K_E0000',
0x0000026D : 'IA32_MTRR_FIX4K_E8000',
0x0000026E : 'IA32_MTRR_FIX4K_F0000',
0x0000026F : 'IA32_MTRR_FIX4K_F8000',
# END


# """
# >>> hex(((1 + 2 + 8) * 8))
# '0x58'
# """
# '((1 + 2 + 8) * 8) : 'IA32_MTRR_FIX_COUNT',

0x00000058 : 'IA32_MTRR_FIX_COUNT',
0x000000FF : 'IA32_MTRR_VARIABLE_COUNT',
# """>>> hex(0x00000058 + 0x000000FF)
# '0x157'
# """
# '(IA32_MTRR_FIX_COUNT + IA32_MTRR_VARIABLE_COUNT) : 'IA32_MTRR_COUNT',
0x00000157 : 'IA32_MTRR_COUNT',

# END

0x00000277 : 'IA32_PAT',
# @defgroup ia32_mc_ctl2 \
#           IA32_MC(i)_CTL2
# BEGIN
0x00000280 : 'IA32_MC0_CTL2',
0x00000281 : 'IA32_MC1_CTL2',
0x00000282 : 'IA32_MC2_CTL2',
0x00000283 : 'IA32_MC3_CTL2',
0x00000284 : 'IA32_MC4_CTL2',
0x00000285 : 'IA32_MC5_CTL2',
0x00000286 : 'IA32_MC6_CTL2',
0x00000287 : 'IA32_MC7_CTL2',
0x00000288 : 'IA32_MC8_CTL2',
0x00000289 : 'IA32_MC9_CTL2',
0x0000028A : 'IA32_MC10_CTL2',
0x0000028B : 'IA32_MC11_CTL2',
0x0000028C : 'IA32_MC12_CTL2',
0x0000028D : 'IA32_MC13_CTL2',
0x0000028E : 'IA32_MC14_CTL2',
0x0000028F : 'IA32_MC15_CTL2',
0x00000290 : 'IA32_MC16_CTL2',
0x00000291 : 'IA32_MC17_CTL2',
0x00000292 : 'IA32_MC18_CTL2',
0x00000293 : 'IA32_MC19_CTL2',
0x00000294 : 'IA32_MC20_CTL2',
0x00000295 : 'IA32_MC21_CTL2',
0x00000296 : 'IA32_MC22_CTL2',
0x00000297 : 'IA32_MC23_CTL2',
0x00000298 : 'IA32_MC24_CTL2',
0x00000299 : 'IA32_MC25_CTL2',
0x0000029A : 'IA32_MC26_CTL2',
0x0000029B : 'IA32_MC27_CTL2',
0x0000029C : 'IA32_MC28_CTL2',
0x0000029D : 'IA32_MC29_CTL2',
0x0000029E : 'IA32_MC30_CTL2',
0x0000029F : 'IA32_MC31_CTL2',
# END

0x000002FF : 'IA32_MTRR_DEF_TYPE',
# @defgroup ia32_fixed_ctr \
#           IA32_FIXED_CTR(n)
# BEGIN
0x00000309 : 'IA32_FIXED_CTR0',
0x0000030A : 'IA32_FIXED_CTR1',
0x0000030B : 'IA32_FIXED_CTR2',
# END

0x00000345 : 'IA32_PERF_CAPABILITIES',
0x0000038D : 'IA32_FIXED_CTR_CTRL',
0x0000038E : 'IA32_PERF_GLOBAL_STATUS',
0x0000038F : 'IA32_PERF_GLOBAL_CTRL',
0x00000390 : 'IA32_PERF_GLOBAL_STATUS_RESET',
0x00000391 : 'IA32_PERF_GLOBAL_STATUS_SET',
0x00000392 : 'IA32_PERF_GLOBAL_INUSE',
0x000003F1 : 'IA32_PEBS_ENABLE',
# @defgroup ia32_mc_ctl \
#           IA32_MC(i)_CTL
# BEGIN
0x00000400 : 'IA32_MC0_CTL',
0x00000404 : 'IA32_MC1_CTL',
0x00000408 : 'IA32_MC2_CTL',
0x0000040C : 'IA32_MC3_CTL',
0x00000410 : 'IA32_MC4_CTL',
0x00000414 : 'IA32_MC5_CTL',
0x00000418 : 'IA32_MC6_CTL',
0x0000041C : 'IA32_MC7_CTL',
0x00000420 : 'IA32_MC8_CTL',
0x00000424 : 'IA32_MC9_CTL',
0x00000428 : 'IA32_MC10_CTL',
0x0000042C : 'IA32_MC11_CTL',
0x00000430 : 'IA32_MC12_CTL',
0x00000434 : 'IA32_MC13_CTL',
0x00000438 : 'IA32_MC14_CTL',
0x0000043C : 'IA32_MC15_CTL',
0x00000440 : 'IA32_MC16_CTL',
0x00000444 : 'IA32_MC17_CTL',
0x00000448 : 'IA32_MC18_CTL',
0x0000044C : 'IA32_MC19_CTL',
0x00000450 : 'IA32_MC20_CTL',
0x00000454 : 'IA32_MC21_CTL',
0x00000458 : 'IA32_MC22_CTL',
0x0000045C : 'IA32_MC23_CTL',
0x00000460 : 'IA32_MC24_CTL',
0x00000464 : 'IA32_MC25_CTL',
0x00000468 : 'IA32_MC26_CTL',
0x0000046C : 'IA32_MC27_CTL',
0x00000470 : 'IA32_MC28_CTL',
# END

# @defgroup ia32_mc_status \
#           IA32_MC(i)_STATUS
# BEGIN
0x00000401 : 'IA32_MC0_STATUS',
0x00000405 : 'IA32_MC1_STATUS',
0x00000409 : 'IA32_MC2_STATUS',
0x0000040D : 'IA32_MC3_STATUS',
0x00000411 : 'IA32_MC4_STATUS',
0x00000415 : 'IA32_MC5_STATUS',
0x00000419 : 'IA32_MC6_STATUS',
0x0000041D : 'IA32_MC7_STATUS',
0x00000421 : 'IA32_MC8_STATUS',
0x00000425 : 'IA32_MC9_STATUS',
0x00000429 : 'IA32_MC10_STATUS',
0x0000042D : 'IA32_MC11_STATUS',
0x00000431 : 'IA32_MC12_STATUS',
0x00000435 : 'IA32_MC13_STATUS',
0x00000439 : 'IA32_MC14_STATUS',
0x0000043D : 'IA32_MC15_STATUS',
0x00000441 : 'IA32_MC16_STATUS',
0x00000445 : 'IA32_MC17_STATUS',
0x00000449 : 'IA32_MC18_STATUS',
0x0000044D : 'IA32_MC19_STATUS',
0x00000451 : 'IA32_MC20_STATUS',
0x00000455 : 'IA32_MC21_STATUS',
0x00000459 : 'IA32_MC22_STATUS',
0x0000045D : 'IA32_MC23_STATUS',
0x00000461 : 'IA32_MC24_STATUS',
0x00000465 : 'IA32_MC25_STATUS',
0x00000469 : 'IA32_MC26_STATUS',
0x0000046D : 'IA32_MC27_STATUS',
0x00000471 : 'IA32_MC28_STATUS',
# END

# @defgroup ia32_mc_addr \
#           IA32_MC(i)_ADDR
# BEGIN
0x00000402 : 'IA32_MC0_ADDR',
0x00000406 : 'IA32_MC1_ADDR',
0x0000040A : 'IA32_MC2_ADDR',
0x0000040E : 'IA32_MC3_ADDR',
0x00000412 : 'IA32_MC4_ADDR',
0x00000416 : 'IA32_MC5_ADDR',
0x0000041A : 'IA32_MC6_ADDR',
0x0000041E : 'IA32_MC7_ADDR',
0x00000422 : 'IA32_MC8_ADDR',
0x00000426 : 'IA32_MC9_ADDR',
0x0000042A : 'IA32_MC10_ADDR',
0x0000042E : 'IA32_MC11_ADDR',
0x00000432 : 'IA32_MC12_ADDR',
0x00000436 : 'IA32_MC13_ADDR',
0x0000043A : 'IA32_MC14_ADDR',
0x0000043E : 'IA32_MC15_ADDR',
0x00000442 : 'IA32_MC16_ADDR',
0x00000446 : 'IA32_MC17_ADDR',
0x0000044A : 'IA32_MC18_ADDR',
0x0000044E : 'IA32_MC19_ADDR',
0x00000452 : 'IA32_MC20_ADDR',
0x00000456 : 'IA32_MC21_ADDR',
0x0000045A : 'IA32_MC22_ADDR',
0x0000045E : 'IA32_MC23_ADDR',
0x00000462 : 'IA32_MC24_ADDR',
0x00000466 : 'IA32_MC25_ADDR',
0x0000046A : 'IA32_MC26_ADDR',
0x0000046E : 'IA32_MC27_ADDR',
0x00000472 : 'IA32_MC28_ADDR',
# END

# @defgroup ia32_mc_misc \
#           IA32_MC(i)_MISC
# BEGIN
0x00000403 : 'IA32_MC0_MISC',
0x00000407 : 'IA32_MC1_MISC',
0x0000040B : 'IA32_MC2_MISC',
0x0000040F : 'IA32_MC3_MISC',
0x00000413 : 'IA32_MC4_MISC',
0x00000417 : 'IA32_MC5_MISC',
0x0000041B : 'IA32_MC6_MISC',
0x0000041F : 'IA32_MC7_MISC',
0x00000423 : 'IA32_MC8_MISC',
0x00000427 : 'IA32_MC9_MISC',
0x0000042B : 'IA32_MC10_MISC',
0x0000042F : 'IA32_MC11_MISC',
0x00000433 : 'IA32_MC12_MISC',
0x00000437 : 'IA32_MC13_MISC',
0x0000043B : 'IA32_MC14_MISC',
0x0000043F : 'IA32_MC15_MISC',
0x00000443 : 'IA32_MC16_MISC',
0x00000447 : 'IA32_MC17_MISC',
0x0000044B : 'IA32_MC18_MISC',
0x0000044F : 'IA32_MC19_MISC',
0x00000453 : 'IA32_MC20_MISC',
0x00000457 : 'IA32_MC21_MISC',
0x0000045B : 'IA32_MC22_MISC',
0x0000045F : 'IA32_MC23_MISC',
0x00000463 : 'IA32_MC24_MISC',
0x00000467 : 'IA32_MC25_MISC',
0x0000046B : 'IA32_MC26_MISC',
0x0000046F : 'IA32_MC27_MISC',
0x00000473 : 'IA32_MC28_MISC',
# END

0x00000480 : 'IA32_VMX_BASIC',
0x00000481 : 'IA32_VMX_PINBASED_CTLS',
0x00000482 : 'IA32_VMX_PROCBASED_CTLS',
0x00000483 : 'IA32_VMX_EXIT_CTLS',
0x00000484 : 'IA32_VMX_ENTRY_CTLS',
0x00000485 : 'IA32_VMX_MISC',
0x00000486 : 'IA32_VMX_CR0_FIXED0',
0x00000487 : 'IA32_VMX_CR0_FIXED1',
0x00000488 : 'IA32_VMX_CR4_FIXED0',
0x00000489 : 'IA32_VMX_CR4_FIXED1',
0x0000048A : 'IA32_VMX_VMCS_ENUM',
0x0000048B : 'IA32_VMX_PROCBASED_CTLS2',
0x0000048C : 'IA32_VMX_EPT_VPID_CAP',
# @defgroup ia32_vmx_true_ctls \
#           IA32_VMX_TRUE_(x)_CTLS
# BEGIN
0x0000048D : 'IA32_VMX_TRUE_PINBASED_CTLS',
0x0000048E : 'IA32_VMX_TRUE_PROCBASED_CTLS',
0x0000048F : 'IA32_VMX_TRUE_EXIT_CTLS',
0x00000490 : 'IA32_VMX_TRUE_ENTRY_CTLS',
# END

0x00000491 : 'IA32_VMX_VMFUNC',
# @defgroup ia32_a_pmc \
#           IA32_A_PMC(n)
# BEGIN
0x000004C1 : 'IA32_A_PMC0',
0x000004C2 : 'IA32_A_PMC1',
0x000004C3 : 'IA32_A_PMC2',
0x000004C4 : 'IA32_A_PMC3',
0x000004C5 : 'IA32_A_PMC4',
0x000004C6 : 'IA32_A_PMC5',
0x000004C7 : 'IA32_A_PMC6',
0x000004C8 : 'IA32_A_PMC7',
# END

0x000004D0 : 'IA32_MCG_EXT_CTL',
0x00000500 : 'IA32_SGX_SVN_STATUS',
0x00000560 : 'IA32_RTIT_OUTPUT_BASE',
0x00000561 : 'IA32_RTIT_OUTPUT_MASK_PTRS',
0x00000570 : 'IA32_RTIT_CTL',
0x00000571 : 'IA32_RTIT_STATUS',
0x00000572 : 'IA32_RTIT_CR3_MATCH',
# @defgroup ia32_rtit_addr \
#           IA32_RTIT_ADDR(x)
# BEGIN
# @defgroup ia32_rtit_addr_a \
#           IA32_RTIT_ADDR(n)_A
# BEGIN
0x00000580 : 'IA32_RTIT_ADDR0_A',
0x00000582 : 'IA32_RTIT_ADDR1_A',
0x00000584 : 'IA32_RTIT_ADDR2_A',
0x00000586 : 'IA32_RTIT_ADDR3_A',
# END

# @defgroup ia32_rtit_addr_b \
#           IA32_RTIT_ADDR(n)_B
# BEGIN
0x00000581 : 'IA32_RTIT_ADDR0_B',
0x00000583 : 'IA32_RTIT_ADDR1_B',
0x00000585 : 'IA32_RTIT_ADDR2_B',
0x00000587 : 'IA32_RTIT_ADDR3_B',
# END

# END

0x00000600 : 'IA32_DS_AREA',
0x000006E0 : 'IA32_TSC_DEADLINE',
0x00000770 : 'IA32_PM_ENABLE',
0x00000771 : 'IA32_HWP_CAPABILITIES',
0x00000772 : 'IA32_HWP_REQUEST_PKG',
0x00000773 : 'IA32_HWP_INTERRUPT',
0x00000774 : 'IA32_HWP_REQUEST',
0x00000777 : 'IA32_HWP_STATUS',
0x00000802 : 'IA32_X2APIC_APICID',
0x00000803 : 'IA32_X2APIC_VERSION',
0x00000808 : 'IA32_X2APIC_TPR',
0x0000080A : 'IA32_X2APIC_PPR',
0x0000080B : 'IA32_X2APIC_EOI',
0x0000080D : 'IA32_X2APIC_LDR',
0x0000080F : 'IA32_X2APIC_SIVR',
# @defgroup ia32_x2apic_isr \
#           IA32_X2APIC_ISR(n)
# BEGIN
0x00000810 : 'IA32_X2APIC_ISR0',
0x00000811 : 'IA32_X2APIC_ISR1',
0x00000812 : 'IA32_X2APIC_ISR2',
0x00000813 : 'IA32_X2APIC_ISR3',
0x00000814 : 'IA32_X2APIC_ISR4',
0x00000815 : 'IA32_X2APIC_ISR5',
0x00000816 : 'IA32_X2APIC_ISR6',
0x00000817 : 'IA32_X2APIC_ISR7',
# END

# @defgroup ia32_x2apic_tmr \
#           IA32_X2APIC_TMR(n)
# BEGIN
0x00000818 : 'IA32_X2APIC_TMR0',
0x00000819 : 'IA32_X2APIC_TMR1',
0x0000081A : 'IA32_X2APIC_TMR2',
0x0000081B : 'IA32_X2APIC_TMR3',
0x0000081C : 'IA32_X2APIC_TMR4',
0x0000081D : 'IA32_X2APIC_TMR5',
0x0000081E : 'IA32_X2APIC_TMR6',
0x0000081F : 'IA32_X2APIC_TMR7',
# END

# @defgroup ia32_x2apic_irr \
#           IA32_X2APIC_IRR(n)
# BEGIN
0x00000820 : 'IA32_X2APIC_IRR0',
0x00000821 : 'IA32_X2APIC_IRR1',
0x00000822 : 'IA32_X2APIC_IRR2',
0x00000823 : 'IA32_X2APIC_IRR3',
0x00000824 : 'IA32_X2APIC_IRR4',
0x00000825 : 'IA32_X2APIC_IRR5',
0x00000826 : 'IA32_X2APIC_IRR6',
0x00000827 : 'IA32_X2APIC_IRR7',
# END

0x00000828 : 'IA32_X2APIC_ESR',
0x0000082F : 'IA32_X2APIC_LVT_CMCI',
0x00000830 : 'IA32_X2APIC_ICR',
0x00000832 : 'IA32_X2APIC_LVT_TIMER',
0x00000833 : 'IA32_X2APIC_LVT_THERMAL',
0x00000834 : 'IA32_X2APIC_LVT_PMI',
0x00000835 : 'IA32_X2APIC_LVT_LINT0',
0x00000836 : 'IA32_X2APIC_LVT_LINT1',
0x00000837 : 'IA32_X2APIC_LVT_ERROR',
0x00000838 : 'IA32_X2APIC_INIT_COUNT',
0x00000839 : 'IA32_X2APIC_CUR_COUNT',
0x0000083E : 'IA32_X2APIC_DIV_CONF',
0x0000083F : 'IA32_X2APIC_SELF_IPI',
0x00000C80 : 'IA32_DEBUG_INTERFACE',
0x00000C81 : 'IA32_L3_QOS_CFG',
0x00000C82 : 'IA32_L2_QOS_CFG',
0x00000C8D : 'IA32_QM_EVTSEL',
0x00000C8E : 'IA32_QM_CTR',
0x00000C8F : 'IA32_PQR_ASSOC',
0x00000D90 : 'IA32_BNDCFGS',
0x00000DA0 : 'IA32_XSS',
0x00000DB0 : 'IA32_PKG_HDC_CTL',
0x00000DB1 : 'IA32_PM_CTL1',
0x00000DB2 : 'IA32_THREAD_STALL',
0xC0000080 : 'IA32_EFER',
0xC0000081 : 'IA32_STAR',
0xC0000082 : 'IA32_LSTAR',
0xC0000083 : 'IA32_CSTAR',
0xC0000084 : 'IA32_FMASK',
0xC0000100 : 'IA32_FS_BASE',
0xC0000101 : 'IA32_GS_BASE',
0xC0000102 : 'IA32_KERNEL_GS_BASE',
0xC0000103 : 'IA32_TSC_AUX',
# END

# end https://github.com/wbenny/ia32-doc
#######################################################
}



class IdaPlugin(object):
    def GetMsrCodeFromOperand(self,ea):
        while True:
            ea = idc.PrevAddr(ea)
            mnemonic = idc.GetMnem(ea)
            operand = idc.GetOpnd(ea, 0)

            # Not imm value :-(
            if mnemonic == "lea" and ("ecx" in operand or "rcx" in operand):
                return None

            if mnemonic == "mov" and ("ecx" in operand or "rcx" in operand):
                if idc.GetOpType(ea,1) == idaapi.idaapi.o_imm:
                    return idc.GetOperandValue(ea, 1)
                else:
                    return None
                #     return 'Not imm' + idc.GetDisasm(ea)

    def GetJumpAddr(self,call_addr, func_ea):
        func_addr = idc.LocByName(idc.GetFunctionName(func_ea))
        ret = int(call_addr - func_addr)
        return hex(ret).replace("0x", "")

    def NormalizeHexValue(self,msr_code):
        msr_code_hex = hex(msr_code)
        if(len(msr_code_hex)>10):
            # msr_code_hex = '0x{}'.format(msr_code_hex[-8:].upper())
            msr_code_hex = msr_code_hex.upper().replace('0xffffffff'.upper(),'0x')
        elif(len(msr_code_hex)<10):
            msr_code_hex = '0x{0:08X}'.format(msr_code)

        msr_code_hex = msr_code_hex.upper().replace('0X','0x').replace('L','')

        return msr_code_hex

    def PrintMsrTable(self,msr_code ,function_ea,inst_ea ):
        mnemonic = idc.GetMnem(inst_ea)
        call_addr = self.GetJumpAddr(inst_ea, function_ea)
        function_name = idc.GetFunctionName(function_ea)+ '+' + call_addr
        dwSize = 30 - len(function_name)
        delimeter = " " * dwSize

        if(msr_code == None):
            msr_code_hex = 'Not imm value'
        else:
            msr_code_hex = self.NormalizeHexValue(msr_code)

        

        if(msr_code == None):
            msr_name = msr_code_hex
        else:
            msr_name = msr_list.get(int(msr_code_hex, 16))

        idc.MakeComm(inst_ea, '{}({})'.format(mnemonic,msr_name))
        idc.SetColor(inst_ea,idc.CIC_ITEM,0xf8abef)

        msr_name_delimeter = (" " * (15 - len(msr_code_hex)))

        print '{}{}| {} | {} {} | {}'.format(function_name,
                                             delimeter,
                                             mnemonic,
                                             msr_code_hex,
                                             msr_name_delimeter,
                                             msr_name)

    def Run(self):
        for function_ea in idautils.Functions():
            for inst_ea in idautils.FuncItems(function_ea):
                if idaapi.isCode(idaapi.getFlags(inst_ea)):
                    mnemonic = idc.GetMnem(inst_ea)
                    if(mnemonic =='rdmsr' or mnemonic=='wrmsr'):
                        msr_code = self.GetMsrCodeFromOperand(inst_ea)
                        self.PrintMsrTable(msr_code,function_ea,inst_ea)


def main():
    print '-'*100
    print '[!] Extracted MSRs from [{}]'.format(idaapi.get_input_file_path() )
    print '-'*100

    IdaPlugin().Run()


if __name__ == '__main__':
    main()
