Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes after porting sandsifter to FreeBSD #53

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
all: injector

injector: injector.o
$(CC) $(CFLAGS) $< -O3 -Wall -l:libcapstone.a -o $@ -pthread
$(CC) $(CFLAGS) $(LIBS) $(LDFLAGS) $< -Wall -l:libcapstone.a -o $@ -pthread

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ -Wall
Expand Down
49 changes: 39 additions & 10 deletions injector.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,24 @@ cs_insn *capstone_insn;

/* 32 vs 64 */

#if __x86_64__
#define IP REG_RIP
#ifdef __linux__
# define PAGE_SIZE 4096
# define EFL gregs[REG_EFL]
# if __x86_64__
# define IP gregs[REG_RIP]
# else
# define IP gregs[REG_EIP]
# endif
#else
#define IP REG_EIP
# include <pthread_np.h>
typedef cpuset_t cpu_set_t;
# if __x86_64__
# define IP mc_rip
# define EFL mc_rflags
# else
# define IP mc_eip
# define EFL mc_eflags
# endif
#endif

/* leave state as 0 */
Expand Down Expand Up @@ -155,7 +169,6 @@ state_t inject_state={
/* x86/64 */

#define UD2_SIZE 2
#define PAGE_SIZE 4096
#define TF 0x100

/* injection */
Expand Down Expand Up @@ -293,6 +306,12 @@ ignore_op_t opcode_blacklist[MAX_BLACKLIST]={
{ "\xcd\x80", "int 0x80" },
/* as will syscall */
{ "\x0f\x05", "syscall" },
#ifdef __FreeBSD__
/* int 92 on FreeBSD triggers DTrace, which will trigger SIGSYS */
{ "\xcd\x92", "int 0x92" },
/* int 93 on FreeBSD is used by Xen */
{ "\xcd\x93", "int 0x93" },
#endif
/* ud2 is an undefined opcode, and messes up a length differential search
* b/c of the fault it throws */
{ "\x0f\xb9", "ud2" },
Expand Down Expand Up @@ -850,7 +869,7 @@ void inject(int insn_size)
void state_handler(int signum, siginfo_t* si, void* p)
{
fault_context=((ucontext_t*)p)->uc_mcontext;
((ucontext_t*)p)->uc_mcontext.gregs[IP]+=UD2_SIZE;
((ucontext_t*)p)->uc_mcontext.IP+=UD2_SIZE;
}

void fault_handler(int signum, siginfo_t* si, void* p)
Expand All @@ -863,7 +882,7 @@ void fault_handler(int signum, siginfo_t* si, void* p)

/* make an initial estimate on the instruction length from the fault address */
insn_length=
(uintptr_t)uc->uc_mcontext.gregs[IP]-(uintptr_t)packet-preamble_length;
(uintptr_t)uc->uc_mcontext.IP-(uintptr_t)packet-preamble_length;

if (insn_length<0) {
insn_length=JMP_LENGTH;
Expand All @@ -880,9 +899,13 @@ void fault_handler(int signum, siginfo_t* si, void* p)
(signum==SIGSEGV||signum==SIGBUS)?(uint32_t)(uintptr_t)si->si_addr:(uint32_t)-1
};

#ifdef __linux__
memcpy(uc->uc_mcontext.gregs, fault_context.gregs, sizeof(fault_context.gregs));
uc->uc_mcontext.gregs[IP]=(uintptr_t)&resume;
uc->uc_mcontext.gregs[REG_EFL]&=~TF;
#else
memcpy(&uc->uc_mcontext, &fault_context, sizeof(fault_context));
#endif
uc->uc_mcontext.IP=(uintptr_t)&resume;
uc->uc_mcontext.EFL&=~TF;
}

void configure_sig_handler(void (*handler)(int, siginfo_t*, void*))
Expand Down Expand Up @@ -1341,7 +1364,13 @@ void pin_core(void)
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(config.core,&mask);
if (sched_setaffinity(0, sizeof(mask), &mask)) {
#ifdef __linux__
if (sched_setaffinity(0, sizeof(mask), &mask))
#else
if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
-1, sizeof(mask), &mask))
#endif
{
printf("error: failed to set cpu\n");
exit(1);
}
Expand Down Expand Up @@ -1439,7 +1468,7 @@ int main(int argc, char** argv)
null_p=mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (null_p==MAP_FAILED) {
printf("null access requires running as root\n");
printf("null access requires running as root, %i\n", errno);
exit(1);
}
}
Expand Down
18 changes: 14 additions & 4 deletions sifter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
import copy
from ctypes import *

INJECTOR = "./injector"
INJECTOR = "injector"
arch = ""

OUTPUT = "./data/"
OUTPUT = os.getenv("HOME") + "/.sandsifter/"
LOG = OUTPUT + "log"
SYNC = OUTPUT + "sync"
TICK = OUTPUT + "tick"
Expand Down Expand Up @@ -679,7 +679,10 @@ def render(self):
time.sleep(self.TIME_SLICE)

def get_cpu_info():
with open("/proc/cpuinfo", "r") as f:
cpuinfo = "/proc/cpuinfo"
if os.uname()[0] == "FreeBSD":
cpuinfo = "/compat/linux" + cpuinfo
with open(cpuinfo, "r") as f:
cpu = [l.strip() for l in f.readlines()[:7]]
return cpu

Expand Down Expand Up @@ -808,9 +811,16 @@ def exit_handler(signal, frame):
if not os.path.exists(OUTPUT):
os.makedirs(OUTPUT)

real_injector, errors = \
subprocess.Popen(
['which', INJECTOR],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
).communicate()
real_injector = real_injector.replace('\n', '') # strip newline from shell output
injector_bitness, errors = \
subprocess.Popen(
['file', INJECTOR],
['file', real_injector],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
).communicate()
Expand Down