Comments (15)
- ((ucontext_t*)p)->uc_mcontext.gregs[IP]+=UD2_SIZE;
+ ((ucontext_t*)p)->uc_mcontext->__ss.__rip+=UD2_SIZE;
Variations of this seem to, at the very least, remove more warnings. Still doesn't compile and I'd be surprised if a straight swap out here worked.
from sandsifter.
I got this to compile, but I'm not sure if the executable still works as intended.
This is ONLY for 64-bit – I didn't take the time to convert these changes for 32-bit, but I imagine it wouldn't be too difficult.
Change 1: Dummy Struct
Modify the following snippet:
Lines 174 to 177 in 8375e61
Delete the entire
dummy_stack
definition. Then, copy the following (to anywhere before the inject_state
typedef struct
definition on line 90!):
typedef struct {
uint64_t dummy_stack_hi[256];
uint64_t dummy_stack_lo[256];
} dumb_stack;
static dumb_stack dummy_stack __attribute__ ((aligned(PAGE_SIZE)));
Then, in the __x86_64__
inject_state
definition, modify the struct:
...
uint64_t rsp;
dumb_stack dumb;
} state_t;
...
and the inject_state
definition:
...
.rsp=0,
.dumb.dummy_stack_lo=0,
.dumb.dummy_stack_hi=0
};
...
We also need to modify the stack reset on line 766:
inject_state.dumb.dummy_stack_lo[0]=0;
And lastly, we need to modify the inline asm here:
Lines 777 to 815 in 8375e61
The asm on line 813 should read:
[rsp]"m"(inject_state.dumb.dummy_stack_lo),
Change 2: uc_mcontext
We need to modify uc_mcontext
references for macOS. Make all of the following changes:
- Line 853:
((ucontext_t*)p)->uc_mcontext->__ss.__rip+=UD2_SIZE;
- Line 866:
(uintptr_t)uc->uc_mcontext->__ss.__rip-(uintptr_t)packet-preamble_length;
- Lines 883-885:
uc->uc_mcontext->__ss = fault_context->__ss;
uc->uc_mcontext->__ss.__rip =(uintptr_t)&resume;
uc->uc_mcontext->__ss.__rflags &=~TF;
Change 3: header file
Create a new file injector.h
with the following contents:
extern char debug, resume, preamble_start, preamble_end;
Then modify the extern definition on line 366.
Line 366 in 8375e61
Change line 366 to:
char debug, resume, preamble_start, preamble_end;
Change 4: pthread
modifications
This code was borrowed from https://yyshen.github.io/2015/01/18/binding_threads_to_cores_osx.html.
Copy the following block underneath the top #include
section.
#define SYSCTL_CORE_COUNT "machdep.cpu.core_count"
typedef struct cpu_set {
uint32_t count;
} cpu_set_t;
static inline void
CPU_ZERO(cpu_set_t *cs) { cs->count = 0; }
static inline void
CPU_SET(int num, cpu_set_t *cs) { cs->count |= (1 << num); }
static inline int
CPU_ISSET(int num, cpu_set_t *cs) { return (cs->count & (1 << num)); }
int sched_getaffinity(pid_t pid, size_t cpu_size, cpu_set_t *cpu_set)
{
int32_t core_count = 0;
size_t len = sizeof(core_count);
int ret = sysctlbyname(SYSCTL_CORE_COUNT, &core_count, &len, 0, 0);
if (ret) {
printf("error while get core count %d\n", ret);
return -1;
}
cpu_set->count = 0;
for (int i = 0; i < core_count; i++) {
cpu_set->count |= (1 << i);
}
return 0;
}
int pthread_setaffinity_np(pthread_t thread, size_t cpu_size,
cpu_set_t *cpu_set)
{
thread_port_t mach_thread;
int core = 0;
for (core = 0; core < 8 * cpu_size; core++) {
if (CPU_ISSET(core, cpu_set)) break;
}
printf("binding to core %d\n", core);
thread_affinity_policy_data_t policy = { core };
mach_thread = pthread_mach_thread_np(thread);
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY,
(thread_policy_t)&policy, 1);
return 0;
}
Then, modify line 1344 to read:
if (pthread_setaffinity_np(0, sizeof(mask), &mask)) {
Lastly, append this to the #include
section
#include <mach/thread_policy.h>
Change 5: Python
The sifter.py
file is designed for Linux and attempts to gather CPU info via /proc/cpuinfo
, which doesn't exist on macOS. So, I made a small change to allow running on a Mac.
Lines 681 to 684 in 8375e61
Modify the
get_cpu_info()
function to:
def get_cpu_info():
p = subprocess.Popen(['/usr/sbin/sysctl','-a'], stdout=subprocess.PIPE)
p.wait()
cpu = [l.strip('machdep.cpu.') for l in str(p.stdout.read()).split('\n') if 'machdep.cpu' in l]
return cpu
Lastly, run make
. If you encounter this error:
/usr/include/ucontext.h:43:2: error: The deprecated ucontext routines require _XOPEN_SOURCE to be defined
Run make
with the CFLAGS
variable:
CFLAGS="-D_XOPEN_SOURCE" make
Hope this helps! Also hopefully the injector
binary still functions as expected. Please comment below with results or findings.
from sandsifter.
Same, I've tried with the bundled MacOS llvm as well as the latest.
from sandsifter.
Pull #6 fixes one of these errors.
Changing <ucontext.h> to <sys/ucontext.h> fixes another.
Changing uc->mcontext.gregs to uc->mcontext->gregs fixed another.
Unfortunately, there's no ->gregs member in uc_mcontext64 on Darwin:
_STRUCT_MCONTEXT64
{
_STRUCT_X86_EXCEPTION_STATE64 __es;
_STRUCT_X86_THREAD_STATE64 __ss;
_STRUCT_X86_FLOAT_STATE64 __fs;
};
Because, apparently, this is dependent on glibc's register reading stuff:
https://fossies.org/dox/glibc-2.25/structmcontext__t.html
This ancient article talks about trying to persuade an old OS X kernel to divulge register state:
Ideally there's a better way these days, but no guarantee there.
from sandsifter.
Happily, ->mcontext64->__ss is nothing but registers:
#if __DARWIN_UNIX03
#define _STRUCT_X86_THREAD_STATE64 struct __darwin_x86_thread_state64
_STRUCT_X86_THREAD_STATE64
{
__uint64_t __rax;
__uint64_t __rbx;
__uint64_t __rcx;
from sandsifter.
cpu_set_t is GNU-only:
https://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html
You can fake the goal here, which is I believe to test one core only, using:
http://jesperrasmussen.com/2013/03/07/limiting-cpu-cores-on-the-fly-in-os-x/
Storing and restoring __ss might be as simple as using plain struct assignment:
- memcpy(uc->uc_mcontext->gregs, fault_context->gregs, sizeof(fault_context->gregs));
+ uc->uc_mcontext->__ss = fault_context->__ss;
And then there's this:
injector.c:778:24: error: invalid operand for inline asm constraint 'i'
__asm__ __volatile__ ("\
from sandsifter.
Which I tried to resolve with 'static dummy', and then managed to get:
cc -c injector.c -o injector.o -Wall
fatal error: error in backend: 32-bit absolute addressing is not supported in 64-bit mode
So we're making progress! But this is where I run out of gas, because I can't debug assembler 32/64 differences, sorry.
from sandsifter.
So it seems the issues we are facing for macOS deal with the XNU kernel architecture as a whole.
-
Instead of using gLibC, we need to use the built-in XNU kernel PTrace calls.
-
We need to modify CPU_SET to use Apples alternative. Which can be described here: http://yyshen.github.io/2015/01/18/binding_threads_to_cores_osx.html.
So in general this code will work, but will need a specific branch for any MACH based micro kernel.
from sandsifter.
So I am working on CPU_SET, and it seems all the functions needed can be called from the Affinity API (According to http://yyshen.github.io/2015/01/18/binding_threads_to_cores_osx.html)
So far the first code block works fine, and compiles with no errors. Also with these code blocks in, the current CPU_SET errors go away, but... this code block needs rewritten it seems.
`int pthread_setaffinity_np(pthread_t thread, size_t cpu_size,
cpu_set_t *cpu_set)
{
pthread_cond_t mach_thread;
int core = 0;
for (core = 0; core < 8 * cpu_size; core++) {
if (CPU_ISSET(core, cpu_set)) break;
}
printf("binding to core %d\n", core);
thread_affinity_policy_data_t policy = { core };
mach_thread = pthread_mach_thread_np(thread);
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY,
(thread_policy_set)&policy, 1);
return 0;
}`
@floatingatoll Would you be able to debug this code? I unfortunately do not know enough C to try.
These are the errors I get:
injector.c:1383:5: error: use of undeclared identifier 'thread_affinity_policy_data_t' thread_affinity_policy_data_t policy = { core }; ^ injector.c:1384:17: error: assigning to 'pthread_cond_t' (aka 'struct _opaque_pthread_cond_t') from incompatible type 'mach_port_t' (aka 'unsigned int') mach_thread = pthread_mach_thread_np(thread); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ injector.c:1385:5: warning: implicit declaration of function 'thread_policy_set' is invalid in C99 [-Wimplicit-function-declaration] thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, ^ injector.c:1386:43: error: use of undeclared identifier 'policy' (thread_policy_set)&policy, 1); ^ injector.c:1385:36: error: use of undeclared identifier 'THREAD_AFFINITY_POLICY' thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, ^ injector.c:1396:7: warning: implicit declaration of function 'sched_setaffinity' is invalid in C99 [-Wimplicit-function-declaration] if (sched_setaffinity(0, sizeof(mask), &mask)) {
EDIT: The Affinity API documentation is here: https://developer.apple.com/library/content/releasenotes/Performance/RN-AffinityAPI/index.html
It says Leopard, but it is still supported and used in the current macOS (Including 10.13)
from sandsifter.
from sandsifter.
Alright it seems like adding #include <mach/thread_policy.h>
does indeed do as you said @floatingatoll
There are now just 8 total errors that need hammered out.
The new Errors go as follows:
injector.c:1385:17: error: assigning to 'pthread_cond_t' (aka 'struct _opaque_pthread_cond_t') from incompatible type 'mach_port_t' (aka 'unsigned int') mach_thread = pthread_mach_thread_np(thread);
and
injector.c:1387:42: error: invalid operands to binary expression ('int (*)()' and 'thread_affinity_policy_data_t' (aka 'struct thread_affinity_policy')) (thread_policy_set)&policy, 1); ~~~~~~~~~~~~~~~~~~~^~~~~~~
from sandsifter.
Found a fix, delete this code block:
`
int pthread_setaffinity_np(pthread_t thread, size_t cpu_size,
cpu_set_t *cpu_set)
{
pthread_cond_t mach_thread;
int core = 0;
for (core = 0; core < 8 * cpu_size; core++) {
if (CPU_ISSET(core, cpu_set)) break;
}
printf("binding to core %d\n", core);
thread_affinity_policy_data_t policy = { core };
mach_thread = pthread_mach_thread_np(thread);
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY,
(thread_policy_set)&policy, 1);
return 0;
}`
6 Errors left! So all we need to do now is figuring out how to get the Program to use Pthread from the kernel!
from sandsifter.
Also stuck at injector.c:818:24: error: invalid operand for inline asm constraint 'i' __asm__ __volatile__ ("\ ^
:/
from sandsifter.
from sandsifter.
@jaketesler Thanks for writing the missing C code we needed! I really should brush up on my coding hehe
from sandsifter.
Related Issues (20)
- Run on 80386 Debian within emulator? HOT 13
- Feature request: Add support for GPUs HOT 1
- have some sort of versioning information
- make fails with injector.c:817:2: error: impossible constraint in ‘asm’ HOT 1
- summarize.py crashes HOT 2
- Resizing terminal window crashes summarize.py
- how to analysis the instructions from sandsifter
- compile error ubuntu 17.04 HOT 1
- I don't understand this.
- File "./sifter.py", line 817, in main arch = re.search(r".*(..)-bit.*", injector_bitness).group(1) HOT 5
- How to install this on Pentium II w/o FPU Debian without internet connection? HOT 12
- mmap_min_addr 0 instead of sudo
- Does not compile HOT 2
- File "./sifter.py", line 196 HOT 4
- injector.c:65:11: fatal error : capstone/capstone.h: No such file or directory HOT 1
- relocation R_X86_64_32S against symbol `dummy_stack' can not be used when making a PIE object... HOT 4
- Disclosure of the "halt catch fire" bug HOT 1
- Injector overflowed sigaltstack
- Make issue on ubuntu. HOT 4
- Found a fork that builds and runs on modern machines HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sandsifter.