@@ -405,24 +405,69 @@ class RegisterCaptureSettings:
405405 offset : int = 0
406406
407407
408- # TODO: remove the offset stuff from register capture, it's useless
409408# NOTE: this registertype is kinda mid, we may need to provide our own
410409def create_capture_hook (
411410 pattern : regex .Pattern | bytes ,
412411 module : str ,
412+ bitness : Literal [32 ] | Literal [64 ],
413413 * ,
414- register_captures : list [RegisterCaptureSettings ]
414+ register_captures : list [RegisterCaptureSettings ],
415415) -> type [JmpHook ]:
416416 """Create a capture hook class
417417
418418 Args:
419419 pattern (regex.Pattern | bytes): Pattern to hook at
420420 module (str): Module to search in
421+ bitness (int): What bitness of hook to create
421422 register_captures (list[RegisterCaptureSettings]): Registers to capture
422423
423424 Returns:
424425 type[JmpHook]: The created capture hook
425426 """
427+
428+ if bitness == 64 :
429+ return _create_capture_hook_64bit (pattern , module , register_captures )
430+ else :
431+ return _create_capture_hook_32bit (pattern , module , register_captures )
432+
433+
434+ def _create_capture_hook_32bit (pattern : regex .Pattern | bytes , module : str , register_captures : list [RegisterCaptureSettings ]):
435+ class CaptureHook (JmpHook ):
436+ PATTERN = pattern
437+ MODULE = module
438+
439+ def get_code (self ) -> list [Instruction ]:
440+ instructions : list [Instruction ] = []
441+
442+ for register_setting in register_captures :
443+ name = get_register_name (register_setting .register )
444+ capture = self .allocate_variable (f"{ name } _capture" , 4 )
445+
446+ if register_setting .derefference is True :
447+ instructions += [
448+ # push <reg>
449+ Instruction .create_reg (Code .PUSH_R32 , register_setting .register ),
450+ # mov <reg>,[<reg>+<offset>]
451+ Instruction .create_reg_mem (Code .MOV_R32_RM32 , register_setting .register , MemoryOperand (register_setting .register , displ = register_setting .offset , displ_size = 4 )),
452+ # mov [<capture_addr>],<reg>
453+ Instruction .create_mem_reg (Code .MOV_RM32_R32 , MemoryOperand (displ = capture .address , displ_size = 4 ), register_setting .register ),
454+ # pop <reg>
455+ Instruction .create_reg (Code .POP_R32 , register_setting .register ),
456+ ]
457+
458+
459+ else :
460+ # mov rax,<reg>
461+ instructions .append (
462+ Instruction .create_mem_reg (Code .MOV_RM32_R32 , MemoryOperand (displ = capture .address , displ_size = 4 ), register_setting .register )
463+ )
464+
465+ return instructions
466+
467+ return CaptureHook
468+
469+
470+ def _create_capture_hook_64bit (pattern : regex .Pattern | bytes , module : str , register_captures : list [RegisterCaptureSettings ]):
426471 for register_setting in register_captures :
427472 if register_setting .register == Register .RAX :
428473 rax_register = register_setting
@@ -443,30 +488,15 @@ def get_code(self) -> list[Instruction]:
443488 # we need to get rax first since it's used to mov the rest
444489 if rax_register is not None :
445490 rax_capture = self .allocate_variable ("RAX_capture" , 8 )
446- if rax_register .derefference is True and rax_register . offset == 0 :
447- # mov rax,[rax]
491+ if rax_register .derefference is True :
492+ # mov rax,[rax+<offset> ]
448493 instructions .append (
449494 Instruction .create_reg_mem (
450495 Code .MOV_R64_RM64 ,
451496 Register .RAX ,
452- MemoryOperand (Register .RAX , displ_size = 8 )
497+ MemoryOperand (Register .RAX , displ = rax_register . offset , displ_size = 8 )
453498 )
454499 )
455- elif rax_register .derefference is False :
456- # mov rax,rax
457- instructions .append (Instruction .create_mem_reg (
458- Code .MOV_MOFFS64_RAX ,
459- MemoryOperand (displ = rax_capture .address , displ_size = 8 ),
460- Register .RAX ,
461- ))
462- else :
463- # mov rax,[rax+<offset>]
464- instructions .append (
465- Instruction .create_reg_mem (
466- Code .MOV_R64_RM64 ,
467- Register .RAX ,
468- MemoryOperand (Register .RAX , displ = rax_register .offset , displ_size = 8 ),
469- ))
470500
471501 # mov [<addr>],rax
472502 instructions .append (Instruction .create_mem_reg (
@@ -479,17 +509,18 @@ def get_code(self) -> list[Instruction]:
479509 name = get_register_name (register_setting .register )
480510 capture = self .allocate_variable (f"{ name } _capture" , 8 )
481511
482- if register_setting .derefference is True and register_setting .offset == 0 :
483- # mov rax,[<reg>]
512+ if register_setting .derefference is True :
513+ # NOTE: this doesn't work for RSP
514+ # mov rax,[<reg>+<offset>]
484515 instructions .append (
485516 Instruction .create_reg_mem (
486517 Code .MOV_R64_RM64 ,
487518 Register .RAX ,
488- MemoryOperand (register_setting .register , displ_size = 8 )
519+ MemoryOperand (register_setting .register , displ = register_setting . offset , displ_size = 8 )
489520 )
490521 )
491522
492- elif register_setting . derefference is False :
523+ else :
493524 # mov rax,<reg>
494525 instructions .append (
495526 Instruction .create_reg_reg (
@@ -498,21 +529,7 @@ def get_code(self) -> list[Instruction]:
498529 register_setting .register ,
499530 )
500531 )
501- else :
502- offset = register_setting .offset
503532
504- # TODO: make sure to account for 32 bit here if support is added
505- if register_setting .register == Register .RSP :
506- offset += 8 # push rax before moves
507-
508- # mov rax,[<reg>+<offset>]
509- instructions .append (
510- Instruction .create_reg_mem (
511- Code .MOV_R64_RM64 ,
512- Register .RAX ,
513- MemoryOperand (base = register_setting .register , displ = offset , displ_size = 8 ),
514- )
515- )
516533
517534 instructions .append (
518535 Instruction .create_mem_reg (
0 commit comments