seccomp-tools 1.1.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +112 -30
  3. data/bin/seccomp-tools +1 -0
  4. data/ext/ptrace/extconf.rb +2 -0
  5. data/ext/ptrace/ptrace.c +107 -5
  6. data/lib/seccomp-tools.rb +5 -0
  7. data/lib/seccomp-tools/asm/asm.rb +5 -2
  8. data/lib/seccomp-tools/asm/compiler.rb +96 -18
  9. data/lib/seccomp-tools/asm/tokenizer.rb +25 -8
  10. data/lib/seccomp-tools/bpf.rb +7 -4
  11. data/lib/seccomp-tools/cli/asm.rb +16 -6
  12. data/lib/seccomp-tools/cli/base.rb +10 -4
  13. data/lib/seccomp-tools/cli/cli.rb +9 -6
  14. data/lib/seccomp-tools/cli/disasm.rb +6 -2
  15. data/lib/seccomp-tools/cli/dump.rb +37 -6
  16. data/lib/seccomp-tools/cli/emu.rb +41 -22
  17. data/lib/seccomp-tools/const.rb +47 -16
  18. data/lib/seccomp-tools/consts/sys_arg.rb +432 -0
  19. data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
  20. data/lib/seccomp-tools/consts/{amd64.rb → sys_nr/amd64.rb} +6 -1
  21. data/lib/seccomp-tools/consts/{i386.rb → sys_nr/i386.rb} +18 -15
  22. data/lib/seccomp-tools/disasm/context.rb +125 -34
  23. data/lib/seccomp-tools/disasm/disasm.rb +5 -2
  24. data/lib/seccomp-tools/dumper.rb +75 -8
  25. data/lib/seccomp-tools/emulator.rb +19 -8
  26. data/lib/seccomp-tools/instruction/alu.rb +7 -2
  27. data/lib/seccomp-tools/instruction/base.rb +5 -3
  28. data/lib/seccomp-tools/instruction/instruction.rb +2 -0
  29. data/lib/seccomp-tools/instruction/jmp.rb +28 -14
  30. data/lib/seccomp-tools/instruction/ld.rb +28 -12
  31. data/lib/seccomp-tools/instruction/ldx.rb +2 -0
  32. data/lib/seccomp-tools/instruction/misc.rb +2 -0
  33. data/lib/seccomp-tools/instruction/ret.rb +14 -2
  34. data/lib/seccomp-tools/instruction/st.rb +4 -2
  35. data/lib/seccomp-tools/instruction/stx.rb +2 -0
  36. data/lib/seccomp-tools/logger.rb +40 -0
  37. data/lib/seccomp-tools/syscall.rb +24 -13
  38. data/lib/seccomp-tools/templates/asm.amd64.asm +26 -0
  39. data/lib/seccomp-tools/templates/asm.c +17 -0
  40. data/lib/seccomp-tools/templates/asm.i386.asm +33 -0
  41. data/lib/seccomp-tools/util.rb +24 -3
  42. data/lib/seccomp-tools/version.rb +3 -1
  43. metadata +51 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 52d71ec73ddfa5dab7d22d982b27b2d4c3610080
4
- data.tar.gz: '08439390a2e4a08d8619eba08b7b66a2814372b1'
2
+ SHA256:
3
+ metadata.gz: fa755fd2e7ed97279b094dfa28bd668aef4ee638005f0b38405066502fc8a30d
4
+ data.tar.gz: 56b0d51796d97a89f67262c36716833d078ce19ea6b58fbb83c2f8bee88b8685
5
5
  SHA512:
6
- metadata.gz: c69c741edae030e7a775dcad768fa983c627cda1d849947c079d45148453a018cbba249abd18faced059b4c4cdc793e746d707e178b2e845804e7bb9a4c70437
7
- data.tar.gz: fc8cc5926cba54d561822b3a75b57c8721b1113ef16117f455c8a91f651dbad16ced7f6e09209d2adcd7a8183f4a1f8d327aa490652fe5f8ee7a3be187fe361a
6
+ metadata.gz: 027f57a717cb63fadeefd4a60213115a27ed51bb1eb3e6b58251690ed7c1d42335086ff4448b480296b77d395ba2e8718fa662e227394abfddaf80b19b769b74
7
+ data.tar.gz: f6aca254b4a43d6c60d5df7e6694b976de1e56fbb6d6585bd46fd17c0849820d76c81f25bbc872dc785576e05eeaaab5d0276a3f065b730988973c5073ace761
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- [![Build Status](https://travis-ci.org/david942j/seccomp-tools.svg?branch=master)](https://travis-ci.org/david942j/seccomp-tools)
1
+ [![Build Status](https://github.com/david942j/seccomp-tools/workflows/build/badge.svg)](https://github.com/david942j/seccomp-tools/actions)
2
+ [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=david942j/seccomp-tools)](https://dependabot.com)
2
3
  [![Code Climate](https://codeclimate.com/github/david942j/seccomp-tools/badges/gpa.svg)](https://codeclimate.com/github/david942j/seccomp-tools)
3
4
  [![Issue Count](https://codeclimate.com/github/david942j/seccomp-tools/badges/issue_count.svg)](https://codeclimate.com/github/david942j/seccomp-tools)
4
5
  [![Test Coverage](https://codeclimate.com/github/david942j/seccomp-tools/badges/coverage.svg)](https://codeclimate.com/github/david942j/seccomp-tools/coverage)
@@ -6,20 +7,20 @@
6
7
  [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](http://choosealicense.com/licenses/mit/)
7
8
 
8
9
  # Seccomp Tools
9
- Provides powerful tools for seccomp analysis.
10
+ Provide powerful tools for seccomp analysis.
10
11
 
11
12
  This project is targeted to (but not limited to) analyze seccomp sandbox in CTF pwn challenges.
12
- Some features might be CTF-specific, but still useful for analysis of seccomp in real-case.
13
+ Some features might be CTF-specific, but still useful for analyzing seccomp in real-case.
13
14
 
14
15
  ## Features
15
- * Dump - Automatically dump seccomp-bpf from binary.
16
- * Disasm - Convert bpf to human readable format.
16
+ * Dump - Automatically dumps seccomp-bpf from execution file(s).
17
+ * Disasm - Converts bpf to human readable format.
17
18
  - Simple decompile.
18
- - Show syscall names.
19
+ - Display syscall names and arguments when possible.
20
+ - Colorful!
19
21
  * Asm - Write seccomp rules is so easy!
20
- * Emu - Emulate seccomp rules.
21
- * (TODO) Solve constraints for executing syscalls (e.g. `execve/open/read/write`).
22
- * Support multi-architectures.
22
+ * Emu - Emulates seccomp rules.
23
+ * Supports multi-architectures.
23
24
 
24
25
  ## Installation
25
26
 
@@ -28,6 +29,12 @@ Available on RubyGems.org!
28
29
  $ gem install seccomp-tools
29
30
  ```
30
31
 
32
+ If you failed when compiling, try:
33
+ ```
34
+ sudo apt install gcc ruby-dev
35
+ ```
36
+ and install seccomp-tools again.
37
+
31
38
  ## Command Line Interface
32
39
 
33
40
  ### seccomp-tools
@@ -38,19 +45,21 @@ $ seccomp-tools --help
38
45
  #
39
46
  # List of commands:
40
47
  #
41
- # dump Automatically dump seccomp bpf from execution file.
42
- # disasm Disassemble seccomp bpf.
43
48
  # asm Seccomp bpf assembler.
49
+ # disasm Disassemble seccomp bpf.
50
+ # dump Automatically dump seccomp bpf from execution file(s).
44
51
  # emu Emulate seccomp rules.
45
52
  #
46
- # See 'seccomp-tools --help <command>' to read about a specific subcommand.
53
+ # See 'seccomp-tools <command> --help' to read about a specific subcommand.
47
54
 
48
- $ seccomp-tools --help dump
49
- # dump - Automatically dump seccomp bpf from execution file.
55
+ $ seccomp-tools dump --help
56
+ # dump - Automatically dump seccomp bpf from execution file(s).
57
+ # NOTE : This function is only available on Linux.
50
58
  #
51
59
  # Usage: seccomp-tools dump [exec] [options]
52
60
  # -c, --sh-exec <command> Executes the given command (via sh).
53
61
  # Use this option if want to pass arguments or do pipe things to the execution file.
62
+ # e.g. use `-c "./bin > /dev/null"` to dump seccomp without being mixed with stdout.
54
63
  # -f, --format FORMAT Output format. FORMAT can only be one of <disasm|raw|inspect>.
55
64
  # Default: disasm
56
65
  # -l, --limit LIMIT Limit the number of calling "prctl(PR_SET_SECCOMP)".
@@ -60,12 +69,14 @@ $ seccomp-tools --help dump
60
69
  # If multiple seccomp syscalls have been invoked (see --limit),
61
70
  # results will be written to FILE, FILE_1, FILE_2.. etc.
62
71
  # For example, "--output out.bpf" and the output files are out.bpf, out_1.bpf, ...
72
+ # -p, --pid PID Dump installed seccomp filters of the existing process.
73
+ # You must have CAP_SYS_ADMIN (e.g. be root) in order to use this option.
63
74
 
64
75
  ```
65
76
 
66
77
  ### dump
67
78
 
68
- Dump the seccomp bpf from an execution file.
79
+ Dumps the seccomp bpf from an execution file.
69
80
  This work is done by the `ptrace` syscall.
70
81
 
71
82
  NOTICE: beware of the execution file will be executed.
@@ -113,7 +124,7 @@ $ seccomp-tools dump spec/binary/twctf-2016-diary -f raw | xxd
113
124
 
114
125
  ### disasm
115
126
 
116
- Disassemble the seccomp from raw bpf.
127
+ Disassembles the seccomp from raw bpf.
117
128
  ```bash
118
129
  $ xxd spec/data/twctf-2016-diary.bpf | head -n 3
119
130
  # 00000000: 2000 0000 0000 0000 1500 0001 0200 0000 ...............
@@ -146,26 +157,27 @@ $ seccomp-tools disasm spec/data/twctf-2016-diary.bpf
146
157
 
147
158
  ### asm
148
159
 
149
- Assemble the seccomp rules into raw bytes.
150
- Very useful when want to write custom seccomp rules.
160
+ Assembles the seccomp rules into raw bytes.
161
+ It's very useful when one wants to write custom seccomp rules.
151
162
 
152
- Supports labels for jumping and use syscall names directly. See example below.
163
+ Supports labels for jumping and uses syscall names directly. See examples below.
153
164
  ```bash
154
165
  $ seccomp-tools asm
155
166
  # asm - Seccomp bpf assembler.
156
167
  #
157
168
  # Usage: seccomp-tools asm IN_FILE [options]
158
169
  # -o, --output FILE Output result into FILE instead of stdout.
159
- # -f, --format FORMAT Output format. FORMAT can only be one of <inspect|raw|carray>.
170
+ # -f, --format FORMAT Output format. FORMAT can only be one of <inspect|raw|c_array|c_source|assembly>.
160
171
  # Default: inspect
161
172
  # -a, --arch ARCH Specify architecture.
162
- # Supported architectures are <amd64|i386>.
173
+ # Supported architectures are <aarch64|amd64|i386>.
174
+ # Default: amd64
163
175
 
164
176
  # Input file for asm
165
177
  $ cat spec/data/libseccomp.asm
166
178
  # # check if arch is X86_64
167
179
  # A = arch
168
- # A == 0xc000003e ? next : dead
180
+ # A == ARCH_X86_64 ? next : dead
169
181
  # A = sys_number
170
182
  # A >= 0x40000000 ? dead : next
171
183
  # A == write ? ok : next
@@ -181,8 +193,52 @@ $ cat spec/data/libseccomp.asm
181
193
  $ seccomp-tools asm spec/data/libseccomp.asm
182
194
  # " \x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\b>\x00\x00\xC0 \x00\x00\x00\x00\x00\x00\x005\x00\x06\x00\x00\x00\x00@\x15\x00\x04\x00\x01\x00\x00\x00\x15\x00\x03\x00\x03\x00\x00\x00\x15\x00\x02\x00 \x00\x00\x00\x15\x00\x01\x00<\x00\x00\x00\x06\x00\x00\x00\x05\x00\x05\x00\x06\x00\x00\x00\x00\x00\xFF\x7F\x06\x00\x00\x00\x00\x00\x00\x00"
183
195
 
184
- $ seccomp-tools asm spec/data/libseccomp.asm -f carray
185
- # unsigned char bpf[] = {32,0,0,0,4,0,0,0,21,0,0,8,62,0,0,192,32,0,0,0,0,0,0,0,53,0,6,0,0,0,0,64,21,0,4,0,1,0,0,0,21,0,3,0,3,0,0,0,21,0,2,0,32,0,0,0,21,0,1,0,60,0,0,0,6,0,0,0,5,0,5,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0};
196
+ $ seccomp-tools asm spec/data/libseccomp.asm -f c_source
197
+ # #include <linux/seccomp.h>
198
+ # #include <stdio.h>
199
+ # #include <stdlib.h>
200
+ # #include <sys/prctl.h>
201
+ #
202
+ # static void install_seccomp() {
203
+ # static unsigned char filter[] = {32,0,0,0,4,0,0,0,21,0,0,8,62,0,0,192,32,0,0,0,0,0,0,0,53,0,6,0,0,0,0,64,21,0,4,0,1,0,0,0,21,0,3,0,3,0,0,0,21,0,2,0,32,0,0,0,21,0,1,0,60,0,0,0,6,0,0,0,5,0,5,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0};
204
+ # struct prog {
205
+ # unsigned short len;
206
+ # unsigned char *filter;
207
+ # } rule = {
208
+ # .len = sizeof(filter) >> 3,
209
+ # .filter = filter
210
+ # };
211
+ # if(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { perror("prctl(PR_SET_NO_NEW_PRIVS)"); exit(2); }
212
+ # if(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &rule) < 0) { perror("prctl(PR_SET_SECCOMP)"); exit(2); }
213
+ # }
214
+
215
+ $ seccomp-tools asm spec/data/libseccomp.asm -f assembly
216
+ # install_seccomp:
217
+ # push rbp
218
+ # mov rbp, rsp
219
+ # push 38
220
+ # pop rdi
221
+ # push 0x1
222
+ # pop rsi
223
+ # xor eax, eax
224
+ # mov al, 0x9d
225
+ # syscall
226
+ # push 22
227
+ # pop rdi
228
+ # lea rdx, [rip + _filter]
229
+ # push rdx /* .filter */
230
+ # push _filter_end - _filter >> 3 /* .len */
231
+ # mov rdx, rsp
232
+ # push 0x2
233
+ # pop rsi
234
+ # xor eax, eax
235
+ # mov al, 0x9d
236
+ # syscall
237
+ # leave
238
+ # ret
239
+ # _filter:
240
+ # .ascii "\040\000\000\000\004\000\000\000\025\000\000\010\076\000\000\300\040\000\000\000\000\000\000\000\065\000\006\000\000\000\000\100\025\000\004\000\001\000\000\000\025\000\003\000\003\000\000\000\025\000\002\000\040\000\000\000\025\000\001\000\074\000\000\000\006\000\000\000\005\000\005\000\006\000\000\000\000\000\377\177\006\000\000\000\000\000\000\000"
241
+ # _filter_end:
186
242
 
187
243
 
188
244
  # let's asm then disasm!
@@ -197,7 +253,7 @@ $ seccomp-tools asm spec/data/libseccomp.asm -f raw | seccomp-tools disasm -
197
253
  # 0005: 0x15 0x03 0x00 0x00000003 if (A == close) goto 0009
198
254
  # 0006: 0x15 0x02 0x00 0x00000020 if (A == dup) goto 0009
199
255
  # 0007: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0009
200
- # 0008: 0x06 0x00 0x00 0x00050005 return ERRNO
256
+ # 0008: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
201
257
  # 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
202
258
  # 0010: 0x06 0x00 0x00 0x00000000 return KILL
203
259
 
@@ -205,17 +261,18 @@ $ seccomp-tools asm spec/data/libseccomp.asm -f raw | seccomp-tools disasm -
205
261
 
206
262
  ### Emu
207
263
 
208
- Emulate seccomp given `sys_nr`, `arg0`, `arg1`, etc.
264
+ Emulates seccomp given `sys_nr`, `arg0`, `arg1`, etc.
209
265
  ```bash
210
266
  $ seccomp-tools emu --help
211
267
  # emu - Emulate seccomp rules.
212
268
  #
213
269
  # Usage: seccomp-tools emu [options] BPF_FILE [sys_nr [arg0 [arg1 ... arg5]]]
214
270
  # -a, --arch ARCH Specify architecture.
215
- # Supported architectures are <amd64|i386>.
271
+ # Supported architectures are <aarch64|amd64|i386>.
272
+ # Default: amd64
216
273
  # -q, --[no-]quiet Run quietly, only show emulation result.
217
274
 
218
- $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
275
+ $ seccomp-tools emu spec/data/libseccomp.bpf write 0x3
219
276
  # line CODE JT JF K
220
277
  # =================================
221
278
  # 0000: 0x20 0x00 0x00 0x00000004 A = arch
@@ -226,7 +283,7 @@ $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
226
283
  # 0005: 0x15 0x03 0x00 0x00000003 if (A == close) goto 0009
227
284
  # 0006: 0x15 0x02 0x00 0x00000020 if (A == dup) goto 0009
228
285
  # 0007: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0009
229
- # 0008: 0x06 0x00 0x00 0x00050005 return ERRNO
286
+ # 0008: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
230
287
  # 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
231
288
  # 0010: 0x06 0x00 0x00 0x00000000 return KILL
232
289
  #
@@ -244,7 +301,32 @@ $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
244
301
 
245
302
  ![emu](https://github.com/david942j/seccomp-tools/blob/master/examples/emu-amigo.png?raw=true)
246
303
 
304
+ ## Architecture Supported
305
+
306
+ - [x] x86_64
307
+ - [x] x32
308
+ - [x] x86
309
+ - [x] arm64 (Thanks to @saagarjha!)
310
+
311
+ ## Development
312
+
313
+ I recommend to use [rbenv](https://github.com/rbenv/rbenv) for your Ruby environment.
314
+
315
+ ### Setup
316
+
317
+ - Install bundler
318
+ - `$ gem install bundler`
319
+ - Clone the source
320
+ - `$ git clone https://github.com/david942j/seccomp-tools && cd seccomp-tools`
321
+ - Install dependencies
322
+ - `$ bundle install`
323
+
324
+ ### Run tests
325
+
326
+ `$ bundle exec rake`
327
+
247
328
  ## I Need You
329
+
248
330
  Any suggestion or feature request is welcome!
249
331
  Feel free to file an issue or send a pull request.
250
- And, if you like this work, I'll be happy to be [stared](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
332
+ And, if you like this work, I'll be happy to be [starred](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
data/bin/seccomp-tools CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'seccomp-tools/cli/cli'
4
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mkmf'
2
4
 
3
5
  extension_name = 'seccomp-tools/ptrace'
data/ext/ptrace/ptrace.c CHANGED
@@ -1,5 +1,16 @@
1
+ // ptrace is only available on Linux, therefore let this file be an empty
2
+ // object when installing on other platforms.
3
+ #if __linux__
4
+
5
+ #include <assert.h>
6
+ #include <errno.h>
7
+ #include <linux/elf.h>
8
+ #include <linux/filter.h>
9
+ #include <stdint.h>
1
10
  #include <sys/ptrace.h>
2
11
  #include <sys/signal.h>
12
+ #include <sys/uio.h>
13
+ #include <sys/wait.h>
3
14
 
4
15
  #include "ruby.h"
5
16
 
@@ -16,10 +27,53 @@ ptrace_peekdata(VALUE _mod, VALUE pid, VALUE addr, VALUE _data) {
16
27
  return LONG2NUM(val);
17
28
  }
18
29
 
30
+ // aarch64 doesn't support PTRACE_PEEKUSER, but it does support
31
+ // PTRACE_GETREGSET which is fairly similar. Since i386 and x86_64 support it
32
+ // too, just use that unconditionally to present the same API for the registers
33
+ // we care about.
19
34
  static VALUE
20
- ptrace_peekuser(VALUE _mod, VALUE pid, VALUE off, VALUE _data) {
21
- long val = ptrace(PTRACE_PEEKUSER, NUM2LONG(pid), NUM2LONG(off), NULL);
22
- return LONG2NUM(val);
35
+ ptrace_peekuser(VALUE _mod, VALUE pid, VALUE off, VALUE _data, VALUE bits) {
36
+ size_t offset = NUM2LONG(off);
37
+ // Unless your registers fill an entire page, an offset greater than this is
38
+ // probably wrong.
39
+ if (offset >= 4096) {
40
+ return LONG2NUM(-1);
41
+ }
42
+ size_t width = NUM2LONG(bits);
43
+ if (width != 32 && width != 64) {
44
+ return LONG2NUM(-1);
45
+ }
46
+ width /= 8;
47
+ union {
48
+ uint32_t val32;
49
+ uint64_t val64;
50
+ } val;
51
+ // Dynamically allocate a buffer to store registers-well, at least enough
52
+ // registers to reach the offset we want. Normally we'd want to use
53
+ // user_pt_regs or similar, but it's difficult to find it available in the
54
+ // the same header across different versions of Linux or libcs, or even with
55
+ // the same *name*, so this is the compromise.
56
+ size_t size = offset + width;
57
+ char *regs = malloc(size);
58
+ if (!regs) {
59
+ return LONG2NUM(-1);
60
+ }
61
+ struct iovec vec = { regs, size };
62
+ if (ptrace(PTRACE_GETREGSET, NUM2LONG(pid), NT_PRSTATUS, &vec) != -1 && vec.iov_len >= size) {
63
+ memcpy(&val, regs + offset, width);
64
+ } else {
65
+ free(regs);
66
+ return LONG2NUM(-1);
67
+ }
68
+ free(regs);
69
+ if (width == sizeof(val.val32)) {
70
+ return LONG2NUM(val.val32);
71
+ } else if (width == sizeof(val.val64)) {
72
+ return LONG2NUM(val.val64);
73
+ } else {
74
+ assert(!"Unreachable");
75
+ return LONG2NUM(-1);
76
+ }
23
77
  }
24
78
 
25
79
  static VALUE
@@ -50,9 +104,44 @@ ptrace_traceme_and_stop(VALUE mod) {
50
104
  return Qnil;
51
105
  }
52
106
 
107
+ static VALUE
108
+ ptrace_attach_and_wait(VALUE _mod, VALUE pid) {
109
+ long val = ptrace(PTRACE_ATTACH, NUM2LONG(pid), 0, 0);
110
+ if(val < 0)
111
+ rb_sys_fail("ptrace attach failed");
112
+ waitpid(NUM2LONG(pid), NULL, 0);
113
+ return Qnil;
114
+ }
115
+
116
+ static VALUE
117
+ ptrace_seccomp_get_filter(VALUE _mod, VALUE pid, VALUE index) {
118
+ long count = ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), NULL);
119
+ struct sock_filter *filter;
120
+ VALUE result;
121
+ if(count < 0)
122
+ rb_sys_fail("ptrace seccomp_get_filter failed");
123
+ filter = ALLOC_N(struct sock_filter, count);
124
+ if(ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), filter) != count) {
125
+ xfree(filter);
126
+ rb_sys_fail("ptrace seccomp_get_filter failed");
127
+ }
128
+ result = rb_str_new((const char *)filter, sizeof(struct sock_filter) * count);
129
+ xfree(filter);
130
+ return result;
131
+ }
132
+
133
+ static VALUE
134
+ ptrace_detach(VALUE _mod, VALUE pid) {
135
+ long val = ptrace(PTRACE_DETACH, NUM2LONG(pid), 0, 0);
136
+ if(val < 0)
137
+ rb_sys_fail(0);
138
+ return Qnil;
139
+ }
140
+
53
141
 
54
142
  void Init_ptrace(void) {
55
143
  VALUE mSeccompTools = rb_define_module("SeccompTools");
144
+ /* The module to wrap ptrace syscall */
56
145
  VALUE mPtrace = rb_define_module_under(mSeccompTools, "Ptrace");
57
146
 
58
147
  /* consts */
@@ -64,13 +153,26 @@ void Init_ptrace(void) {
64
153
  rb_define_const(mPtrace, "O_TRACESYSGOOD", UINT2NUM(PTRACE_O_TRACESYSGOOD));
65
154
  rb_define_const(mPtrace, "O_TRACEVFORK", UINT2NUM(PTRACE_O_TRACEVFORK));
66
155
 
67
- /* ptrace wrapper */
156
+ /* geteventmsg */
68
157
  rb_define_module_function(mPtrace, "geteventmsg", ptrace_geteventmsg, 1);
158
+ /* get data */
69
159
  rb_define_module_function(mPtrace, "peekdata", ptrace_peekdata, 3);
70
- rb_define_module_function(mPtrace, "peekuser", ptrace_peekuser, 3);
160
+ /* get registers */
161
+ rb_define_module_function(mPtrace, "peekuser", ptrace_peekuser, 4);
162
+ /* set ptrace options */
71
163
  rb_define_module_function(mPtrace, "setoptions", ptrace_setoptions, 3);
164
+ /* wait for syscall */
72
165
  rb_define_module_function(mPtrace, "syscall", ptrace_syscall, 3);
166
+ /* wait for its parent to attach */
73
167
  rb_define_module_function(mPtrace, "traceme", ptrace_traceme, 0);
168
+ /* stop itself before parent attaching */
74
169
  rb_define_module_function(mPtrace, "traceme_and_stop", ptrace_traceme_and_stop, 0);
170
+ /* attach to an existing process */
171
+ rb_define_module_function(mPtrace, "attach_and_wait", ptrace_attach_and_wait, 1);
172
+ /* retrieve seccomp filter */
173
+ rb_define_module_function(mPtrace, "seccomp_get_filter", ptrace_seccomp_get_filter, 2);
174
+ /* detach from an existing process */
175
+ rb_define_module_function(mPtrace, "detach", ptrace_detach, 1);
75
176
  }
76
177
 
178
+ #endif /* __linux__ */
data/lib/seccomp-tools.rb CHANGED
@@ -1,8 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # @author david942j
2
4
 
3
5
  # Main module.
4
6
  module SeccompTools
5
7
  end
6
8
 
9
+ require 'seccomp-tools/asm/asm'
10
+ require 'seccomp-tools/disasm/disasm'
7
11
  require 'seccomp-tools/dumper'
12
+ require 'seccomp-tools/emulator'
8
13
  require 'seccomp-tools/version'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'seccomp-tools/asm/compiler'
2
4
  require 'seccomp-tools/util'
3
5
 
@@ -8,10 +10,11 @@ module SeccompTools
8
10
 
9
11
  # Assembler of seccomp bpf.
10
12
  # @param [String] str
13
+ # @param [:amd64, :i386] arch
11
14
  # @return [String]
12
15
  # Raw bpf bytes.
13
16
  # @example
14
- # asm(<<EOS)
17
+ # SeccompTools::Asm.asm(<<-EOS)
15
18
  # # lines start with '#' are comments
16
19
  # A = sys_number # here's a comment, too
17
20
  # A >= 0x40000000 ? dead : next # 'next' is a keyword, denote the next instruction
@@ -25,7 +28,7 @@ module SeccompTools
25
28
  # EOS
26
29
  # #=> <raw binary bytes>
27
30
  def asm(str, arch: nil)
28
- arch = Util.system_arch if arch.nil? # TODO: show warning
31
+ arch = Util.system_arch if arch.nil?
29
32
  compiler = Compiler.new(arch)
30
33
  str.lines.each { |l| compiler.process(l) }
31
34
  compiler.compile!.map(&:asm).join