This tutorial will try to show you howto write a very basic Windows x86 PE injector, which is usually the basis for every self-replicating malware. It may be an advantage for you if you already know some C and Assembler, because I won't explain every single source line or asm instruction. [b]What does it?[/b] This repository contains a dummy executable which does printf something and then gracefully exits. And an injector executable for the proper code injection. The injector places and patches some shellcode in the victim executable and also patches the executable itself. The shellcode is the more important part of the injector. It gathers the important module base address KERNEL32.dll and uses it to find Windows API functions e.g. GetProcAddress. With GetProcAddress found, it will use it to find function addresses like ShellExecuteA. The function then will be called to open [code]http://y2u.be/DLzxrzFCyOs[/code] in your default browser. [b]Get the repo[/b]: The source is located at Tochka's GIT service. You can access it here: [code]http://qxklmrhx7qkzais6.onion/segfault/Torum-Tutorial-01[/code] [b]Build it[/b]: You will require a MingW toolchain, nasm > 2.10 to build it and wine (if you're using Linux) to test it (or a Windows machine). I've used i686-w64-mingw32-gcc version 6.3.0 which gets shipped with Debian stable. Additionally I've used a custom-patched i686-w64-mingw32-gcc based on version 8.2.0 and it also worked like charm. So you should be fine with 6.3.0 (and maybe with 8.2.0). [code] make # build dummy/injector executable make test # same as above but also run a sample injection [/code] The latter command will use [b]wine[/b] to execute the injector with the dummy as first argument. This will start the injection process and if it is successful, the resulting executable will be executed. [b]Run it[/b]: The injector supports two modes of operation: [list=1] [*] without additional arguments (except for argv[0]): test the shellcode and exit [*] with at least one additional argument: inject/patch shellcode/target-executable [/list] [b]Injection process[/b]: This will be the hardest part (for you as reader and for me as writer). I will split this in two parts to make it easier for you. We are assuming that the injector gets executed with at least one additional argument. [list=2] [*] Injector (C) [list=3] [*] open and read the file specified with argv[1] [*] parse the file and do some basic checks (validate PE) [*] extend the last section if it can be used [*] copy the (unpatched) shellcode into the new memory region [*] modify some header values e.g. size of last section, section protections, ... [*] search for a patchable instruction near entry point (AddressOfEntryPoint) [list=] [*] at this point we need to constantly convert pointers to RVA's and vice versa [*] if you don't what RVA's are, just use your favorite search engine (Yes, your sensors are working fine; I want you to use search engines because there is a reason for their existence which only a douche would deny) [/list] [*] search algorithm only reads the first 30 bytes and there is a reason for it [list=] [*] this is a very very basic x86 (en|decoder) [*] it supports currently only 8 different instructions [*] to produce as less as possible falsly patched outputs which would most likely result in an app crash [/list] [*] if a relative JUMP (0xE9) is found, patch its destination address (operand) [list=] [*] since it is a relative jump, we have to recalculate the address [*] we are using our current position (entryVA + i) as source and the shellcode start as destination [*] calculate the new relative offset with: destination - source - 5 [/list] [*] last but not least: shellcode patching [*] we need to patch another relative jump inside the shellcode to jump back to (entry + i + 5) [*] the shellcode marker has to be found first [list=] [*] it marks the patchable part of our shellcode [*] calculate the new relative offset [*] set the relative JUMP back [/list] [*] write the output file [*] the output file prefixed with patched_* is ready to use [/list] [*] Shellcode (ASM) I won't get into detail regarding the grabbing of KERNEL32.dll module base through PEB. If you have any questions just ask them below or use a random search engine to get the details. [list=4] [*] get the KERNEL32.dll base address (HANDLE) right after the shellcode entry is reached [*] get address of LoadLibraryA [*] use it's address to load Shell32.dll [*] get address of ShellExecuteA with Shell32.dll as module base (HANDLE) [*] prepare arguments for ShellExecuteA e.g. URL [*] call ShellExecuteA [*] cleanup the stack [*] marker (0xFF,0xDE,0xAD,0xC0,0xDE) will get patched by the injector [/list] [/list] [b]Remarks[/b]: The injector does currently _only_ patch relative JUMPs (0xE9) found in the first 30 bytes right after the target executable entry point. This is obviously not enough if you want an effective code injector and usually only works for executable compiled with MingW since it uses a relJMP right after the entry to init it's own C-Runtime-Environment. [b]Your task[/b]: Maybe one of you guys can fix the FIXME's so the injector will be more efficient? ;) Any questions? (*segfault) //EDIT: added nasm/wine version info