Kaydet (Commit) 9b8281ec authored tarafından Batuhan Osman TASKAYA's avatar Batuhan Osman TASKAYA

lpyhook

üst d4f0b76e
from __future__ import annotations
import platform
from contextlib import contextmanager
from collections import deque
from dataclasses import dataclass
from typing import Optional, List
import textwrap
@dataclass
class Sign:
typ: str
name: str
args: Optional[Sign] = None
def __str__(self):
return f"{self.typ} {self.name}"
@dataclass
class Pragma:
typ: str
args: Optional[List[str]] = None
content: Optional[str] = None
class Code(deque):
def __str__(self):
return "\n".join(self)
def write(self, *args, **kwargs):
return self.append(*args, **kwargs)
def head(self, *args, **kwargs):
return self.appendleft(*args, **kwargs)
def nl(self, fr):
if fr == "h":
self.head("")
else:
self.write("")
@contextmanager
def gcode(code_type="source", libs=None, alias=None):
code = Code()
try:
yield code
finally:
if code_type == "source":
libs = libs or []
code.nl("h")
for lib in libs:
if not lib.startswith("_"):
code.head(f"#include <{lib}.h>")
else:
code.head(f'#include "{lib[1:]}.h"')
code.nl("h")
elif code_type == "lib":
alias = alias.upper()
code.nl("h")
code.head(f"#define {alias}_H")
code.head(f"#ifndef {alias}_H")
code.nl("t")
code.write("#endif")
code.nl("t")
return code
class CGen:
CGEN_SUPPORTES = {"Linux", "Darwin"}
def __init__(self, alias):
if platform.system() not in self.CGEN_SUPPORTES:
raise OSError(f"LHook doesn't support your platform: {platform.system()}")
self.alias = alias
self.source = None
self.header = None
def generate(self):
with open(f"{self.alias.lower()}.c", "w") as source:
source.write(str(self.source))
with open(f"{self.alias.lower()}.h", "w") as header:
header.write(str(self.header))
def gen_header(self, *signs):
manager = gcode(code_type="lib", alias=self.alias)
with manager as code:
for sign in signs:
code.write(f"{sign}({', '.join(map(str, sign.args))});")
self.header = code
def gen_source(self, source, libs=None, pragmas=None):
manager = gcode(code_type="source", libs=libs, alias=self.alias)
with manager as code:
pragmas = pragmas or []
for pragma in pragmas:
code.write(f"#pragma {pragma.typ}({', '.join(pragma.args)})")
if pragma.content:
code.write("\n".join(pragma.content))
code.write(source)
self.source = code
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include "lpyhook.h"
#pragma pack(push, 1)
static struct {
char push_rax;
char mov_rax[2];
char addr[8];
char jmp_rax[2];
}
jumper = {
.push_rax = 0x50,
.mov_rax = {0x48, 0xb8},
.jmp_rax = {0xff, 0xe0}
};
#pragma pack(pop)
static int up(void* addr) {
return mprotect((char *)((size_t)addr & ~(sysconf(_SC_PAGE_SIZE) -1)), sysconf(_SC_PAGE_SIZE), PROT_WRITE | PROT_READ | PROT_EXEC);
}
int lpyhook(void* t, void* r) {
int count;
if(up(r) || up(t)) {
return 1;
}
for(count = 0; count < 255 && ((unsigned char*)r)[count] != 0x90; ++count);
if(count == 255) {
return 1;
}
memmove(r+1, r, count);
*((unsigned char *)r) = 0x58;
memcpy(jumper.addr, &r, sizeof (void *));
memcpy(t, &jumper, sizeof jumper);
return 0;
}
#ifndef LPYHOOK_H
#define LPYHOOK_H
int lpyhook(void* t, void* r);
#endif
if __name__ == "__main__":
from libcgen import *
lpyhook = CGen("LPyHook")
hook_sign = Sign("int", "lpyhook", [Sign("void*", "t"), Sign("void*", "r")])
lpyhook.gen_header(hook_sign)
packpush_source = (
"static struct {",
f" {Sign('char', 'push_rax')};",
f" {Sign('char', 'mov_rax[2]')};",
f" {Sign('char', 'addr[8]')};",
f" {Sign('char', 'jmp_rax[2]')};",
"}",
"",
"jumper = {",
" .push_rax = 0x50,",
" .mov_rax = {0x48, 0xb8},",
" .jmp_rax = {0xff, 0xe0}",
"};",
)
source_pragmas = [
Pragma("pack", ["push", "1"], packpush_source),
Pragma("pack", ["pop"]),
]
code = textwrap.dedent(
"""
%s(%s) {
return mprotect((char *)((size_t)addr & ~(sysconf(_SC_PAGE_SIZE) -1)), sysconf(_SC_PAGE_SIZE), %s);
}
%s(%s) {
%s;
if(up(r) || up(t)) {
return 1;
}
for(count = 0; count < 255 && ((unsigned char*)r)[count] != 0x90; ++count);
if(count == 255) {
return 1;
}
memmove(r+1, r, count);
*((unsigned char *)r) = 0x58;
memcpy(jumper.addr, &r, sizeof (void *));
memcpy(t, &jumper, sizeof jumper);
return 0;
}
"""
% (
Sign("static int", "up"),
Sign("void*", "addr"),
" | ".join([f"PROT_{op.upper()}" for op in {"read", "write", "exec"}]),
Sign("int", "lpyhook"),
", ".join(map(str, [Sign("void*", "t"), Sign("void*", "r")])),
Sign("int", "count"),
)
)
lpyhook.gen_source(libs=[ "_lpyhook", "string", "unistd", "sys/mman"], pragmas=source_pragmas, source=code)
lpyhook.generate()
import distutils
import os
from setuptools import setup
from setuptools import setup, Extension
from setuptools.command.install import install
from setuptools import setup, find_packages
......@@ -25,7 +25,6 @@ class Installer(install):
if install_suffix == self.extra_path[1]:
self.install_lib = self.install_libbase
setup(
name="cev",
version="0.1",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment