├── HISTORY ├── README ├── functions.cpp ├── functions.h ├── realign.cpp ├── realign.def ├── realign.h ├── realign.sln ├── realign.vcxproj ├── realign.vcxproj.filters ├── resource.h └── rsrc.rc /HISTORY: -------------------------------------------------------------------------------- 1 | 1.6: 2 | - "RealignPEEx" API added: 3 | * option: new file alignment (200h, 400h, 800h, 1000h) 4 | * option: align section rawsizes to new file alignment 5 | * option: strip empty sections from header 6 | - "WipeData" API added: 7 | * wipe section containing data directory 8 | * optionally zerofill data before deleting section (if present) 9 | - "FixChecksum" API added 10 | - "ReBasePEImageEx" API added: 11 | * supports both PE and PE32+ files, the old one doesn't allow a 64bit base 12 | - "MapFile" API added 13 | - "UnmapFile" API added 14 | - RealignPE: 15 | * improved handling of sections with a rawoffset or rawsize of 0 16 | * zerofill unused space in header and sections 17 | - WipeReloc: 18 | * fixed handling for sections not sorted by their rawoffset 19 | * copy entire section header (characteristics!) 20 | * sets IMAGE_FILE_RELOCS_STRIPPED flag in the PE header 21 | - ValidatePE: 22 | * proper calculation of SizeOfHeaders 23 | * improved alignment of raw and virtual offsets + sizes 24 | - support for x64 PE files (PE32+) 25 | - handles RVAs inside the PE header 26 | - support for up to 96 sections 27 | - code can be compiled to an x64 dll/lib 28 | - removed all references to dbghlp.dll 29 | - functions are thread safe 30 | - lots of minor bug fixes 31 | 32 | ----8<----8<----8<-- (begin of fork) --8<----8<----8<----8<---- 33 | 34 | 1.5: 35 | - "ReBasePEImage" API added 36 | 37 | 1.4d: 38 | - offset to section table is now calculated dynamically 39 | 40 | 1.4c: 41 | - "ValidatePE" API added 42 | 43 | 1.4b: 44 | - solved prob with binded files 45 | - new realign mode: nice 46 | 47 | 1.4: 48 | - WipeReloc API added 49 | 50 | 1.3a: 51 | - bugs I caused while fixing the Watcom prob were fixed :) 52 | - fixed a bug that let a lot of files don't work on NT after realigning them 53 | in the normal mode (the PE Signature can't be anywhere in the Header) 54 | 55 | 1.2: 56 | - support for files being compiled with Watcom C/C++ added 57 | - TruncateFile API added 58 | 59 | 1.11: 60 | - SEH added 61 | - Realign API returns error codes 62 | 63 | 1.1: 64 | - hardcore realign mode added 65 | - bugfixes -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is a fork/rewrite of yoda's realignDLL. 2 | It works on PE64 and should be mostly crash-free (knock on wood). 3 | See HISTORY for a complete list of fixes and additions. 4 | -------------------------------------------------------------------------------- /functions.cpp: -------------------------------------------------------------------------------- 1 | #include "functions.h" 2 | 3 | #include 4 | #include // offsetof 5 | 6 | bool GetNTHeader(void * pMap, DWORD dwSize, IMAGE_DOS_HEADER ** opDosH, IMAGE_NT_HEADERS ** opNTH, IMAGE_SECTION_HEADER ** opSecs, WORD * onSecs) 7 | { 8 | IMAGE_DOS_HEADER * pDosH; 9 | IMAGE_NT_HEADERS * pNTH; 10 | 11 | pDosH = (IMAGE_DOS_HEADER *)pMap; 12 | if(dwSize > sizeof(IMAGE_DOS_HEADER) && pDosH->e_magic == IMAGE_DOS_SIGNATURE && pDosH->e_lfanew > 0 && pDosH->e_lfanew < 0x10000000) 13 | { 14 | pNTH = (IMAGE_NT_HEADERS *)((ULONG_PTR)pMap + pDosH->e_lfanew); 15 | if(dwSize >= (pDosH->e_lfanew + sizeof(IMAGE_NT_HEADERS)) && pNTH->Signature == IMAGE_NT_SIGNATURE) 16 | { 17 | if(pNTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC || 18 | pNTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) 19 | { 20 | if(dwSize >= (pDosH->e_lfanew + SizeOfPEHeader(pNTH))) 21 | { 22 | if(opDosH) *opDosH = pDosH; 23 | if(opNTH) *opNTH = pNTH; 24 | if(opSecs) *opSecs = IMAGE_FIRST_SECTION(pNTH); 25 | if(onSecs) *onSecs = pNTH->FileHeader.NumberOfSections; 26 | return true; 27 | } 28 | } 29 | } 30 | } 31 | 32 | return false; 33 | } 34 | 35 | IMAGE_NT_HEADERS * GetNTHeader(void * pMap) 36 | { 37 | IMAGE_DOS_HEADER * pDosH; 38 | IMAGE_NT_HEADERS * pNTH; 39 | 40 | pDosH = (IMAGE_DOS_HEADER *)pMap; 41 | if(pDosH->e_magic == IMAGE_DOS_SIGNATURE && pDosH->e_lfanew > 0 && pDosH->e_lfanew < 0x10000000) 42 | { 43 | pNTH = (IMAGE_NT_HEADERS *)((ULONG_PTR)pMap + pDosH->e_lfanew); 44 | if(pNTH->Signature == IMAGE_NT_SIGNATURE) 45 | { 46 | if(pNTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC || 47 | pNTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) 48 | { 49 | return pNTH; 50 | } 51 | } 52 | } 53 | 54 | return 0; 55 | } 56 | 57 | DWORD SizeOfPEHeader(const IMAGE_NT_HEADERS * pNTH) 58 | { 59 | return (offsetof(IMAGE_NT_HEADERS, OptionalHeader) + pNTH->FileHeader.SizeOfOptionalHeader + (pNTH->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER))); 60 | } 61 | 62 | bool IsPE64(const IMAGE_NT_HEADERS * pNTH) 63 | { 64 | return (pNTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC); 65 | } 66 | 67 | DWORD RVAToOffset(DWORD dwRVA, const void * pMap) 68 | { 69 | const IMAGE_NT_HEADERS * pNTH; 70 | const IMAGE_SECTION_HEADER * SectionTable; 71 | DWORD VAddress, VSize, ROffset, RSize, UpperBound; 72 | unsigned int i; 73 | 74 | pNTH = (IMAGE_NT_HEADERS *)((ULONG_PTR)pMap + ((IMAGE_DOS_HEADER *)pMap)->e_lfanew); 75 | SectionTable = IMAGE_FIRST_SECTION(pNTH); 76 | 77 | if(dwRVA < SectionTable[0].VirtualAddress) // RVA points to header 78 | return dwRVA; 79 | 80 | for(i=0; i < pNTH->FileHeader.NumberOfSections; i++) 81 | { 82 | VAddress = SectionTable[i].VirtualAddress; 83 | VSize = AlignUp(SectionTable[i].Misc.VirtualSize, pNTH->OptionalHeader.SectionAlignment); 84 | ROffset = SectionTable[i].PointerToRawData; 85 | RSize = AlignUp(SectionTable[i].SizeOfRawData, pNTH->OptionalHeader.FileAlignment); 86 | 87 | UpperBound = (RSize < VSize) ? RSize : VSize; 88 | 89 | if((dwRVA >= VAddress) && (dwRVA < (VAddress + UpperBound))) 90 | { 91 | return (dwRVA - VAddress + ROffset); 92 | } 93 | } 94 | 95 | return 0; 96 | } 97 | 98 | DWORD StripSection(void * pMap, DWORD dwFsize, DWORD nSection) 99 | { 100 | IMAGE_NT_HEADERS * pNTH; 101 | IMAGE_SECTION_HEADER * pSH, * pSHC; 102 | DWORD dwNewFsize; 103 | DWORD Diff; 104 | unsigned int i; 105 | 106 | pNTH = GetNTHeader(pMap); 107 | 108 | // section doesn't exist / only one section 109 | if(nSection >= pNTH->FileHeader.NumberOfSections || pNTH->FileHeader.NumberOfSections == 1) 110 | return 0; 111 | 112 | pSHC = IMAGE_FIRST_SECTION(pNTH); // used in loop 113 | pSH = &pSHC[nSection]; // section to delete 114 | 115 | pNTH->FileHeader.NumberOfSections--; 116 | 117 | if(nSection == pNTH->FileHeader.NumberOfSections) 118 | { // last section -> truncate at section start 119 | dwNewFsize = pSH->PointerToRawData; // ???? 120 | 121 | pSH--; 122 | if(IsPE64(pNTH)){ 123 | if(pSH->Misc.PhysicalAddress) 124 | ((IMAGE_NT_HEADERS64 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->Misc.VirtualSize; 125 | else // WATCOM is always a bit special >:-) 126 | ((IMAGE_NT_HEADERS64 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->SizeOfRawData; 127 | } 128 | else{ 129 | if(pSH->Misc.PhysicalAddress) 130 | ((IMAGE_NT_HEADERS32 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->Misc.VirtualSize; 131 | else 132 | ((IMAGE_NT_HEADERS32 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->SizeOfRawData; 133 | } 134 | } 135 | else // not the last section 136 | { 137 | if(pSH->SizeOfRawData != 0) 138 | { 139 | Diff = AlignUp(pSH->SizeOfRawData, HDR3264(pNTH, OptionalHeader.FileAlignment)); 140 | 141 | dwNewFsize = dwFsize - Diff; 142 | 143 | // copy section(s) after this section to the start of this section 144 | memcpy((void *)((ULONG_PTR)pMap + pSH->PointerToRawData), (void *)((ULONG_PTR)pMap + pSH->PointerToRawData + Diff), dwFsize - pSH->PointerToRawData - Diff); 145 | 146 | for(i=0; i <= pNTH->FileHeader.NumberOfSections; i++) 147 | { 148 | if(pSHC->PointerToRawData >= (pSH->PointerToRawData + Diff)) 149 | pSHC->PointerToRawData -= Diff; 150 | pSHC++; 151 | } 152 | } 153 | 154 | // fix section header 155 | if(nSection == 0) 156 | { 157 | pSH->SizeOfRawData = 0; 158 | pNTH->FileHeader.NumberOfSections++; 159 | } 160 | else 161 | { 162 | (pSH-1)->Misc.VirtualSize += pSH->Misc.VirtualSize; 163 | memcpy(pSH, (pSH+1), sizeof(IMAGE_SECTION_HEADER) * (pNTH->FileHeader.NumberOfSections-nSection)); 164 | } 165 | } 166 | 167 | if(nSection != 0) 168 | { // Zerofill last section header 169 | pSH = IMAGE_FIRST_SECTION(pNTH); 170 | memset(&pSH[pNTH->FileHeader.NumberOfSections], 0, sizeof(IMAGE_SECTION_HEADER)); 171 | } 172 | 173 | return dwNewFsize; 174 | } 175 | 176 | void FixVSizes(IMAGE_NT_HEADERS * pNTH) 177 | { 178 | IMAGE_SECTION_HEADER * pSH; 179 | 180 | // fix virtual parts of the PE Header (a must for win2k) 181 | pSH = IMAGE_FIRST_SECTION(pNTH); 182 | for(WORD i=0; i < pNTH->FileHeader.NumberOfSections-1; i++) 183 | { 184 | pSH->Misc.VirtualSize = (pSH+1)->VirtualAddress - pSH->VirtualAddress; 185 | pSH++; 186 | } 187 | // (pSH -> pointer to last section) 188 | 189 | // align last section VSize to Sectionalignment 190 | pSH->Misc.VirtualSize = AlignUp(pSH->Misc.VirtualSize, HDR3264(pNTH, OptionalHeader.SectionAlignment)); 191 | 192 | if(IsPE64(pNTH)){ 193 | if(pSH->Misc.PhysicalAddress) 194 | ((IMAGE_NT_HEADERS64 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->Misc.VirtualSize; 195 | else 196 | ((IMAGE_NT_HEADERS64 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->SizeOfRawData; 197 | } 198 | else{ 199 | if(pSH->Misc.PhysicalAddress) 200 | ((IMAGE_NT_HEADERS32 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->Misc.VirtualSize; 201 | else 202 | ((IMAGE_NT_HEADERS32 *)pNTH)->OptionalHeader.SizeOfImage = pSH->VirtualAddress + pSH->SizeOfRawData; 203 | } 204 | } 205 | 206 | DWORD AlignUp(DWORD dwBadSize, DWORD dwAlignment) 207 | { 208 | dwAlignment--; 209 | return ((dwBadSize+dwAlignment) & ~dwAlignment); 210 | } 211 | 212 | DWORD AlignDown(DWORD dwBadSize, DWORD dwAlignment) 213 | { 214 | dwAlignment--; 215 | return (dwBadSize & ~dwAlignment); 216 | } 217 | 218 | bool ValidFileAlignment(DWORD dwAlign) 219 | { 220 | // lower and upper limits (pecoff spec) 221 | const DWORD MIN_ALIGN = 0x200; 222 | const DWORD MAX_ALIGN = 0x10000; 223 | 224 | if((dwAlign & (dwAlign-1)) != 0) // power of 2 ? 225 | return false; 226 | 227 | if(dwAlign < MIN_ALIGN || dwAlign > 0x10000) 228 | return false; 229 | 230 | return true; 231 | } 232 | -------------------------------------------------------------------------------- /functions.h: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTIONS_H 2 | #define FUNCTIONS_H 3 | 4 | #include 5 | 6 | #define HDR3264(NTH, Field) (IsPE64(NTH) ? (((IMAGE_NT_HEADERS64 *)NTH)->Field) : (((IMAGE_NT_HEADERS32 *)NTH)->Field)) 7 | 8 | static const DWORD FILEALIGNMENT_DOWN = 0x200; 9 | 10 | bool GetNTHeader(void * pMap, DWORD dwSize, IMAGE_DOS_HEADER ** opDosH, IMAGE_NT_HEADERS ** opNTH, IMAGE_SECTION_HEADER ** opSecs, WORD * onSecs); 11 | IMAGE_NT_HEADERS * GetNTHeader(void * pMap); 12 | DWORD SizeOfPEHeader(const IMAGE_NT_HEADERS * pNTH); 13 | bool IsPE64(const IMAGE_NT_HEADERS * pNTH); 14 | DWORD RVAToOffset(DWORD dwRVA, const void * pMap); 15 | DWORD StripSection(void * pMap, DWORD dwFsize, DWORD nSection); 16 | void FixVSizes(IMAGE_NT_HEADERS * pNTH); 17 | DWORD AlignUp(DWORD dwBadSize, DWORD dwAlignment); 18 | DWORD AlignDown(DWORD dwBadSize, DWORD dwAlignment); 19 | bool ValidFileAlignment(DWORD dwAlign); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /realign.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | realign.dll (1.5] by yoda 3 | modifications [1.6) by pezcode 4 | 5 | You are allowed to use this code if you mention my name. (yoda's that is) 6 | */ 7 | 8 | #define NOMINMAX 9 | 10 | #include 11 | #include 12 | #include 13 | #include "realign.h" 14 | #include "functions.h" 15 | 16 | // global variables 17 | HMODULE hDll; 18 | 19 | IMAGE_DOS_HEADER NiceStub = 20 | { 21 | IMAGE_DOS_SIGNATURE, // e_magic 22 | 0x0090, // e_cblp 23 | 0x0003, // e_cp 24 | 0x0000, // e_crlc 25 | 0x0004, // e_cparhdr 26 | 0x0000, // e_minalloc 27 | 0xFFFF, // e_maxalloc 28 | 0x0000, // e_ss 29 | 0x00B8, // e_sp 30 | 0x0000, // e_csum 31 | 0x0000, // e_ip 32 | 0x0000, // e_cs 33 | 0x0040, // e_lfarlc 34 | 0x0000, // e_ovno 35 | {0}, // e_res[4] 36 | 0x0000, // e_oemid 37 | 0x0000, // e_oeminfo 38 | {0}, // e_res2[10] 39 | sizeof(IMAGE_DOS_HEADER) // e_lfanew 40 | }; 41 | 42 | // ---------- 43 | 44 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 45 | { 46 | return TRUE; 47 | } 48 | 49 | // ---------- 50 | 51 | void * __stdcall MapFile(const char * szFilePath, DWORD * pdwFsize) 52 | { 53 | HANDLE hFile; 54 | DWORD dwFsize, dwFsizeHigh; 55 | const DWORD MaxFsize = 1 * 1024 * 1024 * 1024; // GB * MB * KB * B 56 | void * pMap = 0; 57 | DWORD dwBytes; 58 | 59 | hFile = CreateFile(szFilePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 60 | if(hFile != INVALID_HANDLE_VALUE) 61 | { 62 | dwFsize = GetFileSize(hFile, &dwFsizeHigh); 63 | if(!dwFsizeHigh && dwFsize <= MaxFsize) // Files > 1GB not supported 64 | { 65 | if(pdwFsize) *pdwFsize = dwFsize; 66 | pMap = VirtualAlloc(0, dwFsize, MEM_COMMIT, PAGE_READWRITE); 67 | if(pMap) 68 | { 69 | if(!ReadFile(hFile, pMap, dwFsize, &dwBytes, 0)) 70 | { 71 | VirtualFree(pMap, 0, MEM_RELEASE); 72 | pMap = 0; 73 | } 74 | } 75 | } 76 | CloseHandle(hFile); 77 | } 78 | return pMap; 79 | } 80 | 81 | bool __stdcall UnmapFile(const char * szFilePath, void * pMap, DWORD dwFsize) 82 | { 83 | HANDLE hFile; 84 | DWORD dwBytes; 85 | bool RetVal = false; 86 | 87 | hFile = CreateFile(szFilePath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 88 | if(hFile != INVALID_HANDLE_VALUE) 89 | { 90 | RetVal = WriteFile(hFile, pMap, dwFsize, &dwBytes, 0) == TRUE; 91 | SetEndOfFile(hFile); 92 | CloseHandle(hFile); 93 | VirtualFree(pMap, 0, MEM_RELEASE); 94 | } 95 | return RetVal; 96 | } 97 | 98 | bool __stdcall TruncateFile(const char * szFilePath, DWORD dwNewFsize) 99 | { 100 | HANDLE hFile; 101 | 102 | hFile = CreateFile(szFilePath, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 103 | if(hFile != INVALID_HANDLE_VALUE) 104 | { 105 | SetFilePointer(hFile, dwNewFsize, NULL, FILE_BEGIN); 106 | SetEndOfFile(hFile); 107 | CloseHandle(hFile); 108 | return true; 109 | } 110 | return false; 111 | } 112 | 113 | /* 114 | Return values: 115 | 0 - access error while realigning 116 | 1 - at least one parameter is invalid 117 | 2 - invalid PE file 118 | 3 - too many sections - unsupported 119 | 4 - not enough memory 120 | ...else the new filesize 121 | */ 122 | 123 | DWORD __stdcall RealignPE(void * pMap, DWORD dwFsize, BYTE bRealignMode) 124 | { 125 | return RealignPEEx(pMap, dwFsize, bRealignMode, 0x200, false, false); 126 | } 127 | 128 | DWORD __stdcall RealignPEEx(void * pMap, DWORD dwFsize, BYTE bRealignMode, WORD wNewAlign, bool blAlignRawSizes, bool blStripEmptySections) 129 | { 130 | const size_t MAX_SEC_NUM = 96; // max number of sections supported by the Windows loader 131 | IMAGE_DOS_HEADER * pDosH; 132 | IMAGE_NT_HEADERS * pNTH; 133 | IMAGE_SECTION_HEADER * pSH; 134 | BYTE * pSections[MAX_SEC_NUM]; 135 | BYTE * bptrMapBase; 136 | DWORD dwSectionBase, dwHdrSize, dwNewSize; 137 | //WORD wNPEHStart; 138 | //WORD * pW; 139 | BYTE * pCH; 140 | 141 | // TODO asserts 142 | 143 | if(pMap == 0 || dwFsize == 0) 144 | return RA_INVALIDPARAM; 145 | 146 | if(!ValidFileAlignment(wNewAlign)) 147 | return RA_INVALIDPARAM; 148 | 149 | if(!GetNTHeader(pMap, dwFsize, &pDosH, &pNTH, 0, 0)) 150 | return RA_INVALIDPE; 151 | 152 | if(wNewAlign > pNTH->OptionalHeader.SectionAlignment) 153 | return RA_INVALIDPARAM; 154 | 155 | if(pNTH->FileHeader.NumberOfSections > MAX_SEC_NUM) 156 | return RA_TOOMANYSECTIONS; 157 | 158 | bptrMapBase = static_cast(pMap); 159 | 160 | /* Realign the PE Header */ 161 | 162 | dwHdrSize = SizeOfPEHeader(pNTH); 163 | 164 | switch(bRealignMode) 165 | { 166 | /* 167 | case REALIGN_MODE_NORMAL: 168 | 169 | // kill room between the "win32 pls" message and the PE signature 170 | // find the end of the message 171 | pW = (WORD *)(bptrMapBase+sizeof(IMAGE_DOS_HEADER)); 172 | while((*pW != 0 || ((ULONG_PTR)pW % 0x10)) && ((ULONG_PTR)pW < (ULONG_PTR)pNTH)) 173 | (BYTE *)pW++; 174 | wNPEHStart = (WORD)((BYTE*)pW-bptrMapBase); 175 | if(wNPEHStart < pDosH->e_lfanew) 176 | { 177 | memcpy(pW, pNTH, dwHdrSize); // copy the Header to the right place 178 | pDosH->e_lfanew = wNPEHStart; 179 | } 180 | break; 181 | */ 182 | case REALIGN_MODE_HARDCORE: // completely wipe the dos stub 183 | memmove(bptrMapBase+0xC, pNTH, dwHdrSize); 184 | pDosH->e_lfanew = 0xC; // overwrites BaseOfData 185 | break; 186 | case REALIGN_MODE_NORMAL: 187 | case REALIGN_MODE_NICE: // paste new stub, append PE header 188 | if(pDosH->e_lfanew > sizeof(NiceStub)) 189 | { 190 | *pDosH = NiceStub; 191 | memmove(bptrMapBase + sizeof(IMAGE_DOS_HEADER), pNTH, dwHdrSize); 192 | } 193 | break; 194 | default: 195 | return RA_INVALIDPARAM; 196 | } 197 | 198 | // Size of all headers 199 | dwHdrSize += pDosH->e_lfanew; 200 | dwSectionBase = AlignUp(dwHdrSize, wNewAlign); 201 | // get new PE header offset 202 | pNTH = reinterpret_cast(bptrMapBase+pDosH->e_lfanew); 203 | pNTH->OptionalHeader.SizeOfHeaders = dwSectionBase; 204 | 205 | /* Realign all sections */ 206 | 207 | // make a copy of all sections 208 | // this is needed if the sections aren't sorted by their RawOffset (e.g. Petite) 209 | 210 | pSH = IMAGE_FIRST_SECTION(pNTH); 211 | 212 | for(WORD i = 0; i < pNTH->FileHeader.NumberOfSections; i++) 213 | { 214 | if(pSH[i].PointerToRawData == 0) 215 | { 216 | pSH[i].SizeOfRawData = 0; // Don't copy section, no memory allocated! 217 | } 218 | else if(pSH[i].SizeOfRawData != 0) 219 | { 220 | // get a valid RawOffset 221 | pSH[i].PointerToRawData = AlignDown(pSH[i].PointerToRawData, FILEALIGNMENT_DOWN); 222 | // ??? 223 | 224 | // get the smallest size 225 | if(pSH[i].Misc.VirtualSize < pSH[i].SizeOfRawData) 226 | pSH[i].SizeOfRawData = pSH[i].Misc.VirtualSize; 227 | 228 | // Offset outside the file? 229 | if(pSH[i].PointerToRawData > dwFsize) 230 | { 231 | pSH[i].SizeOfRawData = 0; 232 | } 233 | 234 | // If size exceeds filesize, get bytes till end of file 235 | if((pSH[i].PointerToRawData + pSH[i].SizeOfRawData) > dwFsize) 236 | pSH[i].SizeOfRawData = dwFsize - pSH[i].PointerToRawData; 237 | 238 | // get size without trailing zeroes 239 | pCH = bptrMapBase + pSH[i].PointerToRawData + pSH[i].SizeOfRawData - 1; 240 | while(pSH[i].SizeOfRawData != 0 && *pCH == 0) 241 | { 242 | pSH[i].SizeOfRawData--; 243 | pCH--; 244 | } 245 | 246 | if(pSH[i].SizeOfRawData != 0) 247 | { 248 | try 249 | { 250 | pSections[i] = new BYTE[pSH[i].SizeOfRawData]; 251 | } 252 | catch(std::bad_alloc&) 253 | { 254 | for(int j = 0; j < i; j++) 255 | { 256 | delete[] pSections[j]; 257 | } 258 | return RA_OUTOFMEMORY; 259 | } 260 | 261 | memcpy(pSections[i], bptrMapBase+pSH[i].PointerToRawData, pSH[i].SizeOfRawData); 262 | } 263 | } 264 | } 265 | 266 | // Zerofill executable to remove junk 267 | memset(bptrMapBase+dwHdrSize, 0, dwFsize-dwHdrSize); 268 | 269 | // copy sections 270 | for(int i = 0; i < pNTH->FileHeader.NumberOfSections; i++) 271 | { 272 | // set new RawOffset 273 | pSH[i].PointerToRawData = dwSectionBase; 274 | 275 | // don't copy empty sections 276 | if(pSH[i].SizeOfRawData != 0) 277 | { 278 | // copy section to the new place 279 | memcpy(bptrMapBase+dwSectionBase, pSections[i], pSH[i].SizeOfRawData); 280 | 281 | // get aligned size for new RawOffset (not needed for the last section -> return correct file size) 282 | if(blAlignRawSizes || i+1 != pNTH->FileHeader.NumberOfSections) 283 | dwNewSize = AlignUp(pSH[i].SizeOfRawData, wNewAlign); 284 | 285 | // get aligned RawSize 286 | if(blAlignRawSizes) 287 | pSH[i].SizeOfRawData = dwNewSize; 288 | 289 | // get RawOffset for the next section 290 | dwSectionBase += dwNewSize; 291 | } 292 | } 293 | 294 | // Strip sections with a rawsize of 0 295 | if(blStripEmptySections) 296 | { 297 | for(int i = 0; i < pNTH->FileHeader.NumberOfSections; i++) 298 | { 299 | if(pSH[i].SizeOfRawData == 0) 300 | StripSection(pMap, dwFsize, i); 301 | } 302 | } 303 | 304 | pNTH->OptionalHeader.FileAlignment = wNewAlign; 305 | 306 | // delete bound import directories (destroyed if present) 307 | if(IsPE64(pNTH)) 308 | { 309 | IMAGE_NT_HEADERS64 * pNTH64 = reinterpret_cast(pNTH); 310 | pNTH64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0; 311 | pNTH64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0; 312 | } 313 | else 314 | { 315 | IMAGE_NT_HEADERS32 * pNTH32 = reinterpret_cast(pNTH); 316 | pNTH32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0; 317 | pNTH32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0; 318 | } 319 | 320 | // clean up 321 | for(int i = 0; i < pNTH->FileHeader.NumberOfSections; i++) 322 | { 323 | delete[] pSections[i]; 324 | } 325 | 326 | return dwSectionBase; // return the new filesize 327 | } 328 | 329 | DWORD __stdcall ReBasePEImage(void * pMap, DWORD dwNewBase) 330 | { 331 | return ReBasePEImageEx(pMap, std::numeric_limits::max(), dwNewBase); 332 | } 333 | 334 | DWORD __stdcall ReBasePEImageEx(void * pMap, DWORD dwFsize, ULONGLONG ulNewBase) 335 | { 336 | IMAGE_NT_HEADERS * pNTH; 337 | IMAGE_RELOCATION * pR; 338 | DWORD dwRelDir, dwRelOffs, dwOffsAddr, dwRva, Type; 339 | ULONGLONG ulOldBase, ulDelta; 340 | ULONGLONG * pAddr; 341 | WORD * pW; 342 | int nItems; 343 | 344 | if(!GetNTHeader(pMap, dwFsize, 0, &pNTH, 0, 0)) 345 | return RB_INVALIDPE; 346 | 347 | if(ulNewBase & 0xFFFF) 348 | return RB_INVALIDNEWBASE; 349 | 350 | ulOldBase = HDR3264(pNTH, OptionalHeader.ImageBase); 351 | 352 | if(ulOldBase == ulNewBase) 353 | return RB_OK; 354 | 355 | // get relocation dir ptr 356 | dwRelDir = HDR3264(pNTH, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 357 | if(!dwRelDir) 358 | return RB_NORELOCATIONINFO; 359 | 360 | dwRelOffs = RVAToOffset(dwRelDir, pMap); 361 | if(!dwRelOffs || dwRelOffs > dwFsize) 362 | return RB_INVALIDRVA; 363 | 364 | pR = reinterpret_cast(static_cast(pMap) + dwRelOffs); 365 | 366 | /* add delta to relocation items */ 367 | 368 | ulDelta = ulNewBase - ulOldBase; 369 | 370 | __try 371 | { 372 | while(pR->VirtualAddress) 373 | { 374 | if(!pR->SymbolTableIndex) 375 | break; // this shouldn't happen o_O 376 | 377 | // calculate number of items 378 | nItems = (pR->SymbolTableIndex - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(pR->Type); 379 | 380 | // walk block items 381 | pW = &pR->Type; 382 | for(int i = 0; i < nItems; i++) 383 | { 384 | dwRva = (pW[i] & 0xFFF) + pR->VirtualAddress; // get item RVA 385 | Type = pW[i] >> 12; // get relocation type 386 | 387 | dwOffsAddr = RVAToOffset(dwRva, pMap); 388 | if(!dwOffsAddr || dwOffsAddr > dwFsize) 389 | return RB_INVALIDRVA; 390 | 391 | pAddr = reinterpret_cast(static_cast(pMap) + dwOffsAddr); 392 | 393 | // add delta value 394 | switch(Type) 395 | { 396 | case IMAGE_REL_BASED_HIGHLOW: 397 | case IMAGE_REL_BASED_DIR64: 398 | *pAddr += ulDelta; 399 | break; 400 | } 401 | } 402 | 403 | // get next block header 404 | pR = reinterpret_cast(reinterpret_cast(pR) + pR->SymbolTableIndex); 405 | } 406 | } 407 | __except(EXCEPTION_EXECUTE_HANDLER) 408 | { 409 | return RB_ACCESSVIOLATION; 410 | } 411 | 412 | // write new base to header 413 | if(IsPE64(pNTH)) 414 | reinterpret_cast(pNTH)->OptionalHeader.ImageBase = ulNewBase; 415 | else 416 | reinterpret_cast(pNTH)->OptionalHeader.ImageBase = ulNewBase & 0xFFFFFFFF; 417 | 418 | return RB_OK; 419 | } 420 | 421 | /* 422 | Param bData: 423 | 424 | #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory 425 | #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory 426 | #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory 427 | #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory 428 | #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory 429 | #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table 430 | #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory 431 | // IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) 432 | #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data 433 | #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP 434 | #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory 435 | #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory 436 | #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers 437 | #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table 438 | #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors 439 | #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor 440 | */ 441 | 442 | /* 443 | Return values: 444 | -1 - access violation 445 | -2 - no data directory found 446 | -3 - no own section 447 | -4 - invalid PE file 448 | ...else the new raw size 449 | */ 450 | 451 | DWORD __stdcall WipeData(void * pMap, DWORD dwFsize, BYTE bData, bool blZerofill) 452 | { 453 | IMAGE_NT_HEADERS * pNTH; 454 | IMAGE_SECTION_HEADER * pSH; 455 | DWORD dwDataRVA, dwDataOffset, dwDataSize; 456 | DWORD dwNewFsize; 457 | bool bOwnSec = false; 458 | unsigned int i; 459 | 460 | __try // =) 461 | { 462 | if(!GetNTHeader(pMap, dwFsize, 0, &pNTH, &pSH, 0)) 463 | return WD_INVALIDPE; 464 | 465 | // is there a data section ? 466 | if(bData >= HDR3264(pNTH, OptionalHeader.NumberOfRvaAndSizes)) 467 | return WD_NODATA; 468 | dwDataRVA = HDR3264(pNTH, OptionalHeader.DataDirectory[bData].VirtualAddress); 469 | if(!dwDataRVA) 470 | return WD_NODATA; 471 | 472 | if(blZerofill) 473 | { 474 | dwDataOffset = RVAToOffset(dwDataRVA, pMap); 475 | dwDataSize = HDR3264(pNTH, OptionalHeader.DataDirectory[bData].Size); 476 | 477 | if(!dwDataOffset || ((dwDataOffset+dwDataSize) > dwFsize)) 478 | return WD_INVALIDDATA; 479 | 480 | memset(static_cast(pMap) + dwDataOffset, 0, dwDataSize); 481 | } 482 | 483 | // check whether the directory has an own section 484 | for(i = 0; i < pNTH->FileHeader.NumberOfSections; i++) 485 | { 486 | if(pSH[i].VirtualAddress == dwDataRVA) 487 | { 488 | bOwnSec = true; // i == data section index 489 | break; 490 | } 491 | } 492 | 493 | if(!bOwnSec && !blZerofill) 494 | return WD_NOOWNSECTION; 495 | 496 | //if(blZerofill || bOwnSec) 497 | { 498 | // kill data directory entry 499 | if(IsPE64(pNTH)) 500 | { 501 | IMAGE_NT_HEADERS64 * pNTH64 = reinterpret_cast(pNTH); 502 | pNTH64->OptionalHeader.DataDirectory[bData].VirtualAddress = 0; 503 | pNTH64->OptionalHeader.DataDirectory[bData].Size = 0; 504 | } 505 | else 506 | { 507 | IMAGE_NT_HEADERS32 * pNTH32 = reinterpret_cast(pNTH); 508 | pNTH32->OptionalHeader.DataDirectory[bData].VirtualAddress = 0; 509 | pNTH32->OptionalHeader.DataDirectory[bData].Size = 0; 510 | } 511 | } 512 | //else if(!bOwnSec) 513 | // return WD_NOOWNSECTION; 514 | 515 | if(bOwnSec) // delete section 516 | dwNewFsize = StripSection(pMap, dwFsize, i); 517 | } 518 | __except(EXCEPTION_EXECUTE_HANDLER) 519 | { 520 | // an access violation occurred :( 521 | return WD_ACCESSVIOLATION; 522 | } 523 | 524 | return dwNewFsize; 525 | } 526 | 527 | /* 528 | Return values: 529 | -1 - access violation 530 | -2 - no relocation found 531 | -3 - no own section 532 | -4 - dll characteristics found 533 | -5 - invalid PE file 534 | ...else the new raw size 535 | */ 536 | 537 | DWORD __stdcall WipeReloc(void * pMap, DWORD dwFsize) 538 | { 539 | IMAGE_NT_HEADERS * pNTH; 540 | DWORD RetVal; 541 | 542 | if(!GetNTHeader(pMap, dwFsize, 0, &pNTH, 0, 0)) 543 | return WR_INVALIDPE; 544 | 545 | // does the PE have dll characteristics ? 546 | if(pNTH->FileHeader.Characteristics & IMAGE_FILE_DLL) 547 | return WR_NODLL; 548 | 549 | RetVal = WipeData(pMap, dwFsize, IMAGE_DIRECTORY_ENTRY_BASERELOC, false); 550 | if(REALIGNDLLAPI_SUCCESS(RetVal)) 551 | pNTH->FileHeader.Characteristics |= IMAGE_FILE_RELOCS_STRIPPED; 552 | return RetVal; 553 | } 554 | 555 | // Code taken from WineHQ 556 | bool __stdcall FixChecksum(void * pMap, DWORD dwFsize) 557 | { 558 | IMAGE_NT_HEADERS * pNTH; 559 | DWORD dwCalcSum = 0; 560 | WORD * pW; 561 | unsigned int nWordCount; 562 | 563 | if(!GetNTHeader(pMap, dwFsize, NULL, &pNTH, NULL, NULL)) 564 | return false; 565 | 566 | // don't include the old checksum in the new one 567 | pNTH->OptionalHeader.CheckSum = 0; 568 | 569 | nWordCount = (dwFsize+1)/sizeof(WORD); 570 | 571 | pW = static_cast(pMap); 572 | for(unsigned int i = 0; i < nWordCount; i++) 573 | { 574 | dwCalcSum += *pW++; 575 | if(HIWORD(dwCalcSum) != 0) 576 | dwCalcSum = LOWORD(dwCalcSum) + HIWORD(dwCalcSum); 577 | } 578 | dwCalcSum = LOWORD((LOWORD(dwCalcSum) + HIWORD(dwCalcSum))); 579 | 580 | // add file length 581 | dwCalcSum += dwFsize; 582 | 583 | pNTH->OptionalHeader.CheckSum = dwCalcSum; 584 | 585 | return true; 586 | } 587 | 588 | bool __stdcall ValidatePE(void * pMap, DWORD dwFsize) 589 | { 590 | IMAGE_NT_HEADERS * pNTH; 591 | IMAGE_SECTION_HEADER * pSH; 592 | DWORD TempVal; 593 | 594 | if(!GetNTHeader(pMap, dwFsize, NULL, &pNTH, &pSH, NULL)) 595 | return false; 596 | 597 | pNTH->OptionalHeader.SizeOfHeaders = AlignUp((SizeOfPEHeader(pNTH) + static_cast(pMap)->e_lfanew), pNTH->OptionalHeader.FileAlignment); 598 | 599 | // align rawoffsets and sizes 600 | for(int i = 0; i < pNTH->FileHeader.NumberOfSections; i++) 601 | { 602 | TempVal = AlignDown(pSH[i].PointerToRawData, FILEALIGNMENT_DOWN); 603 | if(TempVal != 0) // make sure we don't round down to 0 604 | pSH[i].PointerToRawData = TempVal; 605 | if(pSH[i].PointerToRawData >= dwFsize) // invalid raw offset 606 | pSH[i].PointerToRawData = pSH[i].SizeOfRawData = 0; 607 | // adjust raw size 608 | pSH[i].SizeOfRawData = AlignUp(pSH[i].SizeOfRawData, pNTH->OptionalHeader.FileAlignment); 609 | if((TempVal + pSH[i].SizeOfRawData) > dwFsize) 610 | pSH[i].SizeOfRawData = dwFsize - TempVal; 611 | } 612 | 613 | // fix section VSizes and SizeOfImage 614 | FixVSizes(pNTH); 615 | 616 | return true; 617 | } 618 | 619 | /* 620 | DWORD RebuildResDir(void * pMap, DWORD dwFsize) 621 | { 622 | IMAGE_NT_HEADERS * pNTH; 623 | IMAGE_RESOURCE_DIRECTORY * pResDir; 624 | DWORD dwResRVA; 625 | 626 | if(!GetNTHeader(pMap, dwFsize, NULL, &pNTH, NULL, NULL)) 627 | return RR_INVALIDPE; 628 | 629 | dwResRVA = HDR3264(pNTH, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); 630 | if(!dwResRVA) 631 | return RR_NORESDIR; 632 | 633 | pResDir = (IMAGE_RESOURCE_DIRECTORY *)((ULONG_PTR)pMap + RVAToOffset(dwResRVA, pMap)); 634 | if((void *)pResDir == pMap) 635 | return RR_INVALIDDATA; 636 | } 637 | */ 638 | -------------------------------------------------------------------------------- /realign.def: -------------------------------------------------------------------------------- 1 | LIBRARY realign 2 | EXPORTS 3 | MapFile 4 | UnmapFile 5 | TruncateFile 6 | RealignPE 7 | RealignPEEx 8 | ReBasePEImage 9 | ReBasePEImageEx 10 | WipeReloc 11 | WipeData 12 | FixChecksum 13 | ValidatePE 14 | -------------------------------------------------------------------------------- /realign.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | 4 | Realign.h 5 | --------- 6 | 7 | for version: 1.6 8 | 9 | Include file for Realign.dll. 10 | 11 | by yoda 12 | 13 | *****************************************************************************/ 14 | 15 | #ifndef __Realign_h__ 16 | #define __Realign_h__ 17 | 18 | // Macro to check the success of RealignPE[Ex] and WipeData [WipeReloc] 19 | #define REALIGNDLLAPI_SUCCESS(RetValue) ((signed long)RetValue > 4) 20 | //#define REALIGNDLLAPI_SUCCESS(RetValue) (RetValue < 0xF0000000 && RetValue > 30) 21 | 22 | enum RealignMode : BYTE 23 | { 24 | REALIGN_MODE_NORMAL = 0, 25 | REALIGN_MODE_HARDCORE = 1, 26 | REALIGN_MODE_NICE = 2 27 | }; 28 | 29 | enum RealignError : signed long 30 | { 31 | // RealignPE[Ex] 32 | RA_ACCESSVIOLATION = 0, 33 | RA_INVALIDPARAM = 1, 34 | RA_INVALIDPE = 2, 35 | RA_TOOMANYSECTIONS = 3, 36 | RA_OUTOFMEMORY = 4, 37 | //ReBasePEImage[Ex] 38 | RB_OK = 0, 39 | RB_INVALIDPE = 1, 40 | RB_NORELOCATIONINFO = 2, 41 | RB_INVALIDRVA = 3, 42 | RB_INVALIDNEWBASE = 4, 43 | RB_ACCESSVIOLATION = 5, 44 | // WipeData 45 | WD_ACCESSVIOLATION = -1, 46 | WD_NODATA = -2, 47 | WD_NOOWNSECTION = -3, 48 | WD_INVALIDPE = -4, 49 | WD_INVALIDDATA = -5, 50 | // WipeReloc 51 | WR_ACCESSVIOLATION = -1, 52 | WR_NODATA = -2, 53 | WR_NOOWNSECTION = -3, 54 | WR_NODLL = -4, 55 | WR_INVALIDPE = -5, 56 | // RebuildResDir 57 | RR_INVALIDPE = 0, 58 | RR_NORESDIR = 1, 59 | RR_INVALIDDATA = 2 60 | }; 61 | 62 | /* 63 | // RealignPE[Ex] realign modes 64 | #define REALIGN_MODE_NORMAL 0 65 | #define REALIGN_MODE_HARDCORE 1 66 | #define REALIGN_MODE_NICE 2 67 | 68 | // RealignPE[Ex] return values 69 | #define RA_ACCESSVIOLATION 0 70 | #define RA_INVALIDPARAM 1 71 | #define RA_INVALIDPE 2 72 | #define RA_TOOMANYSECTIONS 3 73 | #define RA_OUTOFMEMORY 4 74 | // ReBasePEImage[Ex] return values 75 | #define RB_OK 0 76 | #define RB_INVALIDPE 1 77 | #define RB_NORELOCATIONINFO 2 78 | #define RB_INVALIDRVA 3 79 | #define RB_INVALIDNEWBASE 4 80 | #define RB_ACCESSVIOLATION 5 81 | // WipeData return values 82 | #define WD_ACCESSVIOLATION -1 83 | #define WD_NODATA -2 84 | #define WD_NOOWNSECTION -3 85 | #define WD_INVALIDPE -4 86 | #define WD_INVALIDDATA -5 87 | // WipeReloc return values 88 | #define WR_ACCESSVIOLATION -1 89 | #define WR_NODATA -2 90 | #define WR_NOOWNSECTION -3 91 | #define WR_NODLL -4 92 | #define WR_INVALIDPE -5 93 | // RebuildResDir return values 94 | #define RR_INVALIDPE 0 95 | #define RR_NORESDIR 1 96 | #define RR_INVALIDDATA 2 97 | */ 98 | 99 | #ifndef __cplusplus 100 | typedef unsigned char bool; 101 | const bool true = 1; 102 | const bool false = 0; 103 | #endif 104 | 105 | // function prototypes 106 | #ifdef __cplusplus 107 | extern "C" 108 | { 109 | #endif 110 | 111 | void * __stdcall MapFile(const char * szFilePath, DWORD * pdwFsize); 112 | bool __stdcall UnmapFile(const char * szFilePath, void * pMap, DWORD dwFsize); 113 | bool __stdcall TruncateFile(const char * szFilePath, DWORD dwNewFsize); 114 | DWORD __stdcall RealignPE(void * pMap, DWORD dwFsize, BYTE bRealignMode); 115 | DWORD __stdcall RealignPEEx(void * pMap, DWORD dwFsize, BYTE bRealignMode, WORD wNewAlign, bool blAlignRawsizes, bool blStripEmptySections); 116 | DWORD __stdcall ReBasePEImage(void * pMap, DWORD dwNewBase); 117 | DWORD __stdcall ReBasePEImageEx(void * pMap, DWORD dwFsize, ULONGLONG ulNewBase); 118 | DWORD __stdcall WipeData(void * pMap, DWORD dwFsize, BYTE bData, bool blZerofill); 119 | DWORD __stdcall WipeReloc(void * pMap, DWORD dwFsize); 120 | bool __stdcall FixChecksum(void * pMap, DWORD dwFsize); 121 | bool __stdcall ValidatePE(void * pMap, DWORD dwFsize); 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif // __Realign_h__ 128 | -------------------------------------------------------------------------------- /realign.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "realign", "realign.vcxproj", "{8F4EC250-65F1-4596-816B-15AAE279E6A4}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Debug|Win32.Build.0 = Debug|Win32 16 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Debug|x64.ActiveCfg = Debug|x64 17 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Debug|x64.Build.0 = Debug|x64 18 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Release|Win32.ActiveCfg = Release|Win32 19 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Release|Win32.Build.0 = Release|Win32 20 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Release|x64.ActiveCfg = Release|x64 21 | {8F4EC250-65F1-4596-816B-15AAE279E6A4}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /realign.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {8F4EC250-65F1-4596-816B-15AAE279E6A4} 23 | realign 24 | Win32Proj 25 | realign 26 | 27 | 28 | 29 | DynamicLibrary 30 | MultiByte 31 | true 32 | 33 | 34 | DynamicLibrary 35 | MultiByte 36 | 37 | 38 | DynamicLibrary 39 | MultiByte 40 | true 41 | 42 | 43 | DynamicLibrary 44 | MultiByte 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | <_ProjectFileVersion>10.0.30319.1 64 | $(SolutionDir)$(Configuration)\$(Platform)\ 65 | $(SolutionDir)$(Configuration)\$(Platform)\ 66 | true 67 | $(SolutionDir)$(Configuration)\$(Platform)\ 68 | $(SolutionDir)$(Configuration)\$(Platform)\ 69 | true 70 | $(SolutionDir)$(Configuration)\$(Platform)\ 71 | $(SolutionDir)$(Configuration)\$(Platform)\ 72 | false 73 | $(SolutionDir)$(Configuration)\$(Platform)\ 74 | $(SolutionDir)$(Configuration)\$(Platform)\ 75 | false 76 | AllRules.ruleset 77 | 78 | 79 | AllRules.ruleset 80 | 81 | 82 | AllRules.ruleset 83 | 84 | 85 | AllRules.ruleset 86 | 87 | 88 | 89 | 90 | 91 | Disabled 92 | WIN32;_DEBUG;_WINDOWS;_USRDLL;REALIGN_EXPORTS;%(PreprocessorDefinitions) 93 | true 94 | EnableFastChecks 95 | MultiThreadedDebugDLL 96 | 97 | 98 | Level3 99 | EditAndContinue 100 | 101 | 102 | $(OutDir)$(TargetName).dll 103 | true 104 | Windows 105 | false 106 | 107 | 108 | MachineX86 109 | realign.def 110 | 111 | 112 | 113 | 114 | X64 115 | 116 | 117 | Disabled 118 | WIN32;_DEBUG;_WINDOWS;_USRDLL;REALIGN_EXPORTS;%(PreprocessorDefinitions) 119 | true 120 | EnableFastChecks 121 | MultiThreadedDebugDLL 122 | Use 123 | Level3 124 | ProgramDatabase 125 | 126 | 127 | $(OutDir)$(TargetName).dll 128 | true 129 | Windows 130 | false 131 | 132 | 133 | MachineX64 134 | realign.def 135 | 136 | 137 | 138 | 139 | MinSpace 140 | false 141 | Size 142 | WIN32;NDEBUG;_WINDOWS;_USRDLL;REALIGN_EXPORTS;%(PreprocessorDefinitions) 143 | true 144 | Sync 145 | MultiThreadedDLL 146 | false 147 | false 148 | 149 | 150 | Level3 151 | ProgramDatabase 152 | CompileAsCpp 153 | 154 | 155 | 0x0409 156 | 157 | 158 | $(OutDir)$(TargetName).dll 159 | false 160 | realign.def 161 | false 162 | Windows 163 | true 164 | true 165 | 166 | 167 | 168 | 169 | false 170 | 171 | 172 | 173 | 174 | MachineX86 175 | 176 | 177 | 178 | 179 | X64 180 | 181 | 182 | MinSpace 183 | false 184 | Size 185 | WIN32;NDEBUG;_WINDOWS;_USRDLL;REALIGN_EXPORTS;%(PreprocessorDefinitions) 186 | true 187 | Sync 188 | MultiThreadedDLL 189 | false 190 | false 191 | 192 | 193 | Level3 194 | 195 | 196 | 197 | 198 | 0x0409 199 | 200 | 201 | $(OutDir)$(TargetName).dll 202 | false 203 | realign.def 204 | false 205 | Windows 206 | true 207 | true 208 | 209 | 210 | 211 | 212 | false 213 | 214 | 215 | 216 | 217 | MachineX64 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /realign.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | 37 | 38 | Resource Files 39 | 40 | 41 | 42 | 43 | Source Files 44 | 45 | 46 | -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by rsrc.rc 4 | // 5 | 6 | // Next default values for new objects 7 | // 8 | #ifdef APSTUDIO_INVOKED 9 | #ifndef APSTUDIO_READONLY_SYMBOLS 10 | #define _APS_NO_MFC 1 11 | #define _APS_NEXT_RESOURCE_VALUE 101 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /rsrc.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pezcode/realign/6d524a868ae1e98b5bfcd78b89b7c6b3e57fa27a/rsrc.rc --------------------------------------------------------------------------------