Skip to content

Instantly share code, notes, and snippets.

@vanhoavn
Created November 6, 2017 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vanhoavn/728e5ec804050572a984b73afd7736e6 to your computer and use it in GitHub Desktop.
Save vanhoavn/728e5ec804050572a984b73afd7736e6 to your computer and use it in GitHub Desktop.
<?php
$cmds = file('seccomp_dump.txt');
$labaleled = [];
foreach($cmds as $nbr => $line) {
list($offset, $op, $jt, $jf, $k, $code) = preg_split("@\s+@", trim($line, "\n\r\t "), 6);
$labaleled[$nbr] = sprintf("%s", $code);
}
$rules = [
[
'rule' =>
[
'A = $mem1',
'X = $mem2',
'A ^= X',
'$mem3 = A',
],
'replace' => '$mem3 = $mem1 ^ $mem2'
],
[
'rule' =>
[# a % b = a - a/b*b
'A = $mem1',
'if (A != 0) goto $line1',
'A = 65536',
'A *= $num2',
'X = A',
'A /= 0x10001',
'A *= 0x10001',
'A = -A',
'A += X',
'if (A != 65536) goto $line2',
'A = 0',
'$mem2 = A',
],
'replace' => '$mem2 = ((CHK0($mem1) * $num2) %0x10001) & 0xFFFF'
],
[
'rule' =>
[
'A = $mem1',
'X = $mem2',
'$mem1 = X',
'$mem2 = A',
],
'replace' => 'SWAP($mem1, $mem2)'
],
[
'rule' =>
[
'A = $mem1',
'X = $mem2',
'A += X',
'A &= 0xffff',
'$mem3 = A',
],
'replace' => '$mem3 = ($mem1 + $mem2) & 0xFFFF'
],
[
'rule' =>
[
'A = $mem1',
'A += $num1',
'A &= 0xffff',
'$mem2 = A',
],
'replace' => '$mem2 = ($mem1 + $num1) & 0xFFFF'
],
[
'rule' =>
[
'X = $num0',
'A = mem[3]',
'A ^= X',
'if (A == $num1) goto $line1',
'return KILL',
'A = mem[2]',
'A ^= X',
'if (A == $num2) goto $line2',
'return KILL',
'A = mem[1]',
'A ^= X',
'if (A == $num3) goto $line3',
'return KILL',
'A = mem[0]',
'A ^= X',
'if (A == $num4) goto $line4',
'return KILL',
],
'replace' => 'REQUIREMEM($num4, $num3, $num2, $num1, $num0)',
],
[
'rule' =>
[
'A = $arg1',
'X = A',
'A &= 0xffff',
'mem[3] = A',
'A = X',
'A >>= 16',
'mem[2] = A',
'A = $arg1 >> 32',
'X = A',
'A &= 0xffff',
'mem[1] = A',
'A = X',
'A >>= 16',
'mem[0] = A',
],
'replace' => 'LOADMEM($arg1)',
]
];
for($i=0;$i<count($labaleled);$i++){
foreach($rules as $rule) {
if(applyRule($labaleled, $i, $rule)) break;
}
}
file_put_contents('seccomp_rebuild.txt', implode("\n", $labaleled));
file_put_contents('seccomp_rebuild_min.txt', implode("\n", array_filter($labaleled)));
file_put_contents('seccomp_rebuild_min_rev.txt', implode("\n", array_reverse(array_filter($labaleled))));
$labaleled = array_values(array_filter($labaleled));
$rules = [
[
'rule' => [
'mem[0] = ((CHK0(mem[0]) * $num1) %0x10001) & 0xFFFF',
'mem[1] = (mem[1] + $num2) & 0xFFFF',
'mem[2] = (mem[2] + $num3) & 0xFFFF',
'mem[3] = ((CHK0(mem[3]) * $num4) %0x10001) & 0xFFFF',
'mem[4] = mem[0] ^ mem[2]',
'mem[5] = mem[1] ^ mem[3]',
'mem[4] = ((CHK0(mem[4]) * $num5) %0x10001) & 0xFFFF',
'mem[5] = (mem[4] + mem[5]) & 0xFFFF',
'mem[5] = ((CHK0(mem[5]) * $num6) %0x10001) & 0xFFFF',
'mem[4] = (mem[4] + mem[5]) & 0xFFFF',
'mem[0] = mem[0] ^ mem[5]',
'mem[1] = mem[1] ^ mem[4]',
'mem[2] = mem[2] ^ mem[5]',
'mem[3] = mem[3] ^ mem[4]',
],
'replace' => 'BLOCK($num1, $num2, $num3, $num4, $num5, $num6)',
],
[
'rule' => [
'mem[0] = ((CHK0(mem[0]) * $num1) %0x10001) & 0xFFFF',
'mem[1] = (mem[1] + $num2) & 0xFFFF',
'mem[2] = (mem[2] + $num3) & 0xFFFF',
'mem[3] = ((CHK0(mem[3]) * $num4) %0x10001) & 0xFFFF',
],
'replace' => 'INITIAL($num1, $num2, $num3, $num4)',
]
];
for($i=0;$i<count($labaleled);$i++){
foreach($rules as $rule) {
if(applyRule($labaleled, $i, $rule)) break;
}
}
file_put_contents('seccomp_block_rebuild.txt', (implode("\n", array_filter($labaleled))));
file_put_contents('seccomp_block_rebuild_rev.txt', (implode("\n", array_reverse(array_filter($labaleled)))));
function applyRule(&$labaleled, $fromIdx, $rule) {
$len = count($rule['rule']);
$vars = [];
for($i=0;$i<$len;$i++) {
if ($fromIdx + $i >= count($labaleled)) return false;
if(!ruleMatch($rule['rule'][$i], $labaleled[$fromIdx + $i], $vars)) {
return false;
}
}
for($i=1;$i<$len;$i++) $labaleled[$fromIdx+$i] = '';
$labaleled[$fromIdx] = buildResult($rule['replace'], $vars);
return true;
}
function buildResult($pattern, $vars){
return preg_replace_callback('@\$([0-9a-z]+)@ism', function($m) use ($vars) {
if (!isset($vars[$m[1]])) return $m[0];
return $vars[$m[1]];
}, $pattern);
}
function ruleMatch($rule, $subject, &$vars) {
$rule = buildResult($rule, $vars);
$rule = preg_quote($rule);
$rule = preg_replace('@\\\\\$arg(\d)@', '(?P<arg$1>args\\[\\d\\])', $rule);
$rule = preg_replace('@\\\\\$num(\d)@', '(?P<num$1>0x[0-9a-f]+|\d+)', $rule);
$rule = preg_replace('@\\\\\$mem(\d)@', '(?P<mem$1>mem\\[\\d\\])', $rule);
$rule = preg_replace('@\\\\\$line(\d)@', '(?P<line$1>\\d+)', $rule);
if(preg_match('@'.$rule.'@', $subject, $m)) {
foreach($m as $k => $v) {
if(!is_numeric($k)) $vars[$k] = $v;
}
return true;
}
return false;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment