mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Add NTSTATUS to windef/add virtual_free/improve nativeutils GetProcAddr + test
This commit is contained in:
@@ -17,19 +17,13 @@ TODO:
|
||||
- Real API arround alloc/free memory in WinProcess..
|
||||
|
||||
- Threading
|
||||
- code injection do real thread stuff
|
||||
- Quid IAT hook stub ? just einit threads and remove this ?
|
||||
|
||||
- Injection
|
||||
- code generated by generate_python_exec_shellcode_64[32] may be reused
|
||||
Just need to passe the address of the python string as argument
|
||||
|
||||
- GetProcesAddress
|
||||
- CRASH if API is not found..
|
||||
- fail when resolving xxxW function
|
||||
|
||||
- Debugger:
|
||||
- clean Syswow64 debugging code (_handle_syswow64_exception)
|
||||
|
||||
FIXME:
|
||||
- WMI
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
|
||||
import dummy_wintypes
|
||||
import struct_parser
|
||||
@@ -8,6 +9,7 @@ import func_parser
|
||||
import def_parser
|
||||
|
||||
|
||||
|
||||
TYPE_EQUIVALENCE = [
|
||||
('PWSTR', 'LPWSTR'),
|
||||
('SIZE_T', 'c_ulong'),
|
||||
@@ -54,10 +56,12 @@ known_type = dummy_wintypes.names + list([x[0] for x in TYPE_EQUIVALENCE])
|
||||
FUNC_FILE = "winfunc.txt"
|
||||
STRUCT_FILE = "winstruct.txt"
|
||||
DEF_FILE = "windef.txt"
|
||||
NTSTATUS_FILE = "ntstatus.txt"
|
||||
|
||||
GENERATED_STRUCT_FILE = "winstructs"
|
||||
GENERATED_FUNC_FILE = "winfuncs"
|
||||
GENERATED_DEF_FILE = "windef"
|
||||
GENERATED_NTSTATUS_FILE = "ntstatus"
|
||||
|
||||
OUT_DIRS = ["..\windows\generated_def"]
|
||||
if len(sys.argv) > 1:
|
||||
@@ -204,6 +208,14 @@ structs, enums = struct_parser.WinStructParser(structs_code).parse()
|
||||
validate_structs(structs, enums, defs)
|
||||
verif_funcs_type(funcs, structs, enums)
|
||||
|
||||
|
||||
# Create Flags for ntstatus
|
||||
nt_status_defs = []
|
||||
for line in open(NTSTATUS_FILE):
|
||||
code, name, descr = line.split("|", 2)
|
||||
nt_status_defs.append(def_parser.WinDef(name, code))
|
||||
defs = nt_status_defs + defs
|
||||
|
||||
defs_ctypes = generate_defs_ctypes(defs)
|
||||
funcs_ctypes = generate_funcs_ctypes(funcs)
|
||||
structs_ctypes = generate_struct_ctypes(structs, enums)
|
||||
@@ -216,5 +228,42 @@ write_to_out_file(GENERATED_DEF_FILE, defs_ctypes)
|
||||
write_to_out_file(GENERATED_FUNC_FILE, funcs_ctypes)
|
||||
write_to_out_file(GENERATED_STRUCT_FILE, structs_ctypes)
|
||||
|
||||
|
||||
NTSTATUS_HEAD = """
|
||||
class NtStatusException(Exception):
|
||||
ALL_STATUS = {}
|
||||
def __init__(self , code):
|
||||
try:
|
||||
x = self.ALL_STATUS[code]
|
||||
except KeyError:
|
||||
x = (code, 'UNKNOW_ERROR', 'Error non documented in ntstatus.py')
|
||||
self.code = x[0]
|
||||
self.name = x[1]
|
||||
self.descr = x[2]
|
||||
|
||||
return super(NtStatusException, self).__init__(*x)
|
||||
|
||||
def __str__(self):
|
||||
return "{e.name}(0x{e.code:x}): {e.descr}".format(e=self)
|
||||
|
||||
@classmethod
|
||||
def register_ntstatus(cls, code, name, descr):
|
||||
if code in cls.ALL_STATUS:
|
||||
return # Use the first def
|
||||
cls.ALL_STATUS[code] = (code, name, descr)
|
||||
"""
|
||||
|
||||
nt_status_exceptions = [NTSTATUS_HEAD]
|
||||
for line in open(NTSTATUS_FILE):
|
||||
code, name, descr = line.split("|", 2)
|
||||
code = int(code, 0)
|
||||
b = descr
|
||||
descr = re.sub(" +", " ", descr[:-1]) # remove \n
|
||||
descr = descr.replace('"', "'")
|
||||
nt_status_exceptions.append('NtStatusException.register_ntstatus({0}, "{1}", "{2}")'.format(hex(code), name, descr))
|
||||
|
||||
|
||||
write_to_out_file(GENERATED_NTSTATUS_FILE, "\n".join(nt_status_exceptions))
|
||||
|
||||
for out_dir in OUT_DIRS:
|
||||
print("Files generated in <{0}>".format(os.path.abspath(out_dir)))
|
||||
|
||||
+27
-49
@@ -83,8 +83,8 @@ class Debugger(object):
|
||||
|
||||
def _dispatch_breakpoint(self, exception, addr):
|
||||
bp = self.breakpoints[addr]
|
||||
bp.trigger(self, exception)
|
||||
return bp
|
||||
x = bp.trigger(self, exception)
|
||||
return x
|
||||
|
||||
def _setup_breakpoint_BP(self, bp, targets):
|
||||
for target in targets:
|
||||
@@ -153,58 +153,30 @@ class Debugger(object):
|
||||
def _handle_unknown_debug_event(self, debug_event):
|
||||
raise NotImplementedError("dwDebugEventCode = {0}".format(debug_event.dwDebugEventCode))
|
||||
|
||||
def _handle_syswow64_exception(self, debug_event):
|
||||
exception = debug_event.u.Exception
|
||||
self._update_debugger_state(debug_event)
|
||||
exception.__class__ = windows.vectored_exception.EEXCEPTION_DEBUG_INFO64
|
||||
excp_code = exception.ExceptionRecord.ExceptionCode
|
||||
excp_addr = exception.ExceptionRecord.ExceptionAddress
|
||||
if excp_code in [EXCEPTION_BREAKPOINT, 0x4000001f] and excp_addr in self.breakpoints:
|
||||
self._dispatch_breakpoint(exception, excp_addr)
|
||||
self._pass_breakpoint(excp_addr)
|
||||
return
|
||||
elif excp_code in [EXCEPTION_SINGLE_STEP, 0x4000001e]:
|
||||
if self.current_thread.tid in self._breakpoint_to_reput:
|
||||
addr = self._breakpoint_to_reput[self.current_thread.tid]
|
||||
del self._breakpoint_to_reput[self.current_thread.tid]
|
||||
# Re-put the breakpoint
|
||||
self.current_process.write_memory(addr, "\xcc")
|
||||
elif excp_addr in self.breakpoints:
|
||||
# Verif that's not a standard BP ?
|
||||
bp = self.breakpoints[excp_addr]
|
||||
bp.trigger(self, exception)
|
||||
ctx = self.current_thread.context
|
||||
ctx.EEFlags.RF = 1
|
||||
self.current_thread.set_context(ctx)
|
||||
else:
|
||||
self.on_exception(exception)
|
||||
else: # Do not trigger self.on_exception if breakpoint was registered
|
||||
self.on_exception(exception)
|
||||
|
||||
def _handle_exception(self, debug_event):
|
||||
"""Handle EXCEPTION_DEBUG_EVENT"""
|
||||
exception = debug_event.u.Exception
|
||||
self._update_debugger_state(debug_event)
|
||||
if windows.current_process.bitness == 64 and self.current_process.bitness == 32:
|
||||
return self._handle_syswow64_exception(debug_event)
|
||||
|
||||
if self.current_process.bitness == 32:
|
||||
if windows.current_process.bitness == 32:
|
||||
exception.__class__ = windows.vectored_exception.EEXCEPTION_DEBUG_INFO32
|
||||
else:
|
||||
exception.__class__ = windows.vectored_exception.EEXCEPTION_DEBUG_INFO64
|
||||
|
||||
excp_code = exception.ExceptionRecord.ExceptionCode
|
||||
excp_addr = exception.ExceptionRecord.ExceptionAddress
|
||||
if excp_code == EXCEPTION_BREAKPOINT and excp_addr in self.breakpoints:
|
||||
self._dispatch_breakpoint(exception, excp_addr)
|
||||
|
||||
if excp_code in [EXCEPTION_BREAKPOINT, STATUS_WX86_BREAKPOINT] and excp_addr in self.breakpoints:
|
||||
continue_flag = self._dispatch_breakpoint(exception, excp_addr)
|
||||
self._pass_breakpoint(excp_addr)
|
||||
return
|
||||
elif excp_code == EXCEPTION_SINGLE_STEP:
|
||||
return continue_flag
|
||||
elif excp_code in [EXCEPTION_SINGLE_STEP, STATUS_WX86_SINGLE_STEP]:
|
||||
if self.current_thread.tid in self._breakpoint_to_reput:
|
||||
addr = self._breakpoint_to_reput[self.current_thread.tid]
|
||||
del self._breakpoint_to_reput[self.current_thread.tid]
|
||||
# Re-put the breakpoint
|
||||
self.current_process.write_memory(addr, "\xcc")
|
||||
return DBG_CONTINUE
|
||||
elif excp_addr in self.breakpoints:
|
||||
# Verif that's not a standard BP ?
|
||||
bp = self.breakpoints[excp_addr]
|
||||
@@ -212,10 +184,11 @@ class Debugger(object):
|
||||
ctx = self.current_thread.context
|
||||
ctx.EEFlags.RF = 1
|
||||
self.current_thread.set_context(ctx)
|
||||
return DBG_CONTINUE
|
||||
else:
|
||||
self.on_exception(exception)
|
||||
return self.on_exception(exception)
|
||||
else: # Do not trigger self.on_exception if breakpoint was registered
|
||||
self.on_exception(exception)
|
||||
return self.on_exception(exception)
|
||||
|
||||
|
||||
def _handle_create_process(self, debug_event):
|
||||
@@ -228,14 +201,14 @@ class Debugger(object):
|
||||
self.processes[self.current_process.pid] = self.current_process
|
||||
self._update_debugger_state(debug_event)
|
||||
self._setup_pending_breakpoints(self.current_process)
|
||||
self.on_create_process(create_process)
|
||||
return self.on_create_process(create_process)
|
||||
# TODO: clode hFile
|
||||
|
||||
def _handle_exit_process(self, debug_event):
|
||||
"""Handle EXIT_PROCESS_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
exit_process = debug_event.u.ExitProcess
|
||||
self.on_exit_process(exit_process)
|
||||
retvalue = self.on_exit_process(exit_process)
|
||||
del self.threads[self.current_thread.tid]
|
||||
del self.processes[self.current_process.pid]
|
||||
# Hack IT, ContinueDebugEvent will close the HANDLE for us
|
||||
@@ -243,6 +216,7 @@ class Debugger(object):
|
||||
dbgprint("Removing handle {0} for {1} (will be closed by continueDebugEvent".format(hex(self.current_process._handle), self.current_process), "HANDLE")
|
||||
del self.current_process._handle
|
||||
del self.current_thread._handle
|
||||
return retvalue
|
||||
|
||||
def _handle_create_thread(self, debug_event):
|
||||
"""Handle CREATE_THREAD_DEBUG_EVENT"""
|
||||
@@ -250,48 +224,52 @@ class Debugger(object):
|
||||
self.current_thread = WinThread._from_handle(create_thread.hThread)
|
||||
self.threads[self.current_thread.tid] = self.current_thread
|
||||
self._setup_pending_breakpoints(self.current_thread)
|
||||
self.on_create_thread(create_thread)
|
||||
return self.on_create_thread(create_thread)
|
||||
|
||||
|
||||
def _handle_exit_thread(self, debug_event):
|
||||
"""Handle EXIT_THREAD_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
exit_thread = debug_event.u.ExitThread
|
||||
self.on_exit_thread(exit_thread)
|
||||
retvalue = self.on_exit_thread(exit_thread)
|
||||
del self.threads[self.current_thread.tid]
|
||||
# Hack IT, ContinueDebugEvent will close the HANDLE for us
|
||||
# Should we make another handle instead ?
|
||||
dbgprint("Removing handle {0} for {1} (will be closed by continueDebugEvent".format(hex(self.current_thread._handle), self.current_thread), "HANDLE")
|
||||
del self.current_thread._handle
|
||||
return retvalue
|
||||
|
||||
def _handle_load_dll(self, debug_event):
|
||||
"""Handle LOAD_DLL_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
load_dll = debug_event.u.LoadDll
|
||||
self.on_load_dll(load_dll)
|
||||
return self.on_load_dll(load_dll)
|
||||
|
||||
def _handle_unload_dll(self, debug_event):
|
||||
"""Handle UNLOAD_DLL_DEBUG_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
unload_dll = debug_event.u.UnloadDll
|
||||
self.on_unload_dll(unload_dll)
|
||||
return self.on_unload_dll(unload_dll)
|
||||
|
||||
def _handle_output_debug_string(self, debug_event):
|
||||
"""Handle OUTPUT_DEBUG_STRING_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
debug_string = debug_event.u.DebugString
|
||||
self.on_output_debug_string(debug_string)
|
||||
return self.on_output_debug_string(debug_string)
|
||||
|
||||
def _handle_rip(self, debug_event):
|
||||
"""Handle RIP_EVENT"""
|
||||
self._update_debugger_state(debug_event)
|
||||
rip_info = debug_event.u.RipInfo
|
||||
self.on_rip(rip_info)
|
||||
return self.on_rip(rip_info)
|
||||
|
||||
# Public API
|
||||
def loop(self):
|
||||
for debug_event in self._debug_event_generator():
|
||||
self._dispatch_debug_event(debug_event)
|
||||
self._finish_debug_event(debug_event, windef.DBG_CONTINUE)
|
||||
dbg_continue_flag = self._dispatch_debug_event(debug_event)
|
||||
if dbg_continue_flag is None:
|
||||
dbg_continue_flag = DBG_CONTINUE
|
||||
self._finish_debug_event(debug_event, dbg_continue_flag)
|
||||
if not self.processes:
|
||||
break
|
||||
|
||||
|
||||
+1659
-1659
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -65,7 +65,7 @@ GetProcAddress64 += x64.Mov("RAX", "RDX")
|
||||
GetProcAddress64 += x64.Mov("RBX", x64.mem("[RAX + 32]")) # RBX : first base ! (base of current module)
|
||||
#GetProcAddress64 += x64.Mov("RBX ", x64.mem("[RAX + 32]")) # RBX : first base ! (base of current module)
|
||||
GetProcAddress64 += x64.Cmp("RBX", 0)
|
||||
GetProcAddress64 += x64.Jz(":NOT_FOUND")
|
||||
GetProcAddress64 += x64.Jz(":DLL_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Mov("RCX", x64.mem("[RAX + 80]")) # RCX = NAME (UNICODE_STRING.Buffer)
|
||||
GetProcAddress64 += x64.Call(":FUNC_STRLENW64")
|
||||
GetProcAddress64 += x64.Mov("RDI", "RCX")
|
||||
@@ -92,6 +92,8 @@ GetProcAddress64 += x64.Mov("EDX", x64.mem("[RAX + 32] ")) # EDX = names array
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX") # RDX = names array
|
||||
GetProcAddress64 += x64.Xor("RCX", "RCX")
|
||||
GetProcAddress64 += x64.Label(":SEARCH_LOOP")
|
||||
GetProcAddress64 += x64.Cmp("RCX", "R13")
|
||||
GetProcAddress64 += x64.Jz(":API_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Mov("ESI", x64.mem("[RDX + RCX * 4]")) # ;Get function name RVA
|
||||
GetProcAddress64 += x64.Add("RSI", "RBX") # ;Get name addr
|
||||
GetProcAddress64 += x64.Push("RCX") # ;Save current index (could use x64 register)
|
||||
@@ -118,6 +120,7 @@ GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.Mov("EDX", x64.mem("[RDX + RCX * 4]"))
|
||||
GetProcAddress64 += x64.Add("RDX", "RBX")
|
||||
GetProcAddress64 += x64.Mov("RAX", "RDX")
|
||||
GetProcAddress64 += x64.Label(":RETURN")
|
||||
GetProcAddress64 += x64.Pop("R13")
|
||||
GetProcAddress64 += x64.Pop("R12")
|
||||
GetProcAddress64 += x64.Pop("R11")
|
||||
@@ -130,9 +133,13 @@ GetProcAddress64 += x64.Pop("RDX")
|
||||
GetProcAddress64 += x64.Pop("RCX")
|
||||
GetProcAddress64 += x64.Pop("RBX")
|
||||
GetProcAddress64 += x64.Ret()
|
||||
GetProcAddress64 += x64.Label(":NOT_FOUND")
|
||||
GetProcAddress64 += x64.Xor("RAX", "RAX")
|
||||
GetProcAddress64 += x64.Ret()
|
||||
GetProcAddress64 += x64.Label(":DLL_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Mov("RAX", 0xfffffffffffffffe)
|
||||
GetProcAddress64 += x64.Jmp(":RETURN")
|
||||
GetProcAddress64 += x64.Label(":API_NOT_FOUND")
|
||||
GetProcAddress64 += x64.Pop("RAX")
|
||||
GetProcAddress64 += x64.Mov("RAX", 0xffffffffffffffff)
|
||||
GetProcAddress64 += x64.Jmp(":RETURN")
|
||||
# Ajout des dependances
|
||||
GetProcAddress64 += StrlenW64
|
||||
GetProcAddress64 += StrlenA64
|
||||
@@ -191,7 +198,7 @@ GetProcAddress32 += x86.Label(":a_dest")
|
||||
GetProcAddress32 += x86.Mov("EAX", "EDX")
|
||||
GetProcAddress32 += x86.Mov("EBX", x86.mem("[EAX + 0x18]")) # EBX : first base ! (base of current module)
|
||||
GetProcAddress32 += x86.Cmp("EBX", 0)
|
||||
GetProcAddress32 += x86.Jz(":NOT_FOUND")
|
||||
GetProcAddress32 += x86.Jz(":DLL_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Mov("ECX", x86.mem("[EAX + 0x30]")) # RCX = NAME (UNICODE_STRING.Buffer)
|
||||
GetProcAddress32 += x86.Push("ECX")
|
||||
GetProcAddress32 += x86.Call(":FUNC_STRLENW32")
|
||||
@@ -219,6 +226,8 @@ GetProcAddress32 += x86.Add("EDX", "EBX") # RDX = names array
|
||||
GetProcAddress32 += x86.Xor("ECX", "ECX")
|
||||
GetProcAddress32 += x86.Mov("ESI", x86.mem("[ESP + 0x20]"))
|
||||
GetProcAddress32 += x86.Label(":SEARCH_LOOP")
|
||||
GetProcAddress32 += x86.Cmp("ECX", "EBP")
|
||||
GetProcAddress32 += x86.Jz(":API_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Mov("EDI", x86.mem("[EDX + ECX * 4]")) # ;Get function name RVA
|
||||
GetProcAddress32 += x86.Add("EDI", "EBX") # ;Get name addr
|
||||
GetProcAddress32 += x86.Push("ECX") # Save current index
|
||||
@@ -255,14 +264,19 @@ GetProcAddress32 += x86.Add("EDX", "EBX")
|
||||
GetProcAddress32 += x86.Mov("EDX", x86.mem("[EDX + ECX * 4]"))
|
||||
GetProcAddress32 += x86.Add("EDX", "EBX")
|
||||
GetProcAddress32 += x86.Mov("EAX", "EDX")
|
||||
GetProcAddress32 += x86.Label(":RETURN")
|
||||
GetProcAddress32 += x86.Pop("EBP")
|
||||
GetProcAddress32 += x86.Pop("ESI")
|
||||
GetProcAddress32 += x86.Pop("EDI")
|
||||
GetProcAddress32 += x86.Pop("ECX")
|
||||
GetProcAddress32 += x86.Pop("EBX")
|
||||
GetProcAddress32 += x86.Ret()
|
||||
GetProcAddress32 += x86.Label(":NOT_FOUND")
|
||||
GetProcAddress32 += x86.Xor("EAX", "EAX")
|
||||
GetProcAddress32 += x86.Ret()
|
||||
GetProcAddress32 += x86.Label(":DLL_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Mov("EAX", 0xfffffffe)
|
||||
GetProcAddress32 += x86.Jmp(":RETURN")
|
||||
GetProcAddress32 += x86.Label(":API_NOT_FOUND")
|
||||
GetProcAddress32 += x86.Pop("EAX")
|
||||
GetProcAddress32 += x86.Mov("EAX", 0xffffffff)
|
||||
GetProcAddress32 += x86.Jmp(":RETURN")
|
||||
GetProcAddress32 += StrlenW32
|
||||
GetProcAddress32 += StrlenA32
|
||||
@@ -371,6 +371,9 @@ class NativeUtilsTestCase(unittest.TestCase):
|
||||
# Put name in test to know which function caused the assert fails
|
||||
self.assertEqual((name, hex(addr)), (name, hex(compute_addr)))
|
||||
|
||||
self.assertEqual(getprocaddr64("YOLO.DLL", "whatever"), 0xfffffffffffffffe)
|
||||
self.assertEqual(getprocaddr64("KERNEL32.DLL", "YOLOAPI"), 0xffffffffffffffff)
|
||||
|
||||
@process_32bit_only
|
||||
def test_strlenw32(self):
|
||||
strlenw32 = windows.native_exec.create_function(nativeutils.StrlenW32.get_code(), [UINT, LPCWSTR])
|
||||
@@ -396,6 +399,10 @@ class NativeUtilsTestCase(unittest.TestCase):
|
||||
self.assertEqual((name, hex(addr)), (name, hex(compute_addr)))
|
||||
|
||||
|
||||
self.assertEqual(getprocaddr32("YOLO.DLL", "whatever"), 0xfffffffe)
|
||||
self.assertEqual(getprocaddr32("KERNEL32.DLL", "YOLOAPI"), 0xffffffff)
|
||||
|
||||
|
||||
class DebuggerTestCase(unittest.TestCase):
|
||||
|
||||
def debuggable_calc_32(self):
|
||||
|
||||
+18
-7
@@ -309,6 +309,9 @@ class Process(AutoHandle):
|
||||
def virtual_alloc(self, size):
|
||||
raise NotImplementedError("virtual_alloc")
|
||||
|
||||
def virtual_free(self):
|
||||
raise NotImplementedError("virtual_free")
|
||||
|
||||
@property
|
||||
def exit_code(self):
|
||||
"""The exit code of the process : ``STILL_ACTIVE`` means the process is not dead
|
||||
@@ -327,13 +330,13 @@ class Process(AutoHandle):
|
||||
"""
|
||||
return self.exit_code != STILL_ACTIVE
|
||||
|
||||
#@contextmanager
|
||||
#def allocated_memory(self, size):
|
||||
# addr = self.virtual_alloc(size)
|
||||
# try:
|
||||
# yield addr
|
||||
# finally:
|
||||
# windows.winproxy.VirtualFreeEx(self.handle, size)
|
||||
@contextmanager
|
||||
def allocated_memory(self, size):
|
||||
addr = self.virtual_alloc(size)
|
||||
try:
|
||||
yield addr
|
||||
finally:
|
||||
windows.winproxy.VirtualFreeEx(self.handle, addr)
|
||||
|
||||
def execute(self, code, parameter=0):
|
||||
"""Execute some native code in the context of the process
|
||||
@@ -548,6 +551,10 @@ class CurrentProcess(Process):
|
||||
"""
|
||||
return winproxy.VirtualAlloc(dwSize=size)
|
||||
|
||||
def virtual_free(self, addr):
|
||||
"""Free memory in the process by virtual_alloc"""
|
||||
return winproxy.VirtualFree(addr)
|
||||
|
||||
def write_memory(self, addr, data):
|
||||
"""Write data at addr"""
|
||||
buffertype = (c_char * len(data)).from_address(addr)
|
||||
@@ -633,6 +640,10 @@ class WinProcess(PROCESSENTRY32, Process):
|
||||
"""
|
||||
return winproxy.VirtualAllocEx(self.handle, dwSize=size)
|
||||
|
||||
def virtual_free(self, addr):
|
||||
"""Free memory in the process by virtual_alloc"""
|
||||
return winproxy.VirtualFreeEx(self.handle, addr)
|
||||
|
||||
def write_memory(self, addr, data):
|
||||
"""Write `data` at `addr`"""
|
||||
return winproxy.WriteProcessMemory(self.handle, addr, lpBuffer=data)
|
||||
|
||||
Reference in New Issue
Block a user