# tramper.py
# Relocates bytes of an API and creates a jump from those bytes to the original API affectively negating a hook.
# TODO !Recalculate Relocated Relative jmp and call addresses.
# public domain code.
from ctypes import *
from win32api import *
from pytcc import pytcc
from struct import pack, unpack
from win32gui import PyGetString, PySetMemory, PySetString
from win32con import MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, PROCESS_ALL_ACCESS
from distorm import Decode
from patcher import OpenProcess, readMemory, writeMemory, allocate, transport
DEBUG = True
def DB (msg):
global DEBUG
if DEBUG: print (msg)
def tramper (apiaddress, hook_size, apiname=None, dllname="kernel32"):
"""tramper (apiaddress, hook_size, apiname=None, dllname="kernel32"):
Creates a duplicate API using the trampoline method and returns its address.
"""
if DEBUG: global hprocess, landing_offset, instructions, landing_address, tramp_memory, tramp_code, original_bytes
if not apiaddress:
dll = LoadLibrary (dllname)
apiaddress = GetProcAddress (dll, apiname)
landing_offset = 0
hprocess = OpenProcess ()
original_bytes = PyGetString (apiaddress, 300)
tramp_memory = allocate (len (original_bytes) + 50, hprocess)
print "Tramp memory: %s %s." % (tramp_memory, hex (tramp_memory))
instructions = Decode (apiaddress, original_bytes)
sizes = iter ([X[1] for X in instructions])
while landing_offset < hook_size:
landing_offset += sizes.next ()
landing_address = apiaddress + landing_offset
DB ("Landing offset : %s %s" % (landing_offset, hex (landing_offset)))
DB ("Landing address: %s %s" % (landing_address, hex (landing_address)))
distance = landing_address - (tramp_memory +landing_offset)
DB ("Distance: %s %s." % (distance, hex (distance)))
tramp_code = original_bytes [:landing_offset] # api start - past hook - to start of instruction
instructions = Decode (apiaddress, tramp_code)
boffset = 0
for offset, size, instruction, hexstr in instructions:
if filter (lambda x:x.lower() in instruction.lower(), ["call", "jmp"]):
raise "[not supported yet] Cannot relocate CALL/JMP Instructions. Address: %s"% (apiaddress + boffset)
boffset += size
#
# TODO !Recalculate Relocated Relative jmp and call addresses.
#
jump_code = '\xe9' + pack ("i", distance - 5) # bytes = jmp (distance - size of jump)
tramp_code += jump_code
# DEBUG
DB ("Tramp [size]: %s [bytes]; %s" % (len(tramp_code), (repr(tramp_code))))
DB ("Tramper api decode.")
if DEBUG: dprint (apiaddress, tramp_code)
# # # #
writeMemory (hprocess, tramp_memory, tramp_code)
CloseHandle (hprocess)
return tramp_memory
def dprint (a, c):
""" pretty print disassembled bytes. dprint (offset, bytes)."""
x = Decode (a, c)
print "[deci addr : hexi addr] [size] instruction\n"
for offset, size, instruction, hexstr in x:
print "[%s : %s] [%s] %s" % (a,hex (a), size, instruction)
a += size
if __name__ == "__main__":
# Test.
lib = LoadLibrary ("kernel32")
OpenProcessAddr = GetProcAddress (lib, "OpenProcess")
FreeLibrary (lib)
trampAddr = tramper (\
apiaddress=OpenProcessAddr, # (optional if apiname is defined) API address to duplicate.
hook_size=10, # size of our API jmp code. (minimum size of relocated API bytes)
apiname=None, # (optional)
dllname="kernel32") # (optional / defaults to kernel32)
# Prototype the OpenProcess trampoline.
duplicate_OpenProcess = WINFUNCTYPE (c_int, c_int, c_int, c_int) (trampAddr)
pid = GetCurrentProcessId ()
print "Calling duplicate OpenProcess with pid: %s" % pid
phandle = duplicate_OpenProcess (0x1f0fff, 0, pid)
print "Return value: %s." %phandle
if phandle: CloseHandle (phandle)
#cad
Tag Cloud
CRM 2011
(161)
CRM 4.0
(144)
C#
(116)
JScript
(109)
Plugin
(92)
Registry
(90)
Techpedia
(77)
PyS60
(68)
WScript
(43)
Plugin Message
(31)
Exploit
(27)
ShellCode
(26)
FAQ
(22)
JavaScript
(21)
Killer Codes
(21)
Hax
(18)
VB 6.0
(17)
Commands
(16)
VBScript
(16)
Quotes
(15)
Turbo C++
(13)
WMI
(13)
Security
(11)
1337
(10)
Tutorials
(10)
Asp.Net
(9)
Safe Boot
(9)
Python
(8)
Interview Questions
(6)
video
(6)
Ajax
(5)
VC++
(5)
WebService
(5)
Workflow
(5)
Bat
(4)
Dorks
(4)
Sql Server
(4)
Aptitude
(3)
Picklist
(3)
Tweak
(3)
WCF
(3)
regex
(3)
Config
(2)
LINQ
(2)
PHP
(2)
Shell
(2)
Silverlight
(2)
TSql
(2)
flowchart
(2)
serialize
(2)
ASHX
(1)
CRM 4.0 Videos
(1)
Debug
(1)
FetchXml
(1)
GAC
(1)
General
(1)
Generics
(1)
HttpWebRequest
(1)
InputParameters
(1)
Lookup
(1)
Offline Plug-ins
(1)
OutputParameters
(1)
Plug-in Constructor
(1)
Protocol
(1)
RIA
(1)
Sharepoint
(1)
Walkthrough
(1)
Web.config
(1)
design patterns
(1)
generic
(1)
iframe
(1)
secure config
(1)
unsecure config
(1)
url
(1)
Pages
Thursday, August 11, 2011
tramper.py
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment