1 '''
2 Helper methods around registers
3
4 @author: Christian Holler (:decoder)
5
6 @license:
7
8 This Source Code Form is subject to the terms of the Mozilla Public
9 License, v. 2.0. If a copy of the MPL was not distributed with this
10 file, You can obtain one at http://mozilla.org/MPL/2.0/.
11
12 @contact: choller@mozilla.com
13 '''
14
15 x86Registers = [ "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp", "eip" ]
16
17 x64Registers = [ "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp", "r8",
18 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rip" ]
19
20 armRegisters = [ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
21 "r10", "r11", "r12", "sp", "lr", "pc", "cpsr" ]
22
23 x86OnlyRegisters = list(set(x86Registers + x64Registers) - set(armRegisters))
24
25 validRegisters = {
26 "X86" : x86Registers,
27 "X64" : x64Registers,
28 "ARM" : armRegisters
29 }
30
32 '''
33 Return a pattern including all register names that are considered valid
34 '''
35 return "(" + '|'.join(["%s"] * len(validRegisters.values())) % tuple(['|'.join(i) for i in validRegisters.values()]) + ")"
36
38 '''
39 Return the stack pointer value from the given register map
40
41 @type registerMap: map
42 @param registerMap: Map of register names to value
43
44 @rtype: long
45 @return: The value of the stack pointer
46 '''
47
48 for reg in ["rsp", "esp", "sp"]:
49 if reg in registerMap:
50 return registerMap[reg]
51
52 raise RuntimeError("Register map does not contain a usable stack pointer!")
53
55 '''
56 Return the instruction pointer value from the given register map
57
58 @type registerMap: map
59 @param registerMap: Map of register names to value
60
61 @rtype: long
62 @return: The value of the instruction pointer
63 '''
64
65 for reg in ["rip", "eip", "pc"]:
66 if reg in registerMap:
67 return registerMap[reg]
68
69 raise RuntimeError("Register map does not contain a usable instruction pointer!")
70
72 '''
73 Return the value of the specified register using the provided register map.
74 This method also works for getting lower register parts out of higher ones.
75
76 @type register: string
77 @param register: The register to get the value for
78
79 @type registerMap: map
80 @param registerMap: Map of register names to values
81
82 @rtype: long
83 @return: The register value
84 '''
85
86
87 if register in registerMap:
88 return registerMap[register]
89
90 if register.startswith("e"):
91
92
93
94
95 higherRegister = register.replace("e", "r", 1)
96 if higherRegister in registerMap:
97 return registerMap[higherRegister] & 0xFFFFFFFFL
98
99 if len(register) == 2:
100
101
102 if register.endswith("x"):
103
104 reg32 = "e" + register
105 if reg32 in registerMap:
106 return registerMap[reg32] & 0xFFFFL
107
108 reg64 = "r" + register
109 if reg64 in registerMap:
110 return registerMap[reg64] & 0xFFFFL
111 elif register.endswith("h"):
112 higherRegister = register.replace("h", "x", 1)
113
114 reg32 = "e" + higherRegister
115 if reg32 in registerMap:
116 return (registerMap[reg32] & 0xFF00L) >> 8
117
118 reg64 = "r" + higherRegister
119 if reg64 in registerMap:
120 return (registerMap[reg64] & 0xFF00L) >> 8
121 elif register.endswith("l"):
122 higherRegister = register.replace("l", "x", 1)
123
124 reg32 = "e" + higherRegister
125 if reg32 in registerMap:
126 return registerMap[reg32] & 0xFFL
127
128 reg64 = "r" + higherRegister
129 if reg64 in registerMap:
130 return registerMap[reg64] & 0xFFL
131
132 return None
133
135 '''
136 Return the bit width (32 or 64 bit) given the registers
137
138 @type registerMap: map
139 @param registerMap: Map of register names to value
140
141 @rtype: int
142 @return: The bit width
143 '''
144 if "rax" in registerMap:
145 return 64
146
147 return 32
148
150 '''
151 Return true, if the the given registers are X86 compatible, such as x86 or x86-64.
152 ARM, PPC and your PDP-15 will fail this check and we don't support it right now.
153
154 @type registerMap: map
155 @param registerMap: Map of register names to value
156
157 @rtype: bool
158 @return: True if the architecture is X86 compatible, False otherwise
159 '''
160 for register in x86OnlyRegisters:
161 if register in registerMap:
162 return True
163 return False
164