{{
import datetime
import malcat
from helpers import naturalsize



def pval(key, val=None, fmt="{}", va=False, pa=False, rva=False, size=False, kalign=30, valign=0, formated=False):
    r = "[normal]{}[/normal]:".format(key)
    lr = len(r) - 17
    if lr < kalign:
        r += (" "*(kalign-lr))
    if isinstance(val, malcat.StructAccess) or isinstance(val, malcat.FieldAccess):
        if val.has_enum and val.enum:
            d = "[color6]{}[/color6]([dim]{}[/dim])".format(val.enum, fmt.format(val.value))
            formated = True
            ld = len(d) - len("[color3][/color3][dim][/dim]")
        elif size:
            d = naturalsize(val.value, binary=True)
            ld = len(d)
        else:
            toprint = val.value
            if type(toprint) == str:
                toprint = toprint.replace("[", "\\[")
            d = fmt.format(toprint)
            ld = len(d)
        val = val.value
    elif size and type(val) == int:
        d = naturalsize(val, binary=True)
        ld = len(d)
    else:
        d = fmt.format(val)
        ld = len(d)
    if not formated:
        if type(val) == int: 
            if val == 0:
                grp = "dim"
            elif pa:
                grp = "fa"
            elif rva:
                grp = "rva"
            elif va:
                grp = "va"
            else:
                grp = "normal"
        else:
            grp = "normal"
        d = "[{}]{}[/{}]".format(grp,d,grp)
    if ld < valign:
        d += (" "*(valign-ld))
    write(r+d)  
def bitfieldpp(fa):
    s = []
    for i in range(fa.count - 1, -1, -1):
        bit = fa.at(i)
        if bit.value:
            s.append("[color5]{}[/color5]([dim]{:X}[/dim])".format(bit.name, 1 << i))
    if s:
        return  " + ".join(s)
    else:
        return "[dim]0[/dim]"

def pbitfield(key, fa, kalign=30):    
    r = "[normal]{}[/normal]:".format(key)
    lr = len(r) - 17
    if lr < kalign:
        r += (" "*(kalign-lr))
    write(r + bitfieldpp(fa))

def sections_rights(rights):
    s = ""
    for e in [
        ("MemRead", "R"),
        ("MemWrite", "W"),
        ("MemExecute", "X"),
        ("ScnAlign1", "1"),
        ("ScnAlign2", "2"),
        ("ScnAlign8", "8"),
        ("MemShared", "S"),
        ("MemNotPaged", "P"),
        ("MemNotCached", "H"),
        ("MemDiscardable", "D"),
        ("SctCntCode", "C"),
        ("SctCntInitializedData", "I"),
        ("SctCntUnititializedData", "U"),
        ]:
        if rights[e[0]]:
            s += "[color5]{}[/color5]".format(e[1])
        else:
            s += "[dim]∙[/dim]"
    return s

def rsrc_name(n):
    if type(n) == int:
        return "#{:d}".format(n)
    else:
        return n.replace("[", "\\[")

def display_entropy(start, size):
    if start is None or size <= 0:
        return " "
    entropy = analysis.entropy[start:start+size]
    return "[ent-{val}:{ent}] [/ent-{val}]".format(val=entropy//4, ent=entropy)

def print_offset(off):
    if off < analysis.file.size:
        return "[fa]{:08x}[/fa]".format(off)
    else:
        return "[error]{:08x}[/error]".format(off)

def print_rva(rva):
    ea = analysis.map.from_rva(rva)
    if ea is not None:
        ea = analysis.map.to_phys(ea)
    if ea is not None:
        return "[rva]{:08x}[/rva]".format(rva)
    else:
        return "[error]{:08x}[/error]".format(rva)
}}
{{

}}

[color1]System information[/color1]
{{ if "SystemInformation" in analysis.struct: }}
{{ sysinfo = analysis.struct.SystemInformation }}
  {{ pval("Platform", sysinfo.PlatformId, "{}", valign=24) }} {{ pval("Version", f"{sysinfo['MajorVersion']}.{sysinfo['MinorVersion']} build {sysinfo['BuildNumber']}", "{}") }}
  {{ pbitfield("Installed software", sysinfo.SuiteMask) }}
  {{ pval("Processor", sysinfo.ProcessorArchitecture, "{}", valign=24) }} {{ pval("CPU revision", sysinfo.ProcessorRevision, "{}") }}
{{ :endif }}
{{ if "MiscInformation" in analysis.struct: }}
{{ miscinfo = analysis.struct.MiscInformation }}
  {{ pval("ProcessorCurrentSpeed", miscinfo.ProcessorCurrentMhz, "{} Mhz", valign=24) }} {{ pval("ProcessorMaximumSpeed", miscinfo.ProcessorMaximumMhz, "{} Mhz") }}
{{ :endif }}

[color1]Modules[/color1]
{{ for module in analysis.parser.map: }}
  [color2]{{module.name}}[/color2] [dim]({{module.type}})[/dim]
    {{ pval("Imagebase", module.base, "{:08x}", valign=24, va=True) }} {{ pval("Size", module.size, size=True) }}
    {{ pval("Path", module.path, "{}") }} 
    {{ pval("Version", module.version, "{}") }} 
    {{ pval("Debug path", module.debug_path, "{}") }} 

{{ :endfor }}
