This is a tool I wrote to aid in exploitation of Windows PE files, its sole purpose is to find the location of instructions that jump into registers.
Those familiar with software exploitation will know why it’s useful to have the Virtual Address of a "JMP ESP" in memory…
I’ve released this tool on a few sites already but I figured I may as well post it here too…
Below is the source code, I’ve also uploaded a copy of the compiled version to this server…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | // JmpFinder V1.4 By KOrUPt with credit Napalm for helping :) #pragma comment(linker,"/BASE:0x400000 /FILEALIGN:0x200 /MERGE:.rdata=.text /MERGE:.data=.text /SECTION:.text,EWR /IGNORE:4078") #pragma comment(lib, "version.lib") #include <windows.h> #include <stdio.h> #include "x86opsize.cpp" // < hackjob for scITE :p struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *lpTranslate; DWORD FileToVa(DWORD dwFileAddr, PIMAGE_NT_HEADERS pNtHeaders) // By Napalm { PIMAGE_SECTION_HEADER lpSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeaders + sizeof(IMAGE_NT_HEADERS)); for(WORD 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 NULL; } int main(int argc, char* argv[]) { PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeaders; PIMAGE_SECTION_HEADER lpSecHdr; HANDLE hFile, hFileMap; LPBYTE hMap; char subBlock[256]; char jmpTable[][4] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", 0 }; LPVOID versionInfo, versionOutput; DWORD dwSize, fsize, i, useOpsize = 0; UINT generic = 0; printf("[*] Jmp Finder V1.4 By KOrUPt\n"); if(argc < 2){ printf("[-] Usage: %s <file> [IncrementByOpSize]\n", argv[0]); return 0; } if(argc == 3){ printf("[*] Incrementing by instruction size\n"); useOpsize = 1; } // map file hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE){ printf("[-] Cannot open %s\n", argv[1]); return 0; } hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if(!hFileMap){ printf("[-] CreateFileMapping failed\n"); CloseHandle(hFile); return 0; } hMap = (LPBYTE)MapViewOfFile(hFileMap, FILE_READ_ACCESS, 0, 0, 0); if(!hMap){ printf("[-] MapViewOfFile failed\n"); CloseHandle(hFileMap); CloseHandle(hFile); return 0; } fsize = GetFileSize(hFile, 0); if(fsize < (sizeof(IMAGE_DOS_SIGNATURE) + sizeof(IMAGE_NT_HEADERS)) || fsize == INVALID_FILE_SIZE){ printf("[-] PE Headers not found\n"); CloseHandle(hFileMap); CloseHandle(hFile); return 0; } 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; } if(pNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386){ printf("[-] Architecture not supported\n"); goto cleanup; } printf("[*] Scanning file: %s\n", argv[1]); // get version info if((dwSize = GetFileVersionInfoSize(argv[1], &i))){ versionInfo = malloc(dwSize); if(versionInfo){ if(GetFileVersionInfo(argv[1], 0, dwSize, versionInfo)){ if(VerQueryValue(versionInfo, "\\VarFileInfo\\Translation", (LPVOID *)&lpTranslate, &generic)){ wsprintf(subBlock, "\\StringFileInfo\\%04x%04x\\FileVersion", lpTranslate[0].wLanguage, lpTranslate[0].wCodePage); if(VerQueryValue(versionInfo, subBlock, (LPVOID *)&versionOutput, &generic)) printf("[+] File Version: %s\n\n", versionOutput); } } free(versionInfo); } } lpSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeaders + sizeof(IMAGE_NT_HEADERS)); for(i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++){ if(lpSecHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE){ BYTE bOpcode2; LPBYTE lpStart = (hMap + lpSecHdr->PointerToRawData); LPBYTE lpEnd = (lpStart + lpSecHdr->SizeOfRawData); while(lpStart < lpEnd){ bOpcode2 = *(lpStart + 1); if(*lpStart == 0xFF && bOpcode2 >= 0xE0 && bOpcode2 <= 0xE7){ printf("%Jmp %s located!", jmpTable[bOpcode2 & 0xF]); printf("\n[*] Virtual Address: 0x%08lX\n[*] FileOffset: 0x%08lX\n\n", FileToVa((lpStart - hMap), pNtHeaders), (lpStart - hMap)); } if(useOpsize) lpStart += x86opsize(lpStart); else lpStart++; } } lpSecHdr++; } printf("[+] Happy Stack Smashing :)!\n"); cleanup: FlushViewOfFile(hMap, 0); UnmapViewOfFile(hMap); CloseHandle(hFileMap); CloseHandle(hFile); return 0; } |
Download: http://korupt.co.uk/JmpFinder.exe
I look forward to reading your comments and such, if you’ve any questions please let me know! KOrUPt.