Compare commits
9 Commits
objc-hooki
...
benchmark
Author | SHA1 | Date | |
---|---|---|---|
465aed7ba1 | |||
998d5844e7 | |||
78a8ca45d5 | |||
3e99eff22d | |||
8be97742c9 | |||
792316f4ea | |||
62fa58f039 | |||
62daeb1c52 | |||
37c2f93383 |
@ -483,10 +483,10 @@ func (mc *MachoContext) removeSymtabCommand() {
|
||||
fmt.Printf("// Erase at=0x%x size=0x%x\n", start, size)
|
||||
mc.file.WriteAt(make([]byte, size), start)
|
||||
|
||||
symtab_fix.symoff = 0
|
||||
symtab_fix.nsyms = 0
|
||||
symtab_fix.stroff = 0
|
||||
symtab_fix.strsize = 0
|
||||
// symtab_fix.symoff = 0
|
||||
// symtab_fix.nsyms = 0
|
||||
// symtab_fix.stroff = 0
|
||||
// symtab_fix.strsize = 0
|
||||
mc.file.Seek(ptr, io.SeekStart)
|
||||
mc.file.Write(symtab_fix.Serialize(mc))
|
||||
break
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"unsafe"
|
||||
"unsafe"
|
||||
|
||||
. "ios-wrapper/pkg/ios"
|
||||
)
|
||||
@ -15,10 +15,10 @@ import (
|
||||
import "C"
|
||||
|
||||
func (mc *MachoContext) CollectObjectiveCClasses() {
|
||||
var objc_const *bytes.Reader
|
||||
var objc_const_start uint64
|
||||
var objc_const_end uint64
|
||||
// var objc_methname []byte
|
||||
var objc_const *bytes.Reader
|
||||
var objc_const_start uint64
|
||||
var objc_const_end uint64
|
||||
// var objc_methname []byte
|
||||
|
||||
for _, cmd := range mc.commands {
|
||||
if cmd.Cmd() == LC_MAIN {
|
||||
@ -29,18 +29,18 @@ func (mc *MachoContext) CollectObjectiveCClasses() {
|
||||
}
|
||||
var segment = cmd.(*Segment64)
|
||||
|
||||
// we assume the binary comes in perfect ordering, that is as laid out below
|
||||
// we assume the binary comes in perfect ordering, that is as laid out below
|
||||
|
||||
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__TEXT")) == 0 {
|
||||
for _, section := range segment.Sections() {
|
||||
buffer := make([]byte, section.Size())
|
||||
mc.file.ReadAt(buffer, int64(section.Offset()))
|
||||
buffer := make([]byte, section.Size())
|
||||
mc.file.ReadAt(buffer, int64(section.Offset()))
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_stubs")) == 0 {
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_methlist")) == 0 {
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_methname")) == 0 {
|
||||
// objc_methname := buffer
|
||||
// objc_methname := buffer
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_classname")) == 0 {
|
||||
}
|
||||
@ -50,8 +50,8 @@ func (mc *MachoContext) CollectObjectiveCClasses() {
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA_CONST")) == 0 {
|
||||
for _, section := range segment.Sections() {
|
||||
buffer := make([]byte, section.Size())
|
||||
mc.file.ReadAt(buffer, int64(section.Offset()))
|
||||
buffer := make([]byte, section.Size())
|
||||
mc.file.ReadAt(buffer, int64(section.Offset()))
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_classlist")) == 0 {
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_nlclslist")) == 0 {
|
||||
@ -59,16 +59,16 @@ func (mc *MachoContext) CollectObjectiveCClasses() {
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_imageinfo")) == 0 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA")) == 0 {
|
||||
for _, section := range segment.Sections() {
|
||||
buffer := make([]byte, section.Size())
|
||||
mc.file.ReadAt(buffer, int64(section.Offset()))
|
||||
reader := bytes.NewReader(buffer)
|
||||
buffer := make([]byte, section.Size())
|
||||
mc.file.ReadAt(buffer, int64(section.Offset()))
|
||||
reader := bytes.NewReader(buffer)
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_const")) == 0 {
|
||||
objc_const = reader
|
||||
objc_const_start = uint64(section.Offset())
|
||||
objc_const_end = objc_const_start + section.Size()
|
||||
objc_const = reader
|
||||
objc_const_start = uint64(section.Offset())
|
||||
objc_const_end = objc_const_start + section.Size()
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_selrefs")) == 0 {
|
||||
}
|
||||
@ -77,90 +77,89 @@ func (mc *MachoContext) CollectObjectiveCClasses() {
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_superrefs")) == 0 {
|
||||
}
|
||||
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_data")) == 0 {
|
||||
// this section contains a series of class_t
|
||||
// struct _class_t {
|
||||
// struct _class_t *isa;
|
||||
// struct _class_t * const superclass;
|
||||
// void *cache;
|
||||
// IMP *vtable;
|
||||
// struct class_ro_t *ro;
|
||||
// };
|
||||
// this section contains a series of class_t
|
||||
// struct _class_t {
|
||||
// struct _class_t *isa;
|
||||
// struct _class_t * const superclass;
|
||||
// void *cache;
|
||||
// IMP *vtable;
|
||||
// struct class_ro_t *ro;
|
||||
// };
|
||||
|
||||
for i := uint64(0); i < (section.Size() / uint64(mc.pointersize * 5)); i++ {
|
||||
var isa uint64
|
||||
var superclass uint64
|
||||
var cache uint64
|
||||
var vtable uint64
|
||||
var ro uint64
|
||||
binary.Read(reader, mc.byteorder, &isa)
|
||||
binary.Read(reader, mc.byteorder, &superclass)
|
||||
binary.Read(reader, mc.byteorder, &cache)
|
||||
binary.Read(reader, mc.byteorder, &vtable)
|
||||
binary.Read(reader, mc.byteorder, &ro)
|
||||
for i := uint64(0); i < (section.Size() / uint64(mc.pointersize*5)); i++ {
|
||||
var isa uint64
|
||||
var superclass uint64
|
||||
var cache uint64
|
||||
var vtable uint64
|
||||
var ro uint64
|
||||
binary.Read(reader, mc.byteorder, &isa)
|
||||
binary.Read(reader, mc.byteorder, &superclass)
|
||||
binary.Read(reader, mc.byteorder, &cache)
|
||||
binary.Read(reader, mc.byteorder, &vtable)
|
||||
binary.Read(reader, mc.byteorder, &ro)
|
||||
|
||||
fmt.Printf("at=0x%x\n", section.Offset()+uint32(i)*mc.pointersize*5)
|
||||
fmt.Printf("isa=0x%x superclass=0x%x\n", isa, superclass)
|
||||
fmt.Printf("cache=0x%x vtable=0x%x\n", cache, vtable)
|
||||
fmt.Printf("ro=0x%x\n", ro)
|
||||
|
||||
fmt.Printf("at=0x%x\n", section.Offset() + uint32(i) * mc.pointersize * 5)
|
||||
fmt.Printf("isa=0x%x superclass=0x%x\n", isa, superclass)
|
||||
fmt.Printf("cache=0x%x vtable=0x%x\n", cache, vtable)
|
||||
fmt.Printf("ro=0x%x\n", ro)
|
||||
var bind int
|
||||
var ret1 uint64
|
||||
var ret2 uint64
|
||||
C.ParseFixValue(C.int(2), C.uint64_t(ro),
|
||||
(*C.int)(unsafe.Pointer(&bind)),
|
||||
(*C.uint64_t)(unsafe.Pointer(&ret1)),
|
||||
(*C.uint64_t)(unsafe.Pointer(&ret2)),
|
||||
)
|
||||
|
||||
var bind int
|
||||
var ret1 uint64
|
||||
var ret2 uint64
|
||||
C.ParseFixValue(C.int(2), C.uint64_t(ro),
|
||||
(*C.int)(unsafe.Pointer(&bind)),
|
||||
(*C.uint64_t)(unsafe.Pointer(&ret1)),
|
||||
(*C.uint64_t)(unsafe.Pointer(&ret2)),
|
||||
)
|
||||
// is rebase, because ro points to objc_const
|
||||
// and address is in range
|
||||
if bind != 1 && ret1 >= objc_const_start && ret1 < objc_const_end {
|
||||
offset := ret1 - objc_const_start
|
||||
objc_const.Seek(int64(offset), 0)
|
||||
|
||||
// is rebase, because ro points to objc_const
|
||||
// and address is in range
|
||||
if (bind != 1 && ret1 >= objc_const_start && ret1 < objc_const_end) {
|
||||
offset := ret1 - objc_const_start
|
||||
objc_const.Seek(int64(offset), 0)
|
||||
// struct _class_ro_t {
|
||||
// uint32_t const flags;
|
||||
// uint32_t const instanceStart;
|
||||
// uint32_t const instanceSize;
|
||||
// uint32_t const reserved; // only when building for 64bit targets
|
||||
// const uint8_t * const ivarLayout;
|
||||
// const char *const name;
|
||||
// const struct _method_list_t * const baseMethods;
|
||||
// const struct _protocol_list_t *const baseProtocols;
|
||||
// const struct _ivar_list_t *const ivars;
|
||||
// const uint8_t * const weakIvarLayout;
|
||||
// const struct _prop_list_t * const properties;
|
||||
// };
|
||||
|
||||
// struct _class_ro_t {
|
||||
// uint32_t const flags;
|
||||
// uint32_t const instanceStart;
|
||||
// uint32_t const instanceSize;
|
||||
// uint32_t const reserved; // only when building for 64bit targets
|
||||
// const uint8_t * const ivarLayout;
|
||||
// const char *const name;
|
||||
// const struct _method_list_t * const baseMethods;
|
||||
// const struct _protocol_list_t *const baseProtocols;
|
||||
// const struct _ivar_list_t *const ivars;
|
||||
// const uint8_t * const weakIvarLayout;
|
||||
// const struct _prop_list_t * const properties;
|
||||
// };
|
||||
var tmp uint32
|
||||
var ivarLayout uint64 // ptr
|
||||
var name uint64 // ptr
|
||||
var baseMethods uint64 // ptr
|
||||
var baseProtocols uint64 // ptr
|
||||
var ivars uint64 // ptr
|
||||
var weakIvarLayout uint64 // ptr
|
||||
var properties uint64 // ptr
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &ivarLayout)
|
||||
binary.Read(objc_const, mc.byteorder, &name)
|
||||
binary.Read(objc_const, mc.byteorder, &baseMethods)
|
||||
binary.Read(objc_const, mc.byteorder, &baseProtocols)
|
||||
binary.Read(objc_const, mc.byteorder, &ivars)
|
||||
binary.Read(objc_const, mc.byteorder, &weakIvarLayout)
|
||||
binary.Read(objc_const, mc.byteorder, &properties)
|
||||
|
||||
var tmp uint32
|
||||
var ivarLayout uint64 // ptr
|
||||
var name uint64 // ptr
|
||||
var baseMethods uint64 // ptr
|
||||
var baseProtocols uint64 // ptr
|
||||
var ivars uint64 // ptr
|
||||
var weakIvarLayout uint64 // ptr
|
||||
var properties uint64 // ptr
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &tmp)
|
||||
binary.Read(objc_const, mc.byteorder, &ivarLayout)
|
||||
binary.Read(objc_const, mc.byteorder, &name)
|
||||
binary.Read(objc_const, mc.byteorder, &baseMethods)
|
||||
binary.Read(objc_const, mc.byteorder, &baseProtocols)
|
||||
binary.Read(objc_const, mc.byteorder, &ivars)
|
||||
binary.Read(objc_const, mc.byteorder, &weakIvarLayout)
|
||||
binary.Read(objc_const, mc.byteorder, &properties)
|
||||
|
||||
fmt.Printf("method list: %x\n", baseMethods)
|
||||
}
|
||||
fmt.Printf("========\n")
|
||||
}
|
||||
fmt.Printf("method list: %x\n", baseMethods)
|
||||
}
|
||||
fmt.Printf("========\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -482,7 +481,7 @@ func (mc *MachoContext) ReworkForObjc() {
|
||||
}
|
||||
}
|
||||
|
||||
encode_movz((data_end - text_start) + (shellcode_size - len(shellcode_start))+3)
|
||||
encode_movz((data_end - text_start) + (shellcode_size - len(shellcode_start)) + 3)
|
||||
|
||||
shellcode_offset = text_start - shellcode_size
|
||||
shellcode_bytes := append(shellcode_start, offset...)
|
||||
@ -519,7 +518,7 @@ func (mc *MachoContext) ReworkForObjc() {
|
||||
offset += 4
|
||||
}
|
||||
|
||||
// make __TEXT writable lol
|
||||
mc.file.Seek(0, 0)
|
||||
mc.file.WriteAt([]byte{0x7}, 0xa0)
|
||||
// make __TEXT writable lol
|
||||
mc.file.Seek(0, 0)
|
||||
mc.file.WriteAt([]byte{0x7}, 0xa0)
|
||||
}
|
||||
|
2
research/custom_loader/.gitignore
vendored
2
research/custom_loader/.gitignore
vendored
@ -1 +1,3 @@
|
||||
out/
|
||||
coreutils-9.1/
|
||||
*.tar.xz
|
||||
|
@ -1533,7 +1533,7 @@ uint64_t find_replace_cls_refs(struct libcache cache) {
|
||||
for (int nclass = 0; nclass < size / sizeof(struct _class_t); nclass++, data_ptr++) {
|
||||
if (!data_ptr->ro)
|
||||
continue;
|
||||
if (data_ptr->ro->flags & 0x01) { continue; }
|
||||
if (data_ptr->ro->flags & 0x01/*if meta class*/) { continue; }
|
||||
if (custom_strcmp(data_ptr->ro->name, "Hooker") == 0){
|
||||
printf("Found Hooker @ %p\n", data_ptr);
|
||||
return (uint64_t)data_ptr;
|
||||
|
220
research/custom_loader/benchmark.py
Normal file
220
research/custom_loader/benchmark.py
Normal file
@ -0,0 +1,220 @@
|
||||
# import unittest
|
||||
import subprocess, resource
|
||||
import lief
|
||||
import os
|
||||
# import time
|
||||
import re
|
||||
|
||||
PATH = "./coreutils-9.1/src"
|
||||
|
||||
class Line:
|
||||
file = None
|
||||
@classmethod
|
||||
def init(cls):
|
||||
cls.file = open("out.csv", "w")
|
||||
cls.file.write("Name,File size(KiB),Number of symbols,Number of imports,Restoration time(s),Execution time(s),File size(KiB),Number of symbols,Number of imports,Restoration time(s),Execution time(s)\n")
|
||||
|
||||
def write(self):
|
||||
out = f"{self.name},{self.norm_size},{self.norm_symbols},{self.norm_imports},0,{self.norm_exe:.3f},{self.obf_size},{self.obf_symbols},{self.obf_imports},{self.restore:.3f},{self.obf_exe:.3f}\n"
|
||||
self.file.write(out)
|
||||
|
||||
def __init__(self, name: str) -> None:
|
||||
self.name = name
|
||||
self.norm_path = f"{PATH}/{name}"
|
||||
self.obf_path = f"{PATH}/{name}-dir/out/{name}-fixed"
|
||||
|
||||
def numOfSymbols(sym: list) -> int:
|
||||
count = 0
|
||||
for i in sym:
|
||||
if i.type != 0:
|
||||
count += 1
|
||||
return count
|
||||
|
||||
def numOfImports(imp: list) -> int:
|
||||
count = 0
|
||||
for i in imp:
|
||||
if i.name != "":
|
||||
count += 1
|
||||
return count
|
||||
|
||||
def setup(binpath: str, libpath: str = None):
|
||||
if os.path.isdir("/tmp/test"):
|
||||
os.system("rm -rf /tmp/test")
|
||||
os.mkdir("/tmp/test")
|
||||
# if libpath:
|
||||
# os.system(f"cp {binpath} {libpath} ./test_file.txt /tmp/test")
|
||||
# else:
|
||||
# os.system(f"cp {binpath} ./test_file.txt /tmp/test")
|
||||
os.system("cp ./test_file.txt /tmp/test")
|
||||
|
||||
|
||||
# class Benchmark(unittest.TestCase):
|
||||
def info(l: Line):
|
||||
l.norm_size = int(os.path.getsize(l.norm_path) / 1024)
|
||||
l.obf_size = int(os.path.getsize(l.obf_path) / 1024)
|
||||
|
||||
norm = lief.parse(l.norm_path)
|
||||
obf = lief.parse(l.obf_path)
|
||||
|
||||
l.norm_symbols = numOfSymbols(norm.symbols)
|
||||
l.obf_symbols = numOfSymbols(obf.symbols)
|
||||
l.norm_imports = numOfImports(norm.imported_functions)
|
||||
l.obf_imports = numOfImports(obf.imported_functions)
|
||||
|
||||
def run(l, cmd):
|
||||
print(f"[+] Running benchmark for {l.name} with command \"{cmd}\"")
|
||||
cmd = cmd.split(" ")
|
||||
setup(l.norm_path)
|
||||
start = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime
|
||||
p1 = subprocess.run([l.norm_path] + cmd, capture_output=True)
|
||||
end = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime
|
||||
l.norm_exe = end - start
|
||||
|
||||
setup(l.obf_path)
|
||||
start = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime
|
||||
p2 = subprocess.run([l.obf_path] + cmd, capture_output=True)
|
||||
end = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime
|
||||
if p2.returncode == -11:
|
||||
print(f"\033[91m[!] Error in {l.name} (segfault)\033[0m")
|
||||
Line.file.write(f"{l.name},segfault\n")
|
||||
return
|
||||
# print(p2.stdout)
|
||||
match = re.search(b"restoration library time: ([0-9.]+)", p2.stdout)
|
||||
l.restore = float(match.group(1))
|
||||
l.obf_exe = end - start
|
||||
if p2.returncode != p1.returncode:
|
||||
print(f"\033[91m[!] Error in {l.name} (diff exit code)\033[0m")
|
||||
Line.file.write(f"{l.name},exit code diff\n")
|
||||
return
|
||||
l.write()
|
||||
# if p1.stdout in p2.stdout:
|
||||
# l.write()
|
||||
# else:
|
||||
# print(f"\033[91m[!] Error in {l.name} (stdout diff)\033[0m")
|
||||
# print(p1.stdout)
|
||||
# print("-"*20)
|
||||
# print(p2.stdout)
|
||||
|
||||
# Line.file.write(f"{l.name},stdout diff\n")
|
||||
|
||||
|
||||
def test_basic(name, cmd):
|
||||
l = Line(name)
|
||||
info(l)
|
||||
run(l, cmd)
|
||||
|
||||
test_data = [
|
||||
("md5sum", "/tmp/test/test_file.txt"),
|
||||
("split", "/tmp/test/test_file.txt /tmp/test/out"),
|
||||
("cat", "/tmp/test/test_file.txt"),
|
||||
("mkfifo", "/tmp/test/a"),
|
||||
("shuf", "--random-source=/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("pathchk", "/tmp/test/test_file.txt"),
|
||||
("expand", "/tmp/test/test_file.txt"),
|
||||
("tty", ""),
|
||||
("basename", "/tmp/test/test_file.txt"),
|
||||
("nice", ""),
|
||||
("truncate", "-s 0 /tmp/test/test_file.txt"),
|
||||
("echo", "hello"),
|
||||
("du", "-h /tmp"),
|
||||
("ptx", "/tmp/test/test_file.txt"),
|
||||
("join", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("df", "--help"),
|
||||
("pwd", ""),
|
||||
("test", "-f /tmp/test_file.txt"),
|
||||
("csplit", "/tmp/test_file.txt 1"),
|
||||
("sort", "/tmp/test_file.txt"),
|
||||
("whoami", ""),
|
||||
("touch", "/tmp/test/a"),
|
||||
("unlink", "/tmp/test/test_file.txt"),
|
||||
("b2sum", "/tmp/test/test_file.txt"),
|
||||
("sleep", "1"),
|
||||
("fmt", "/tmp/test/test_file.txt"),
|
||||
("stty", ""),
|
||||
("logname", ""),
|
||||
("chgrp", "root /tmp/test/test_file.txt"),
|
||||
("printenv", ""),
|
||||
("seq", "1 10"),
|
||||
("uname", ""),
|
||||
("sha224sum", "/tmp/test/test_file.txt"),
|
||||
("od", "/tmp/test/test_file.txt"),
|
||||
("date", ""),
|
||||
("base64", "/tmp/test/test_file.txt"),
|
||||
("realpath", "/tmp/test/test_file.txt"),
|
||||
("readlink", "/tmp/test/test_file.txt"),
|
||||
("dircolors", ""),
|
||||
("timeout", "1s sleep 2"),
|
||||
("tac", "/tmp/test/test_file.txt"),
|
||||
("numfmt", "1000"),
|
||||
("wc", "/tmp/test/test_file.txt"),
|
||||
("basenc", "/tmp/test/test_file.txt"),
|
||||
("comm", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("nproc", ""),
|
||||
("expr", "1"),
|
||||
("cksum", "/tmp/test/test_file.txt"),
|
||||
("printf", "hello"),
|
||||
("groups", ""),
|
||||
("chcon", "-t s0 /tmp/test/test_file.txt"),
|
||||
("factor", "10"),
|
||||
("tail", "-n 1 /tmp/test/test_file.txt"),
|
||||
("env", ""),
|
||||
("pr", "/tmp/test/test_file.txt"),
|
||||
("head", "-n 1 /tmp/test/test_file.txt"),
|
||||
("kill", "$$"),
|
||||
("uniq", "/tmp/test/test_file.txt"),
|
||||
("stat", "-f /tmp/test/test_file.txt"),
|
||||
("link", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
# ("make-prime-list", "10"), # build fail
|
||||
("sum", "/tmp/test/test_file.txt"),
|
||||
("tsort", "/tmp/test/test_file.txt"),
|
||||
# ("extract-magic", "/tmp/test/test_file.txt"), build fail
|
||||
("mknod", "/tmp/test/test_file.txt"),
|
||||
("users", ""),
|
||||
("dd", "--help"),
|
||||
("who", ""),
|
||||
("sha1sum", "/tmp/test/test_file.txt"),
|
||||
("mktemp", ""),
|
||||
("cut", "-c 1 /tmp/test/test_file.txt"),
|
||||
("sha256sum", "/tmp/test/test_file.txt"),
|
||||
("dir", "/tmp/test/test_file.txt"),
|
||||
("mkdir", "/tmp/test/a"),
|
||||
("nl", "/tmp/test/test_file.txt"),
|
||||
("ginstall", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("shred", "-u /tmp/test/test_file.txt"),
|
||||
("fold", "-w 10 /tmp/test/test_file.txt"),
|
||||
("rmdir", "/tmp/test/a"),
|
||||
("sha384sum", "/tmp/test/test_file.txt"),
|
||||
("mv", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("dirname", "/tmp/test/test_file.txt"),
|
||||
("id", ""),
|
||||
("base32", "/tmp/test/test_file.txt"),
|
||||
("pinky", ""),
|
||||
("ln", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("hostid", ""),
|
||||
("chroot", "/tmp/test /tmp/test/test_file.txt"),
|
||||
("ls", "/tmp/test"),
|
||||
("true", ""),
|
||||
("cp", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("sync", ""),
|
||||
("yes", "--help"),
|
||||
("unexpand", "/tmp/test/test_file.txt"),
|
||||
("chown", "root /tmp/test/test_file.txt"),
|
||||
("getlimits", ""),
|
||||
("chmod", "777 /tmp/test/test_file.txt"),
|
||||
("uptime", ""),
|
||||
("rm", "/tmp/test/test_file.txt"),
|
||||
("vdir", "/tmp/test"),
|
||||
("false", ""),
|
||||
("sha512sum", "/tmp/test/test_file.txt"),
|
||||
("tr", "a b /tmp/test/test_file.txt"),
|
||||
("paste", "/tmp/test/test_file.txt /tmp/test/test_file.txt"),
|
||||
("nohup", "sleep 1")
|
||||
]
|
||||
|
||||
# core="tee md5sum split cat shuf mkfifo pathchk runcon expand tty basename nice truncate echo du ptx join df pwd test csplit sort whoami touch dcgen unlink b2sum sleep fmt stty logname chgrp printenv seq uname sha224sum od date base64 realpath readlink dircolors timeout tac numfmt wc basenc comm nproc expr stdbuf cksum printf groups chcon factor tail env pr head kill uniq stat link make-prime-list sum tsort extract-magic mknod users dd who sha1sum mktemp cut sha256sum dir mkdir nl ginstall shred fold rmdir sha384sum mv dirname id base32 pinky ln hostid chroot ls true cp sync yes unexpand chown getlimits chmod uptime rm vdir false sha512sum tr paste nohup"
|
||||
|
||||
if __name__ == "__main__":
|
||||
Line.init()
|
||||
for name, cmd in test_data:
|
||||
test_basic(name, cmd)
|
||||
# unittest.main()
|
11
research/custom_loader/install.sh
Normal file
11
research/custom_loader/install.sh
Normal file
@ -0,0 +1,11 @@
|
||||
curl -LO https://ftp.gnu.org/gnu/coreutils/coreutils-9.1.tar.xz
|
||||
|
||||
tar -xvf coreutils-9.1.tar.xz
|
||||
|
||||
cd coreutils-9.1
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
rm coreutils-9.1.tar.xz
|
||||
|
27
research/custom_loader/obfuscate.sh
Executable file
27
research/custom_loader/obfuscate.sh
Executable file
@ -0,0 +1,27 @@
|
||||
rm -r coreutils-9.1/src/*-dir
|
||||
|
||||
core="tee md5sum split cat shuf mkfifo pathchk runcon expand tty basename nice truncate echo du ptx join df pwd test csplit sort whoami touch dcgen unlink b2sum sleep fmt stty logname chgrp printenv seq uname sha224sum od date base64 realpath readlink dircolors timeout tac numfmt wc basenc comm nproc expr stdbuf cksum printf groups chcon factor tail env pr head kill uniq stat link make-prime-list sum tsort extract-magic mknod users dd who sha1sum mktemp cut sha256sum dir mkdir nl ginstall shred fold rmdir sha384sum mv dirname id base32 pinky ln hostid chroot ls true cp sync yes unexpand chown getlimits chmod uptime rm vdir false sha512sum tr paste nohup"
|
||||
for i in $core; do
|
||||
echo "[+] $i"
|
||||
WD=coreutils-9.1/src/${i}-dir
|
||||
OUT=$WD/out
|
||||
mkdir -p $WD
|
||||
mkdir -p $OUT
|
||||
|
||||
cp b.cc $WD
|
||||
|
||||
{
|
||||
clang++ -mmacosx-version-min=14 -o $OUT/libb.dylib -shared dummy.cc
|
||||
|
||||
../../macho-go/bin/ios-wrapper pepe -o $OUT/${i}-fixed -b $OUT/b.bcell --dylibs=./$OUT/libb.dylib --remove-imports --remove-exports --remove-symbol-table --remove-others coreutils-9.1/src/${i}
|
||||
../../macho-go/bin/ios-wrapper bcell2header -b $OUT/b.bcell -o $OUT/b.h
|
||||
|
||||
clang++ -mmacosx-version-min=14 -o $OUT/libb.dylib -shared -Wl,-reexport_library out/libc.dylib $WD/b.cc
|
||||
|
||||
codesign --force --deep -s - $OUT/${i}-fixed
|
||||
codesign --force --deep -s - $OUT/libb.dylib
|
||||
chmod +x $OUT/${i}-fixed
|
||||
} > /dev/null 2>&1
|
||||
done
|
||||
|
||||
|
104
research/custom_loader/out_x86_64.csv
Normal file
104
research/custom_loader/out_x86_64.csv
Normal file
@ -0,0 +1,104 @@
|
||||
Name,File size(KiB),Number of symbols,Number of imports,Restoration time(s),Execution time(s),File size(KiB),Number of symbols,Number of imports,Restoration time(s),Execution time(s)
|
||||
md5sum,segfault
|
||||
split,150,1321,101,0,0.003,169,0,4,0.002,0.005
|
||||
cat,124,916,84,0,0.003,143,0,4,0.002,0.005
|
||||
mkfifo,121,819,78,0,0.003,140,0,4,0.002,0.004
|
||||
shuf,149,1255,91,0,0.004,168,0,4,0.002,0.005
|
||||
pathchk,121,791,79,0,0.003,139,0,4,0.001,0.004
|
||||
expand,123,904,82,0,0.003,142,0,4,0.002,0.005
|
||||
tty,120,773,77,0,0.003,139,0,4,0.001,0.004
|
||||
basename,121,805,74,0,0.003,140,0,4,0.001,0.004
|
||||
nice,121,802,79,0,0.003,139,0,4,0.002,0.004
|
||||
truncate,123,868,81,0,0.003,141,0,4,0.002,0.005
|
||||
echo,118,710,67,0,0.003,137,0,4,0.001,0.004
|
||||
du,321,2323,130,0,0.003,341,0,4,0.003,0.005
|
||||
ptx,257,1763,111,0,0.031,277,0,4,0.002,0.038
|
||||
join,146,1164,90,0,0.013,165,0,4,0.002,0.018
|
||||
df,197,1797,102,0,0.003,217,0,4,0.002,0.005
|
||||
pwd,122,861,86,0,0.003,141,0,4,0.002,0.004
|
||||
test,121,826,71,0,0.003,140,0,4,0.002,0.004
|
||||
csplit,235,1559,106,0,0.003,255,0,4,0.002,0.005
|
||||
sort,239,2154,146,0,0.004,258,0,5,0.003,0.007
|
||||
whoami,120,790,77,0,0.003,139,0,4,0.002,0.004
|
||||
touch,187,1406,108,0,0.003,206,0,4,0.003,0.006
|
||||
unlink,121,817,77,0,0.003,140,0,4,0.002,0.004
|
||||
b2sum,141,956,88,0,0.004,160,0,5,0.002,0.005
|
||||
sleep,123,848,79,0,0.003,141,0,4,0.002,0.005
|
||||
fmt,139,908,81,0,0.007,158,0,4,0.003,0.010
|
||||
stty,158,1023,89,0,0.003,177,0,4,0.002,0.005
|
||||
logname,120,789,76,0,0.003,139,0,4,0.002,0.004
|
||||
chgrp,171,1433,105,0,0.003,190,0,4,0.003,0.006
|
||||
printenv,120,769,75,0,0.003,138,0,4,0.001,0.004
|
||||
seq,139,887,83,0,0.003,158,0,4,0.002,0.004
|
||||
uname,120,786,76,0,0.003,139,0,4,0.001,0.004
|
||||
sha224sum,segfault
|
||||
od,161,1156,90,0,0.022,181,0,4,0.002,0.023
|
||||
date,195,1178,95,0,0.003,215,0,4,0.002,0.005
|
||||
base64,122,856,81,0,0.003,141,0,4,0.002,0.005
|
||||
realpath,145,1078,81,0,0.003,164,0,4,0.002,0.005
|
||||
readlink,144,1042,81,0,0.003,163,0,4,0.002,0.005
|
||||
dircolors,159,1012,96,0,0.003,178,0,4,0.002,0.004
|
||||
timeout,124,888,95,0,0.006,142,0,4,0.002,0.007
|
||||
tac,216,1387,97,0,0.003,235,0,4,0.002,0.005
|
||||
numfmt,160,1079,92,0,0.003,179,0,4,0.002,0.005
|
||||
wc,146,1104,95,0,0.004,165,0,4,0.002,0.006
|
||||
basenc,145,1163,81,0,0.003,164,0,4,0.003,0.005
|
||||
comm,126,948,84,0,0.004,144,0,4,0.002,0.006
|
||||
nproc,121,817,79,0,0.003,140,0,4,0.002,0.004
|
||||
expr,232,1436,102,0,0.003,252,0,4,0.002,0.004
|
||||
cksum,187,1436,115,0,0.004,206,0,5,0.002,0.006
|
||||
printf,122,853,74,0,0.003,141,0,4,0.001,0.004
|
||||
groups,122,843,82,0,0.003,141,0,4,0.002,0.005
|
||||
chcon,169,1380,96,0,0.003,188,0,4,0.002,0.005
|
||||
factor,183,1284,115,0,0.003,202,0,4,0.003,0.006
|
||||
tail,165,1192,95,0,0.003,184,0,4,0.003,0.006
|
||||
env,142,1007,92,0,0.003,161,0,4,0.002,0.004
|
||||
pr,185,1370,101,0,0.005,204,0,4,0.002,0.007
|
||||
head,142,994,81,0,0.003,161,0,4,0.002,0.004
|
||||
kill,121,802,81,0,0.003,140,0,4,0.002,0.004
|
||||
uniq,142,987,86,0,0.003,161,0,4,0.002,0.006
|
||||
stat,209,1561,108,0,0.003,228,0,4,0.002,0.005
|
||||
link,121,818,78,0,0.003,140,0,4,0.002,0.005
|
||||
sum,140,923,86,0,0.003,159,0,4,0.002,0.005
|
||||
tsort,123,891,83,0,0.008,142,0,4,0.003,0.015
|
||||
mknod,123,875,81,0,0.003,142,0,4,0.002,0.005
|
||||
users,121,818,81,0,0.003,140,0,4,0.002,0.004
|
||||
dd,165,1284,101,0,0.003,184,0,5,0.002,0.005
|
||||
who,142,972,97,0,0.003,161,0,4,0.002,0.004
|
||||
sha1sum,segfault
|
||||
mktemp,126,960,86,0,0.003,145,0,4,0.002,0.004
|
||||
cut,140,903,88,0,0.003,159,0,4,0.002,0.005
|
||||
sha256sum,segfault
|
||||
dir,281,2551,148,0,0.003,301,0,5,0.003,0.005
|
||||
mkdir,144,1019,92,0,0.003,163,0,4,0.002,0.005
|
||||
nl,214,1377,92,0,0.004,233,0,4,0.002,0.006
|
||||
ginstall,239,2490,161,0,0.003,259,0,4,0.004,0.006
|
||||
shred,151,1215,109,0,0.003,170,0,4,0.002,0.005
|
||||
fold,122,843,80,0,0.004,141,0,4,0.002,0.005
|
||||
rmdir,123,863,83,0,0.003,142,0,4,0.002,0.005
|
||||
sha384sum,segfault
|
||||
mv,238,2461,149,0,0.003,258,0,4,0.004,0.007
|
||||
dirname,121,798,74,0,0.003,139,0,4,0.001,0.004
|
||||
id,141,940,88,0,0.003,160,0,4,0.002,0.005
|
||||
base32,122,861,81,0,0.003,141,0,4,0.002,0.005
|
||||
pinky,125,929,98,0,0.003,144,0,4,0.002,0.005
|
||||
ln,179,1589,111,0,0.003,198,0,4,0.003,0.006
|
||||
hostid,120,783,75,0,0.003,139,0,4,0.001,0.004
|
||||
chroot,148,1170,99,0,0.003,167,0,4,0.003,0.006
|
||||
ls,281,2551,148,0,0.003,301,0,5,0.003,0.006
|
||||
true,118,708,65,0,0.003,137,0,4,0.001,0.004
|
||||
cp,233,2273,148,0,0.003,253,0,4,0.003,0.006
|
||||
sync,121,809,80,0,0.003,140,0,4,0.002,0.004
|
||||
yes,121,801,75,0,0.003,140,0,4,0.003,0.008
|
||||
unexpand,123,907,82,0,0.003,142,0,4,0.003,0.009
|
||||
chown,172,1449,107,0,0.003,191,0,4,0.003,0.006
|
||||
getlimits,137,808,78,0,0.004,156,0,4,0.003,0.008
|
||||
chmod,165,1245,92,0,0.003,184,0,4,0.002,0.004
|
||||
uptime,140,924,93,0,0.003,159,0,5,0.003,0.009
|
||||
rm,171,1417,98,0,0.003,190,0,5,0.003,0.008
|
||||
vdir,281,2551,148,0,0.003,301,0,5,0.005,0.011
|
||||
false,118,708,65,0,0.003,137,0,4,0.003,0.008
|
||||
sha512sum,segfault
|
||||
tr,142,1049,83,0,0.003,161,0,4,0.003,0.009
|
||||
paste,122,880,77,0,0.004,141,0,4,0.003,0.009
|
||||
nohup,123,856,82,0,0.005,142,0,4,0.003,0.012
|
|
3384
research/custom_loader/test_file.txt
Normal file
3384
research/custom_loader/test_file.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user