I want to change context (Rdx, Rax etc.) everytime a specific function gets called. My solution: I seted up a breakpoint at function event.get_thread().set_context({"Rdx" : "bla bla"})

My problem: The FPS of the game drops to 16 Is there another method to do this without FPS problem ?

# -*- coding: utf-8 -*-
import time
import os,code
import winappdbg
import psutil
pid = None
process_name = "process.exe"
for process in psutil.process_iter():
    if process.name() == process_name:
        pid  = process.pid
def handle(event):
    global count
    count += 1
    print(f"Changed Slot: {count}")
global event2, count, alloc
alloc = None
event2 = None
count = 0
def eventHandler(event):
    code = event.get_event_code()
    if code == winappdbg.win32.LOAD_DLL_DEBUG_EVENT:
        module = event.get_module()
        if module.match_name("user32.dll"):
            print ("Setting breakpoint")
            global event2
            event2 = event
            event.debug.break_at(event.get_pid(), 0x7FF60DA6C47E, handle)
debu = winappdbg.Debug(eventHandler, bKillOnExit=False)
proc = debu.attach(pid)
except KeyboardInterrupt:
    event2.debug.dont_break_at(event2.get_pid(), 0x7FF60DA6C47E)
  • The process of handling breakpoints is very slow, as you've observed. This is a case where you'd typically use a trampoline ---overwrite the first few instructions of the target function to instead jump to your own function that increments a counter, then executes the instructions you overwrote from the original function, before flowing back to the original function. The real trick is making sure you don't lose any register state in the process. Sometimes it's better to let the target function store off preserved registers before bouncing out to your routine. Dec 13, 2021 at 3:00
  • As for how you get your function into the program's address space: there's usually some alignment padding after the executable section, so you can expand it to make room for new instructions. Otherwise, .dll/.so injection is a good way to get code into the target address space. There are lots of ways to get code into another program's address space...they range from simple to very complex. Dec 13, 2021 at 3:03
  • Yes, this was on my mind. Is this what you mean ? jmp myFunctionAddress
    – Yusuf2020
    Dec 13, 2021 at 15:50
  • yeah, but since that jump is likely about 5 bytes, the routine you jump to will need to effectively do pushf; inc <your counter>; popf; <whatever instructions you overwrote with the jmp>; jmp <back to the next instruction after what you overwrote>. The instructions above are x86, and all assumes your target function has a valid stack frame to use, and makes some assumptions about the calling conventions of your platform. Dec 13, 2021 at 22:43
  • Hi,I did what you said and it worked, Thanks. I want to ask you something. I've found a breakpoint type called software breakpoint (Cheat Engine uses it). This breakpoint style doesn't lower the FPS of game. Do you know how I can use this method and get registers (RBX, RAX etc.) ? I can use C++.
    – Yusuf2020
    Jan 2 at 17:50


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.