├── bin └── DLLPackager.exe ├── doc ├── compile.txt ├── exe.after.png ├── exe.before.png ├── loader.txt └── main.txt ├── gpl.txt ├── readme.md └── src ├── defines.h ├── loader.cpp ├── loader.h ├── main.cpp ├── res.rc └── resource.h /bin/DLLPackager.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwfpl/rewolf-dllpackager/45e47d4fbb65b4dc2eeef51965c235b58c505621/bin/DLLPackager.exe -------------------------------------------------------------------------------- /doc/compile.txt: -------------------------------------------------------------------------------- 1 | Add all files from src directory to project. 2 | Set these options in Visual Studio: 3 | (tested on VS2k5) 4 | 5 | General: 6 | Character Set: Not Set 7 | 8 | C/C++: 9 | Optimization: 10 | Inline Function Expansion: Only __inline (/Ob1) 11 | 12 | Code Generation: 13 | Buffer Security Check: No (/GS-) 14 | 15 | 16 | -------------------------------------------------------------------------------- /doc/exe.after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwfpl/rewolf-dllpackager/45e47d4fbb65b4dc2eeef51965c235b58c505621/doc/exe.after.png -------------------------------------------------------------------------------- /doc/exe.before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwfpl/rewolf-dllpackager/45e47d4fbb65b4dc2eeef51965c235b58c505621/doc/exe.before.png -------------------------------------------------------------------------------- /doc/loader.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | Relocatable helper functions: 3 | 4 | - ldrMemMove 5 | - ldrStrLen 6 | - ldrUpperCase 7 | - ldrStrCmp 8 | 9 | -------------------------------------------------------------------------------- 10 | Address retrievers: 11 | 12 | - ldrGetDllStructAddress - returns the address of DLLs structure, DLL structure 13 | looks like this: 14 | 15 | DWORD fileSize; // raw size of DLL, filled during packaging 16 | DWORD loadedImageBase; // image base, filled by loader 17 | BYTE* dllOffset; // virtual address of DLL in executable 18 | DWORD lenFilename; // length of fileName 19 | BYTE fileName[lenFilename]; // file name 20 | 21 | - ldrGetRemovedImportsAddress - returns the address of imports descriptors 22 | removed from original executable 23 | - ldrGetFunctionsTable - returns the address of Functions Table. Function Table 24 | looks like this: 25 | 26 | DWORD LoadLibraryA; // LoadLibraryA function address, filled by 27 | // loader, copied from IAT 28 | DWORD GetProcAddress; // -"- 29 | DWORD VirtualAlloc; // function address, filled by loader 30 | // (GetProcAddress) 31 | DWORD emuGetProcAddress; // GetPrcAddress emulation function address, 32 | // filled during compilation 33 | DWORD emuLoadLibraryA; // -"- 34 | DWORD emuGetModuleHandleA; // -"- 35 | DWORD GetModuleHandleA; // function address, filled by loader 36 | // (GetProcAddress) 37 | DWORD thunkLoadLibraryA; // +ImageBase, address of address in IAT, 38 | // filled during compilation 39 | DWORD thunkGetProcAddress; // -"- 40 | DWORD oldLLANamePtr; // +ImageBase, will be explained later 41 | DWORD oldGPANamePtr; // -"- 42 | DWORD originalEntryPoint 43 | char xchgLLABuf[13]; // will be explained later 44 | char xchgGPABuf[15]; // -"- 45 | 46 | -------------------------------------------------------------------------------- 47 | Text retrievers: 48 | 49 | - ldrGetGetProcAddressText 50 | - ldrGetLoadLibraryAText 51 | - ldrGetGetModuleHandleText 52 | - ldrGetKernel32Text 53 | - ldrGetVirtualAllocText 54 | 55 | all functions from this group look like this: 56 | 57 | call _txt 58 | db 'some text',0 59 | _txt: 60 | pop eax 61 | ret 62 | 63 | it's the simplest way to retrieve const char*, and it's relocatable. 64 | 65 | -------------------------------------------------------------------------------- 66 | APIs proxy: 67 | 68 | - ldrVirtualAlloc 69 | - ldrLoadLibraryA 70 | - ldrGetProcAddress 71 | - ldrGetModuleHandleA 72 | 73 | functions from this group look like this: 74 | 75 | call $+5 76 | pop edx 77 | call ldrGetFunctionsTable 78 | add eax, 4*XX ; XX - index in Functions Table 79 | sub edx, 5 80 | mov word ptr [edx], 0x25FF 81 | mov dword ptr [edx+2], eax 82 | jmp edx 83 | 84 | this function on first hit will get address of API from Functions Table, and 85 | next it will set: 86 | 87 | jmp dword ptr [address in Functions Table] 88 | 89 | on the beginning of the function. 90 | -------------------------------------------------------------------------------- 91 | Emulators: 92 | 93 | - emuLoadLibraryA 94 | - emuGetProcAddress 95 | - emuGetModuleHandleA 96 | 97 | functions commented in source code 98 | 99 | -------------------------------------------------------------------------------- 100 | Others: 101 | 102 | - ldrMain - main loader function, entry point of bundled executable. 103 | - dummy - dummy function to count loader size 104 | 105 | -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /doc/main.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | Helper functions: 3 | 4 | - rva2raw - converts RVA to raw offset 5 | - VirtualReAlloc - reallocates virtual memory 6 | - DialogProc - dialog proc 7 | - WinMain - main 8 | 9 | -------------------------------------------------------------------------------- 10 | Packaging functions: 11 | 12 | - genDllStruct - generates DLL structure 13 | - Bundle - main packaging functions, comments in source code 14 | 15 | -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /gpl.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ``` 2 | -------------------------------------------------------------------------------- 3 | Name....: DLLPackager v1.0.1 - source code 4 | Author..: ReWolf 5 | Date....: XI.2006 6 | Rel.Date: VI.2007 7 | 8 | 9 | e.mail..: rewolf@poczta.onet.pl 10 | www.....: http://blog.rewolf.pl 11 | -------------------------------------------------------------------------------- 12 | ``` 13 | Simple tool to bundle DLL's with executable (similar to PEBundle or MoleBox). 'Simple' means there is no encryption or compression. It's coded fully in C++ (also loader). 14 | 15 | #### **Principle of operation:** #### 16 | ![http://rewolf.pl/gfx/custom/exe_before.png](http://rewolf.pl/gfx/custom/exe_before.png) 17 | ![http://rewolf.pl/gfx/custom/exe_after.png](http://rewolf.pl/gfx/custom/exe_after.png) 18 | 19 | ``` 20 | -------------------------------------------------------------------------------- 21 | Files: 22 | 23 | gpl.txt - GNU GPL license text 24 | bin\DLLPackager.exe - compiled executable 25 | doc\exe.after.png - diagram - represents executable after packagging 26 | doc\exe.before.png - diagram - represents executable before packagging 27 | doc\compile.txt - instructions for compiler setup 28 | doc\loader.txt - comments for src\loader.cpp 29 | doc\main.txt - comments for src\main.cpp 30 | src\loader.cpp - loader source code 31 | src\main.cpp - main app source code 32 | src\defines.h - macros definitios 33 | src\loader.h - header file for loader.cpp 34 | src\resource.h - resources header 35 | src\res.rc - resources file 36 | 37 | -------------------------------------------------------------------------------- 38 | ``` 39 | #### **Related links:** #### 40 | * http://blog.rewolf.pl/blog/?p=11 41 | * http://blog.rewolf.pl/blog/?p=18 42 | -------------------------------------------------------------------------------- /src/defines.h: -------------------------------------------------------------------------------- 1 | /* DLLPackager v1.0 2 | * Copyright 2007 ReWolf 3 | * Contact: 4 | * rewolf@poczta.onet.pl 5 | * http://rewolf.pl 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #define TRUNC(a, b) (a + (b - ((a % b) ? (a % b) : b))) 23 | //#define TEST -------------------------------------------------------------------------------- /src/loader.cpp: -------------------------------------------------------------------------------- 1 | /* DLLPackager v1.0 2 | * Copyright 2007 ReWolf 3 | * Contact: 4 | * rewolf@poczta.onet.pl 5 | * http://rewolf.pl 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | 23 | #include 24 | #include "defines.h" 25 | 26 | void CALLBACK ldrMemMove(BYTE* dest, BYTE* src, int size) 27 | { 28 | for (int i = 0; i < size; i++) dest[i] = src[i]; 29 | } 30 | 31 | DWORD CALLBACK ldrStrLen(char* str) 32 | { 33 | int len = 0; 34 | while (str[len]) len++; 35 | return len; 36 | } 37 | 38 | char* CALLBACK ldrUpperCase(char* str) 39 | { 40 | int i = 0; 41 | while (str[i]) 42 | { 43 | if ((str[i] >= 'a') && (str[i] <= 'z')) str[i] -= 0x20; 44 | i++; 45 | } 46 | return str; 47 | } 48 | 49 | int CALLBACK ldrStrCmp(char* str1, char* str2) 50 | { 51 | DWORD len1 = ldrStrLen(str1); 52 | DWORD len2 = ldrStrLen(str2); 53 | 54 | //if (len1 != len2) return -1; 55 | 56 | char* strMin = (len1 < len2) ? str1 : str2; 57 | 58 | int i = 0; 59 | while (strMin[i]) 60 | { 61 | if (str1[i] < str2[i]) return -1; 62 | if (str1[i] > str2[i]) return 1; 63 | i++; 64 | } 65 | 66 | if (len1 < len2) return -1; 67 | else if (len1 == len2) return 0; 68 | else return 1; 69 | } 70 | 71 | __declspec(naked) BYTE* ldrGetDllStructAddress() 72 | { 73 | __asm 74 | { 75 | mov eax, 0x12345678 76 | ret 77 | } 78 | } 79 | 80 | __declspec(naked) IMAGE_IMPORT_DESCRIPTOR* ldrGetRemovedImportsAddress() 81 | { 82 | __asm 83 | { 84 | mov eax, 0x90ABCDEF 85 | ret 86 | } 87 | } 88 | 89 | __declspec(naked) DWORD* ldrGetFunctionsTable() 90 | { 91 | __asm 92 | { 93 | mov eax, 0x87654321 94 | ret 95 | } 96 | } 97 | 98 | __declspec(naked) char* ldrGetGetProcAddressText() 99 | { 100 | __asm 101 | { 102 | call _n 103 | _emit 'G' 104 | _emit 'e' 105 | _emit 't' 106 | _emit 'P' 107 | _emit 'r' 108 | _emit 'o' 109 | _emit 'c' 110 | _emit 'A' 111 | _emit 'd' 112 | _emit 'd' 113 | _emit 'r' 114 | _emit 'e' 115 | _emit 's' 116 | _emit 's' 117 | _emit 0 118 | _n: 119 | pop eax 120 | ret 121 | } 122 | } 123 | 124 | __declspec(naked) char* ldrGetLoadLibraryAText() 125 | { 126 | __asm 127 | { 128 | call _n 129 | _emit 'L' 130 | _emit 'o' 131 | _emit 'a' 132 | _emit 'd' 133 | _emit 'L' 134 | _emit 'i' 135 | _emit 'b' 136 | _emit 'r' 137 | _emit 'a' 138 | _emit 'r' 139 | _emit 'y' 140 | _emit 'A' 141 | _emit 0 142 | _n: 143 | pop eax 144 | ret 145 | } 146 | } 147 | 148 | __declspec(naked) char* ldrGetGetModuleHandleText() 149 | { 150 | __asm 151 | { 152 | call _n 153 | _emit 'G' 154 | _emit 'e' 155 | _emit 't' 156 | _emit 'M' 157 | _emit 'o' 158 | _emit 'd' 159 | _emit 'u' 160 | _emit 'l' 161 | _emit 'e' 162 | _emit 'H' 163 | _emit 'a' 164 | _emit 'n' 165 | _emit 'd' 166 | _emit 'l' 167 | _emit 'e' 168 | _emit 'A' 169 | _emit 0 170 | _n: 171 | pop eax 172 | ret 173 | } 174 | } 175 | 176 | __declspec(naked) char* ldrGetKernel32Text() 177 | { 178 | __asm 179 | { 180 | call _n 181 | _emit 'K' 182 | _emit 'E' 183 | _emit 'R' 184 | _emit 'N' 185 | _emit 'E' 186 | _emit 'L' 187 | _emit '3' 188 | _emit '2' 189 | _emit '.' 190 | _emit 'D' 191 | _emit 'L' 192 | _emit 'L' 193 | _emit 0 194 | _n: 195 | pop eax 196 | ret 197 | } 198 | } 199 | 200 | __declspec(naked) char* ldrGetVirtualAllocText() 201 | { 202 | __asm 203 | { 204 | call _n 205 | _emit 'V' 206 | _emit 'i' 207 | _emit 'r' 208 | _emit 't' 209 | _emit 'u' 210 | _emit 'a' 211 | _emit 'l' 212 | _emit 'A' 213 | _emit 'l' 214 | _emit 'l' 215 | _emit 'o' 216 | _emit 'c' 217 | _emit 0 218 | _n: 219 | pop eax 220 | ret 221 | } 222 | } 223 | 224 | #ifdef TEST 225 | #define ldrVirtualAlloc VirtualAlloc 226 | #define ldrLoadLibraryA LoadLibraryA 227 | #define ldrGetProcAddress GetProcAddress 228 | #define ldrGetModuleHandleA GetModuleHandleA 229 | #else 230 | __declspec(naked) LPVOID CALLBACK ldrVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) 231 | { 232 | __asm 233 | { 234 | call $+5 235 | pop edx 236 | call ldrGetFunctionsTable 237 | add eax, 8 238 | sub edx, 5 239 | mov word ptr [edx], 0x25FF 240 | mov dword ptr [edx+2], eax 241 | jmp edx 242 | } 243 | } 244 | __declspec(naked) HMODULE CALLBACK ldrLoadLibraryA(LPCTSTR lpFileName) 245 | { 246 | __asm 247 | { 248 | call $+5 249 | pop edx 250 | call ldrGetFunctionsTable 251 | sub edx, 5 252 | mov word ptr [edx], 0x25FF 253 | mov dword ptr [edx+2], eax 254 | jmp edx 255 | } 256 | } 257 | 258 | __declspec(naked) HMODULE CALLBACK ldrGetProcAddress(HMODULE hModule, LPCSTR lpProcName) 259 | { 260 | __asm 261 | { 262 | call $+5 263 | pop edx 264 | call ldrGetFunctionsTable 265 | add eax, 4 266 | sub edx, 5 267 | mov word ptr [edx], 0x25FF 268 | mov dword ptr [edx+2], eax 269 | jmp edx 270 | } 271 | } 272 | 273 | __declspec(naked) HMODULE CALLBACK ldrGetModuleHandleA(LPCSTR lpModuleName) 274 | { 275 | __asm 276 | { 277 | call $+5 278 | pop edx 279 | call ldrGetFunctionsTable 280 | add eax, 6*4 281 | sub edx, 5 282 | mov word ptr [edx], 0x25FF 283 | mov dword ptr [edx+2], eax 284 | jmp edx 285 | } 286 | } 287 | #endif 288 | 289 | HMODULE CALLBACK emuLoadLibraryA(char* fileName); 290 | 291 | LPVOID CALLBACK emuGetProcAddress(HMODULE hModule, LPCSTR lpProcname) 292 | { 293 | //check if lpProcname is emulated 294 | DWORD* ldrFuncTab = ldrGetFunctionsTable(); 295 | 296 | if ((DWORD)lpProcname & 0xFFFF0000) 297 | { 298 | char* funcName = ldrGetGetProcAddressText(); 299 | if (!ldrStrCmp((char*)lpProcname, funcName)) return (LPVOID)ldrFuncTab[3]; 300 | 301 | funcName = ldrGetLoadLibraryAText(); 302 | if (!ldrStrCmp((char*)lpProcname, funcName)) return (LPVOID)ldrFuncTab[4]; 303 | 304 | funcName = ldrGetGetModuleHandleText(); 305 | if (!ldrStrCmp((char*)lpProcname, funcName)) return (LPVOID)ldrFuncTab[5]; 306 | } 307 | 308 | //check if hModule is base of bundled DLL 309 | BYTE* dllStructAddr = ldrGetDllStructAddress(); 310 | 311 | bool found = false; 312 | while ((*(DWORD*)dllStructAddr) && !found) 313 | { 314 | if (((DWORD*)dllStructAddr)[1] == (DWORD)hModule) found = true; 315 | else dllStructAddr += ((DWORD*)dllStructAddr)[3] + 0x10 + 1; 316 | } 317 | 318 | //if not call original GetProcAddress 319 | if (!found) return ldrGetProcAddress(hModule, lpProcname); 320 | 321 | //else dllStructAddr points to strcuture that describe bundled DLL 322 | 323 | //setting pointers to standard PE structures 324 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)(((DWORD*)dllStructAddr)[2]); 325 | IMAGE_NT_HEADERS* inh = (IMAGE_NT_HEADERS*)((BYTE*)((DWORD*)dllStructAddr)[2] + idh->e_lfanew); 326 | //IMAGE_SECTION_HEADER* ish = (IMAGE_SECTION_HEADER*)((BYTE*)((DWORD*)dllStructAddr)[2] + idh->e_lfanew + inh->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4); 327 | 328 | // 329 | IMAGE_EXPORT_DIRECTORY* ied = (IMAGE_EXPORT_DIRECTORY*)((BYTE*)hModule + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 330 | 331 | //searching for lpProcname in export table 332 | LPVOID retVal = 0; 333 | DWORD* funcTab = (DWORD*)((BYTE*)hModule + ied->AddressOfFunctions); 334 | if (!((DWORD)lpProcname & 0xFFFF0000)) 335 | { 336 | //ordinal 337 | if (((DWORD)lpProcname) > ied->NumberOfFunctions + ied->Base) return 0; 338 | retVal = (BYTE*)hModule + funcTab[(DWORD)lpProcname - ied->Base]; 339 | } 340 | else 341 | { 342 | //name 343 | DWORD* namesTab = (DWORD*)((BYTE*)hModule + ied->AddressOfNames); 344 | WORD* ordinalsTab = (WORD*)((BYTE*)hModule + ied->AddressOfNameOrdinals); 345 | 346 | int left = 0; 347 | int right = ied->NumberOfNames - 1; 348 | int current; 349 | while ((left <= right) && !retVal) 350 | { 351 | current = (left + right) / 2; 352 | int cmpVal = ldrStrCmp((char*)hModule + namesTab[current], (char*)lpProcname); 353 | if (cmpVal == 1) right = current; 354 | else if (cmpVal == -1) left = current + 1; 355 | else retVal = (BYTE*)hModule + funcTab[ordinalsTab[current]]; 356 | } 357 | } 358 | 359 | //forwarded exports handling 360 | if (((DWORD)retVal > (DWORD)hModule + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) && 361 | (DWORD)retVal < (DWORD)hModule + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 362 | { 363 | int i = 0; 364 | while (((char*)retVal)[i] != '.') i++; 365 | i++; 366 | DWORD tmp = *(DWORD*)((BYTE*)retVal + i); 367 | *(DWORD*)((BYTE*)retVal + i) = 0x4c4c44; //'DLL',0 368 | 369 | HMODULE tmpLib = emuLoadLibraryA((char*)retVal); 370 | 371 | *(DWORD*)((BYTE*)retVal + i) = tmp; 372 | retVal = emuGetProcAddress(tmpLib, (char*)retVal + i); 373 | } 374 | 375 | return retVal; 376 | } 377 | 378 | HMODULE CALLBACK emuGetModuleHandleA(LPCTSTR lpModuleName) 379 | { 380 | BYTE* dllStructAddr = ldrGetDllStructAddress(); 381 | 382 | if ((DWORD)lpModuleName == 0) return ldrGetModuleHandleA(0); 383 | 384 | int j = ldrStrLen((char*)lpModuleName) - 1; 385 | while ((lpModuleName[j] != '\\') && (j)) j--; 386 | if (j) j++; 387 | ldrUpperCase((char*)lpModuleName + j); 388 | bool found = false; 389 | while ((*(DWORD*)dllStructAddr) && !found) 390 | { 391 | if (!ldrStrCmp((char*)lpModuleName + j, (char*)dllStructAddr + 0x10)) found = true; 392 | else dllStructAddr += ((DWORD*)dllStructAddr)[3] + 0x10 + 1; 393 | } 394 | 395 | if(!found) return ldrGetModuleHandleA((LPCTSTR)lpModuleName); 396 | else return (HMODULE)((DWORD*)dllStructAddr)[1]; 397 | } 398 | 399 | HMODULE CALLBACK emuLoadLibraryA(char* fileName) 400 | { 401 | 402 | BYTE* dllStructAddr = ldrGetDllStructAddress(); 403 | 404 | //check if library is bundled 405 | int j = ldrStrLen(fileName) - 1; 406 | while ((fileName[j] != '\\') && (j)) j--; 407 | if (j) j++; 408 | ldrUpperCase(fileName + j); 409 | bool found = false; 410 | while ((*(DWORD*)dllStructAddr) && !found) 411 | { 412 | if (!ldrStrCmp(fileName + j, (char*)dllStructAddr + 0x10)) found = true; 413 | else dllStructAddr += ((DWORD*)dllStructAddr)[3] + 0x10 + 1; 414 | } 415 | 416 | //if not, call original LoadLibraryA 417 | if(!found) return ldrLoadLibraryA((LPCTSTR)fileName); 418 | 419 | //check if library already loaded 420 | if (((DWORD*)dllStructAddr)[1]) return (HMODULE)((DWORD*)dllStructAddr)[1]; 421 | 422 | //setting pointers to standard PE structures 423 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)(((DWORD*)dllStructAddr)[2]); 424 | IMAGE_NT_HEADERS* inh = (IMAGE_NT_HEADERS*)((BYTE*)((DWORD*)dllStructAddr)[2] + idh->e_lfanew); 425 | IMAGE_SECTION_HEADER* ish = (IMAGE_SECTION_HEADER*)((BYTE*)((DWORD*)dllStructAddr)[2] + idh->e_lfanew + inh->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4); 426 | 427 | //mapping sections to memory 428 | BYTE* newImageBase = (BYTE*)ldrVirtualAlloc((LPVOID)inh->OptionalHeader.ImageBase, inh->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_EXECUTE_READWRITE); 429 | if (!newImageBase) newImageBase = (BYTE*)ldrVirtualAlloc(0, inh->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_EXECUTE_READWRITE); 430 | if (!newImageBase) return 0; 431 | ldrVirtualAlloc(newImageBase, (BYTE*)ish - (BYTE*)idh + inh->FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 432 | ldrMemMove(newImageBase, (BYTE*)((DWORD*)dllStructAddr)[2], TRUNC(((BYTE*)ish - (BYTE*)idh + inh->FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER)), inh->OptionalHeader.FileAlignment)); 433 | for (int i = 0; i < inh->FileHeader.NumberOfSections; i++) 434 | { 435 | ldrVirtualAlloc(newImageBase + ish[i].VirtualAddress, ish[i].Misc.VirtualSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 436 | ldrMemMove(newImageBase + ish[i].VirtualAddress, (BYTE*)((DWORD*)dllStructAddr)[2] + ish[i].PointerToRawData, TRUNC(ish[i].SizeOfRawData, inh->OptionalHeader.FileAlignment)); 437 | } 438 | 439 | //imports 440 | IMAGE_IMPORT_DESCRIPTOR* iid = (IMAGE_IMPORT_DESCRIPTOR*)(newImageBase + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 441 | while (iid->Name) 442 | { 443 | HMODULE hLib = emuLoadLibraryA((char*)newImageBase + iid->Name); 444 | int thunkIndex = 0; 445 | while (((DWORD*)(newImageBase + iid->FirstThunk))[thunkIndex]) 446 | { 447 | if (((DWORD*)(newImageBase + iid->FirstThunk))[thunkIndex] & 0x80000000) 448 | { 449 | //ordinals 450 | ((DWORD*)(newImageBase + iid->FirstThunk))[thunkIndex] = (DWORD)emuGetProcAddress(hLib, (LPCSTR)(((DWORD*)(newImageBase + iid->FirstThunk))[thunkIndex] & 0xFFFF)); 451 | } 452 | else 453 | { 454 | //names 455 | ((DWORD*)(newImageBase + iid->FirstThunk))[thunkIndex] = (DWORD)emuGetProcAddress(hLib, (LPCSTR)newImageBase + ((DWORD*)(newImageBase + iid->FirstThunk))[thunkIndex] + 2); 456 | } 457 | thunkIndex++; 458 | } 459 | iid++; 460 | } 461 | 462 | //relocations 463 | if ((DWORD)newImageBase != inh->OptionalHeader.ImageBase) 464 | { 465 | if (!inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) return 0; 466 | 467 | BYTE* relocPtr = newImageBase + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; 468 | DWORD delta = (DWORD)newImageBase - inh->OptionalHeader.ImageBase; 469 | 470 | while (*(DWORD*)relocPtr) 471 | { 472 | DWORD relocRVA = ((DWORD*)relocPtr)[0]; 473 | DWORD blockSize = ((DWORD*)relocPtr)[1]; 474 | 475 | for (int i = 0; i < (blockSize - 8) / 2; i++) 476 | { 477 | if (((WORD*)(relocPtr + 8))[i] & 0xF000) 478 | { 479 | *(DWORD*)(newImageBase + relocRVA + (((WORD*)(relocPtr + 8))[i] & 0xFFF)) += delta; 480 | } 481 | } 482 | relocPtr += blockSize; 483 | } 484 | } 485 | 486 | ((DWORD*)dllStructAddr)[1] = (DWORD)newImageBase; 487 | 488 | //calling DllMain 489 | if (inh->OptionalHeader.AddressOfEntryPoint) 490 | { 491 | typedef bool (__stdcall *_dllMain)(HANDLE hInstDLL, DWORD dwReason, LPVOID lpvReserved); 492 | _dllMain dllMain = (_dllMain)(newImageBase + inh->OptionalHeader.AddressOfEntryPoint); 493 | if (!dllMain(newImageBase, DLL_PROCESS_ATTACH, 0)) 494 | { 495 | ((DWORD*)dllStructAddr)[1] = 0; 496 | return 0; 497 | } 498 | } 499 | 500 | return (HMODULE)newImageBase; 501 | } 502 | 503 | void CALLBACK ldrMain() 504 | { 505 | DWORD* funcTable = ldrGetFunctionsTable(); 506 | 507 | funcTable[0] = *(DWORD*)funcTable[7]; 508 | funcTable[1] = *(DWORD*)funcTable[8]; 509 | HMODULE kernelHandle = ldrLoadLibraryA((LPCTSTR)ldrGetKernel32Text()); 510 | funcTable[2] = (DWORD)ldrGetProcAddress(kernelHandle, (LPCSTR)ldrGetVirtualAllocText()); 511 | funcTable[6] = (DWORD)ldrGetProcAddress(kernelHandle, (LPCSTR)ldrGetGetModuleHandleText()); 512 | 513 | if (((BYTE*)funcTable + 12*4)[0]) 514 | { 515 | //restore function name exchenged with LoadLibraryA during packaging 516 | ldrMemMove((BYTE*)funcTable[9], (BYTE*)funcTable + 12*4, 13); 517 | *(DWORD*)funcTable[7] = (DWORD)ldrGetProcAddress(kernelHandle, (LPCSTR)funcTable[9]); 518 | } 519 | 520 | if (((BYTE*)funcTable + 12*4 + 13)[0]) 521 | { 522 | //restore function name exchenged with GetProcAddress during packaging 523 | ldrMemMove((BYTE*)funcTable[10], (BYTE*)funcTable + 12*4 + 13, 15); 524 | *(DWORD*)funcTable[8] = (DWORD)ldrGetProcAddress(kernelHandle, (LPCSTR)funcTable[10]); 525 | } 526 | 527 | //filling import table of bundled DLLs 528 | IMAGE_IMPORT_DESCRIPTOR* remImps = ldrGetRemovedImportsAddress(); 529 | HMODULE thisModule = ldrGetModuleHandleA(0); 530 | while (remImps->Name) 531 | { 532 | HMODULE curLib = emuLoadLibraryA((char*)((BYTE*)thisModule + remImps->Name)); 533 | int i = 0; 534 | DWORD* thunks = (DWORD*)((BYTE*)thisModule + remImps->FirstThunk); 535 | while (thunks[i]) 536 | { 537 | if (thunks[i] & 0x80000000) 538 | { 539 | //ordinal 540 | thunks[i] = (DWORD)emuGetProcAddress(curLib, (LPCSTR)(thunks[i] & 0xFFFF)); 541 | } 542 | else 543 | { 544 | //name 545 | thunks[i] = (DWORD)emuGetProcAddress(curLib, (LPCSTR)((BYTE*)thisModule + thunks[i] + 2)); 546 | } 547 | i++; 548 | } 549 | remImps++; 550 | } 551 | 552 | //setting addressess of emulated functions in IAT 553 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)thisModule; 554 | IMAGE_NT_HEADERS* inh = (IMAGE_NT_HEADERS*)((BYTE*)thisModule + idh->e_lfanew); 555 | IMAGE_IMPORT_DESCRIPTOR* origImports = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)thisModule + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 556 | 557 | while (origImports->Name) 558 | { 559 | if (!ldrStrCmp((char*)thisModule + origImports->Name, (char*)ldrGetKernel32Text())) 560 | { 561 | DWORD* thunks = (DWORD*)((BYTE*)thisModule + origImports->FirstThunk); 562 | while (*thunks) 563 | { 564 | if (*thunks == funcTable[0]) *thunks = funcTable[4]; //LoadLibraryA 565 | else if (*thunks == funcTable[1]) *thunks = funcTable[3]; //GetProcAddress 566 | else if (*thunks == funcTable[6]) *thunks = funcTable[5]; //GetModulehandleA 567 | thunks++; 568 | } 569 | } 570 | origImports++; 571 | } 572 | 573 | //jump to original entry point 574 | __asm 575 | { 576 | mov eax, funcTable 577 | add eax, 44 578 | jmp dword ptr [eax] 579 | } 580 | } 581 | 582 | __declspec(naked) void dummy() 583 | { 584 | __asm 585 | { 586 | _emit 'D' 587 | _emit 'L' 588 | _emit 'L' 589 | _emit 'P' 590 | _emit 'a' 591 | _emit 'c' 592 | _emit 'k' 593 | _emit 'a' 594 | _emit 'g' 595 | _emit 'e' 596 | _emit 'r' 597 | } 598 | } 599 | -------------------------------------------------------------------------------- /src/loader.h: -------------------------------------------------------------------------------- 1 | /* DLLPackager v1.0 2 | * Copyright 2007 ReWolf 3 | * Contact: 4 | * rewolf@poczta.onet.pl 5 | * http://rewolf.pl 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | void CALLBACK ldrMemMove(BYTE* dest, BYTE* src, int size); 23 | DWORD CALLBACK ldrStrLen(char* str); 24 | char* CALLBACK ldrUpperCase(char* str); 25 | int CALLBACK ldrStrCmp(char* str1, char* str2); 26 | BYTE* ldrGetDllStructAddress(); 27 | IMAGE_IMPORT_DESCRIPTOR* ldrGetRemovedImportsAddress(); 28 | DWORD* ldrGetFunctionsTable(); 29 | char* ldrGetGetProcAddressText(); 30 | char* ldrGetLoadLibraryAText(); 31 | char* ldrGetGetModuleHandleText(); 32 | char* ldrGetKernel32Text(); 33 | char* ldrGetVirtualAllocText(); 34 | LPVOID CALLBACK ldrVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); 35 | HMODULE CALLBACK ldrLoadLibraryA(LPCTSTR lpFileName); 36 | HMODULE CALLBACK ldrGetProcAddress(HMODULE hModule, LPCSTR lpProcName); 37 | HMODULE CALLBACK ldrGetModuleHandleA(LPCSTR lpModuleName); 38 | LPVOID CALLBACK emuGetProcAddress(HMODULE hModule, LPCSTR lpProcname); 39 | HMODULE CALLBACK emuGetModuleHandleA(LPCTSTR lpModuleName); 40 | HMODULE CALLBACK emuLoadLibraryA(char* fileName); 41 | void CALLBACK ldrMain(); 42 | void dummy(); -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* DLLPackager v1.0 2 | * Copyright 2007 ReWolf 3 | * Contact: 4 | * rewolf@poczta.onet.pl 5 | * http://rewolf.pl 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | /* 23 | * Changes: 24 | * 25 | * rrrr-mm-dd - author 26 | * 2007-06-18 - ReWolf - corrected some problems with LoadLibrary and GetProcAddress 27 | * searching (reported by Gynvael Coldwind) 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include "resource.h" 35 | #include 36 | #include 37 | 38 | #include "defines.h" 39 | #include "loader.h" 40 | 41 | DWORD rva2raw(WORD NumOfSections, IMAGE_SECTION_HEADER* FSH, DWORD rva) 42 | { 43 | for (int i = NumOfSections-1; i >= 0; i--) 44 | if (FSH[i].VirtualAddress <= rva) 45 | return FSH[i].PointerToRawData + rva - FSH[i].VirtualAddress; 46 | return 0xFFFFFFFF; 47 | } 48 | 49 | LPVOID VirtualReAlloc(LPVOID hOldMem, unsigned int OldSize, unsigned int NewSize) 50 | { 51 | LPVOID tmp = VirtualAlloc(0, NewSize, MEM_COMMIT, PAGE_READWRITE); 52 | memmove(tmp, hOldMem, OldSize); 53 | VirtualFree(hOldMem, 0, MEM_RELEASE); 54 | return tmp; 55 | } 56 | 57 | 58 | BYTE* genDllStruct(std::vector& paths, std::vector& names, DWORD baseOffset, DWORD* size) 59 | { 60 | DWORD structSize = 0; 61 | DWORD dllsSize = 0; 62 | std::vector fSizes; 63 | //counting DLLs sizes 64 | for (unsigned int i = 0; i < paths.size(); i++) 65 | { 66 | structSize += 16 + (DWORD)names[i].length() + 1; 67 | HANDLE tmp = CreateFile(paths[i].c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 68 | fSizes.push_back(GetFileSize(tmp, 0)); 69 | CloseHandle(tmp); 70 | dllsSize += fSizes[i]; 71 | } 72 | 73 | //memory allocation for DLL structure 74 | *size = structSize + 4 + dllsSize; 75 | BYTE* retVal = (BYTE*)GlobalAlloc(GMEM_FIXED, *size); 76 | 77 | if (retVal) 78 | { 79 | int current = 0; 80 | int curDlls = 0; 81 | for (unsigned int i = 0; i < paths.size(); i++) 82 | { 83 | //setting values in DLL structure for each DLL 84 | ((DWORD*)(retVal + current))[0] = fSizes[i]; 85 | ((DWORD*)(retVal + current))[1] = 0; 86 | ((DWORD*)(retVal + current))[2] = baseOffset + structSize + 4 + curDlls; 87 | ((DWORD*)(retVal + current))[3] = (DWORD)names[i].length(); 88 | memmove(retVal + current + 16, names[i].c_str(), names[i].length() + 1); 89 | current += 16 + (DWORD)names[i].length() + 1; 90 | 91 | //reading DLL 92 | HANDLE tmp = CreateFile(paths[i].c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 93 | DWORD tmp2; 94 | ReadFile(tmp, retVal + structSize + 4 + curDlls, fSizes[i], &tmp2, 0); 95 | CloseHandle(tmp); 96 | curDlls += fSizes[i]; 97 | } 98 | } 99 | 100 | return retVal; 101 | } 102 | 103 | void Bundle(char* exeName, HWND dllListBoxHandle, HWND logListBoxHandle) 104 | { 105 | #define LOG(a) { int _u_u = (int)SendMessage(logListBoxHandle, LB_ADDSTRING, 0, (LPARAM)a); SendMessage(logListBoxHandle, LB_SETCURSEL, _u_u, 0); } 106 | #define LOGRET(a) { SendMessage(logListBoxHandle, LB_ADDSTRING, 0, (LPARAM)a); return; } 107 | #define LOGRET2(a) { SendMessage(logListBoxHandle, LB_ADDSTRING, 0, (LPARAM)a); VirtualFree(hExeMem, 0, MEM_RELEASE); return; } 108 | #define EXEMEMCHECK(a, b) if (((BYTE*)a < (BYTE*)hExeMem) || ((BYTE*)a > (BYTE*)hExeMem + fileSize)) LOGRET2(b) 109 | 110 | //open and read executable to memory 111 | HANDLE hExeFile = CreateFile(exeName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 112 | if (hExeFile == INVALID_HANDLE_VALUE) LOGRET("Cannot open executable file."); 113 | DWORD fileSize = GetFileSize(hExeFile, 0); 114 | LPVOID hExeMem = VirtualAlloc(0, fileSize, MEM_COMMIT, PAGE_READWRITE); 115 | if (!hExeMem) 116 | { 117 | CloseHandle(hExeFile); 118 | LOG("Memory allocation error."); 119 | } 120 | DWORD tmp; 121 | ReadFile(hExeFile, hExeMem, fileSize, &tmp, 0); 122 | CloseHandle(hExeFile); 123 | 124 | //setting pointers to standard PE structures 125 | //IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)hExeMem; 126 | EXEMEMCHECK(&((IMAGE_DOS_HEADER*)hExeMem)->e_lfanew, "Memory error (e_lfanew)."); 127 | IMAGE_NT_HEADERS* inh = (IMAGE_NT_HEADERS*)((BYTE*)hExeMem + ((IMAGE_DOS_HEADER*)hExeMem)->e_lfanew); 128 | EXEMEMCHECK(&inh->FileHeader.SizeOfOptionalHeader, "Memory error (SizeOfOptionalHeader)."); 129 | IMAGE_SECTION_HEADER* ish = (IMAGE_SECTION_HEADER*)((BYTE*)hExeMem + ((IMAGE_DOS_HEADER*)hExeMem)->e_lfanew + inh->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4); 130 | 131 | //setting writeable attribute to all sections 132 | for (int i = 0; i < inh->FileHeader.NumberOfSections; i++) 133 | { 134 | ish[i].Characteristics |= 0x80000000; 135 | } 136 | 137 | //searching for DLLs in executable imports table 138 | DWORD importsRaw = rva2raw(inh->FileHeader.NumberOfSections, ish, inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 139 | IMAGE_IMPORT_DESCRIPTOR* iidPtr = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hExeMem + importsRaw); 140 | EXEMEMCHECK(iidPtr, "Memory error (importsRaw)."); 141 | 142 | unsigned int libCnt = (unsigned int)SendMessage(dllListBoxHandle, LB_GETCOUNT, 0, 0); 143 | std::vector remIIDVector; 144 | std::vector newIIDVector; 145 | std::vector libsToBundle; 146 | std::vector pathsToLibs; 147 | int curLib = 0; 148 | 149 | // 150 | DWORD thunkLoadLibraryA = 0; 151 | DWORD thunkGetProcAddress = 0; 152 | DWORD oldLLANamePtr = 0; 153 | DWORD oldGPANamePtr = 0; 154 | char xchgLLABuf[13] = {0}; 155 | char xchgGPABuf[15] = {0}; 156 | 157 | while (iidPtr[curLib].Name) 158 | { 159 | DWORD nameRaw = rva2raw(inh->FileHeader.NumberOfSections, ish, iidPtr[curLib].Name); 160 | EXEMEMCHECK((BYTE*)hExeMem + nameRaw, "Memory error (nameRaw)."); 161 | strupr((char*)hExeMem + nameRaw); 162 | 163 | //checking if in imports from kernel32 occuring LoadLibraryA and GetProcAddress 164 | //if not it will change any suitable import name to LoadLibraryA or GetProcAddress 165 | DWORD probLLA = 0; //12 166 | char* xchgLLA; 167 | DWORD probGPA = 0; //14 168 | char* xchgGPA; 169 | if (!strcmp((char*)hExeMem + nameRaw, "KERNEL32.DLL") && !thunkGetProcAddress) 170 | { 171 | DWORD* thunks = (DWORD*)((char*)hExeMem + rva2raw(inh->FileHeader.NumberOfSections, ish, iidPtr[curLib].FirstThunk)); 172 | EXEMEMCHECK(thunks, "Memory error (thunks)."); 173 | int i = 0; 174 | while (thunks[i]) 175 | { 176 | char* curImpName = (char*)hExeMem + rva2raw(inh->FileHeader.NumberOfSections, ish, thunks[i]) + 2; 177 | EXEMEMCHECK(curImpName, "Memory error (curImpName)."); 178 | if (!probGPA && (strlen(curImpName) >= 14)) 179 | { 180 | //if (strlen(curImpName) >= 14) 181 | { 182 | probGPA = iidPtr[curLib].FirstThunk + i*4; 183 | xchgGPA = curImpName; 184 | oldGPANamePtr = thunks[i] + 2; 185 | } 186 | } 187 | else if (!probLLA) 188 | { 189 | if (strlen(curImpName) >= 12) 190 | { 191 | probLLA = iidPtr[curLib].FirstThunk + i*4; 192 | xchgLLA = curImpName; 193 | oldLLANamePtr = thunks[i] + 2; 194 | } 195 | } 196 | 197 | if (!thunkGetProcAddress) 198 | { 199 | if (!strcmp(curImpName, "GetProcAddress")) 200 | { 201 | thunkGetProcAddress = iidPtr[curLib].FirstThunk + i*4; 202 | LOG("GetProcAddress found."); 203 | } 204 | } 205 | if (!thunkLoadLibraryA) 206 | { 207 | if (!strcmp(curImpName, "LoadLibraryA")) 208 | { 209 | thunkLoadLibraryA = iidPtr[curLib].FirstThunk + i*4; 210 | LOG("LoadLibraryA found."); 211 | } 212 | } 213 | i++; 214 | } 215 | char logTmp[256]; 216 | if (!thunkLoadLibraryA) 217 | { 218 | if (!probLLA) LOGRET2("Problem with adding LoadLibraryA."); 219 | memmove(xchgLLABuf, xchgLLA, 13); 220 | sprintf(logTmp, "Changing %s to LoadLibraryA.", xchgLLA); 221 | memmove(xchgLLA, "LoadLibraryA", 13); 222 | thunkLoadLibraryA = probLLA; 223 | LOG(logTmp); 224 | } 225 | if (!thunkGetProcAddress) 226 | { 227 | if (!probGPA) LOGRET2("Problem with adding GetProcAddress."); 228 | memmove(xchgGPABuf, xchgGPA, 15); 229 | sprintf(logTmp, "Changing %s to GetProcAddress.", xchgGPA); 230 | memmove(xchgGPA, "GetProcAddress", 15); 231 | thunkGetProcAddress = probGPA; 232 | LOG(logTmp); 233 | } 234 | } 235 | 236 | bool ifExist = false; 237 | 238 | for (unsigned int i = 0; i < libCnt; i++) 239 | { 240 | char libName[256]; 241 | SendMessage(dllListBoxHandle, LB_GETTEXT, i, (LPARAM)libName); 242 | 243 | int j = (int)strlen(libName) - 1; 244 | while ((libName[j] != '\\') && (j)) j--; 245 | if (j) j++; 246 | strupr(libName + j); 247 | 248 | if (libsToBundle.size() < libCnt) 249 | { 250 | if (i >= libsToBundle.size()) 251 | { 252 | libsToBundle.push_back(libName + j); 253 | LOG(libName + j); 254 | pathsToLibs.push_back(libName); 255 | } 256 | } 257 | 258 | 259 | if (!strcmp(libName + j, (char*)hExeMem + nameRaw)) 260 | { 261 | char logTmp[100]; 262 | sprintf(logTmp, "Removing %s from original import table.", libName + j); 263 | LOG(logTmp); 264 | remIIDVector.push_back(iidPtr[curLib]); 265 | ifExist = true; 266 | break; 267 | } 268 | } 269 | if (!ifExist) newIIDVector.push_back(iidPtr[curLib]); 270 | curLib++; 271 | } 272 | 273 | for (unsigned int i = 0; i < newIIDVector.size(); i++) memmove(&iidPtr[i], &newIIDVector[i], sizeof(IMAGE_IMPORT_DESCRIPTOR)); 274 | memset(&iidPtr[newIIDVector.size()], 0, sizeof(IMAGE_IMPORT_DESCRIPTOR)); 275 | 276 | char logTmp[256]; 277 | 278 | //calculating address (virtual and raw) of new section 279 | DWORD newSectionRawOff = ish[inh->FileHeader.NumberOfSections - 1].PointerToRawData + TRUNC(ish[inh->FileHeader.NumberOfSections - 1].SizeOfRawData, inh->OptionalHeader.FileAlignment); 280 | DWORD newSectionRVA = inh->OptionalHeader.SizeOfImage; 281 | 282 | DWORD ldrCodeSize = (DWORD)((BYTE*)dummy - (BYTE*)ldrMemMove); 283 | sprintf(logTmp, "Size of appended code: %d", ldrCodeSize); 284 | LOG(logTmp); 285 | #define LDRDATASIZE 76 286 | /* 287 | DWORD LoadLibraryA; // 288 | DWORD GetProcAddress; // 289 | DWORD VirtualAlloc; // 290 | DWORD emuGetProcAddress; // 291 | DWORD emuLoadLibraryA; // 292 | DWORD emuGetModuleHandleA; // look in loader.txt for details 293 | DWORD GetModuleHandleA; // 294 | DWORD thunkLoadLibraryA; // 295 | DWORD thunkGetProcAddress; // 296 | DWORD oldLLANamePtr; // 297 | DWORD oldGPANamePtr; // 298 | DWORD originalEntryPoint 299 | char xchgLLABuf[13]; // 300 | char xchgGPABuf[15]; // 301 | */ 302 | DWORD ldrDllStructAddressToCorrect = (DWORD)(LDRDATASIZE + (BYTE*)ldrGetDllStructAddress - (BYTE*)ldrMemMove + 1); 303 | DWORD ldrFunctionsTableToCorrect = (DWORD)(LDRDATASIZE + (BYTE*)ldrGetFunctionsTable - (BYTE*)ldrMemMove + 1); 304 | DWORD ldrRemImportsAddrToCorrect = (DWORD)(LDRDATASIZE + (BYTE*)ldrGetRemovedImportsAddress - (BYTE*)ldrMemMove + 1); 305 | 306 | DWORD dllsSize; 307 | BYTE* dlls = genDllStruct(pathsToLibs, libsToBundle, inh->OptionalHeader.ImageBase + LDRDATASIZE + ldrCodeSize + (remIIDVector.size() + 1)*sizeof(IMAGE_IMPORT_DESCRIPTOR) + newSectionRVA, &dllsSize); 308 | 309 | IMAGE_SECTION_HEADER newSection; 310 | memset(&newSection, 0, sizeof(IMAGE_SECTION_HEADER)); 311 | char secName[8] = ".DLL "; 312 | memmove(newSection.Name, secName, 8); 313 | newSection.Characteristics = 0xE0000060; 314 | newSection.PointerToRawData = newSectionRawOff; 315 | newSection.SizeOfRawData = TRUNC((LDRDATASIZE + ldrCodeSize + dllsSize + (remIIDVector.size() + 1)*sizeof(IMAGE_IMPORT_DESCRIPTOR)), inh->OptionalHeader.FileAlignment); 316 | newSection.VirtualAddress = newSectionRVA; 317 | newSection.Misc.VirtualSize = TRUNC((LDRDATASIZE + ldrCodeSize + dllsSize + (remIIDVector.size() + 1)*sizeof(IMAGE_IMPORT_DESCRIPTOR)), inh->OptionalHeader.SectionAlignment); 318 | 319 | sprintf(logTmp, "Size of new section: %d", newSection.SizeOfRawData); 320 | LOG(logTmp); 321 | 322 | LPVOID oldMem = hExeMem; 323 | hExeMem = VirtualReAlloc(hExeMem, fileSize, fileSize + newSection.SizeOfRawData); 324 | //correction of inh and ish pointers 325 | IMAGE_NT_HEADERS* inh2 = (IMAGE_NT_HEADERS*)((BYTE*)hExeMem + ((BYTE*)inh - (BYTE*)oldMem)); 326 | IMAGE_SECTION_HEADER* ish2 = (IMAGE_SECTION_HEADER*)((BYTE*)hExeMem + ((BYTE*)ish - (BYTE*)oldMem)); 327 | 328 | //generating functions table 329 | #define LDRITEMCNT 12 330 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[0] = 0; 331 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[1] = 0; 332 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[2] = 0; 333 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[3] = inh2->OptionalHeader.ImageBase + newSection.VirtualAddress + LDRDATASIZE + ((BYTE*)emuGetProcAddress - (BYTE*)ldrMemMove); 334 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[4] = inh2->OptionalHeader.ImageBase + newSection.VirtualAddress + LDRDATASIZE + ((BYTE*)emuLoadLibraryA - (BYTE*)ldrMemMove); 335 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[5] = inh2->OptionalHeader.ImageBase + newSection.VirtualAddress + LDRDATASIZE + ((BYTE*)emuGetModuleHandleA - (BYTE*)ldrMemMove); 336 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[6] = 0; 337 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[7] = inh2->OptionalHeader.ImageBase + thunkLoadLibraryA; 338 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[8] = inh2->OptionalHeader.ImageBase + thunkGetProcAddress; 339 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[9] = inh2->OptionalHeader.ImageBase + oldLLANamePtr; 340 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[10] = inh2->OptionalHeader.ImageBase + oldGPANamePtr; 341 | ((DWORD*)((BYTE*)hExeMem + newSectionRawOff))[11] = inh2->OptionalHeader.ImageBase + inh2->OptionalHeader.AddressOfEntryPoint; 342 | memmove((BYTE*)hExeMem + newSectionRawOff + LDRITEMCNT*4, xchgLLABuf, 13); 343 | memmove((BYTE*)hExeMem + newSectionRawOff + LDRITEMCNT*4 + 13, xchgGPABuf, 15); 344 | //copying loader code to new memory 345 | memmove((BYTE*)hExeMem + newSectionRawOff + LDRDATASIZE, ldrMemMove, ldrCodeSize); 346 | 347 | //correction of addressess returned by: ldrGetRemovedImportsAddress, ldrGetFunctionsTable, ldrGetDllStructAddress 348 | *((DWORD*)((BYTE*)hExeMem + newSectionRawOff + ldrDllStructAddressToCorrect)) = inh2->OptionalHeader.ImageBase + newSectionRVA + LDRDATASIZE + ldrCodeSize + (remIIDVector.size() + 1)*sizeof(IMAGE_IMPORT_DESCRIPTOR); 349 | *((DWORD*)((BYTE*)hExeMem + newSectionRawOff + ldrFunctionsTableToCorrect)) = inh2->OptionalHeader.ImageBase + newSectionRVA; 350 | *((DWORD*)((BYTE*)hExeMem + newSectionRawOff + ldrRemImportsAddrToCorrect)) = inh2->OptionalHeader.ImageBase + newSectionRVA + LDRDATASIZE + ldrCodeSize; 351 | 352 | //copying to loader import descriptors removed from original import table 353 | unsigned int i = 0; 354 | for (i = 0; i < remIIDVector.size(); i++) 355 | { 356 | memmove((BYTE*)hExeMem + newSectionRawOff + LDRDATASIZE + ldrCodeSize + i*sizeof(IMAGE_IMPORT_DESCRIPTOR), &remIIDVector[i], sizeof(IMAGE_IMPORT_DESCRIPTOR)); 357 | } 358 | memset((BYTE*)hExeMem + newSectionRawOff + LDRDATASIZE + ldrCodeSize + i*sizeof(IMAGE_IMPORT_DESCRIPTOR), 0, sizeof(IMAGE_IMPORT_DESCRIPTOR)); 359 | i++; 360 | 361 | //copying DLL structure 362 | memmove((BYTE*)hExeMem + newSectionRawOff + LDRDATASIZE + ldrCodeSize + i*sizeof(IMAGE_IMPORT_DESCRIPTOR), dlls, dllsSize); 363 | GlobalFree(dlls); 364 | 365 | //correcting PE header 366 | memmove(&ish2[inh2->FileHeader.NumberOfSections], &newSection, sizeof(IMAGE_SECTION_HEADER)); 367 | inh2->FileHeader.NumberOfSections++; 368 | inh2->OptionalHeader.AddressOfEntryPoint = newSection.VirtualAddress + LDRDATASIZE + ((BYTE*)ldrMain - (BYTE*)ldrMemMove); 369 | inh2->OptionalHeader.SizeOfImage += newSection.Misc.VirtualSize; 370 | 371 | //saving new executable 372 | char outFileName[256]; 373 | sprintf(outFileName, "%s.bundled.exe", exeName); 374 | HANDLE outFile = CreateFile(outFileName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 375 | WriteFile(outFile, hExeMem, fileSize + newSection.SizeOfRawData, &tmp, 0); 376 | CloseHandle(outFile); 377 | sprintf(logTmp, "OK: %s", outFileName); 378 | LOG(logTmp); 379 | 380 | VirtualFree(hExeMem, 0, MEM_RELEASE); 381 | 382 | #undef LDRITEMCNT 383 | #undef LDRDATASIZE 384 | #undef EXEMEMCHECK 385 | #undef LOGRET2 386 | #undef LOGRET 387 | #undef LOG 388 | } 389 | 390 | BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 391 | { 392 | switch (uMsg) 393 | { 394 | case WM_CLOSE: 395 | EndDialog(hwndDlg, 0); 396 | break; 397 | case WM_COMMAND: 398 | { 399 | switch (wParam) 400 | { 401 | case BTN_EXIT: 402 | EndDialog(hwndDlg, 0); 403 | break; 404 | case BTN_OPEN: 405 | { 406 | OPENFILENAME ofn; 407 | memset(&ofn, 0, sizeof(OPENFILENAME)); 408 | ofn.lStructSize = sizeof(OPENFILENAME); 409 | ofn.hwndOwner = hwndDlg; 410 | BYTE fileName[256]; 411 | fileName[0] = 0; 412 | ofn.lpstrFile = (LPSTR)fileName; 413 | ofn.nMaxFile = 256; 414 | ofn.Flags = OFN_FILEMUSTEXIST; 415 | GetOpenFileName(&ofn); 416 | SetDlgItemText(hwndDlg, EDIT_FILENAME, ofn.lpstrFile); 417 | } 418 | break; 419 | case BTN_ADDLIB: 420 | { 421 | OPENFILENAME ofn; 422 | memset(&ofn, 0, sizeof(OPENFILENAME)); 423 | ofn.lStructSize = sizeof(OPENFILENAME); 424 | ofn.hwndOwner = hwndDlg; 425 | BYTE fileName[256]; 426 | fileName[0] = 0; 427 | ofn.lpstrFile = (LPSTR)fileName; 428 | ofn.nMaxFile = 256; 429 | ofn.Flags = OFN_FILEMUSTEXIST; 430 | GetOpenFileName(&ofn); 431 | if (fileName[0]) SendDlgItemMessage(hwndDlg, LB_LIBS, LB_ADDSTRING, 0, (LPARAM)fileName); 432 | } 433 | break; 434 | case BTN_DELLIB: 435 | { 436 | int sel = (int)SendDlgItemMessage(hwndDlg, LB_LIBS, LB_GETCURSEL, 0, 0); 437 | if (sel != LB_ERR) SendDlgItemMessage(hwndDlg, LB_LIBS, LB_DELETESTRING, sel, 0); 438 | } 439 | break; 440 | case BTN_BUNDLE: 441 | { 442 | char fileName[256]; 443 | fileName[0] = 0; 444 | GetDlgItemText(hwndDlg, EDIT_FILENAME, (LPSTR)fileName, 256); 445 | int libCnt = (int)SendDlgItemMessage(hwndDlg, LB_LIBS, LB_GETCOUNT, 0, 0); 446 | if (fileName[0] && libCnt) Bundle(fileName, GetDlgItem(hwndDlg, LB_LIBS), GetDlgItem(hwndDlg, LB_LOG)); 447 | else SendDlgItemMessage(hwndDlg, LB_LOG, LB_ADDSTRING, 0, (LPARAM)"Select executable and at least one DLL."); 448 | } 449 | break; 450 | case BTN_ABT: 451 | { 452 | MessageBox(hwndDlg, "DLLPackager v1.0\n\nAuthor\t: ReWolf\ne-mail\t: rewolf@poczta.onet.pl\nwww\t: http://rewolf.pl", "About", MB_ICONINFORMATION); 453 | } 454 | } 455 | } 456 | break; 457 | } 458 | return 0; 459 | } 460 | 461 | int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 462 | { 463 | DialogBoxParam(hInstance, (LPCSTR)IDD_DIALOG1, 0, DialogProc, 0); 464 | return 0; 465 | } 466 | -------------------------------------------------------------------------------- /src/res.rc: -------------------------------------------------------------------------------- 1 | /* DLLPackager v1.0 2 | * Copyright 2007 ReWolf 3 | * Contact: 4 | * rewolf@poczta.onet.pl 5 | * http://rewolf.pl 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #include "WinUser.h" 23 | #include "resource.h" 24 | 25 | 26 | IDD_DIALOG1 DIALOGEX 0, 0, 334, 193 27 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 28 | CAPTION "DLLPackager - ReWolf" 29 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 30 | BEGIN 31 | EDITTEXT EDIT_FILENAME,4,4,300,12,ES_AUTOHSCROLL | NOT WS_BORDER,WS_EX_STATICEDGE 32 | PUSHBUTTON "...",BTN_OPEN,308,4,18,12,BS_FLAT 33 | LISTBOX LB_LIBS,4,20,324,72,LBS_NOINTEGRALHEIGHT | NOT WS_BORDER | WS_VSCROLL | WS_TABSTOP,WS_EX_STATICEDGE 34 | PUSHBUTTON "Add Library",BTN_ADDLIB,4,96,66,12,BS_FLAT 35 | PUSHBUTTON "Remove Library",BTN_DELLIB,72,96,66,12,BS_FLAT 36 | PUSHBUTTON "Bundle",BTN_BUNDLE,280,96,48,12,BS_FLAT 37 | PUSHBUTTON "Exit",BTN_EXIT,228,96,48,12,BS_FLAT 38 | LISTBOX LB_LOG,4,112,324,76,LBS_NOINTEGRALHEIGHT | NOT WS_BORDER | WS_VSCROLL | WS_TABSTOP,WS_EX_STATICEDGE 39 | PUSHBUTTON "About",BTN_ABT,176,96,48,12,BS_FLAT 40 | END 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- 1 | /* DLLPackager v1.0 2 | * Copyright 2007 ReWolf 3 | * Contact: 4 | * rewolf@poczta.onet.pl 5 | * http://rewolf.pl 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #define IDD_DIALOG1 101 23 | #define EDIT_FILENAME 1001 24 | #define BTN_OPEN 1002 25 | #define LB_LIBS 1003 26 | #define BTN_ADDLIB 1004 27 | #define BTN_DELLIB 1005 28 | #define BTN_BUNDLE 1006 29 | #define BTN_EXIT 1007 30 | #define BTN_EXIT2 1008 31 | #define BTN_ABT 1008 32 | #define LB_LOG 1009 33 | --------------------------------------------------------------------------------