├── .gitignore ├── Makefile ├── README.md └── src ├── main.c ├── main ├── Makefile ├── main.c └── main.h ├── mem_load.c └── mem_load.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### C template 3 | # Prerequisites 4 | *.d 5 | 6 | # Object files 7 | *.o 8 | *.ko 9 | *.obj 10 | *.elf 11 | 12 | # Linker output 13 | *.ilk 14 | *.map 15 | *.exp 16 | 17 | # Precompiled Headers 18 | *.gch 19 | *.pch 20 | 21 | # Libraries 22 | *.lib 23 | *.a 24 | *.la 25 | *.lo 26 | 27 | # Shared objects (inc. Windows DLLs) 28 | *.dll 29 | *.so 30 | *.so.* 31 | *.dylib 32 | 33 | # Executables 34 | *.exe 35 | *.out 36 | *.app 37 | *.i*86 38 | *.x86_64 39 | *.hex 40 | 41 | # Debug files 42 | *.dSYM/ 43 | *.su 44 | *.idb 45 | *.pdb 46 | 47 | # Kernel Module Compile Results 48 | *.mod* 49 | *.cmd 50 | .tmp_versions/ 51 | modules.order 52 | Module.symvers 53 | Mkfile.old 54 | dkms.conf 55 | 56 | ### macOS template 57 | # General 58 | .DS_Store 59 | .AppleDouble 60 | .LSOverride 61 | 62 | # Icon must end with two \r 63 | Icon 64 | 65 | # Thumbnails 66 | ._* 67 | 68 | # Files that might appear in the root of a volume 69 | .DocumentRevisions-V100 70 | .fseventsd 71 | .Spotlight-V100 72 | .TemporaryItems 73 | .Trashes 74 | .VolumeIcon.icns 75 | .com.apple.timemachine.donotpresent 76 | 77 | # Directories potentially created on remote AFP share 78 | .AppleDB 79 | .AppleDesktop 80 | Network Trash Folder 81 | Temporary Items 82 | .apdisk 83 | 84 | ### JetBrains template 85 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 86 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 87 | .idea 88 | # User-specific stuff 89 | .idea/**/workspace.xml 90 | .idea/**/tasks.xml 91 | .idea/**/usage.statistics.xml 92 | .idea/**/dictionaries 93 | .idea/**/shelf 94 | 95 | # Generated files 96 | .idea/**/contentModel.xml 97 | 98 | # Sensitive or high-churn files 99 | .idea/**/dataSources/ 100 | .idea/**/dataSources.ids 101 | .idea/**/dataSources.local.xml 102 | .idea/**/sqlDataSources.xml 103 | .idea/**/dynamic.xml 104 | .idea/**/uiDesigner.xml 105 | .idea/**/dbnavigator.xml 106 | 107 | # Gradle 108 | .idea/**/gradle.xml 109 | .idea/**/libraries 110 | 111 | # Gradle and Maven with auto-import 112 | # When using Gradle or Maven with auto-import, you should exclude module files, 113 | # since they will be recreated, and may cause churn. Uncomment if using 114 | # auto-import. 115 | # .idea/artifacts 116 | # .idea/compiler.xml 117 | # .idea/jarRepositories.xml 118 | # .idea/modules.xml 119 | # .idea/*.iml 120 | # .idea/modules 121 | # *.iml 122 | # *.ipr 123 | 124 | # CMake 125 | cmake-build-*/ 126 | 127 | # Mongo Explorer plugin 128 | .idea/**/mongoSettings.xml 129 | 130 | # File-based project format 131 | *.iws 132 | 133 | # IntelliJ 134 | out/ 135 | 136 | # mpeltonen/sbt-idea plugin 137 | .idea_modules/ 138 | 139 | # JIRA plugin 140 | atlassian-ide-plugin.xml 141 | 142 | # Cursive Clojure plugin 143 | .idea/replstate.xml 144 | 145 | # Crashlytics plugin (for Android Studio and IntelliJ) 146 | com_crashlytics_export_strings.xml 147 | crashlytics.properties 148 | crashlytics-build.properties 149 | fabric.properties 150 | 151 | # Editor-based Rest Client 152 | .idea/httpRequests 153 | 154 | # Android studio 3.1+ serialized cache file 155 | .idea/caches/build_file_checksums.ser 156 | 157 | ### Linux template 158 | *~ 159 | 160 | # temporary files which can be created if a process still has a handle open of a deleted file 161 | .fuse_hidden* 162 | 163 | # KDE directory preferences 164 | .directory 165 | 166 | # Linux trash folder which might appear on any partition or disk 167 | .Trash-* 168 | 169 | # .nfs files are created when an open file is removed but is still being accessed 170 | .nfs* 171 | 172 | ### Windows template 173 | # Windows thumbnail cache files 174 | Thumbs.db 175 | Thumbs.db:encryptable 176 | ehthumbs.db 177 | ehthumbs_vista.db 178 | 179 | # Dump file 180 | *.stackdump 181 | 182 | # Folder config file 183 | [Dd]esktop.ini 184 | 185 | # Recycle Bin used on file shares 186 | $RECYCLE.BIN/ 187 | 188 | # Windows Installer files 189 | *.cab 190 | *.msi 191 | *.msix 192 | *.msm 193 | *.msp 194 | 195 | # Windows shortcuts 196 | *.lnk 197 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | LD=ld 3 | OBJDIR:=$(shell [ -d obj ] || mkdir obj && echo "obj") 4 | CFLAGS=-Wall -Wextra -std=c11 -g 5 | LDFLAGS=-ldl 6 | 7 | P=main.out 8 | OBJ=src/main.o src/mem_load.o libmain.o 9 | 10 | .PHONY: $(P) 11 | 12 | $(P): $(OBJDIR)/src $(patsubst %, $(OBJDIR)/%, $(OBJ)) 13 | 14 | $(CC) $(filter %.o, $^) -o $@ $(LDFLAGS) 15 | 16 | 17 | $(OBJDIR)/libmain.o: src/main/libmain.so 18 | $(LD) -r -b binary -o $@ $^ 19 | 20 | src/main/libmain.so: 21 | $(MAKE) -C src/main 22 | 23 | $(OBJDIR)/%.o: %.c 24 | $(CC) $(CFLAGS) -c -o $@ $< 25 | 26 | $(OBJDIR)/src: 27 | mkdir -p $@ 28 | 29 | clean: 30 | $(MAKE) -C src/main clean 31 | rm -rf $(P) obj -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MemLoadProgram 2 | This is a proof of concept for loading shared object directly from memory without accessing the actual Linux file system. 3 | 4 | This project can only run on Linux, because it uses `memfd_create` which is not portable. 5 | 6 | # Build 7 | Use `make` to build this project, `make clean` cleanup artifact generated by build system. 8 | 9 | # TODO 10 | - Decrypt .so in runtime to further proof the necessity of loading program directly from memory. 11 | - Auto-encrypt shared object in build system. 12 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "mem_load.h" 5 | 6 | extern uint8_t _binary_src_main_libmain_so_start; 7 | extern uint8_t _binary_src_main_libmain_so_end; 8 | extern uint32_t _binary_src_main_libmain_so_size; 9 | 10 | int main() { 11 | 12 | fprintf(stderr, "[info] Section Size: %lu\n", &(_binary_src_main_libmain_so_end) - &(_binary_src_main_libmain_so_start)); 13 | int fd = setup_memfd(); 14 | void *handle = dlopen_handle(fd); 15 | if (handle == NULL){ 16 | 17 | } 18 | int (*main_prog)(); 19 | main_prog = (int(*)())dlsym(handle, "entry"); 20 | if(main_prog != NULL){ 21 | main_prog(); 22 | } 23 | else{ 24 | fprintf(stderr, "[-] dlsym error\n"); 25 | } 26 | dlclose(handle); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /src/main/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | OBJDIR:=$(shell [ -d ../../obj/src/main ] || mkdir -p ../../obj/src/main && echo "../../obj/src/main") 3 | CFLAGS=-Wall -Wextra -std=c11 -O2 -fPIC 4 | LDFLAGS=-shared 5 | 6 | P=libmain.so 7 | OBJ=main.o 8 | 9 | .PHONY: $(P) 10 | 11 | $(P): $(patsubst %, $(OBJDIR)/%, $(OBJ)) 12 | $(CC) $(filter %.o, $^) -o $@ $(LDFLAGS) 13 | 14 | $(OBJDIR)/%.o: %.c 15 | $(CC) $(CFLAGS) -c -o $@ $< 16 | 17 | clean: 18 | rm -rf $(P) -------------------------------------------------------------------------------- /src/main/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by jw910731 on 2020/12/20. 3 | // 4 | 5 | #include "main.h" 6 | #include 7 | 8 | int entry(){ 9 | printf("閃瞎了我的單身狗眼\n"); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/main.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by jw910731 on 2020/12/20. 3 | // 4 | 5 | #ifndef MEMLOADPROG_MAIN_H 6 | #define MEMLOADPROG_MAIN_H 7 | 8 | int entry(); 9 | 10 | #endif //MEMLOADPROG_MAIN_H 11 | -------------------------------------------------------------------------------- /src/mem_load.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by jw910731 on 2020/12/20. 3 | // 4 | 5 | #include "mem_load.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // add in link time 16 | extern unsigned char _binary_src_main_libmain_so_start; 17 | extern unsigned char _binary_src_main_libmain_so_end; 18 | extern uint32_t _binary_src_main_libmain_so_size; 19 | 20 | void error(const char *s){ 21 | char result[strlen(s)+strlen("[-] ")]; 22 | strcpy(result, "[-] "); 23 | strcat(result, s); 24 | perror(result); 25 | exit(EXIT_FAILURE); 26 | } 27 | 28 | int setup_memfd(){ 29 | int memfd; 30 | memfd = memfd_create("main_prog_fd", 0); 31 | if (memfd == -1){ 32 | error("memfd_create()"); 33 | } 34 | if(write(memfd, &(_binary_src_main_libmain_so_start), &(_binary_src_main_libmain_so_end) - &(_binary_src_main_libmain_so_start)) < 0){ 35 | close(memfd); 36 | error("write()"); 37 | } 38 | return memfd; 39 | } 40 | 41 | void *dlopen_handle(int fd){ 42 | char path[1024]; 43 | snprintf(path, 1024, "/proc/%d/fd/%d", getpid(), fd); 44 | void *dlHandle = dlopen(path, RTLD_LAZY); 45 | if(!dlHandle){ 46 | fprintf(stderr, "[-] dlopen(): %s\n", dlerror()); 47 | exit(EXIT_FAILURE); 48 | } 49 | return dlHandle; 50 | } -------------------------------------------------------------------------------- /src/mem_load.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by jw910731 on 2020/12/20. 3 | // 4 | 5 | #ifndef MEMLOADPROG_MEM_LOAD_H 6 | #define MEMLOADPROG_MEM_LOAD_H 7 | 8 | int setup_memfd(); 9 | void *dlopen_handle(int fd); 10 | void error(const char *s); 11 | 12 | #endif //MEMLOADPROG_MEM_LOAD_H 13 | --------------------------------------------------------------------------------