summaryrefslogtreecommitdiff
path: root/plugins/python/liveconv/converters.py
blob: ef35f59ece0ac3e119a56314501c53f93beb6f15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

from datetime import datetime, timedelta
from pychrysalide.arch import vmpa
import string
import struct


def data_to_number(content, addr, order, fmt):
    """Convert to a number, if possible."""

    size =  struct.calcsize(order + fmt)

    data = content.read_raw(addr, size)

    value = struct.unpack(order + fmt, data)[0]

    return str(value)


def data_to_time(content, addr, order, fmt):
    """Convert to a number, if possible."""

    size =  struct.calcsize(order + fmt)

    data = content.read_raw(addr, size)

    value = struct.unpack(order + fmt, data)[0]

    return str(datetime(1970, 1, 1) + timedelta(seconds=value))


# Cf. FILETIME structure
# https://docs.microsoft.com/fr-fr/windows/win32/api/minwinbase/ns-minwinbase-filetime

def data_to_filetime(content, addr, order):
    """Convert to a Windows FILETIME, if possible."""

    data = content.read_raw(addr, 8)

    value = struct.unpack(order + 'Q', data)[0]

    us = value / 10.

    return str(datetime(1601, 1, 1) + timedelta(microseconds=us))


# Cf. DosDateTimeToFileTime()
# https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-dosdatetimetofiletime

def data_to_dos_time(content, addr, order):
    """Convert to a MS-DOS time, if possible."""

    data = content.read_raw(addr, 2)

    value = struct.unpack(order + 'H', data)[0]

    seconds = (value & 0x1f) * 2
    minutes = (value & 0x7e0) >> 5
    hours = (value & 0xf800) >> 11

    return '%02u:%02u:%02u' % (hours, minutes, seconds)

def data_to_dos_date(content, addr, order):
    """Convert to a MS-DOS date, if possible."""

    data = content.read_raw(addr, 2)

    value = struct.unpack(order + 'H', data)[0]

    day = (value & 0x1f)
    month = (value & 0x1e0) >> 5
    year = ((value & 0xfe00) >> 9) + 1980

    return '%u/%u/%u' % (month, day, year)


def data_to_char(content, addr, order):
    """Convert to a character, if possible."""

    data = content.read_raw(addr, 1)

    value = struct.unpack(order + 'c', data)[0]

    ch = chr(value[0])

    return ch if ch in string.printable else '-'


def data_to_ansi(content, addr, order):
    """Convert to an ANSI string, if possible."""

    result = None

    while True:

        try:

            data = content.read_raw(addr, 1)

            value = struct.unpack(order + 'c', data)[0]

            ch = chr(value[0])

            if not(ch in string.printable):
                break

            if result:
                result += ch
            else:
                result = ch

        except:
            pass

    return result if result else '-'


def _data_to_utf(content, addr, utf):
    """Convert to an UTF-X string, if possible."""

    result = None

    length = 0

    while True:

        try:

            start = vmpa(addr.phys, 0)
            data = content.read_raw(start, length + 1)

            result = data.decode(utf)

            length += 1

        except Exception as e:
            break

    if length > 0:

        data = content.read_raw(addr, length)

        result = data.decode('utf-8')

    else:
        result = '-'

    return result


def data_to_utf8(content, addr, order):
    """Convert to an UTF-8 string, if possible."""

    return _data_to_utf(content, addr, 'utf-8')


def data_to_utf16(content, addr, order):
    """Convert to an UTF-16 string, if possible."""

    return _data_to_utf(content, addr, 'utf-16')