-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathx86cpToMemory.py
More file actions
executable file
·84 lines (66 loc) · 2.96 KB
/
x86cpToMemory.py
File metadata and controls
executable file
·84 lines (66 loc) · 2.96 KB
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
# Copyright 2004-2010 Grant T. Olson.
# See license.txt for terms.
from x86inst import RELATIVE,DIRECT
from x86PackUnpack import ulongToString
from x86asm import PYTHON
import pyasm.excmem as excmem
import logging, sys
if sys.platform == 'win32':
import win32api, pywintypes
from sys import dllhandle
def runtimeResolve(funcName):
try:
addr = win32api.GetProcAddress(dllhandle,funcName)
except pywintypes.error:
raise RuntimeError("Unable to resolve external symbol '%s'" % funcName)
return addr
elif sys.platform in ('linux2'):
def runtimeResolve(funcName):
return excmem.GetSymbolAddress(funcName)
else:
raise RuntimeError("Don't know how to resolve external symbols for platform '%s'" % sys.platform)
class CpToMemory:
def __init__(self,cp):
self.cp = cp
self.symbols = {}
self.resolvedCode = ''
def LookupAddress(self,sym):
if self.symbols.has_key(sym):
return self.symbols[sym]
else: #try runtime resolution, currently windows specific
funcaddress = runtimeResolve(sym)
self.symbols[sym] = funcaddress
return funcaddress
def BindPythonFunctions(self,glb=None,bindFunction=excmem.BindFunctionAddress):
if glb is None:
glb = globals()
for proc in self.cp.CodeSymbols:
if proc[2] == PYTHON:
glb[proc[0]] = bindFunction(proc[1] + self.codeAddr)
def MakeMemory(self,glb=None):
if not glb:
glb = globals()
self.codeAddr = excmem.AllocateExecutableMemory(len(self.cp.Code))
self.dataAddr = excmem.AllocateExecutableMemory(len(self.cp.Data))
self.symbols = {}
for sym in self.cp.CodeSymbols:
self.symbols[sym[0]] = sym[1] + self.codeAddr
for sym in self.cp.DataSymbols:
self.symbols[sym[0]] = sym[1] + self.dataAddr
self.resolvedCode = self.cp.Code # nondestructive on cp
for patch in self.cp.CodePatchins:
if patch[2] == DIRECT:
resolvedAddr = self.LookupAddress(patch[0])
elif patch[2] == RELATIVE:
#XXX
# I'm just assuming that the pathin is at the end of a function
# and the next instrution address is that +4
# Is this valid or do I need to calculate?
resolvedAddr = self.LookupAddress(patch[0]) - (self.codeAddr + patch[1] + 4)
else:
raise RuntimeError("Invalid patchin information")
self.resolvedCode = self.resolvedCode[:patch[1]] + ulongToString(resolvedAddr) \
+ self.resolvedCode[patch[1]+4:]
assert len(self.resolvedCode) == len(self.cp.Code)
excmem.LoadExecutableMemoryString(self.codeAddr,self.resolvedCode)
excmem.LoadExecutableMemoryString(self.dataAddr,self.cp.Data)