forked from KVM-VMI/nitro
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from KVM-VMI/linux_argument_map
Linux argument map
- Loading branch information
Showing
3 changed files
with
82 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,51 @@ | ||
from enum import Enum | ||
import struct | ||
|
||
from enum import Enum | ||
from nitro.event import SyscallType | ||
|
||
class SyscallArgumentType(Enum): | ||
register = 0 | ||
memory = 1 | ||
|
||
|
||
class ArgumentMap: | ||
|
||
ARG_SIZE = { | ||
SyscallType.syscall: 'P', # x64 -> 8 bytes | ||
SyscallType.sysenter: 'I' # x32 -> 4 bytes | ||
} | ||
|
||
__slots__ = ( | ||
"event", | ||
"name", | ||
"process", | ||
"modified" | ||
"modified", | ||
"arg_size_format" | ||
) | ||
|
||
def __init__(self, event, name, process): | ||
self.event = event | ||
self.name = name | ||
self.process = process | ||
self.modified = {} | ||
self.arg_size_format = self.ARG_SIZE[self.event.type] | ||
|
||
def get_argument_value(self, arg_type, opaque): | ||
if arg_type == SyscallArgumentType.register: | ||
value = self.event.get_register(opaque) | ||
else: | ||
# memory | ||
size = struct.calcsize(self.arg_size_format) | ||
addr = self.event.regs.rsp + (opaque * size) | ||
value, *rest = struct.unpack(self.arg_size_format, self.process.read_memory(addr, size)) | ||
return value | ||
|
||
def set_argument_value(self, arg_type, opaque, value): | ||
if arg_type == SyscallArgumentType.register: | ||
self.event.update_register(opaque, value) | ||
else: | ||
# memory | ||
size = struct.calcsize(self.arg_size_format) | ||
addr = self.event.regs.rsp + (opaque * size) | ||
buffer = struct.pack(self.arg_size_format, value) | ||
self.process.write_memory(addr, buffer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,49 @@ | ||
from nitro.backends.arguments import ArgumentMap | ||
import struct | ||
|
||
from nitro.event import SyscallType | ||
from nitro.backends.arguments import ArgumentMap, SyscallArgumentType | ||
|
||
class LinuxArgumentMap(ArgumentMap): | ||
|
||
CONVENTION = { | ||
SyscallType.syscall: [ | ||
(SyscallArgumentType.register, 'rdi'), | ||
(SyscallArgumentType.register, 'rsi'), | ||
(SyscallArgumentType.register, 'rdx'), | ||
(SyscallArgumentType.register, 'r10'), | ||
(SyscallArgumentType.register, 'r9'), | ||
(SyscallArgumentType.register, 'r8'), | ||
], | ||
SyscallType.sysenter: [ | ||
(SyscallArgumentType.register, 'rbx'), | ||
(SyscallArgumentType.register, 'rcx'), | ||
(SyscallArgumentType.register, 'rdx'), | ||
(SyscallArgumentType.register, 'rsi'), | ||
(SyscallArgumentType.register, 'rdi'), | ||
(SyscallArgumentType.register, 'rbp'), | ||
], | ||
} | ||
|
||
def __getitem__(self, index): | ||
raise NotImplementedError() | ||
try: | ||
arg_type, opaque = self.CONVENTION[self.event.type][index] | ||
except KeyError as error: | ||
raise RuntimeError('Unknown convention') from error | ||
except IndexError: | ||
raise RuntimeError('Invalid argument index: Linux syscalls are ' | ||
'limited to 6 parameters') | ||
|
||
return self.get_argument_value(arg_type, opaque) | ||
|
||
|
||
def __setitem__(self, index, value): | ||
raise NotImplementedError() | ||
try: | ||
arg_type, opaque = self.CONVENTION[self.event.type][index] | ||
except KeyError as error: | ||
raise RuntimeError('Unknown convention') from error | ||
except IndexError: | ||
raise RuntimeError('Invalid argument index: Linux syscalls are ' | ||
'limited to 6 parameters') | ||
|
||
self.set_argument_value(arg_type, opaque, value) | ||
self.modified[index] = value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters