├── .gitignore ├── LICENSE ├── README.md └── src ├── 3rdParty ├── pugiconfig.hpp ├── pugixml.cpp └── pugixml.hpp ├── Parasite ├── ApiHooks │ ├── ApiHook.cpp │ └── ApiHook.h ├── Common │ ├── LockMgr.cpp │ ├── LockMgr.h │ ├── ModuleInstance.cpp │ ├── ModuleInstance.h │ ├── SysUtils.h │ ├── common.cpp │ └── common.h ├── ConfigLoader.cpp ├── ConfigLoader.h ├── ReadMe.txt ├── parasite.aps ├── parasite.cpp ├── parasite.def ├── parasite.h ├── parasite.rc ├── parasite.vcxproj ├── parasite.vcxproj.filters ├── res │ └── parasite.rc2 ├── resource.h ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── WinValgrind.sln ├── WinValgrind ├── ReadMe.txt ├── Resource.h ├── WinValgrind.cpp ├── WinValgrind.h ├── WinValgrind.rc ├── WinValgrind.vcxproj ├── WinValgrind.vcxproj.filters ├── WinValgrindCtrl.cpp ├── WinValgrindCtrl.h ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── ext-dependencies └── x86 │ ├── dbghelp.dll │ └── symsrv.dll └── svnremove.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 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 | WinValgrind ( valgrind for windows ) : Resource leak tracking tool for windows. 294 | Copyright (C) 2013 anshulgoel27 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 | {signature of Ty Coon}, 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 | WinValgrind 2 | =========== 3 | 4 | WinValgrind ( valgrind for windows ) : Resource leak tracking tool for windows. 5 | 6 | Being a linux programmer, we often feel the need of the powerful memory leak detection tool similar to Valgrind on Windows environment also. 7 | 8 | WinValgrind? is a resource leak tracking tool which will offer complete detection of Handle leaks, GDI objects leak & Memory leaks, with a simple to use command line user interface. 9 | 10 | WinValgrind? takes inspiration from Valgrind and enables the user to track down memory issues without changing a single line of code. 11 | 12 | 13 | How to build 14 | ============= 15 | Before building the tool you need to have some prerequisite on your computer. 16 | 17 | Visual studio 2k10 to latest... ( I have built in vs 2k12). 18 | Debugging tools for windows. 19 | SVN client like tortoisesvn. 20 | To build the tool from source, check out the source in some local directory. Open WinValgrind?.sln and hit build solution.. Now you are ready to go :) 21 | 22 | In the output folder you will get: 23 | 24 | 1.) WinValgrind?.exe --> command line interface utility to inject the parasite into a process. 25 | 26 | 2.) parasite.dll --> Spy DLL which hook the windows API's. 27 | 28 | -->Enable logging for the tool by setting the value of "WINVAL_LOG" environment variable as 1. 29 | 30 | How to use the tool 31 | =================== 32 | 33 | Note : Tool is currently at initial stage of development, therefore I have yet not decided whether to go with the GUI. 34 | 35 | Tool is very simple to use, just follow the below steps to get started.. 36 | 37 | Execute winvalgrind.exe on windows command prompt to see all command line options. 38 | 39 | usage: winvalgrind [-gc] | [-sm ] 40 | 41 | -gc Generate the config file template. 42 | -sm start monitoring the process. 43 | 44 | 1.) First you need to generate the default config.xml template. 45 | 46 | --> Execute "winvalgrind.exe -gc" 47 | 48 | ----> This command will generate the default config.xml file into the winvalgrind.exe directory. 49 | *------------ Config.xml default template-------------------* 50 | 51 | 52 | 53 | 54 | MEMORY 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | --> Config.xml, serves as configuration file which will be read/loaded to set the initialisation parameters for parasite.dll. 67 | 68 | --> MonitorType tag's value define type of tracing user want to enable. 69 | 70 | -----> MEMORY : Memory leak detection. 71 | 72 | -----> GDI : GDI object leak detection. 73 | 74 | -----> HANDLE: Handle leak detection. 75 | 76 | --> PDBInfo tags define the path to the symbol file. 77 | 78 | ----> 1st pdbinfo is the path to the directory of parasite.dll. 79 | 80 | ----> 2nd is the system DLL path. 81 | 82 | Note: path 1 & 2 are compulsory, do not remove them. 83 | 84 | ----> 3rd is the Microsoft symbol server path, which is optional. 85 | 86 | 2.) Edit the generated config.xml. 87 | 88 | --> Set the monitor type. 89 | 90 | --> Add the symbol path of the application you want to monitor. 91 | 92 | 3.) Start the application you want to monitor. 93 | 94 | 4.) Execute "winvalgrind.exe -sm ". 95 | 96 | Once the monitoring starts you will see below internal command line which you can use to control the application. 97 | 98 | -------------------------------------- 99 | Monitoring started for pid 100 | 101 | Command options 102 | 103 | -d Dump the leak trace. 104 | -c Clear leaks. 105 | -e Exit. 106 | 107 | > 108 | 109 | --------------------------------------- 110 | 111 | Internals of tool 112 | ================= 113 | 114 | Basically this application works by hooking all the windows API's which are used to allocate and deallocate memory. 115 | 116 | Now, after the hooking is complete, For each allocation of memory I save its stack in stl map address keys. Map entry for a address is only cleared if, respective deallocation function is called on that address. 117 | 118 | at-last, all the remaining entries in map are treated as leaked once, and there stack is dumped to file. 119 | 120 | 121 | Currently supported API hooks 122 | ============================= 123 | 124 | Handle allocation APIs GDI object allocation APIs Memory allocation APIs 125 | ---------------------- -------------------------- ---------------------- 126 | 127 | LoadLibraryA LoadBitmapA HeapAlloc 128 | LoadLibraryW LoadBitmapW HeapFree 129 | LoadLibraryExA LoadImageA HeapReAlloc 130 | LoadLibraryExW LoadImageW VirtualAlloc 131 | GetProcAddress CreateBitmap VirtualFree 132 | CreateEventA CreateBitmapIndirect VirtualAllocEx 133 | CreateEventW CreateCompatibleBitmap VirtualFreeEx 134 | CreateEventExA CreateDIBitmap GlobalAlloc 135 | CreateEventExW CreateDIBSection GlobalReAlloc 136 | OpenEventA CreateDiscardableBitmap GlobalFree 137 | OpenEventW CopyImage LocalAlloc 138 | CreateMutexA GetIconInfo LocalReAlloc 139 | CreateMutexW GetIconInfoExA LocalFree 140 | CreateMutexExA GetIconInfoExA MapViewOfFile 141 | CreateMutexExW DeleteObject MapViewOfFileEx 142 | OpenMutexA CopyIcon UnmapViewOfFile 143 | OpenMutexW CreateIcon CoTaskMemAlloc 144 | CreateSemaphoreA CreateIconFromResource CoTaskMemRealloc 145 | CreateSemaphoreW CreateIconFromResourceEx CoTaskMemFree 146 | CreateSemaphoreExA CreateIconIndirect 147 | CreateSemaphoreExW DestroyIcon 148 | OpenSemaphoreA DuplicateIcon 149 | OpenSemaphoreW ExtractAssociatedIconA 150 | CreateWaitableTimerA ExtractAssociatedIconW 151 | CreateWaitableTimerW ExtractAssociatedIconExA 152 | CreateWaitableTimerExA ExtractAssociatedIconExW 153 | CreateWaitableTimerExW ExtractIconA 154 | OpenWaitableTimerA ExtractIconW 155 | OpenWaitableTimerW ExtractIconExA 156 | CreateFileA ExtractIconExW 157 | CreateFileW LoadIconA 158 | CreateFileTransactedA LoadIconW 159 | CreateFileTransactedW PrivateExtractIconsA 160 | FindFirstFileA PrivateExtractIconsW 161 | FindFirstFileW CreateCursor 162 | FindFirstFileExA LoadCursorA 163 | FindFirstFileExW LoadCursorW 164 | FindFirstFileExW LoadCursorFromFileA 165 | FindFirstFileNameW LoadCursorFromFileW 166 | FindFirstFileTransactedA DestroyCursor 167 | FindFirstFileTransactedW CreateBrushIndirect 168 | FindFirstStreamTransactedW CreateSolidBrush 169 | FindFirstStreamW CreatePatternBrush 170 | FindClose CreateDIBPatternBrush 171 | OpenFileById CreateDIBPatternBrushPt 172 | ReOpenFile CreateHatchBrush 173 | CreateIoCompletionPort CreateCompatibleDC 174 | CreateRestrictedToken CreateDCA 175 | DuplicateToken CreateDCW 176 | DuplicateTokenEx CreateICA 177 | OpenProcessToken CreateICW 178 | OpenThreadToken GetDC 179 | FindFirstChangeNotificationA GetDCEx 180 | FindFirstChangeNotificationW GetWindowDC 181 | FindCloseChangeNotification ReleaseDC 182 | CreateMemoryResourceNotification DeleteDC 183 | CreateFileMappingA CreateFontA 184 | CreateFileMappingW CreateFontW 185 | CreateFileMappingNumaA CreateFontIndirectA 186 | CreateFileMappingNumaW CreateFontIndirectW 187 | OpenFileMappingA CreateMetaFileA 188 | OpenFileMappingW CreateMetaFileW 189 | HeapCreate CreateEnhMetaFileA 190 | HeapDestroy CreateEnhMetaFileW 191 | GlobalAlloc GetEnhMetaFileA 192 | GlobalReAlloc GetEnhMetaFileW 193 | GlobalFree GetMetaFileA 194 | LocalAlloc GetMetaFileW 195 | LocalReAlloc DeleteMetaFile 196 | LocalFree DeleteEnhMetaFile 197 | CreateProcessA CopyEnhMetaFileA 198 | CreateProcessW CopyEnhMetaFileW 199 | CreateProcessAsUserA CloseEnhMetaFile 200 | CreateProcessAsUserW CloseMetaFile 201 | CreateProcessWithLogonW CreatePen 202 | CreateProcessWithTokenW CreatePenIndirect 203 | OpenProcess ExtCreatePen 204 | CreateThread PathToRegion 205 | CreateRemoteThread CreateEllipticRgn 206 | OpenThread CreateEllipticRgnIndirect 207 | CreateJobObjectA CreatePolygonRgn 208 | CreateJobObjectW CreatePolyPolygonRgn 209 | CreateMailslotA CreateRectRgn 210 | CreateMailslotW CreateRectRgnIndirect 211 | CreatePipe CreateRoundRectRgn 212 | CreateNamedPipeA ExtCreateRegion 213 | CreateNamedPipeW CreateHalftonePalette 214 | RegCreateKeyExA CreatePalette 215 | RegCreateKeyExW 216 | RegCreateKeyTransactedA 217 | RegCreateKeyTransactedW 218 | RegOpenCurrentUser 219 | RegOpenKeyA 220 | RegOpenKeyW 221 | RegOpenKeyExA 222 | RegOpenKeyExW 223 | RegOpenKeyTransactedA 224 | RegOpenKeyTransactedW 225 | RegOpenUserClassesRoot 226 | RegCreateKeyA 227 | RegCreateKeyW 228 | RegCloseKey 229 | DuplicateHandle 230 | CloseHandle 231 | 232 | What is coming up? 233 | ================== 234 | 235 | --> GUI 236 | 237 | --> Overall performance improvements. 238 | 239 | Contact me 240 | ========== 241 | Do you want to participate? if yes, then contact me at anshulgoel27@gmail.com 242 | -------------------------------------------------------------------------------- /src/3rdParty/pugiconfig.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * pugixml parser - version 1.2 3 | * -------------------------------------------------------- 4 | * Copyright (C) 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) 5 | * Report bugs and download new versions at http://pugixml.org/ 6 | * 7 | * This library is distributed under the MIT License. See notice at the end 8 | * of this file. 9 | * 10 | * This work is based on the pugxml parser, which is: 11 | * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) 12 | */ 13 | 14 | #ifndef HEADER_PUGICONFIG_HPP 15 | #define HEADER_PUGICONFIG_HPP 16 | 17 | // Uncomment this to enable wchar_t mode 18 | // #define PUGIXML_WCHAR_MODE 19 | 20 | // Uncomment this to disable XPath 21 | // #define PUGIXML_NO_XPATH 22 | 23 | // Uncomment this to disable STL 24 | // #define PUGIXML_NO_STL 25 | 26 | // Uncomment this to disable exceptions 27 | // #define PUGIXML_NO_EXCEPTIONS 28 | 29 | // Set this to control attributes for public classes/functions, i.e.: 30 | // #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL 31 | // #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL 32 | // #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall 33 | // In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead 34 | 35 | // Uncomment this to switch to header-only version 36 | // #define PUGIXML_HEADER_ONLY 37 | // #include "pugixml.cpp" 38 | 39 | // Tune these constants to adjust memory-related behavior 40 | // #define PUGIXML_MEMORY_PAGE_SIZE 32768 41 | // #define PUGIXML_MEMORY_OUTPUT_STACK 10240 42 | // #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 43 | 44 | #endif 45 | 46 | /** 47 | * Copyright (c) 2006-2012 Arseny Kapoulkine 48 | * 49 | * Permission is hereby granted, free of charge, to any person 50 | * obtaining a copy of this software and associated documentation 51 | * files (the "Software"), to deal in the Software without 52 | * restriction, including without limitation the rights to use, 53 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 54 | * copies of the Software, and to permit persons to whom the 55 | * Software is furnished to do so, subject to the following 56 | * conditions: 57 | * 58 | * The above copyright notice and this permission notice shall be 59 | * included in all copies or substantial portions of the Software. 60 | * 61 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 62 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 63 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 64 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 65 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 66 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 67 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 68 | * OTHER DEALINGS IN THE SOFTWARE. 69 | */ 70 | -------------------------------------------------------------------------------- /src/Parasite/ApiHooks/ApiHook.h: -------------------------------------------------------------------------------- 1 | #ifndef _APIHOOK_H_ 2 | #define _APIHOOK_H_ 3 | 4 | 5 | #include 6 | #include 7 | using namespace std; 8 | #include 9 | #include 10 | 11 | 12 | #define HOOK_IMPORT(Function, DLL) HookImport(#DLL ##".dll",#Function,(PROC)CApiHookMgr::My##Function) 13 | 14 | ////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // Forward declarations 17 | // 18 | ////////////////////////////////////////////////////////////////////////////// 19 | 20 | 21 | class CHookedFunctions; 22 | 23 | ////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // class CApiHookMgr 26 | // 27 | ////////////////////////////////////////////////////////////////////////////// 28 | class CApiHookMgr 29 | { 30 | public: 31 | CApiHookMgr(); 32 | virtual ~CApiHookMgr(); 33 | public: 34 | // 35 | // Hook up an API 36 | // 37 | BOOL HookImport( 38 | PCSTR pszCalleeModName, 39 | PCSTR pszFuncName, 40 | PROC pfnHook 41 | ); 42 | // 43 | // Restore hooked up API function 44 | // 45 | BOOL UnHookImport( 46 | PCSTR pszCalleeModName, 47 | PCSTR pszFuncName 48 | ); 49 | 50 | // Hook all needed system functions in order to trap loading libraries 51 | BOOL HookSystemFuncs(); 52 | 53 | // Hook handle alloc functions 54 | BOOL HookHandleAllocFuncs(); 55 | 56 | // Hook memory alloc functions 57 | BOOL HookMemAllocFuncs(); 58 | 59 | // Hook GDI object alloc functions 60 | BOOL HookGDIAllocFuncs(); 61 | 62 | // 63 | // Unhook all functions and restore original ones 64 | // 65 | void UnHookAllFuncs(); 66 | // 67 | // Indicates whether there is hooked function 68 | // 69 | BOOL AreThereHookedFunctions(); 70 | // 71 | // Hooked API count 72 | // 73 | size_t HookedFunctionCount() const; 74 | 75 | private: 76 | // 77 | // Let's allow CApiHookMgr to access private methods of CHookedFunction 78 | // 79 | friend class CHookedFunction; 80 | // 81 | // Create a critical section on the stack 82 | // 83 | static CCSWrapper sm_CritSec; 84 | // 85 | // Handle to current module 86 | // 87 | HMODULE m_hmodThisInstance; 88 | // 89 | // Container keeps track of all hacked functions 90 | // 91 | static CHookedFunctions* sm_pHookedFunctions; 92 | // 93 | // Determines whether all system functions has been successfuly hacked 94 | // 95 | BOOL m_bSystemFuncsHooked; 96 | 97 | // 98 | // Determines whether all handle alloc functions has been successfuly hacked 99 | // 100 | BOOL m_bHandleFuncsHooked; 101 | 102 | // 103 | // Determines whether all memory allocation functions has been successfuly hacked 104 | // 105 | BOOL m_bMemFuncsHooked; 106 | 107 | // 108 | // Determines whether all GDI object allocation functions has been successfuly hacked 109 | // 110 | BOOL m_bGDIFuncsHooked; 111 | 112 | // 113 | // Used when a DLL is newly loaded after hooking a function 114 | // 115 | static void WINAPI HackModuleOnLoad( 116 | HMODULE hmod, 117 | DWORD dwFlags 118 | ); 119 | // 120 | // Used to trap events when DLLs are loaded 121 | // 122 | static HMODULE WINAPI CApiHookMgr::MyLoadLibraryA( 123 | PCSTR pszModuleName 124 | ); 125 | static HMODULE WINAPI CApiHookMgr::MyLoadLibraryW( 126 | PCWSTR pszModuleName 127 | ); 128 | static HMODULE WINAPI CApiHookMgr::MyLoadLibraryExA( 129 | PCSTR pszModuleName, 130 | HANDLE hFile, 131 | DWORD dwFlags 132 | ); 133 | static HMODULE WINAPI CApiHookMgr::MyLoadLibraryExW( 134 | PCWSTR pszModuleName, 135 | HANDLE hFile, 136 | DWORD dwFlags 137 | ); 138 | // 139 | // Returns address of replacement function if hooked function is requested 140 | // 141 | static FARPROC WINAPI CApiHookMgr::MyGetProcAddress( 142 | HMODULE hmod, 143 | PCSTR pszProcName 144 | ); 145 | // 146 | // Returns original address of the API function 147 | // 148 | static FARPROC WINAPI GetProcAddressWindows( 149 | HMODULE hmod, 150 | PCSTR pszProcName 151 | ); 152 | 153 | ////////////////////////////////////////////////////////////// 154 | // Memory alloc methods hooks 155 | ////////////////////////////////////////////////////////////// 156 | static LPVOID WINAPI MyHeapAlloc( IN HANDLE hHeap, IN DWORD dwFlags, IN SIZE_T dwBytes ); 157 | static LPVOID WINAPI MyHeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes ); 158 | static LPVOID WINAPI MyVirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect ); 159 | static BOOL WINAPI MyVirtualFree( LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType ); 160 | static LPVOID WINAPI MyVirtualAllocEx( HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect ); 161 | static BOOL WINAPI MyVirtualFreeEx( HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType ); 162 | static BOOL WINAPI MyHeapFree( HANDLE hHeap, DWORD dwFlags, LPVOID lpMem ); 163 | static LPVOID WINAPI MyCoTaskMemAlloc( SIZE_T cb); 164 | static LPVOID WINAPI MyCoTaskMemRealloc(LPVOID pv, SIZE_T cb); 165 | static void WINAPI MyCoTaskMemFree( LPVOID pv ); 166 | static LPVOID WINAPI MyMapViewOfFile( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap ); 167 | static LPVOID WINAPI MyMapViewOfFileEx( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress ); 168 | static BOOL WINAPI MyUnmapViewOfFile( LPCVOID lpBaseAddress ); 169 | 170 | // static int myntmapviewofsection( handle sectionhandle, handle processhandle, pvoid *baseaddress, 171 | // ulong_ptr zerobits, size_t commitsize, plarge_integer sectionoffset, psize_t viewsize, 172 | // section_inherit inheritdisposition, ulong allocationtype, ulong win32protect ); 173 | // static int myntunmapviewofsection( handle processhandle, pvoid baseaddress ); 174 | 175 | ////////////////////////////////////////////////////////////// 176 | // Handle alloc methods hooks 177 | ////////////////////////////////////////////////////////////// 178 | static HANDLE WINAPI MyCreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPCSTR lpName); 179 | static HANDLE WINAPI MyCreateEventW( LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPCWSTR lpName); 180 | static HANDLE WINAPI MyCreateEventExA( LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags,DWORD dwDesiredAccess); 181 | static HANDLE WINAPI MyCreateEventExW( LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess ); 182 | static HANDLE WINAPI MyOpenEventA( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName); 183 | static HANDLE WINAPI MyOpenEventW( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName ); 184 | static HANDLE WINAPI MyCreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner, LPCSTR lpName ); 185 | static HANDLE WINAPI MyCreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCWSTR lpName); 186 | static HANDLE WINAPI MyCreateMutexExA(LPSECURITY_ATTRIBUTES lpEventAttributes,LPCSTR lpName,DWORD dwFlags,DWORD dwDesiredAccess); 187 | static HANDLE WINAPI MyCreateMutexExW(LPSECURITY_ATTRIBUTES lpEventAttributes,LPCWSTR lpName,DWORD dwFlags,DWORD dwDesiredAccess); 188 | static HANDLE WINAPI MyOpenMutexA(DWORD dwDesiredAccess,BOOL bInheritHandle,LPCSTR lpName); 189 | static HANDLE WINAPI MyOpenMutexW(DWORD dwDesiredAccess,BOOL bInheritHandle,LPCWSTR lpName); 190 | static HANDLE WINAPI MyCreateSemaphoreA( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount,LPCSTR lpName ); 191 | static HANDLE WINAPI MyCreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCWSTR lpName); 192 | static HANDLE WINAPI MyCreateSemaphoreExA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCSTR lpName,DWORD dwFlags,DWORD dwDesiredAccess); 193 | static HANDLE WINAPI MyCreateSemaphoreExW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCWSTR lpName,DWORD dwFlags,DWORD dwDesiredAccess); 194 | static HANDLE WINAPI MyOpenSemaphoreA(DWORD dwDesiredAccess,BOOL bInheritHandle,LPCSTR lpName); 195 | static HANDLE WINAPI MyOpenSemaphoreW(DWORD dwDesiredAccess,BOOL bInheritHandle,LPWSTR lpName); 196 | static HANDLE WINAPI MyCreateWaitableTimerA( LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCSTR lpTimerName); 197 | static HANDLE WINAPI MyCreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes,BOOL bManualReset,LPCWSTR lpTimerName); 198 | static HANDLE WINAPI MyCreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes,LPCSTR lpTimerName,DWORD dwFlags,DWORD dwDesiredAccess); 199 | static HANDLE WINAPI MyCreateWaitableTimerExW(LPSECURITY_ATTRIBUTES lpTimerAttributes,LPCWSTR lpTimerName,DWORD dwFlags,DWORD dwDesiredAccess); 200 | static HANDLE WINAPI MyOpenWaitableTimerA(DWORD dwDesiredAccess,BOOL bInheritHandle,LPCSTR lpTimerName); 201 | static HANDLE WINAPI MyOpenWaitableTimerW(DWORD dwDesiredAccess,BOOL bInheritHandle,LPCWSTR lpTimerName); 202 | 203 | // file function 204 | static HANDLE WINAPI MyCreateFileA(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile); 205 | static HANDLE WINAPI MyCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile); 206 | static HANDLE WINAPI MyCreateFileTransactedA(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile,HANDLE hTransaction,PUSHORT pusMiniVersion,PVOID lpExtendedParameter); 207 | static HANDLE WINAPI MyCreateFileTransactedW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile,HANDLE hTransaction,PUSHORT pusMiniVersion,PVOID lpExtendedParameter ); 208 | static HANDLE WINAPI MyFindFirstFileA(LPCSTR lpFileName,LPWIN32_FIND_DATAA lpFindFileData); 209 | static HANDLE WINAPI MyFindFirstFileW(LPCWSTR lpFileName,LPWIN32_FIND_DATAW lpFindFileData); 210 | static HANDLE WINAPI MyFindFirstFileExA(LPCSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags); 211 | static HANDLE WINAPI MyFindFirstFileExW(LPCWSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags); 212 | static HANDLE WINAPI MyFindFirstFileNameTransactedW (LPCWSTR lpFileName,DWORD dwFlags,LPDWORD StringLength,PWCHAR LinkName,HANDLE hTransaction); 213 | static HANDLE WINAPI MyFindFirstFileNameW (LPCWSTR lpFileName,DWORD dwFlags,LPDWORD StringLength,PWCHAR LinkName); 214 | static HANDLE WINAPI MyFindFirstFileTransactedA(LPCSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags,HANDLE hTransaction); 215 | static HANDLE WINAPI MyFindFirstFileTransactedW(LPCWSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags,HANDLE hTransaction); 216 | static HANDLE WINAPI MyFindFirstStreamTransactedW(LPCWSTR lpFileName,STREAM_INFO_LEVELS InfoLevel,LPVOID lpFindStreamData,DWORD dwFlags,HANDLE hTransaction); 217 | static HANDLE WINAPI MyFindFirstStreamW( LPCWSTR lpFileName,STREAM_INFO_LEVELS InfoLevel,LPVOID lpFindStreamData,DWORD dwFlags); 218 | static BOOL WINAPI MyFindClose( HANDLE hFindFile); 219 | static HANDLE WINAPI MyOpenFileById(HANDLE hFile,LPFILE_ID_DESCRIPTOR lpFileID,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwFlags); 220 | static HANDLE WINAPI MyReOpenFile(HANDLE hOriginalFile,DWORD dwDesiredAccess,DWORD dwShareMode,DWORD dwFlags); 221 | static HANDLE WINAPI MyCreateIoCompletionPort(HANDLE FileHandle,HANDLE ExistingCompletionPort,ULONG_PTR CompletionKey,DWORD NumberOfConcurrentThreads); 222 | 223 | //Authorization function 224 | static BOOL WINAPI MyCreateRestrictedToken(HANDLE ExistingTokenHandle,DWORD Flags,DWORD DisableSidCount,PSID_AND_ATTRIBUTES SidsToDisable,DWORD DeletePrivilegeCount,PLUID_AND_ATTRIBUTES PrivilegesToDelete,DWORD RestrictedSidCount,PSID_AND_ATTRIBUTES SidsToRestrict,PHANDLE NewTokenHandle); 225 | static BOOL WINAPI MyDuplicateToken(HANDLE ExistingTokenHandle,SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,PHANDLE DuplicateTokenHandle); 226 | static BOOL WINAPI MyDuplicateTokenEx(HANDLE hExistingToken,DWORD dwDesiredAccess,LPSECURITY_ATTRIBUTES lpTokenAttributes,SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,TOKEN_TYPE TokenType,PHANDLE phNewToken); 227 | static BOOL WINAPI MyOpenProcessToken(HANDLE ProcessHandle,DWORD DesiredAccess,PHANDLE TokenHandle); 228 | static BOOL WINAPI MyOpenThreadToken(HANDLE ThreadHandle,DWORD DesiredAccess,BOOL OpenAsSelf,PHANDLE TokenHandle); 229 | 230 | //Directory management 231 | static HANDLE WINAPI MyFindFirstChangeNotificationA(LPCSTR lpPathName,BOOL bWatchSubtree,DWORD dwNotifyFilter); 232 | static HANDLE WINAPI MyFindFirstChangeNotificationW(LPCWSTR lpPathName,BOOL bWatchSubtree,DWORD dwNotifyFilter); 233 | static BOOL WINAPI MyFindCloseChangeNotification(HANDLE hChangeHandle); 234 | 235 | // File mapping 236 | static HANDLE WINAPI MyCreateMemoryResourceNotification( MEMORY_RESOURCE_NOTIFICATION_TYPE NotificationType ); 237 | static HANDLE WINAPI MyCreateFileMappingA( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName ); 238 | static HANDLE WINAPI MyCreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCWSTR lpName ); 239 | static HANDLE WINAPI MyCreateFileMappingNumaA( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName, DWORD nndPreferred ); 240 | static HANDLE WINAPI MyCreateFileMappingNumaW( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCWSTR lpName, DWORD nndPreferred) ; 241 | static HANDLE WINAPI MyOpenFileMappingA( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName ); 242 | static HANDLE WINAPI MyOpenFileMappingW( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName ); 243 | 244 | //Memory 245 | static HANDLE WINAPI MyHeapCreate( DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize ); 246 | static BOOL WINAPI MyHeapDestroy(HANDLE hHeap ); 247 | 248 | //Process and thread 249 | static BOOL WINAPI MyCreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 250 | static BOOL WINAPI MyCreateProcessW( LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 251 | static BOOL WINAPI MyCreateProcessAsUserA(HANDLE hToken,LPCSTR lpApplicationName,LPSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); 252 | static BOOL WINAPI MyCreateProcessAsUserW(HANDLE hToken,LPWSTR lpApplicationName,LPWSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); 253 | static BOOL WINAPI MyCreateProcessWithLogonW(LPCWSTR lpUsername,LPCWSTR lpDomain,LPCWSTR lpPassword,DWORD dwLogonFlags,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); 254 | static BOOL WINAPI MyCreateProcessWithTokenW(HANDLE hToken,DWORD dwLogonFlags,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); 255 | static HANDLE WINAPI MyOpenProcess( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId ); 256 | static HANDLE WINAPI MyCreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 257 | static HANDLE WINAPI MyCreateRemoteThread( HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 258 | static HANDLE WINAPI MyOpenThread( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId ); 259 | static HANDLE WINAPI MyCreateJobObjectA( LPSECURITY_ATTRIBUTES lpJobAttributes, LPCSTR lpName ); 260 | static HANDLE WINAPI MyCreateJobObjectW( LPSECURITY_ATTRIBUTES lpJobAttributes, LPCWSTR lpName ); 261 | 262 | //Mail slot 263 | static HANDLE WINAPI MyCreateMailslotA( LPCSTR lpName, DWORD nMaxMessageSize, DWORD lReadTimeout, LPSECURITY_ATTRIBUTES lpSecurityAttributes ); 264 | static HANDLE WINAPI MyCreateMailslotW( LPCWSTR lpName, DWORD nMaxMessageSize, DWORD lReadTimeout, LPSECURITY_ATTRIBUTES lpSecurityAttributes ); 265 | 266 | // pipe 267 | static BOOL WINAPI MyCreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize ); 268 | static HANDLE WINAPI MyCreateNamedPipeA( LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes ); 269 | static HANDLE WINAPI MyCreateNamedPipeW( LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes ); 270 | 271 | //Registry 272 | static LSTATUS WINAPI MyRegCreateKeyExA( HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ); 273 | static LSTATUS WINAPI MyRegCreateKeyExW ( HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ); 274 | static LSTATUS WINAPI MyRegCreateKeyTransactedA( HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition, HANDLE hTransaction, PVOID pExtendedParemeter ); 275 | static LSTATUS WINAPI MyRegCreateKeyTransactedW( HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition, HANDLE hTransaction, PVOID pExtendedParemeter ); 276 | static LSTATUS WINAPI MyRegOpenCurrentUser( REGSAM samDesired, PHKEY phkResult ); 277 | static LSTATUS WINAPI MyRegOpenKeyA ( HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult ); 278 | static LSTATUS WINAPI MyRegOpenKeyW ( HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult ); 279 | static LSTATUS WINAPI MyRegOpenKeyExA ( HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult ); 280 | static LSTATUS WINAPI MyRegOpenKeyExW ( HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult ); 281 | static LSTATUS WINAPI MyRegOpenKeyTransactedA ( HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult, HANDLE hTransaction, PVOID pExtendedParemeter ); 282 | static LSTATUS WINAPI MyRegOpenKeyTransactedW ( HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult, HANDLE hTransaction, PVOID pExtendedParemeter ); 283 | static LSTATUS WINAPI MyRegOpenUserClassesRoot( HANDLE hToken, DWORD dwOptions, REGSAM samDesired, PHKEY phkResult ); 284 | static LSTATUS WINAPI MyRegCreateKeyA ( HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult ); 285 | static LSTATUS WINAPI MyRegCreateKeyW ( HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult ); 286 | static LSTATUS WINAPI MyRegCloseKey ( HKEY hKey ); 287 | 288 | // Timers 289 | static HANDLE WINAPI MyCreateTimerQueue(void); 290 | static BOOL WINAPI MyCreateTimerQueueTimer(PHANDLE phNewTimer,HANDLE TimerQueue,WAITORTIMERCALLBACK Callback,PVOID Parameter,DWORD DueTime,DWORD Period,ULONG Flags); 291 | static BOOL WINAPI MyDeleteTimerQueueTimer(HANDLE TimerQueue,HANDLE Timer,HANDLE CompletionEvent); 292 | static BOOL WINAPI MyDeleteTimerQueueEx(HANDLE TimerQueue,HANDLE CompletionEvent); 293 | static BOOL WINAPI MyDeleteTimerQueue(HANDLE TimerQueue); 294 | 295 | //Critical section 296 | static void WINAPI MyInitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 297 | static BOOL WINAPI MyInitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection,DWORD dwSpinCount,DWORD Flags); 298 | static BOOL WINAPI MyInitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection,DWORD dwSpinCount); 299 | static void WINAPI MyDeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection); 300 | 301 | 302 | static BOOL WINAPI MyDuplicateHandle(HANDLE hSourceProcessHandle,HANDLE hSourceHandle,HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwOptions); 303 | static BOOL WINAPI MyCloseHandle( HANDLE hObject ); 304 | 305 | static HANDLE WINAPI MyGlobalAlloc( UINT uFlags, SIZE_T dwBytes ); 306 | static HANDLE WINAPI MyGlobalReAlloc( HGLOBAL hMem, SIZE_T dwBytes, UINT uFlags ); 307 | static HANDLE WINAPI MyGlobalFree( HGLOBAL hMem ); 308 | static HLOCAL WINAPI MyLocalAlloc( UINT uFlags, SIZE_T uBytes ); 309 | static HLOCAL WINAPI MyLocalReAlloc( HLOCAL hMem, SIZE_T uBytes, UINT uFlags ); 310 | static HLOCAL WINAPI MyLocalFree(HLOCAL hMem ); 311 | 312 | 313 | ////////////////////////////////////////////////////////////// 314 | // GDI object alloc methods hooks 315 | ////////////////////////////////////////////////////////////// 316 | 317 | // Bitmap 318 | static HANDLE WINAPI MyLoadImageA(HINSTANCE hInst,LPCSTR name,UINT type,int cx,int cy,UINT fuLoad); 319 | static HANDLE WINAPI MyLoadImageW( HINSTANCE hInst,LPCWSTR name,UINT type,int cx,int cy,UINT fuLoad); 320 | static HBITMAP WINAPI MyLoadBitmapA( HINSTANCE hInstance, LPCSTR lpBitmapName); 321 | static HBITMAP WINAPI MyLoadBitmapW( HINSTANCE hInstance, LPCWSTR lpBitmapName ); 322 | static HANDLE WINAPI MyLoadImageADef( HINSTANCE hInst, LPCSTR name, UINT type,int cx,int cy, UINT fuLoad); 323 | static HANDLE WINAPI MyLoadImageWDef( HINSTANCE hInst, LPCWSTR name, UINT type, int cx, int cy, UINT fuLoad); 324 | static HBITMAP WINAPI MyCreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, CONST VOID *lpBits); 325 | static HBITMAP WINAPI MyCreateBitmapIndirect( CONST BITMAP *pbm ); 326 | static HBITMAP WINAPI MyCreateCompatibleBitmap( HDC hdc, int cx, int cy); 327 | static HBITMAP WINAPI MyCreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits, CONST BITMAPINFO *pbmi, UINT iUsage); 328 | static HBITMAP WINAPI MyCreateDIBSection( HDC hdc, CONST BITMAPINFO *lpbmi, UINT usage, VOID **ppvBits, HANDLE hSection, DWORD offset); 329 | static HBITMAP WINAPI MyCreateDiscardableBitmap( HDC hdc, int cx, int cy); 330 | static HANDLE WINAPI MyCopyImage( HANDLE h, UINT type, int cx, int cy, UINT flags); 331 | static BOOL WINAPI MyDeleteObject( HGDIOBJ ho); 332 | 333 | // Icons 334 | static BOOL WINAPI MyGetIconInfo( HICON hIcon, PICONINFO piconinfo); 335 | static BOOL WINAPI MyGetIconInfoExA( HICON hicon, PICONINFOEXA piconinfo); 336 | static BOOL WINAPI MyGetIconInfoExW( HICON hicon,PICONINFOEXW piconinfo); 337 | static HICON WINAPI MyCreateIcon(HINSTANCE hInstance,int nWidth,int nHeight,BYTE cPlanes,BYTE cBitsPixel,CONST BYTE *lpbANDbits,CONST BYTE *lpbXORbits); 338 | static HICON WINAPI MyCreateIconFromResource( PBYTE presbits, DWORD dwResSize, BOOL fIcon, DWORD dwVer); 339 | static HICON WINAPI MyCreateIconFromResourceEx( PBYTE presbits, DWORD dwResSize,BOOL fIcon,DWORD dwVer,int cxDesired,int cyDesired,UINT Flags ); 340 | static HICON WINAPI MyCreateIconIndirect( PICONINFO piconinfo ); 341 | static BOOL WINAPI MyDestroyIcon(HICON hIcon); 342 | static HICON WINAPI MyDuplicateIcon(HINSTANCE hInst, HICON hIcon); 343 | static HICON WINAPI MyExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIcon); 344 | static HICON WINAPI MyExtractAssociatedIconW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIcon); 345 | static HICON WINAPI MyExtractAssociatedIconExA(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIconIndex, LPWORD lpiIconId); 346 | static HICON WINAPI MyExtractAssociatedIconExW(HINSTANCE hInst,LPWSTR lpIconPath, LPWORD lpiIconIndex, LPWORD lpiIconId); 347 | static HICON WINAPI MyExtractIconA(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex); 348 | static HICON WINAPI MyExtractIconW(HINSTANCE hInst, LPCWSTR lpszExeFileName, UINT nIconIndex); 349 | static UINT WINAPI MyExtractIconExA(LPCSTR lpszFile, int nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIcons); 350 | static UINT WINAPI MyExtractIconExW(LPCWSTR lpszFile, int nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIcons); 351 | static HICON WINAPI MyLoadIconA( HINSTANCE hInstance, LPCSTR lpIconName ); 352 | static HICON WINAPI MyLoadIconW( HINSTANCE hInstance, LPCWSTR lpIconName ); 353 | static UINT WINAPI MyPrivateExtractIconsA( LPCSTR szFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid, UINT nIcons, UINT flags); 354 | static UINT WINAPI MyPrivateExtractIconsW( LPCWSTR szFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid,UINT nIcons,UINT flags); 355 | static HICON WINAPI MyCopyIcon( HICON hIcon); 356 | 357 | // Cursors 358 | static HCURSOR WINAPI MyCreateCursor( HINSTANCE hInst, int xHotSpot, int yHotSpot,int nWidth, int nHeight, CONST VOID *pvANDPlane,CONST VOID *pvXORPlane); 359 | static HCURSOR WINAPI MyLoadCursorA( HINSTANCE hInstance, LPCSTR lpCursorName); 360 | static HCURSOR WINAPI MyLoadCursorW( HINSTANCE hInstance, LPCWSTR lpCursorName); 361 | static HCURSOR WINAPI MyLoadCursorFromFileA( LPCSTR lpFileName ); 362 | static HCURSOR WINAPI MyLoadCursorFromFileW( LPCWSTR lpFileName ); 363 | static BOOL WINAPI MyDestroyCursor( HCURSOR hCursor ); 364 | 365 | // Brush 366 | static HBRUSH WINAPI MyCreateBrushIndirect( CONST LOGBRUSH *plbrush); 367 | static HBRUSH WINAPI MyCreateSolidBrush( COLORREF color); 368 | static HBRUSH WINAPI MyCreatePatternBrush( HBITMAP hbm); 369 | static HBRUSH WINAPI MyCreateDIBPatternBrush( HGLOBAL h, UINT iUsage); 370 | static HBRUSH WINAPI MyCreateDIBPatternBrushPt( CONST VOID *lpPackedDIB, UINT iUsage); 371 | static HBRUSH WINAPI MyCreateHatchBrush( int iHatch, COLORREF color); 372 | 373 | // DC 374 | static HDC WINAPI MyCreateCompatibleDC( HDC hdc ); 375 | static HDC WINAPI MyCreateDCA( LPCSTR pwszDriver, LPCSTR pwszDevice, LPCSTR pszPort, CONST DEVMODEA * pdm ); 376 | static HDC WINAPI MyCreateDCW( LPCWSTR pwszDriver, LPCWSTR pwszDevice, LPCWSTR pszPort, CONST DEVMODEW * pdm ); 377 | static HDC WINAPI MyCreateICA( LPCSTR pszDriver, LPCSTR pszDevice, LPCSTR pszPort, CONST DEVMODEA * pdm ); 378 | static HDC WINAPI MyCreateICW( LPCWSTR pszDriver, LPCWSTR pszDevice, LPCWSTR pszPort, CONST DEVMODEW * pdm ); 379 | static HDC WINAPI MyGetDC( HWND hWnd ); 380 | static HDC WINAPI MyGetDCEx( HWND hWnd, HRGN hrgnClip, DWORD flags ); 381 | static HDC WINAPI MyGetWindowDC( HWND hWnd ); 382 | static int WINAPI MyReleaseDC( HWND hWnd, HDC hDC); 383 | static BOOL WINAPI MyDeleteDC( HDC hdc); 384 | 385 | // Font 386 | static HFONT WINAPI MyCreateFontA( int cHeight, int cWidth, int cEscapement, int cOrientation, int cWeight, DWORD bItalic, 387 | DWORD bUnderline, DWORD bStrikeOut, DWORD iCharSet, DWORD iOutPrecision, DWORD iClipPrecision, 388 | DWORD iQuality, DWORD iPitchAndFamily, LPCSTR pszFaceName); 389 | 390 | static HFONT WINAPI MyCreateFontW( int cHeight, int cWidth, int cEscapement, int cOrientation, int cWeight, DWORD bItalic, 391 | DWORD bUnderline, DWORD bStrikeOut, DWORD iCharSet, DWORD iOutPrecision, DWORD iClipPrecision, 392 | DWORD iQuality, DWORD iPitchAndFamily, LPCWSTR pszFaceName); 393 | 394 | static HFONT WINAPI MyCreateFontIndirectA( CONST LOGFONTA *lplf); 395 | static HFONT WINAPI MyCreateFontIndirectW( CONST LOGFONTW *lplf); 396 | 397 | // Meta File 398 | static HDC WINAPI MyCreateMetaFileA( LPCSTR pszFile ); 399 | static HDC WINAPI MyCreateMetaFileW( LPCWSTR pszFile ); 400 | static HDC WINAPI MyCreateEnhMetaFileA( HDC hdc, LPCSTR lpFilename, CONST RECT *lprc, LPCSTR lpDesc); 401 | static HDC WINAPI MyCreateEnhMetaFileW( HDC hdc, LPCWSTR lpFilename, CONST RECT *lprc, LPCWSTR lpDesc); 402 | static HENHMETAFILE WINAPI MyGetEnhMetaFileA( LPCSTR lpName ); 403 | static HENHMETAFILE WINAPI MyGetEnhMetaFileW( LPCWSTR lpName ); 404 | static HMETAFILE WINAPI MyGetMetaFileA( LPCSTR lpName); 405 | static HMETAFILE WINAPI MyGetMetaFileW( LPCWSTR lpName ); 406 | static BOOL WINAPI MyDeleteMetaFile( HMETAFILE hmf ); 407 | static BOOL WINAPI MyDeleteEnhMetaFile( HENHMETAFILE hmf ); 408 | static HENHMETAFILE WINAPI MyCopyEnhMetaFileA( HENHMETAFILE hEnh, LPCSTR lpFileName); 409 | static HENHMETAFILE WINAPI MyCopyEnhMetaFileW( HENHMETAFILE hEnh, LPCWSTR lpFileName); 410 | static HENHMETAFILE WINAPI MyCloseEnhMetaFile( HDC hdc); 411 | static HMETAFILE WINAPI MyCloseMetaFile( HDC hdc); 412 | 413 | // Pen 414 | static HPEN WINAPI MyCreatePen( int iStyle, int cWidth, COLORREF color); 415 | static HPEN WINAPI MyCreatePenIndirect( CONST LOGPEN *plpen); 416 | static HPEN WINAPI MyExtCreatePen( DWORD iPenStyle, DWORD cWidth, CONST LOGBRUSH *plbrush, DWORD cStyle, CONST DWORD *pstyle); 417 | 418 | // Region 419 | static HRGN WINAPI MyPathToRegion( HDC hdc); 420 | static HRGN WINAPI MyCreateEllipticRgn( int x1, int y1, int x2, int y2); 421 | static HRGN WINAPI MyCreateEllipticRgnIndirect( CONST RECT *lprect); 422 | static HRGN WINAPI MyCreatePolygonRgn( CONST POINT *pptl, int cPoint, int iMode); 423 | static HRGN WINAPI MyCreatePolyPolygonRgn( CONST POINT *pptl, CONST INT *pc, int cPoly, int iMode); 424 | static HRGN WINAPI MyCreateRectRgn( int x1, int y1, int x2, int y2); 425 | static HRGN WINAPI MyCreateRectRgnIndirect( CONST RECT *lprect); 426 | static HRGN WINAPI MyCreateRoundRectRgn( int x1, int y1, int x2, int y2, int w, int h); 427 | static HRGN WINAPI MyExtCreateRegion( CONST XFORM * lpx, DWORD nCount, CONST RGNDATA * lpData); 428 | 429 | // Palette 430 | static HPALETTE WINAPI MyCreateHalftonePalette( HDC hdc); 431 | static HPALETTE WINAPI MyCreatePalette( CONST LOGPALETTE * plpal ); 432 | 433 | 434 | 435 | // 436 | // Add a newly intercepted function to the container 437 | // 438 | BOOL AddHook( 439 | PCSTR pszCalleeModName, 440 | PCSTR pszFuncName, 441 | PROC pfnOrig, 442 | PROC pfnHook 443 | ); 444 | // 445 | // Remove intercepted function from the container 446 | // 447 | BOOL RemoveHook( 448 | PCSTR pszCalleeModName, 449 | PCSTR pszFuncName 450 | ); 451 | }; 452 | 453 | 454 | ////////////////////////////////////////////////////////////////////////////// 455 | // 456 | // class CHookedFunction 457 | // 458 | ////////////////////////////////////////////////////////////////////////////// 459 | class CHookedFunction 460 | { 461 | public: 462 | CHookedFunction( 463 | CHookedFunctions* pHookedFunctions, 464 | PCSTR pszCalleeModName, 465 | PCSTR pszFuncName, 466 | PROC pfnOrig, 467 | PROC pfnHook 468 | ); 469 | virtual ~CHookedFunction(); 470 | 471 | PCSTR Get_CalleeModName() const; 472 | PCSTR Get_FuncName() const; 473 | PROC Get_pfnHook() const; 474 | PROC Get_pfnOrig() const; 475 | // 476 | // Set up a new hook function 477 | // 478 | BOOL HookImport(); 479 | // 480 | // Restore the original API handler 481 | // 482 | BOOL UnHookImport(); 483 | // 484 | // Replace the address of the function in the IAT of a specific module 485 | // 486 | BOOL ReplaceInOneModule( 487 | PCSTR pszCalleeModName, 488 | PROC pfnCurrent, 489 | PROC pfnNew, 490 | HMODULE hmodCaller 491 | ); 492 | // 493 | // Indicates whether the hooked function is mandatory one 494 | // 495 | BOOL IsMandatory(); 496 | 497 | private: 498 | CHookedFunctions* m_pHookedFunctions; 499 | BOOL m_bHooked; 500 | char m_szCalleeModName[MAX_PATH]; 501 | char m_szFuncName[MAX_PATH]; 502 | PROC m_pfnOrig; 503 | PROC m_pfnHook; 504 | // 505 | // Maximum private memory address 506 | // 507 | static PVOID sm_pvMaxAppAddr; 508 | // 509 | // Perform actual replacing of function pointers 510 | // 511 | BOOL DoHook( 512 | BOOL bHookOrRestore, 513 | PROC pfnCurrent, 514 | PROC pfnNew 515 | ); 516 | // 517 | // Replace the address of a imported function entry in all modules 518 | // 519 | BOOL ReplaceInAllModules( 520 | BOOL bHookOrRestore, 521 | PCSTR pszCalleeModName, 522 | PROC pfnCurrent, 523 | PROC pfnNew 524 | ); 525 | }; 526 | 527 | 528 | ////////////////////////////////////////////////////////////////////////////// 529 | // 530 | // class CNocaseCmp 531 | // 532 | // Implements case-insensitive string compare 533 | // 534 | ////////////////////////////////////////////////////////////////////////////// 535 | class CNocaseCmp 536 | { 537 | public: 538 | // 539 | // A built-in highly efficient method for case-insensitive string compare. 540 | // Returns true, when string x is less than string y 541 | // 542 | bool operator()(const string& x, const string& y) const 543 | { 544 | return ( _stricmp(x.c_str(), y.c_str()) < 0 ); 545 | } 546 | }; 547 | 548 | 549 | ////////////////////////////////////////////////////////////////////////////// 550 | // 551 | // class CHookedFunctions 552 | // 553 | ////////////////////////////////////////////////////////////////////////////// 554 | class CHookedFunctions: public map 555 | { 556 | public: 557 | CHookedFunctions(CApiHookMgr* pApiHookMgr); 558 | virtual ~CHookedFunctions(); 559 | public: 560 | // 561 | // Return the address of an CHookedFunction object 562 | // 563 | CHookedFunction* GetHookedFunction( 564 | PCSTR pszCalleeModName, 565 | PCSTR pszFuncName 566 | ); 567 | // 568 | // Return the address of an CHookedFunction object 569 | // 570 | CHookedFunction* GetHookedFunction( 571 | HMODULE hmod, 572 | PCSTR pszFuncName 573 | ); 574 | // 575 | // Add a new object to the container 576 | // 577 | BOOL AddHook(CHookedFunction* pHook); 578 | // 579 | // Remove exising object pointer from the container 580 | // 581 | BOOL RemoveHook(CHookedFunction* pHook); 582 | private: 583 | // 584 | // Return the name of the function from EAT by its ordinal value 585 | // 586 | BOOL GetFunctionNameFromExportSection( 587 | HMODULE hmodOriginal, 588 | DWORD dwFuncOrdinalNum, 589 | PSTR pszFuncName 590 | ); 591 | // 592 | // Return the name of the function by its ordinal value 593 | // 594 | void GetFunctionNameByOrdinal( 595 | PCSTR pszCalleeModName, 596 | DWORD dwFuncOrdinalNum, 597 | PSTR pszFuncName 598 | ); 599 | 600 | 601 | 602 | CApiHookMgr* m_pApiHookMgr; 603 | }; 604 | 605 | 606 | 607 | #endif // !defined(_APIHOOK_H_) 608 | -------------------------------------------------------------------------------- /src/Parasite/Common/LockMgr.cpp: -------------------------------------------------------------------------------- 1 | #include "LockMgr.h" 2 | 3 | ////////////////////////////////////////////////////////////////////////////// 4 | // 5 | // class CCSWrapper 6 | // 7 | // CRTICIAL_SECTION user object wrapper 8 | // 9 | ////////////////////////////////////////////////////////////////////////////// 10 | 11 | ////////////////////////////////////////////////////////////////////////////// 12 | // 13 | // Constructor 14 | // 15 | ////////////////////////////////////////////////////////////////////////////// 16 | CCSWrapper::CCSWrapper() 17 | { 18 | m_nSpinCount = 0; 19 | ::InitializeCriticalSection( &m_cs ); 20 | } 21 | 22 | ////////////////////////////////////////////////////////////////////////////// 23 | // 24 | // Destructor 25 | // 26 | ////////////////////////////////////////////////////////////////////////////// 27 | CCSWrapper::~CCSWrapper() 28 | { 29 | ::DeleteCriticalSection( &m_cs ); 30 | } 31 | 32 | 33 | ////////////////////////////////////////////////////////////////////////////// 34 | // Enter 35 | // 36 | // This function waits for ownership of the specified critical section object 37 | ////////////////////////////////////////////////////////////////////////////// 38 | void CCSWrapper::Enter() 39 | { 40 | ::EnterCriticalSection( &m_cs ); 41 | m_nSpinCount++; 42 | } 43 | 44 | ////////////////////////////////////////////////////////////////////////////// 45 | // Leave 46 | // 47 | // Releases ownership of the specified critical section object. 48 | ////////////////////////////////////////////////////////////////////////////// 49 | void CCSWrapper::Leave() 50 | { 51 | m_nSpinCount--; 52 | ::LeaveCriticalSection( &m_cs ); 53 | } 54 | 55 | //--------------------- End of the file ------------------------------------- 56 | -------------------------------------------------------------------------------- /src/Parasite/Common/LockMgr.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOCKMGR_H_ 2 | #define _LOCKMGR_H_ 3 | 4 | #include "..\stdafx.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////////// 7 | // 8 | // class CCSWrapper 9 | // 10 | // Win32 CRTICIAL_SECTION user object wrapper 11 | // 12 | ////////////////////////////////////////////////////////////////////////////// 13 | class CCSWrapper 14 | { 15 | public: 16 | CCSWrapper(); 17 | virtual ~CCSWrapper(); 18 | // 19 | // This function waits for ownership of the specified critical section object 20 | // 21 | void Enter(); 22 | // 23 | // Releases ownership of the specified critical section object. 24 | // 25 | void Leave(); 26 | private: 27 | CRITICAL_SECTION m_cs; 28 | long m_nSpinCount; 29 | }; 30 | 31 | 32 | 33 | ////////////////////////////////////////////////////////////////////////////// 34 | // 35 | // class CLockMgr 36 | // 37 | // Provides the access-control mechanism used in controlling access to a resource 38 | // in a multithreaded environment. This class is used in combination with 39 | // CCSWrapper and rather than direct calls for locking and unlocking shared 40 | // resources, it performs it in the constructor and the destructor of the class. 41 | // Having this approach we can just simply instantiate an object of type CCSWrapper 42 | // on the stack in the beginning of the target method. The object will be 43 | // automatically released when it goes out of the scope. This solves the issues 44 | // with exception handling of the protected by CCSWrapper code. 45 | // 46 | ////////////////////////////////////////////////////////////////////////////// 47 | template 48 | class CLockMgr 49 | { 50 | public: 51 | // 52 | // Constructor 53 | // 54 | CLockMgr(T& lockObject, BOOL bEnabled): 55 | m_rLockObject( lockObject ), 56 | m_bEnabled( bEnabled ) 57 | { 58 | if ( m_bEnabled ) 59 | m_rLockObject.Enter(); 60 | } 61 | // 62 | // Destructor 63 | // 64 | virtual ~CLockMgr() 65 | { 66 | if ( m_bEnabled ) 67 | m_rLockObject.Leave(); 68 | } 69 | private: 70 | T& m_rLockObject; 71 | BOOL m_bEnabled; 72 | }; 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /src/Parasite/Common/ModuleInstance.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "..\stdafx.h" 3 | #include "ModuleInstance.h" 4 | #include "SysUtils.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////////// 7 | // 8 | // class CElements 9 | // 10 | ////////////////////////////////////////////////////////////////////////////// 11 | CElements::CElements(): 12 | CModuleList() 13 | { 14 | 15 | } 16 | 17 | CElements::~CElements() 18 | { 19 | 20 | } 21 | ////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // class CLibHandler 24 | // 25 | ////////////////////////////////////////////////////////////////////////////// 26 | CLibHandler::CLibHandler(CRunningProcesses* pProcesses): 27 | m_pProcesses(pProcesses) 28 | { 29 | 30 | } 31 | 32 | CLibHandler::~CLibHandler() 33 | { 34 | 35 | } 36 | 37 | 38 | ////////////////////////////////////////////////////////////////////////////// 39 | // 40 | // class CTaskManager 41 | // 42 | ////////////////////////////////////////////////////////////////////////////// 43 | CTaskManager::CTaskManager(): 44 | m_pLibHandler(NULL) 45 | { 46 | m_pProcesses = new CRunningProcesses(); 47 | 48 | if (IsPsapiSupported()) 49 | m_pLibHandler = new CPsapiHandler(m_pProcesses); 50 | else 51 | if (IsToolHelpSupported()) 52 | m_pLibHandler = new CToolhelpHandler(m_pProcesses); 53 | } 54 | 55 | CTaskManager::~CTaskManager() 56 | { 57 | delete m_pLibHandler; 58 | delete m_pProcesses; 59 | } 60 | 61 | ////////////////////////////////////////////////////////////////////////////// 62 | // Populate 63 | // 64 | // Populate the process and modules list using PSAPI or ToolHlp32 65 | ////////////////////////////////////////////////////////////////////////////// 66 | BOOL CTaskManager::Populate(BOOL bPopulateModules) 67 | { 68 | m_pProcesses->ReleaseAll(); 69 | return m_pLibHandler->PopulateProcesses(bPopulateModules); 70 | } 71 | 72 | 73 | ////////////////////////////////////////////////////////////////////////////// 74 | // PopulateProcess 75 | // 76 | // Populate the module list using PSAPI or ToolHlp32 77 | ////////////////////////////////////////////////////////////////////////////// 78 | BOOL CTaskManager::PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules) 79 | { 80 | m_pProcesses->ReleaseAll(); 81 | return m_pLibHandler->PopulateProcess(dwProcessId, bPopulateModules); 82 | } 83 | 84 | 85 | ////////////////////////////////////////////////////////////////////////////// 86 | // GetProcessCount 87 | // 88 | // Returns a number of currently loaded processes 89 | ////////////////////////////////////////////////////////////////////////////// 90 | DWORD CTaskManager::GetProcessCount() const 91 | { 92 | return m_pProcesses->GetCount(); 93 | } 94 | 95 | 96 | ////////////////////////////////////////////////////////////////////////////// 97 | // GetProcessByIndex 98 | // 99 | // Returns a process from the container 100 | ////////////////////////////////////////////////////////////////////////////// 101 | CExeModuleInstance* CTaskManager::GetProcessByIndex(DWORD dwIndex) 102 | { 103 | return static_cast(m_pProcesses->GetModule(dwIndex)); 104 | } 105 | 106 | ////////////////////////////////////////////////////////////////////////////// 107 | // GetProcessById 108 | // 109 | // Returns a process by its ID 110 | ////////////////////////////////////////////////////////////////////////////// 111 | CExeModuleInstance* CTaskManager::GetProcessById(DWORD dwProcessId) 112 | { 113 | return static_cast 114 | (m_pProcesses->GetProcessById(dwProcessId)); 115 | } 116 | 117 | ////////////////////////////////////////////////////////////////////////////// 118 | // 119 | // class CLoadedModules 120 | // 121 | ////////////////////////////////////////////////////////////////////////////// 122 | CLoadedModules::CLoadedModules(DWORD dwProcessId): 123 | CElements(), 124 | m_dwProcessId(dwProcessId) 125 | { 126 | 127 | } 128 | 129 | CLoadedModules::~CLoadedModules() 130 | { 131 | 132 | } 133 | 134 | ////////////////////////////////////////////////////////////////////////////// 135 | // 136 | // class CRunningProcesses 137 | // 138 | ////////////////////////////////////////////////////////////////////////////// 139 | CRunningProcesses::CRunningProcesses(): 140 | CElements() 141 | { 142 | 143 | } 144 | 145 | CRunningProcesses::~CRunningProcesses() 146 | { 147 | 148 | } 149 | 150 | CExeModuleInstance* CRunningProcesses::GetProcessById(DWORD dwProcessId) 151 | { 152 | CExeModuleInstance* pResult = NULL; 153 | CExeModuleInstance* pProcess; 154 | 155 | for (DWORD i = 0; i < GetCount(); i++) 156 | { 157 | pProcess = static_cast( GetModule(i) ); 158 | if (pProcess->Get_ProcessId() == dwProcessId) 159 | { 160 | pResult = pProcess; 161 | break; 162 | } // if 163 | } // for 164 | return pResult; 165 | } 166 | 167 | ////////////////////////////////////////////////////////////////////////////// 168 | // 169 | // class CPsapiHandler 170 | // 171 | ////////////////////////////////////////////////////////////////////////////// 172 | CPsapiHandler::CPsapiHandler(CRunningProcesses* pProcesses): 173 | CLibHandler(pProcesses), 174 | m_hModPSAPI(NULL), 175 | m_pfnEnumProcesses(NULL), 176 | m_pfnEnumProcessModules(NULL), 177 | m_pfnGetModuleFileNameExA(NULL) 178 | { 179 | 180 | } 181 | 182 | CPsapiHandler::~CPsapiHandler() 183 | { 184 | Finalize(); 185 | } 186 | 187 | ////////////////////////////////////////////////////////////////////////////// 188 | // Initialize 189 | // 190 | ////////////////////////////////////////////////////////////////////////////// 191 | BOOL CPsapiHandler::Initialize() 192 | { 193 | BOOL bResult = FALSE; 194 | // 195 | // Get to the 3 functions in PSAPI.DLL dynamically. We can't 196 | // be sure that PSAPI.DLL has been installed 197 | // 198 | if (NULL == m_hModPSAPI) 199 | m_hModPSAPI = ::LoadLibraryA("PSAPI.DLL"); 200 | 201 | if (NULL != m_hModPSAPI) 202 | { 203 | m_pfnEnumProcesses = (PFNENUMPROCESSES) 204 | ::GetProcAddress(m_hModPSAPI,"EnumProcesses"); 205 | 206 | m_pfnEnumProcessModules = (PFNENUMPROCESSMODULES) 207 | ::GetProcAddress(m_hModPSAPI, "EnumProcessModules"); 208 | 209 | m_pfnGetModuleFileNameExA = (PFNGETMODULEFILENAMEEXA) 210 | ::GetProcAddress(m_hModPSAPI, "GetModuleFileNameExA"); 211 | 212 | } 213 | bResult = 214 | m_pfnEnumProcesses 215 | && m_pfnEnumProcessModules 216 | && m_pfnGetModuleFileNameExA; 217 | 218 | return bResult; 219 | } 220 | 221 | ////////////////////////////////////////////////////////////////////////////// 222 | // Finalize 223 | // 224 | ////////////////////////////////////////////////////////////////////////////// 225 | void CPsapiHandler::Finalize() 226 | { 227 | if (NULL != m_hModPSAPI) 228 | ::FreeLibrary(m_hModPSAPI); 229 | } 230 | 231 | ////////////////////////////////////////////////////////////////////////////// 232 | // PopulateModules 233 | // 234 | // Populate the module list using PSAPI 235 | ////////////////////////////////////////////////////////////////////////////// 236 | BOOL CPsapiHandler::PopulateModules(CModuleInstance* pProcess) 237 | { 238 | BOOL bResult = TRUE; 239 | CModuleInstance *pDllModuleInstance = NULL; 240 | 241 | if (TRUE == Initialize()) 242 | { 243 | DWORD pidArray[1024]; 244 | DWORD cbNeeded; 245 | DWORD nProcesses; 246 | // EnumProcesses returns an array with process IDs 247 | if (m_pfnEnumProcesses(pidArray, sizeof(pidArray), &cbNeeded)) 248 | { 249 | // Determine number of processes 250 | nProcesses = cbNeeded / sizeof(DWORD); 251 | // Release the container 252 | pProcess->ReleaseModules(); 253 | 254 | for (DWORD i = 0; i < nProcesses; i++) 255 | { 256 | HMODULE hModuleArray[1024]; 257 | HANDLE hProcess; 258 | DWORD pid = pidArray[i]; 259 | DWORD nModules; 260 | // Let's open the process 261 | hProcess = ::OpenProcess( 262 | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 263 | FALSE, pid); 264 | 265 | if (!hProcess) 266 | continue; 267 | 268 | if (static_cast(pProcess)->Get_ProcessId() != pid) 269 | { 270 | ::CloseHandle(hProcess); 271 | continue; 272 | } 273 | 274 | // EnumProcessModules function retrieves a handle for 275 | // each module in the specified process. 276 | if (!m_pfnEnumProcessModules( 277 | hProcess, hModuleArray, 278 | sizeof(hModuleArray), &cbNeeded)) 279 | { 280 | ::CloseHandle(hProcess); 281 | continue; 282 | } 283 | 284 | // Calculate number of modules in the process 285 | nModules = cbNeeded / sizeof(hModuleArray[0]); 286 | for (DWORD j = 0; j < nModules; j++) 287 | { 288 | HMODULE hModule = hModuleArray[j]; 289 | char szModuleName[MAX_PATH]; 290 | m_pfnGetModuleFileNameExA( 291 | hProcess, 292 | hModule, 293 | szModuleName, 294 | sizeof(szModuleName) 295 | ); 296 | 297 | if (0 == j) // First module is the EXE. 298 | { 299 | // Do nothing. 300 | } // if 301 | else // Not the first module. It's a DLL 302 | { 303 | pDllModuleInstance = new CModuleInstance( 304 | szModuleName, 305 | hModule 306 | ); 307 | pProcess->AddModule(pDllModuleInstance); 308 | } // else 309 | } // for 310 | ::CloseHandle(hProcess); // We're done with this process handle 311 | } // for 312 | bResult = TRUE; 313 | } // if 314 | else 315 | { 316 | bResult = FALSE; 317 | } 318 | } // if 319 | else 320 | { 321 | bResult = FALSE; 322 | } 323 | return bResult; 324 | } 325 | 326 | 327 | ////////////////////////////////////////////////////////////////////////////// 328 | // PopulateProcesses 329 | // 330 | // Populate the process list using PSAPI 331 | ////////////////////////////////////////////////////////////////////////////// 332 | 333 | BOOL CPsapiHandler::PopulateProcesses(BOOL bPopulateModules) 334 | { 335 | BOOL bResult = TRUE; 336 | CExeModuleInstance* pProcessInfo; 337 | char szModuleName[MAX_PATH]; 338 | 339 | if (TRUE == Initialize()) 340 | { 341 | DWORD pidArray[1024]; 342 | DWORD cbNeeded; 343 | DWORD nProcesses; 344 | 345 | if (m_pfnEnumProcesses(pidArray, sizeof(pidArray), &cbNeeded)) 346 | { 347 | // Determine number of processes 348 | nProcesses = cbNeeded / sizeof(DWORD); 349 | m_pProcesses->ReleaseAll(); 350 | for (DWORD i = 0; i < nProcesses; i++) 351 | { 352 | HMODULE hModuleArray[1024]; 353 | HANDLE hProcess; 354 | DWORD pid = pidArray[i]; 355 | DWORD nModules; 356 | hProcess = ::OpenProcess( 357 | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 358 | FALSE, 359 | pid 360 | ); 361 | if (!hProcess) 362 | continue; 363 | 364 | if (!m_pfnEnumProcessModules(hProcess, hModuleArray, 365 | sizeof(hModuleArray), &cbNeeded)) 366 | { 367 | ::CloseHandle(hProcess); 368 | continue; 369 | } 370 | // Calculate number of modules in the process 371 | nModules = cbNeeded / sizeof(hModuleArray[0]); 372 | 373 | for (DWORD j = 0; j < nModules; j++) 374 | { 375 | HMODULE hModule = hModuleArray[j]; 376 | 377 | m_pfnGetModuleFileNameExA( 378 | hProcess, 379 | hModule, 380 | szModuleName, 381 | sizeof(szModuleName) 382 | ); 383 | 384 | if (0 == j) // First module is the EXE. Just add it to the map 385 | { 386 | pProcessInfo = new CExeModuleInstance( 387 | this, 388 | szModuleName, 389 | hModule, 390 | pid 391 | ); 392 | m_pProcesses->Add(*pProcessInfo); 393 | if (bPopulateModules) 394 | pProcessInfo->PopulateModules(); 395 | break; 396 | } // if 397 | } // for 398 | ::CloseHandle(hProcess); 399 | } // for 400 | 401 | bResult = TRUE; 402 | } // if 403 | else 404 | { 405 | bResult = FALSE; 406 | } 407 | } // if 408 | else 409 | { 410 | bResult = FALSE; 411 | } 412 | 413 | return bResult; 414 | } 415 | 416 | ////////////////////////////////////////////////////////////////////////////// 417 | // PopulateProcess 418 | // 419 | // Populate all modules of a single process 420 | // 421 | ////////////////////////////////////////////////////////////////////////////// 422 | BOOL CPsapiHandler::PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules) 423 | { 424 | BOOL bResult = TRUE; 425 | CExeModuleInstance* pProcessInfo; 426 | 427 | if (TRUE == Initialize()) 428 | { 429 | m_pProcesses->ReleaseAll(); 430 | HMODULE hModuleArray[1024]; 431 | HANDLE hProcess; 432 | DWORD nModules; 433 | DWORD cbNeeded; 434 | hProcess = ::OpenProcess( 435 | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 436 | FALSE, 437 | dwProcessId 438 | ); 439 | if (hProcess) 440 | { 441 | if (!m_pfnEnumProcessModules( 442 | hProcess, 443 | hModuleArray, 444 | sizeof(hModuleArray), 445 | &cbNeeded 446 | )) 447 | ::CloseHandle(hProcess); 448 | else 449 | { 450 | // Calculate number of modules in the process 451 | nModules = cbNeeded / sizeof(hModuleArray[0]); 452 | 453 | for (DWORD j = 0; j < nModules; j++) 454 | { 455 | HMODULE hModule = hModuleArray[j]; 456 | char szModuleName[MAX_PATH]; 457 | 458 | m_pfnGetModuleFileNameExA( 459 | hProcess, 460 | hModule, 461 | szModuleName, 462 | sizeof(szModuleName) 463 | ); 464 | 465 | if (0 == j) // First module is the EXE. Just add it to the map 466 | { 467 | pProcessInfo = new CExeModuleInstance( 468 | this, 469 | szModuleName, 470 | hModule, 471 | dwProcessId 472 | ); 473 | m_pProcesses->Add(*pProcessInfo); 474 | if (bPopulateModules) 475 | pProcessInfo->PopulateModules(); 476 | break; 477 | } // if 478 | } // for 479 | ::CloseHandle(hProcess); 480 | } // if 481 | } // if 482 | } // if 483 | else 484 | { 485 | bResult = FALSE; 486 | } 487 | return bResult; 488 | } 489 | 490 | ////////////////////////////////////////////////////////////////////////////// 491 | // 492 | // class CToolhelpHandler 493 | // 494 | ////////////////////////////////////////////////////////////////////////////// 495 | CToolhelpHandler::CToolhelpHandler(CRunningProcesses* pProcesses): 496 | CLibHandler(pProcesses) 497 | { 498 | 499 | } 500 | 501 | CToolhelpHandler::~CToolhelpHandler() 502 | { 503 | 504 | } 505 | 506 | 507 | ////////////////////////////////////////////////////////////////////////////// 508 | // Initialize 509 | // 510 | ////////////////////////////////////////////////////////////////////////////// 511 | BOOL CToolhelpHandler::Initialize() 512 | { 513 | BOOL bResult = FALSE; 514 | HINSTANCE hInstLib; 515 | 516 | hInstLib = ::LoadLibraryA("Kernel32.DLL"); 517 | if (NULL != hInstLib) 518 | { 519 | // 520 | // We must link to these functions of Kernel32.DLL explicitly. Otherwise 521 | // a module using this code would fail to load under Windows NT, which does not 522 | // have the Toolhelp32 functions in the Kernel32. 523 | // 524 | m_pfnCreateToolhelp32Snapshot = (PFNCREATETOOLHELP32SNAPSHOT) 525 | ::GetProcAddress(hInstLib, "CreateToolhelp32Snapshot"); 526 | m_pfnProcess32First = (PFNPROCESS32FIRST) 527 | ::GetProcAddress(hInstLib, "Process32First"); 528 | m_pfnProcess32Next = (PFNPROCESS32NEXT) 529 | ::GetProcAddress(hInstLib, "Process32Next"); 530 | m_pfnModule32First = (PFNMODULE32FIRST) 531 | ::GetProcAddress(hInstLib, "Module32First"); 532 | m_pfnModule32Next = (PFNMODULE32NEXT) 533 | ::GetProcAddress(hInstLib, "Module32Next"); 534 | 535 | ::FreeLibrary( hInstLib ); 536 | 537 | bResult = m_pfnCreateToolhelp32Snapshot && 538 | m_pfnProcess32First && 539 | m_pfnProcess32Next && 540 | m_pfnModule32First && 541 | m_pfnModule32Next; 542 | } // if 543 | 544 | 545 | return bResult; 546 | } 547 | 548 | ////////////////////////////////////////////////////////////////////////////// 549 | // PopulateModules 550 | // 551 | // Populate the module list using ToolHelp32 552 | ////////////////////////////////////////////////////////////////////////////// 553 | BOOL CToolhelpHandler::PopulateModules(CModuleInstance* pProcess) 554 | { 555 | BOOL bResult = TRUE; 556 | CModuleInstance *pDllModuleInstance = NULL; 557 | HANDLE hSnapshot = INVALID_HANDLE_VALUE; 558 | 559 | hSnapshot = m_pfnCreateToolhelp32Snapshot( 560 | TH32CS_SNAPMODULE, 561 | static_cast(pProcess)->Get_ProcessId()); 562 | 563 | MODULEENTRY32 me = { sizeof(me) }; 564 | 565 | for (BOOL bOk = ModuleFirst(hSnapshot, &me); bOk; bOk = ModuleNext(hSnapshot, &me)) 566 | { 567 | // We don't need to add to the list the process itself. 568 | // The module list should keep references to DLLs only 569 | if (0 != _stricmp(pProcess->GetBaseName(), me.szModule)) 570 | { 571 | pDllModuleInstance = new CModuleInstance(me.szExePath, me.hModule); 572 | pProcess->AddModule(pDllModuleInstance); 573 | } 574 | else 575 | // 576 | // However, we should fix up the module of the EXE, because 577 | // th32ModuleID member has meaning only to the tool help functions 578 | // and it is not usable by Win32 API elements. 579 | // 580 | { 581 | pProcess->Set_Module( me.hModule ); 582 | } 583 | } // for 584 | 585 | if (hSnapshot != INVALID_HANDLE_VALUE) 586 | ::CloseHandle(hSnapshot); 587 | 588 | return bResult; 589 | } 590 | 591 | BOOL CToolhelpHandler::ModuleFirst(HANDLE hSnapshot, PMODULEENTRY32 pme) const 592 | { 593 | return m_pfnModule32First(hSnapshot, pme); 594 | } 595 | 596 | BOOL CToolhelpHandler::ModuleNext(HANDLE hSnapshot, PMODULEENTRY32 pme) const 597 | { 598 | return m_pfnModule32Next(hSnapshot, pme); 599 | } 600 | 601 | 602 | BOOL CToolhelpHandler::ProcessFirst(HANDLE hSnapshot, PROCESSENTRY32* pe32) const 603 | { 604 | return m_pfnProcess32First(hSnapshot, pe32); 605 | } 606 | 607 | BOOL CToolhelpHandler::ProcessNext(HANDLE hSnapshot, PROCESSENTRY32* pe32) const 608 | { 609 | return m_pfnProcess32Next(hSnapshot, pe32); 610 | } 611 | 612 | ////////////////////////////////////////////////////////////////////////////// 613 | // PopulateProcesses 614 | // 615 | // Populate the process list using Toolhelp 616 | ////////////////////////////////////////////////////////////////////////////// 617 | 618 | BOOL CToolhelpHandler::PopulateProcesses(BOOL bPopulateModules) 619 | { 620 | return PopulateProcess(NULL, bPopulateModules); 621 | } 622 | 623 | ////////////////////////////////////////////////////////////////////////////// 624 | // PopulateProcess 625 | // 626 | // Populate all modules of a single process 627 | // 628 | ////////////////////////////////////////////////////////////////////////////// 629 | BOOL CToolhelpHandler::PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules) 630 | { 631 | BOOL bResult = FALSE; 632 | CExeModuleInstance* pProcessInfo; 633 | HANDLE hSnapshot = INVALID_HANDLE_VALUE; 634 | 635 | if (TRUE == Initialize()) 636 | { 637 | hSnapshot = m_pfnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, dwProcessId); 638 | 639 | PROCESSENTRY32 pe32 = { sizeof(pe32) }; 640 | 641 | for (BOOL bOk = ProcessFirst(hSnapshot, &pe32); bOk; bOk = ProcessNext(hSnapshot, &pe32)) 642 | { 643 | if ( (dwProcessId != NULL) && (dwProcessId != pe32.th32ProcessID) ) 644 | continue; 645 | 646 | pProcessInfo = new CExeModuleInstance( 647 | this, 648 | pe32.szExeFile, 649 | NULL, // We will fix up later this value 650 | pe32.th32ProcessID 651 | ); 652 | m_pProcesses->Add(*pProcessInfo); 653 | if (bPopulateModules) 654 | pProcessInfo->PopulateModules(); 655 | 656 | if (dwProcessId != NULL) 657 | break; 658 | } // for 659 | 660 | if (hSnapshot != INVALID_HANDLE_VALUE) 661 | ::CloseHandle(hSnapshot); 662 | 663 | bResult = TRUE; 664 | } 665 | 666 | return bResult; 667 | } 668 | 669 | 670 | ////////////////////////////////////////////////////////////////////////////// 671 | // 672 | // class CModuleList 673 | // 674 | ////////////////////////////////////////////////////////////////////////////// 675 | 676 | CModuleList::CModuleList() 677 | { 678 | 679 | } 680 | 681 | CModuleList::~CModuleList() 682 | { 683 | ReleaseAll(); 684 | } 685 | 686 | ////////////////////////////////////////////////////////////////////////////// 687 | // Add 688 | // 689 | // Add new object to the container 690 | ////////////////////////////////////////////////////////////////////////////// 691 | void CModuleList::Add(CModuleInstance &moduleInstance) 692 | { 693 | push_back(&moduleInstance); 694 | } 695 | 696 | ////////////////////////////////////////////////////////////////////////////// 697 | // ReleaseAll 698 | // 699 | // Release all objects and clear the list 700 | ////////////////////////////////////////////////////////////////////////////// 701 | void CModuleList::ReleaseAll() 702 | { 703 | CModuleList::iterator itr; 704 | CModuleInstance *pModuleInstance; 705 | 706 | for (itr = begin(); itr != end(); ++itr) 707 | { 708 | pModuleInstance = *itr; 709 | delete pModuleInstance; 710 | } // for 711 | clear(); 712 | } 713 | 714 | ////////////////////////////////////////////////////////////////////////////// 715 | // GetModule 716 | // 717 | // Return a module object by its index (Pascal-like style) 718 | ////////////////////////////////////////////////////////////////////////////// 719 | CModuleInstance* CModuleList::GetModule(DWORD dwIndex) const 720 | { 721 | return at(dwIndex); 722 | } 723 | 724 | ////////////////////////////////////////////////////////////////////////////// 725 | // GetCount 726 | // 727 | // Return number of items in the container 728 | ////////////////////////////////////////////////////////////////////////////// 729 | DWORD CModuleList::GetCount() const 730 | { 731 | return size(); 732 | } 733 | 734 | ////////////////////////////////////////////////////////////////////////////// 735 | // 736 | // class CModuleInstance 737 | // 738 | ////////////////////////////////////////////////////////////////////////////// 739 | CModuleInstance::CModuleInstance(char *pszName, HMODULE hModule): 740 | m_pszName(NULL), 741 | m_hModule(NULL), 742 | m_pInternalList(NULL) 743 | { 744 | Set_Name(pszName); 745 | Set_Module(hModule); 746 | 747 | } 748 | 749 | CModuleInstance::~CModuleInstance() 750 | { 751 | delete m_pInternalList; 752 | 753 | if (NULL != m_pszName) 754 | delete [] m_pszName; 755 | } 756 | 757 | 758 | void CModuleInstance::AddModule(CModuleInstance* pModuleInstance) 759 | { 760 | if (NULL == m_pInternalList) 761 | m_pInternalList = new CModuleList(); 762 | m_pInternalList->Add(*pModuleInstance); 763 | } 764 | 765 | void CModuleInstance::ReleaseModules() 766 | { 767 | if (NULL != m_pInternalList) 768 | m_pInternalList->ReleaseAll(); 769 | } 770 | 771 | char* CModuleInstance::Get_Name() const 772 | { 773 | return m_pszName; 774 | } 775 | 776 | char* CModuleInstance::GetBaseName() const 777 | { 778 | char *pdest; 779 | int ch = '\\'; 780 | // Search backward 781 | pdest = strrchr(m_pszName, ch); 782 | if(pdest != NULL) 783 | return &pdest[1]; 784 | else 785 | return m_pszName; 786 | } 787 | 788 | void CModuleInstance::Set_Name(char *pszName) 789 | { 790 | if (NULL != m_pszName) 791 | delete [] m_pszName; 792 | if ((NULL != pszName) && (strlen(pszName))) 793 | { 794 | m_pszName = new char[strlen(pszName) + 1]; 795 | strcpy(m_pszName, pszName); 796 | } 797 | else 798 | { 799 | m_pszName = new char[strlen("\0") + 1]; 800 | strcpy(m_pszName, "\0"); 801 | } 802 | 803 | } 804 | 805 | HMODULE CModuleInstance::Get_Module() const 806 | { 807 | return m_hModule; 808 | } 809 | 810 | void CModuleInstance::Set_Module(HMODULE module) 811 | { 812 | m_hModule = module; 813 | } 814 | 815 | 816 | ////////////////////////////////////////////////////////////////////////////// 817 | // 818 | // class CExeModuleInstance 819 | // 820 | ////////////////////////////////////////////////////////////////////////////// 821 | 822 | CExeModuleInstance::CExeModuleInstance( 823 | CLibHandler* pLibHandler, 824 | char* pszName, 825 | HMODULE hModule, 826 | DWORD dwProcessId 827 | ): 828 | CModuleInstance(pszName, hModule), 829 | m_pLibHandler(pLibHandler), 830 | m_dwProcessId(dwProcessId) 831 | { 832 | 833 | } 834 | 835 | CExeModuleInstance::~CExeModuleInstance() 836 | { 837 | 838 | } 839 | 840 | DWORD CExeModuleInstance::Get_ProcessId() const 841 | { 842 | return m_dwProcessId; 843 | } 844 | 845 | BOOL CExeModuleInstance::PopulateModules() 846 | { 847 | return m_pLibHandler->PopulateModules(this); 848 | } 849 | 850 | 851 | DWORD CExeModuleInstance::GetModuleCount() 852 | { 853 | return m_pInternalList ? m_pInternalList->GetCount() : 0; 854 | } 855 | 856 | CModuleInstance* CExeModuleInstance::GetModuleByIndex(DWORD dwIndex) 857 | { 858 | return m_pInternalList ? m_pInternalList->GetModule(dwIndex) : NULL; 859 | } 860 | 861 | //----------------------------End of the file ------------------------------- -------------------------------------------------------------------------------- /src/Parasite/Common/ModuleInstance.h: -------------------------------------------------------------------------------- 1 | 2 | #if !defined(_MODULEINSTANCE_H_) 3 | #define _MODULEINSTANCE_H_ 4 | 5 | 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // Forward declaration 13 | class CModuleInstance; 14 | class CModuleList; 15 | class CRunningProcesses; 16 | class CExeModuleInstance; 17 | 18 | ////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // typedefs for ToolHelp32 functions 21 | // 22 | // We must link to these functions of Kernel32.DLL explicitly. Otherwise 23 | // a module using this code would fail to load under Windows NT, which does not 24 | // have the Toolhelp32 functions in the Kernel 32. 25 | // 26 | ////////////////////////////////////////////////////////////////////////////// 27 | typedef HANDLE (WINAPI * PFNCREATETOOLHELP32SNAPSHOT)( 28 | DWORD dwFlags, 29 | DWORD th32ProcessID 30 | ); 31 | 32 | typedef BOOL (WINAPI * PFNPROCESS32FIRST)( 33 | HANDLE hSnapshot, 34 | LPPROCESSENTRY32 lppe 35 | ); 36 | 37 | typedef BOOL (WINAPI * PFNPROCESS32NEXT)( 38 | HANDLE hSnapshot, 39 | LPPROCESSENTRY32 lppe 40 | ); 41 | 42 | typedef BOOL (WINAPI * PFNMODULE32FIRST)( 43 | HANDLE hSnapshot, 44 | LPMODULEENTRY32 lpme 45 | ); 46 | 47 | typedef BOOL (WINAPI * PFNMODULE32NEXT)( 48 | HANDLE hSnapshot, 49 | LPMODULEENTRY32 lpme 50 | ); 51 | 52 | 53 | ////////////////////////////////////////////////////////////////////////////// 54 | // 55 | // typedefs for PSAPI.DLL functions 56 | // 57 | ////////////////////////////////////////////////////////////////////////////// 58 | typedef BOOL (WINAPI * PFNENUMPROCESSES)( 59 | DWORD * lpidProcess, 60 | DWORD cb, 61 | DWORD * cbNeeded 62 | ); 63 | 64 | typedef BOOL (WINAPI * PFNENUMPROCESSMODULES)( 65 | HANDLE hProcess, 66 | HMODULE *lphModule, 67 | DWORD cb, 68 | LPDWORD lpcbNeeded 69 | ); 70 | 71 | typedef DWORD (WINAPI * PFNGETMODULEFILENAMEEXA)( 72 | HANDLE hProcess, 73 | HMODULE hModule, 74 | LPSTR lpFilename, 75 | DWORD nSize 76 | ); 77 | 78 | 79 | ////////////////////////////////////////////////////////////////////////////// 80 | // 81 | // class CModuleList 82 | // 83 | // A simple container for maintaining CModuleInstance objects 84 | // 85 | ////////////////////////////////////////////////////////////////////////////// 86 | class CModuleList: private std::vector 87 | { 88 | public: 89 | CModuleList(); 90 | virtual ~CModuleList(); 91 | // 92 | // Add new object to the container 93 | // 94 | void Add(CModuleInstance &moduleInstance); 95 | // 96 | // Release all objects and clear the list 97 | // 98 | void ReleaseAll(); 99 | // 100 | // Return a module object by its index (Pascal-like style) 101 | // 102 | CModuleInstance* GetModule(DWORD dwIndex) const; 103 | // 104 | // Return number of items in the container 105 | // 106 | DWORD GetCount() const; 107 | }; 108 | 109 | ////////////////////////////////////////////////////////////////////////////// 110 | // 111 | // class CElements 112 | // 113 | ////////////////////////////////////////////////////////////////////////////// 114 | class CElements: public CModuleList 115 | { 116 | public: 117 | CElements(); 118 | virtual ~CElements(); 119 | }; 120 | 121 | ////////////////////////////////////////////////////////////////////////////// 122 | // 123 | // class CLibHandler 124 | // 125 | ////////////////////////////////////////////////////////////////////////////// 126 | class CLibHandler 127 | { 128 | public: 129 | CLibHandler(CRunningProcesses* pProcesses); 130 | virtual ~CLibHandler(); 131 | 132 | virtual BOOL PopulateModules(CModuleInstance* pProcess) = 0; 133 | virtual BOOL PopulateProcesses(BOOL bPopulateModules) = 0; 134 | virtual BOOL PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules) = 0; 135 | protected: 136 | CRunningProcesses* m_pProcesses; 137 | }; 138 | 139 | ////////////////////////////////////////////////////////////////////////////// 140 | // 141 | // class CTaskManager 142 | // 143 | ////////////////////////////////////////////////////////////////////////////// 144 | class CTaskManager 145 | { 146 | public: 147 | CTaskManager(); 148 | virtual ~CTaskManager(); 149 | 150 | BOOL Populate(BOOL bPopulateModules); 151 | BOOL PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules); 152 | DWORD GetProcessCount() const; 153 | CExeModuleInstance* GetProcessByIndex(DWORD dwIndex); 154 | CExeModuleInstance* GetProcessById(DWORD dwProcessId); 155 | private: 156 | CLibHandler *m_pLibHandler; 157 | CRunningProcesses *m_pProcesses; 158 | }; 159 | 160 | 161 | ////////////////////////////////////////////////////////////////////////////// 162 | // 163 | // class CLoadedModules 164 | // 165 | ////////////////////////////////////////////////////////////////////////////// 166 | class CLoadedModules: public CElements 167 | { 168 | public: 169 | CLoadedModules(DWORD dwProcessId); 170 | virtual ~CLoadedModules(); 171 | protected: 172 | DWORD m_dwProcessId; 173 | }; 174 | 175 | ////////////////////////////////////////////////////////////////////////////// 176 | // 177 | // class CRunningProcesses 178 | // 179 | ////////////////////////////////////////////////////////////////////////////// 180 | class CRunningProcesses: public CElements 181 | { 182 | public: 183 | CRunningProcesses(); 184 | virtual ~CRunningProcesses(); 185 | CExeModuleInstance* GetProcessById(DWORD dwProcessId); 186 | }; 187 | 188 | 189 | ////////////////////////////////////////////////////////////////////////////// 190 | // 191 | // class CPsapiHandler 192 | // 193 | ////////////////////////////////////////////////////////////////////////////// 194 | class CPsapiHandler: public CLibHandler 195 | { 196 | public: 197 | CPsapiHandler(CRunningProcesses* pProcesses); 198 | virtual ~CPsapiHandler(); 199 | 200 | BOOL Initialize(); 201 | void Finalize(); 202 | virtual BOOL PopulateModules(CModuleInstance* pProcess); 203 | virtual BOOL PopulateProcesses(BOOL bPopulateModules); 204 | virtual BOOL PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules); 205 | private: 206 | HMODULE m_hModPSAPI; 207 | PFNENUMPROCESSES m_pfnEnumProcesses; 208 | PFNENUMPROCESSMODULES m_pfnEnumProcessModules; 209 | PFNGETMODULEFILENAMEEXA m_pfnGetModuleFileNameExA; 210 | }; 211 | 212 | ////////////////////////////////////////////////////////////////////////////// 213 | // 214 | // class CToolhelpHandler 215 | // 216 | ////////////////////////////////////////////////////////////////////////////// 217 | class CToolhelpHandler: public CLibHandler 218 | { 219 | public: 220 | CToolhelpHandler(CRunningProcesses* pProcesses); 221 | virtual ~CToolhelpHandler(); 222 | 223 | BOOL Initialize(); 224 | virtual BOOL PopulateModules(CModuleInstance* pProcess); 225 | virtual BOOL PopulateProcesses(BOOL bPopulateModules); 226 | virtual BOOL PopulateProcess(DWORD dwProcessId, BOOL bPopulateModules); 227 | private: 228 | BOOL ModuleFirst(HANDLE hSnapshot, PMODULEENTRY32 pme) const; 229 | BOOL ModuleNext(HANDLE hSnapshot, PMODULEENTRY32 pme) const; 230 | BOOL ProcessFirst(HANDLE hSnapshot, PROCESSENTRY32* pe32) const; 231 | BOOL ProcessNext(HANDLE hSnapshot, PROCESSENTRY32* pe32) const; 232 | // 233 | // ToolHelp function pointers 234 | // 235 | PFNCREATETOOLHELP32SNAPSHOT m_pfnCreateToolhelp32Snapshot; 236 | PFNPROCESS32FIRST m_pfnProcess32First; 237 | PFNPROCESS32NEXT m_pfnProcess32Next; 238 | PFNMODULE32FIRST m_pfnModule32First; 239 | PFNMODULE32NEXT m_pfnModule32Next; 240 | }; 241 | 242 | ////////////////////////////////////////////////////////////////////////////// 243 | // 244 | // class CModuleInstance 245 | // 246 | // Represents exactly one loaded module 247 | // 248 | ////////////////////////////////////////////////////////////////////////////// 249 | class CModuleInstance 250 | { 251 | public: 252 | CModuleInstance(char *pszName, HMODULE hModule); 253 | virtual ~CModuleInstance(); 254 | 255 | void AddModule(CModuleInstance* pModuleInstance); 256 | void ReleaseModules(); 257 | 258 | // Returns Full path and filename of the executable file for the process or DLL 259 | char* Get_Name() const; 260 | // Sets Full path and filename of the executable file for the process or DLL 261 | void Set_Name(char *pszName); 262 | // Returns module handle 263 | HMODULE Get_Module() const; 264 | void Set_Module(HMODULE module); 265 | // Returns only the filename of the executable file for the process or DLL 266 | char* GetBaseName() const; 267 | 268 | private: 269 | char *m_pszName; 270 | HMODULE m_hModule; 271 | protected: 272 | CModuleList *m_pInternalList; 273 | }; 274 | 275 | ////////////////////////////////////////////////////////////////////////////// 276 | // 277 | // class CExeModuleInstance 278 | // 279 | // Represents exactly one loaded EXE module 280 | // 281 | ////////////////////////////////////////////////////////////////////////////// 282 | class CExeModuleInstance: public CModuleInstance 283 | { 284 | public: 285 | CExeModuleInstance( 286 | CLibHandler* pLibHandler, 287 | char* pszName, 288 | HMODULE hModule, 289 | DWORD dwProcessId 290 | ); 291 | virtual ~CExeModuleInstance(); 292 | // Returns process id 293 | DWORD Get_ProcessId() const; 294 | BOOL PopulateModules(); 295 | DWORD GetModuleCount(); 296 | CModuleInstance* GetModuleByIndex(DWORD dwIndex); 297 | private: 298 | DWORD m_dwProcessId; 299 | CLibHandler* m_pLibHandler; 300 | }; 301 | 302 | 303 | #endif -------------------------------------------------------------------------------- /src/Parasite/Common/SysUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYSUTILS_H_ 2 | #define _SYSUTILS_H_ 3 | 4 | 5 | #include "..\stdafx.h" 6 | 7 | 8 | static BOOL IsToolHelpSupported() 9 | { 10 | 11 | BOOL bResult(FALSE); 12 | HMODULE hModToolHelp; 13 | PROC pfnCreateToolhelp32Snapshot; 14 | 15 | hModToolHelp = ::LoadLibrary( "KERNEL32.DLL" ); 16 | if (NULL != hModToolHelp) 17 | { 18 | pfnCreateToolhelp32Snapshot = ::GetProcAddress( 19 | hModToolHelp, 20 | "CreateToolhelp32Snapshot" 21 | ); 22 | bResult = (NULL != pfnCreateToolhelp32Snapshot); 23 | ::FreeLibrary(hModToolHelp); 24 | } // if 25 | 26 | return bResult; 27 | } 28 | 29 | 30 | static BOOL IsPsapiSupported() 31 | { 32 | BOOL bResult = FALSE; 33 | HMODULE hModPSAPI = NULL; 34 | 35 | hModPSAPI = ::LoadLibrary( "PSAPI.DLL" ); 36 | bResult = (NULL != hModPSAPI); 37 | if (NULL != hModPSAPI) 38 | ::FreeLibrary(hModPSAPI); 39 | 40 | return bResult; 41 | } 42 | 43 | static BOOL WINAPI IsWindows9x() 44 | { 45 | BOOL bResult = FALSE; 46 | OSVERSIONINFO vi = { sizeof(vi) }; 47 | 48 | ::GetVersionEx(&vi); 49 | if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) 50 | bResult = TRUE; 51 | 52 | return bResult; 53 | } 54 | 55 | 56 | static BOOL WINAPI IsWindowsNT4() 57 | { 58 | OSVERSIONINFO vi = { sizeof(vi) }; 59 | 60 | ::GetVersionEx(&vi); 61 | 62 | return ( (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) && 63 | (vi.dwMajorVersion == 4) ); 64 | } 65 | 66 | ////////////////////////////////////////////////////////////////////////////// 67 | // ModuleFromAddress 68 | // 69 | // Returns the HMODULE that contains the specified memory address 70 | ////////////////////////////////////////////////////////////////////////////// 71 | static HMODULE ModuleFromAddress(PVOID pv) 72 | { 73 | MEMORY_BASIC_INFORMATION mbi; 74 | 75 | return ((::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 76 | ? (HMODULE) mbi.AllocationBase : NULL); 77 | } 78 | 79 | ////////////////////////////////////////////////////////////////////////////// 80 | // GetProcessHostFullName 81 | // 82 | // Return the path and the name of the current process 83 | ////////////////////////////////////////////////////////////////////////////// 84 | static BOOL GetProcessHostFullName(char* pszFullFileName) 85 | { 86 | DWORD dwResult = 0; 87 | ::ZeroMemory((PBYTE)pszFullFileName, MAX_PATH); 88 | if (TRUE != ::IsBadReadPtr((PBYTE)pszFullFileName, MAX_PATH)) 89 | dwResult = ::GetModuleFileName( 90 | NULL, // handle to module 91 | pszFullFileName, // file name of module 92 | MAX_PATH // size of buffer 93 | ); 94 | 95 | return (dwResult != 0); 96 | } 97 | 98 | 99 | ////////////////////////////////////////////////////////////////////////////// 100 | // GetProcessHostName 101 | // 102 | // Return the name of the current process 103 | ////////////////////////////////////////////////////////////////////////////// 104 | static BOOL GetProcessHostName(char* pszFullFileName) 105 | { 106 | BOOL bResult; 107 | char *pdest; 108 | 109 | int ch = '\\'; 110 | 111 | bResult = GetProcessHostFullName(pszFullFileName); 112 | if (bResult) 113 | { 114 | // Search backward 115 | pdest = strrchr(pszFullFileName, ch); 116 | if( pdest != NULL ) 117 | strcpy(pszFullFileName,&pdest[1]); 118 | } // if 119 | 120 | return bResult; 121 | } 122 | 123 | ////////////////////////////////////////////////////////////////////////////// 124 | // GetProcessHostName 125 | // 126 | // Return the name of the current process 127 | ////////////////////////////////////////////////////////////////////////////// 128 | static BOOL ExtractModuleFileName(char* pszFullFileName) 129 | { 130 | BOOL bResult = FALSE; 131 | 132 | if (TRUE != ::IsBadReadPtr(pszFullFileName, MAX_PATH)) 133 | { 134 | char *pdest; 135 | int ch = '\\'; 136 | 137 | // Search backward 138 | pdest = strrchr(pszFullFileName, ch); 139 | if( pdest != NULL ) 140 | strcpy(pszFullFileName, &pdest[1]); 141 | 142 | bResult = TRUE; 143 | } // if 144 | 145 | return bResult; 146 | } 147 | 148 | ////////////////////////////////////////////////////////////////////////////// 149 | // ReplaceFileName 150 | // 151 | ////////////////////////////////////////////////////////////////////////////// 152 | static BOOL ReplaceFileName( 153 | char* pszOldFileName, 154 | char* pszBaseNewFileName, 155 | char* pszNewFileName 156 | ) 157 | { 158 | BOOL bResult = FALSE; 159 | char *pdest; 160 | int ch = '\\'; 161 | 162 | if ( 163 | (TRUE != ::IsBadReadPtr(pszOldFileName, strlen(pszOldFileName) + 1)) && 164 | (TRUE != ::IsBadReadPtr(pszBaseNewFileName, strlen(pszBaseNewFileName) + 1)) 165 | ) 166 | { 167 | if (TRUE != ::IsBadReadPtr(pszNewFileName, MAX_PATH)) 168 | { 169 | ::ZeroMemory(pszNewFileName, sizeof(MAX_PATH)); 170 | strcpy(pszNewFileName, pszOldFileName); 171 | // Search backward and replaces the dll name with the hook one 172 | pdest = strrchr(pszNewFileName, ch); 173 | if( pdest != NULL ) 174 | strcpy(&pdest[1], pszBaseNewFileName); 175 | else 176 | strcpy(pszNewFileName, pszBaseNewFileName); 177 | 178 | bResult = TRUE; 179 | } // if 180 | } // if 181 | 182 | return bResult; 183 | } 184 | 185 | ////////////////////////////////////////////////////////////////////////////// 186 | // ReplaceFileName 187 | // 188 | ////////////////////////////////////////////////////////////////////////////// 189 | static BOOL ReplaceFileName( 190 | HINSTANCE hOldFile, 191 | char* pszBaseNewFileName, 192 | char* pszNewFileName 193 | ) 194 | { 195 | BOOL bResult = FALSE; 196 | char szFileName[MAX_PATH]; 197 | 198 | if (TRUE != ::IsBadReadPtr(pszBaseNewFileName, strlen(pszBaseNewFileName) + 1)) 199 | { 200 | if (TRUE != ::IsBadReadPtr(pszNewFileName, MAX_PATH)) 201 | { 202 | ::ZeroMemory(pszNewFileName, sizeof(MAX_PATH)); 203 | if (NULL != hOldFile) 204 | { 205 | if (0 != ::GetModuleFileName(hOldFile, szFileName, MAX_PATH)) 206 | bResult = 207 | ReplaceFileName( 208 | szFileName, 209 | pszBaseNewFileName, 210 | pszNewFileName); 211 | } // if 212 | } // if 213 | } // if 214 | 215 | return bResult; 216 | } 217 | 218 | // 219 | // Converts a string to a boolean value 220 | // 221 | static BOOL StrToBool(const char* pszValue) 222 | { 223 | return ( (0 == _stricmp("YES", pszValue)) || 224 | (0 == _stricmp("Y", pszValue)) || 225 | (0 == _stricmp("TRUE", pszValue)) ); 226 | } 227 | 228 | // 229 | // Converts a boolean value to a string 230 | // 231 | static void BoolToStr(BOOL bValue, char* pszResult) 232 | { 233 | bValue ? strcpy(pszResult, "Yes") : 234 | strcpy(pszResult, "No"); 235 | } 236 | 237 | // 238 | // Trims leading spaces and control characters from a string 239 | // 240 | static void TrimLeft( 241 | const char* pszParam, 242 | char* pszResult 243 | ) 244 | { 245 | char szBuffer[MAX_PATH]; 246 | strcpy(szBuffer, "\0"); 247 | if ( (TRUE != ::IsBadStringPtr(pszParam, MAX_PATH)) && 248 | (strlen(pszParam) > 0) ) 249 | { 250 | DWORD dwIndex = 0; 251 | while ( (dwIndex < strlen(pszParam)) && (pszParam[dwIndex] == ' ') ) 252 | dwIndex++; 253 | if (dwIndex < strlen(pszParam)) 254 | strcpy(szBuffer, &pszParam[dwIndex]); 255 | } // if 256 | strcpy(pszResult, szBuffer); 257 | } 258 | 259 | // 260 | // Trims trailing spaces and control characters from a string 261 | // 262 | static void TrimRight( 263 | const char* pszParam, 264 | char* pszResult 265 | ) 266 | { 267 | char szBuffer[MAX_PATH]; 268 | strcpy(szBuffer, "\0"); 269 | if ( (TRUE != ::IsBadStringPtr(pszParam, MAX_PATH)) && 270 | (strlen(pszParam) > 0) ) 271 | { 272 | int nIndex = strlen(pszParam) - 1; 273 | while ( (nIndex >= 0) && (pszParam[nIndex] == ' ') ) 274 | nIndex--; 275 | if (nIndex >= 0) 276 | { 277 | memcpy( 278 | (PBYTE)szBuffer, 279 | (PBYTE)pszParam, 280 | (nIndex + 1) 281 | ); 282 | szBuffer[nIndex+1] = 0; 283 | } // if 284 | } // if 285 | strcpy(pszResult, szBuffer); 286 | } 287 | 288 | // 289 | // Trims leading and trailing spaces and control characters from a string 290 | // 291 | static void Trim( 292 | const char* pszParam, 293 | char* pszResult 294 | ) 295 | { 296 | TrimLeft(pszParam, pszResult); 297 | TrimRight(pszParam, pszResult); 298 | } 299 | 300 | 301 | 302 | // 303 | // Return next entry of an comma separated string 304 | // 305 | static BOOL GetNextCommaSeparatedString( 306 | const char* pszParam, 307 | char* pszResult, 308 | DWORD dwLength, 309 | long* pnCommaPos 310 | ) 311 | { 312 | *pnCommaPos = -1; 313 | BOOL bResult = FALSE; 314 | char* pdest; 315 | strcpy(pszResult, "\0"); 316 | 317 | if (strlen(pszParam) > 0) 318 | { 319 | ::ZeroMemory((PBYTE)pszResult, dwLength); 320 | 321 | pdest = const_cast(strstr(pszParam, ",")); 322 | if (pdest) 323 | *pnCommaPos = pdest - pszParam - 1; 324 | else 325 | *pnCommaPos = strlen(pszParam); 326 | memcpy( 327 | (PBYTE)pszResult, 328 | (PBYTE)pszParam, 329 | ((*pnCommaPos) + 1) 330 | ); 331 | (*pnCommaPos)++; 332 | 333 | Trim(pszResult, pszResult); 334 | 335 | bResult = TRUE; 336 | } // if 337 | 338 | return bResult; 339 | } 340 | 341 | 342 | ////////////////////////////////////////////////////////////////////////////// 343 | // UnicodeToAnsi 344 | // 345 | // Tranlsates Unicode to Ansi strings 346 | ////////////////////////////////////////////////////////////////////////////// 347 | static BOOL UnicodeToAnsi( 348 | LPWSTR pszwUniString, 349 | LPSTR pszAnsiBuff, 350 | DWORD dwAnsiBuffSize 351 | ) 352 | { 353 | int iRet ; 354 | iRet = ::WideCharToMultiByte( 355 | CP_ACP, 356 | 0, 357 | pszwUniString, 358 | -1, 359 | pszAnsiBuff, 360 | dwAnsiBuffSize, 361 | NULL, 362 | NULL 363 | ); 364 | return (0 != iRet); 365 | } 366 | 367 | 368 | #endif -------------------------------------------------------------------------------- /src/Parasite/Common/common.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | HOOK_TYPE_e g_Config::g_HookType = HT_HANDLE; 4 | int g_Config::g_StackDepth = 20; 5 | bool g_Config::g_bTrack = true; 6 | bool g_Config::g_bHooked = false; 7 | CCriticalSection g_Config::SyncObj; 8 | map g_Config::m_MemMap; 9 | CString g_Config::sDllPath; 10 | 11 | #ifdef _M_IX86 12 | void StackDump( LPVOID pMem, DWORD dwBytes) 13 | { 14 | STACKFRAME64 stStackFrame = {0}; 15 | CONTEXT stContext = {0}; 16 | stContext.ContextFlags = CONTEXT_ALL; 17 | __asm call x 18 | __asm x: pop eax 19 | __asm mov stContext.Eip, eax 20 | __asm mov stContext.Ebp, ebp 21 | __asm mov stContext.Esp, esp 22 | 23 | stStackFrame.AddrPC.Offset = stContext.Eip; 24 | stStackFrame.AddrPC.Mode = AddrModeFlat; 25 | stStackFrame.AddrFrame.Offset = stContext.Ebp; 26 | stStackFrame.AddrFrame.Mode = AddrModeFlat; 27 | stStackFrame.AddrStack.Offset = stContext.Esp; 28 | stStackFrame.AddrStack.Mode = AddrModeFlat; 29 | 30 | // BYTE SymBol[ sizeof(SYMBOL_INFO) + STACKWALK_MAX_NAMELEN ] = {0}; 31 | // 32 | // SYMBOL_INFO* pSymbol = (SYMBOL_INFO*)SymBol; 33 | // pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); 34 | // pSymbol->MaxNameLen = STACKWALK_MAX_NAMELEN; 35 | // 36 | // IMAGEHLP_LINE64 Line = {0}; 37 | // Line.SizeOfStruct = sizeof( IMAGEHLP_LINE64 ); 38 | 39 | HANDLE hProcess = GetCurrentProcess(); 40 | MEM_INFO stInfo; 41 | //stInfo.parCallStack = new STACK_ARRAY; 42 | 43 | //void * p = AllocMem(sizeof(STACK_ARRAY)); 44 | //stInfo.parCallStack = new( (void*)p ) STACK_ARRAY; 45 | 46 | stInfo.nMemSize = dwBytes; 47 | for( int i =0; i < g_Config::g_StackDepth ; i++ )// only retrieve 40 functions 48 | { 49 | BOOL b = StackWalk64( IMAGE_FILE_MACHINE_I386, hProcess, GetCurrentThread(), 50 | &stStackFrame ,&stContext, 0, 51 | SymFunctionTableAccess64 , SymGetModuleBase64, NULL ); 52 | if ( !b ) 53 | { 54 | break; 55 | } 56 | DWORD64 dwDisplacement = 0; 57 | if (stStackFrame.AddrPC.Offset == stStackFrame.AddrReturn.Offset) 58 | { 59 | break; 60 | } 61 | 62 | ////////////////////////////////////////////////////////////////////////// 63 | //if( SymFromAddr( hProcess, stStackFrame.AddrPC.Offset, &dwDisplacement, pSymbol )) 64 | //{ 65 | // CString cs = "Ordinal823"; 66 | // if( cs == pSymbol->Name) 67 | // { 68 | // break; 69 | // } 70 | // 71 | //} 72 | ////////////////////////////////////////////////////////////////////////// 73 | 74 | if( i <= 1 )// ignore the functions on the top of stack which is our own. 75 | { 76 | continue; 77 | } 78 | stInfo.parCallStack.push_back( stStackFrame.AddrPC.Offset ); 79 | } 80 | g_Config::m_MemMap[pMem] = stInfo; 81 | } 82 | 83 | #else 84 | void StackDump( LPVOID pMem, SIZE_T dwBytes) 85 | { 86 | 87 | CONTEXT Context; 88 | //KNONVOLATILE_CONTEXT_POINTERS NvContext; 89 | //UNWIND_HISTORY_TABLE UnwindHistoryTable; 90 | PRUNTIME_FUNCTION RuntimeFunction; 91 | PVOID HandlerData; 92 | ULONG64 EstablisherFrame; 93 | ULONG64 ImageBase; 94 | 95 | //OutputDebugString(L"StackTrace64: Executing stack trace...\n"); 96 | 97 | // 98 | // First, we'll get the caller's context. 99 | // 100 | 101 | RtlCaptureContext(&Context); 102 | 103 | // 104 | // Initialize the (optional) unwind history table. 105 | // 106 | 107 | /*RtlZeroMemory( 108 | &UnwindHistoryTable, 109 | sizeof(UNWIND_HISTORY_TABLE));*/ 110 | 111 | 112 | //BYTE SymBol[ sizeof(SYMBOL_INFO) + STACKWALK_MAX_NAMELEN ] = {0}; 113 | //SYMBOL_INFO* pSymbol = (SYMBOL_INFO*)SymBol; 114 | //DWORD64 dwDisplacement; 115 | 116 | HANDLE hProcess = GetCurrentProcess(); 117 | MEM_INFO stInfo; 118 | //stInfo.parCallStack = new STACK_ARRAY; 119 | 120 | //void * p = AllocMem(sizeof(STACK_ARRAY)); 121 | //stInfo.parCallStack = new( (void*)p ) STACK_ARRAY; 122 | 123 | stInfo.nMemSize = dwBytes; 124 | for( int i =0; i < g_StackDepth ; i++ )// only retrieve 40 functions 125 | { 126 | // 127 | // Try to look up unwind metadata for the current function. 128 | // 129 | 130 | RuntimeFunction = RtlLookupFunctionEntry( 131 | Context.Rip, 132 | &ImageBase, 133 | NULL 134 | ); 135 | 136 | /*RtlZeroMemory( 137 | &NvContext, 138 | sizeof(KNONVOLATILE_CONTEXT_POINTERS));*/ 139 | 140 | if (!RuntimeFunction) 141 | { 142 | // 143 | // If we don't have a RUNTIME_FUNCTION, then we've encountered 144 | // a leaf function. Adjust the stack approprately. 145 | // 146 | 147 | Context.Rip = (ULONG64)(*(PULONG64)Context.Rsp); 148 | Context.Rsp += 8; 149 | } 150 | else 151 | { 152 | // 153 | // Otherwise, call upon RtlVirtualUnwind to execute the unwind for 154 | // us. 155 | // 156 | 157 | RtlVirtualUnwind( 158 | 0, //UNW_FLAG_NHANDLER, 159 | ImageBase, 160 | Context.Rip, 161 | RuntimeFunction, 162 | &Context, 163 | &HandlerData, 164 | &EstablisherFrame, 165 | NULL ); 166 | } 167 | 168 | // 169 | // If we reach an RIP of zero, this means that we've walked off the end 170 | // of the call stack and are done. 171 | // 172 | 173 | if (!Context.Rip) 174 | break; 175 | 176 | ////////////////////////////////////////////////////////////////////////// 177 | 178 | //if( SymFromAddr( hProcess, Context.Rip, &dwDisplacement, pSymbol )) 179 | //{ 180 | // CString cs = "Ordinal823"; 181 | // if( cs == pSymbol->Name) 182 | // { 183 | // break; 184 | // } 185 | // 186 | //} 187 | ////////////////////////////////////////////////////////////////////////// 188 | 189 | if( i <= 1 )// ignore the functions on the top of stack which is our own. 190 | { 191 | continue; 192 | } 193 | stInfo.parCallStack.push_back( Context.Rip ); 194 | } 195 | g_Config::m_MemMap[pMem] = stInfo; 196 | } 197 | #endif 198 | 199 | 200 | void CreateCallStack( LPVOID lpMem, SIZE_T dwBytes ) 201 | { 202 | if( !lpMem ) 203 | { 204 | return; 205 | } 206 | try 207 | { 208 | CSingleLock lockObj( &g_Config::SyncObj, TRUE ); 209 | if( g_Config::g_bHooked && g_Config::g_bTrack ) 210 | { 211 | g_Config::g_bTrack = false; 212 | StackDump( lpMem, dwBytes ); 213 | #ifdef ENABLE_LOG 214 | CString cs; 215 | cs.Format( "Allocating %x" ,(UINT)lpMem); 216 | OutputDebugString(cs); 217 | #endif 218 | g_Config::g_bTrack = true; 219 | } 220 | } 221 | catch(...) 222 | { 223 | } 224 | 225 | } 226 | 227 | void RemovCallStack( LPVOID lpMem ) 228 | { 229 | try 230 | { 231 | if( !lpMem ) 232 | { 233 | return; 234 | } 235 | 236 | CSingleLock lockObj( &g_Config::SyncObj, TRUE ); 237 | if( g_Config::g_bHooked && g_Config::g_bTrack ) 238 | { 239 | g_Config::g_bTrack = false; 240 | MEM_INFO stInfo; 241 | if( g_Config::m_MemMap.find(lpMem)!=g_Config::m_MemMap.end()) 242 | { 243 | //delete stInfo.parCallStack; 244 | stInfo = g_Config::m_MemMap[lpMem]; 245 | stInfo.parCallStack.clear(); 246 | stInfo.parCallStack.~vector(); 247 | g_Config::m_MemMap.erase(lpMem); 248 | #ifdef ENABLE_LOG 249 | CString cs; 250 | cs.Format( "De-allocating %x" ,(UINT)lpMem); 251 | OutputDebugString(cs); 252 | #endif 253 | } 254 | g_Config::g_bTrack = true; 255 | } 256 | } 257 | catch(...) 258 | { 259 | } 260 | } 261 | 262 | -------------------------------------------------------------------------------- /src/Parasite/Common/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_DEF_ 2 | #define _COMMON_DEF_ 3 | 4 | #include "..\stdafx.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | enum HOOK_TYPE_e 14 | { 15 | HT_UNKNOWN = 0, 16 | HT_MEMORY = 1, 17 | HT_GDI = 2, 18 | HT_HANDLE = 3, 19 | HT_NOTHING = 4 20 | }; 21 | 22 | typedef vector STACK_ARRAY; 23 | struct MEM_INFO 24 | { 25 | STACK_ARRAY parCallStack; 26 | SIZE_T nMemSize; 27 | }; 28 | 29 | struct g_Config 30 | { 31 | static HOOK_TYPE_e g_HookType; 32 | static int g_StackDepth; 33 | static bool g_bTrack; 34 | static bool g_bHooked; 35 | static CCriticalSection SyncObj; 36 | static map g_Config::m_MemMap; 37 | static CString sDllPath; 38 | }; 39 | 40 | 41 | enum HANDLE_TYPES_e 42 | { 43 | TYPE_EVENT_HANDLE, 44 | TYPE_MUTEX_HANDLE, 45 | TYPE_SEMAPHOR_HANDLE, 46 | TYPE_CRITICAL_SECTION_HANDLE, 47 | TYPE_WAIT_TIMER_HANDLE, 48 | TYPE_FILE_HANDLE, 49 | TYPE_TOKEN_HANDLE, 50 | TYPE_CHANGE_NOFICATION_HANDLE, 51 | TYPE_MEMEORY_MAPPED_FILE_HANDLE, 52 | TYPE_MEMORY_HANDLE, 53 | TYPE_PROCESS_HANDLE, 54 | TYPE_THREAD_HANDLE, 55 | TYPE_JOB_HANDLE, 56 | TYPE_MAIL_SLOT_HANDLE, 57 | TYPE_PIPE_HANDLE, 58 | TYPE_REGISTRY_HANDLE, 59 | TYPE_TIMER_QUEUE, 60 | TYPE_UNKNOWN 61 | }; 62 | 63 | 64 | 65 | 66 | ////////////////////////////////////////////////////////////// 67 | //////////global variables and declarations////////////////// 68 | 69 | 70 | #define STACKWALK_MAX_NAMELEN 1024 71 | 72 | void StackDump( LPVOID pMem, DWORD dwBytes); 73 | void CreateCallStack( LPVOID lpMem, SIZE_T dwBytes ); 74 | void RemovCallStack( LPVOID lpMem ); 75 | void CopyStack(LPVOID lpExisting, LPVOID lpNew, int nType ); 76 | 77 | #endif -------------------------------------------------------------------------------- /src/Parasite/ConfigLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include 3 | #include 4 | #include "parasite.h" 5 | #include "ConfigLoader.h" 6 | #include 7 | 8 | #ifdef _DEBUG 9 | #define new DEBUG_NEW 10 | #undef THIS_FILE 11 | static char THIS_FILE[] = __FILE__; 12 | #endif 13 | 14 | using namespace std; 15 | 16 | bool CConfigLoader::LoadConfig() 17 | { 18 | pugi::xml_document doc; 19 | 20 | m_csDllPath = g_Config::sDllPath; 21 | 22 | dlog("Loading config.xml...") 23 | if(!doc.load_file(m_csDllPath + "config.xml")) 24 | { 25 | dlog("Failed to load config.xml. Default config loaded.") 26 | 27 | return LoadDLL(); 28 | } 29 | 30 | pugi::xml_node pdb = doc.child("WinValgrind").child("PDBInfo"); 31 | pugi::xml_node pdbinfo = pdb.child("PDBInfo1"); 32 | int index = 2; 33 | 34 | do 35 | { 36 | if(pdbinfo==NULL) 37 | break; 38 | m_symbolVec.push_back(pdbinfo.attribute("path").value()); 39 | std::string nextPath = "PDBInfo" + std::to_string (index++); 40 | pdbinfo = pdb.child(nextPath.c_str()); 41 | 42 | }while(pdbinfo!=NULL); 43 | 44 | 45 | if(!LoadDLL()) return false; 46 | 47 | string monType = doc.child("WinValgrind").child("MonitorType").text().get(); 48 | std::transform(monType.begin(), monType.end(),monType.begin(), ::toupper); 49 | 50 | if(monType.compare("MEMORY") == 0) 51 | { 52 | g_Config::g_HookType = HT_MEMORY; 53 | } 54 | else if (monType.compare("GDI") == 0) 55 | { 56 | g_Config::g_HookType = HT_GDI; 57 | } 58 | else 59 | { 60 | g_Config::g_HookType = HT_HANDLE; 61 | } 62 | 63 | return true; 64 | } 65 | 66 | bool CConfigLoader::LoadDLL() 67 | { 68 | dlog("loading symbols...") 69 | HMODULE hModule = GetModuleHandle( _T("dbghelp.dll")); 70 | SymRefreshModuleListDef pSymRefreshModuleList; 71 | 72 | if( hModule ) 73 | { 74 | pSymRefreshModuleList = (SymRefreshModuleListDef)GetProcAddress( hModule, _T("SymRefreshModuleList")); 75 | CString csLoadedDll; 76 | GetModuleFileName( hModule, csLoadedDll.GetBuffer(MAX_PATH), MAX_PATH ); 77 | csLoadedDll.ReleaseBuffer(); 78 | if( !pSymRefreshModuleList ) 79 | { 80 | dlog( "Your application has already loaded dbghelp.dll from " + csLoadedDll + "\n\nFor acqurate results, replace this dll with the latest version of dbghelp.dll coming with \"Debugging tools for windows\" or with the dll the application folder of this utility."); 81 | } 82 | else 83 | { 84 | dlog( "Your application has already loaded dbghelp.dll from " + csLoadedDll + " Please confirm that the symsrv.dll exists in th same folder. Otherwise symbol server will not work."); 85 | } 86 | 87 | } 88 | else 89 | { 90 | dlog("loading dbghelp.dll...") 91 | 92 | m_csDllPath += _T("dbghelp.dll"); 93 | 94 | hModule = LoadLibrary( m_csDllPath ); 95 | if( !hModule) 96 | { 97 | dlog("loaded dbghelp.dll from system path") 98 | 99 | hModule = LoadLibrary( _T("dbghelp.dll")); 100 | pSymRefreshModuleList = (SymRefreshModuleListDef)GetProcAddress( hModule, _T("SymRefreshModuleList")); 101 | if( !pSymRefreshModuleList ) 102 | { 103 | dlog( "Failed to load the dbghelp.dll from the local directory\n\n The application will continue with the default dbghelp.dll. But some feature may be unavailable.") 104 | } 105 | 106 | } 107 | else 108 | { 109 | dlog(m_csDllPath+" loaded") 110 | 111 | pSymRefreshModuleList = (SymRefreshModuleListDef)GetProcAddress( hModule, _T("SymRefreshModuleList")); 112 | } 113 | 114 | } 115 | int nCount = m_symbolVec.size(); 116 | m_csPath.Empty(); 117 | for( int nId = 0;nId < nCount; nId++ ) 118 | { 119 | CString csItem = m_symbolVec[nId].c_str(); 120 | m_csPath += csItem + _T(";"); 121 | } 122 | 123 | dlog("symbol paths from config.xml "+m_csPath) 124 | 125 | SymCleanup(GetCurrentProcess()); 126 | CString csWholePath = m_csPath; 127 | csWholePath.TrimRight( ';' ); 128 | 129 | dlog("Going to load symbols from path "+csWholePath) 130 | 131 | DWORD dwOption = SymGetOptions(); 132 | dwOption |= SYMOPT_CASE_INSENSITIVE|SYMOPT_LOAD_LINES|SYMOPT_FAIL_CRITICAL_ERRORS| 133 | SYMOPT_LOAD_ANYTHING|SYMOPT_UNDNAME; 134 | 135 | SymSetOptions( dwOption ); 136 | CWinThread* pThread = AfxBeginThread( ThreadEntry, this ); 137 | HANDLE hThread = pThread->m_hThread; 138 | 139 | 140 | BOOL fInvadeProcess = (0 == pSymRefreshModuleList)?TRUE:FALSE; 141 | 142 | if(fInvadeProcess) 143 | { 144 | dlog("symbol modules will be loaded for the process") 145 | } 146 | 147 | BOOL bRet = SymInitialize(GetCurrentProcess(), (LPTSTR)csWholePath.operator LPCTSTR() , fInvadeProcess ); 148 | SymRegisterCallback64( GetCurrentProcess(),SymRegisterCallbackProc64,(ULONG64 )this ); 149 | 150 | while( !m_ProgressDlg.m_hWnd )// wait untill the dialog is created 151 | { 152 | Sleep( 50 ); 153 | } 154 | 155 | if( pSymRefreshModuleList ) 156 | { 157 | dlog("refresing module symbol list") 158 | pSymRefreshModuleList( GetCurrentProcess()); 159 | } 160 | 161 | m_ProgressDlg.SendMessage( WM_CLOSE ); 162 | WaitForSingleObject( hThread, 10000 ); 163 | return true; 164 | } 165 | 166 | BOOL CALLBACK CConfigLoader::SymRegisterCallbackProc64(HANDLE hProcess, 167 | ULONG ActionCode, 168 | ULONG64 CallbackData, 169 | ULONG64 UserContext 170 | ) 171 | 172 | { 173 | if( CBA_DEFERRED_SYMBOL_LOAD_START == ActionCode ) 174 | { 175 | PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 pSybolLoadInfo = (PIMAGEHLP_DEFERRED_SYMBOL_LOAD64)CallbackData; 176 | CConfigLoader* pDlg = (CConfigLoader*)UserContext; 177 | CString csLoadtext = _T("Loading symbol for file: "); 178 | csLoadtext += pSybolLoadInfo->FileName; 179 | 180 | dlog(csLoadtext) 181 | 182 | if (pDlg->m_ProgressDlg) 183 | pDlg->m_ProgressDlg.SetDlgItemText( IDC_LOAD_INFO, csLoadtext ); 184 | } 185 | return FALSE; 186 | } 187 | UINT __cdecl CConfigLoader::ThreadEntry( LPVOID pParam ) 188 | { 189 | CConfigLoader* pDlg = (CConfigLoader*)pParam; 190 | pDlg->ShowWaitDialog(); 191 | return 0; 192 | } 193 | 194 | void CConfigLoader::ShowWaitDialog() 195 | { 196 | m_ProgressDlg.DoModal(); 197 | } -------------------------------------------------------------------------------- /src/Parasite/ConfigLoader.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_LOADER_ 2 | #define _CONFIG_LOADER_ 3 | 4 | #include 5 | #include 6 | 7 | typedef BOOL (WINAPI * SymRefreshModuleListDef)( HANDLE hProcess ); 8 | 9 | class CConfigLoader 10 | { 11 | private: 12 | std::vector m_symbolVec; 13 | bool LoadDLL(); 14 | CDialog m_ProgressDlg; 15 | CString m_csPath; 16 | CString m_csDllPath; 17 | protected: 18 | static UINT __cdecl ThreadEntry( LPVOID pParam ); 19 | static BOOL CALLBACK SymRegisterCallbackProc64( HANDLE hProcess, 20 | ULONG ActionCode, 21 | ULONG64 CallbackData, 22 | ULONG64 UserContext ); 23 | void ShowWaitDialog(); 24 | public: 25 | CConfigLoader() : 26 | m_ProgressDlg( IDD_SYM_PROG ) 27 | { 28 | 29 | } 30 | bool LoadConfig(); 31 | }; 32 | 33 | #endif -------------------------------------------------------------------------------- /src/Parasite/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | MICROSOFT FOUNDATION CLASS LIBRARY : parasite Project Overview 3 | ======================================================================== 4 | 5 | 6 | AppWizard has created this parasite DLL for you. This DLL not only 7 | demonstrates the basics of using the Microsoft Foundation classes but 8 | is also a starting point for writing your DLL. 9 | 10 | This file contains a summary of what you will find in each of the files that 11 | make up your parasite DLL. 12 | 13 | parasite.vcxproj 14 | This is the main project file for VC++ projects generated using an Application Wizard. 15 | It contains information about the version of Visual C++ that generated the file, and 16 | information about the platforms, configurations, and project features selected with the 17 | Application Wizard. 18 | 19 | parasite.vcxproj.filters 20 | This is the filters file for VC++ projects generated using an Application Wizard. 21 | It contains information about the association between the files in your project 22 | and the filters. This association is used in the IDE to show grouping of files with 23 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 24 | "Source Files" filter). 25 | 26 | parasite.h 27 | This is the main header file for the DLL. It declares the 28 | CParasiteApp class. 29 | 30 | parasite.cpp 31 | This is the main DLL source file. It contains the class CParasiteApp. 32 | 33 | parasite.rc 34 | This is a listing of all of the Microsoft Windows resources that the 35 | program uses. It includes the icons, bitmaps, and cursors that are stored 36 | in the RES subdirectory. This file can be directly edited in Microsoft 37 | Visual C++. 38 | 39 | res\parasite.rc2 40 | This file contains resources that are not edited by Microsoft 41 | Visual C++. You should place all resources not editable by 42 | the resource editor in this file. 43 | 44 | parasite.def 45 | This file contains information about the DLL that must be 46 | provided to run with Microsoft Windows. It defines parameters 47 | such as the name and description of the DLL. It also exports 48 | functions from the DLL. 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | Other standard files: 52 | 53 | StdAfx.h, StdAfx.cpp 54 | These files are used to build a precompiled header (PCH) file 55 | named parasite.pch and a precompiled types file named StdAfx.obj. 56 | 57 | Resource.h 58 | This is the standard header file, which defines new resource IDs. 59 | Microsoft Visual C++ reads and updates this file. 60 | 61 | ///////////////////////////////////////////////////////////////////////////// 62 | Other notes: 63 | 64 | AppWizard uses "TODO:" to indicate parts of the source code you 65 | should add to or customize. 66 | 67 | ///////////////////////////////////////////////////////////////////////////// 68 | -------------------------------------------------------------------------------- /src/Parasite/parasite.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshulgoel27/WinValgrind/6a9c89c3295d19343f9250ed9aad1d9bc2867e7c/src/Parasite/parasite.aps -------------------------------------------------------------------------------- /src/Parasite/parasite.cpp: -------------------------------------------------------------------------------- 1 | // parasite.cpp : Defines the initialization routines for the DLL. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "parasite.h" 6 | #include "ConfigLoader.h" 7 | 8 | 9 | // CParasiteApp 10 | 11 | BEGIN_MESSAGE_MAP(CParasiteApp, CWinApp) 12 | END_MESSAGE_MAP() 13 | 14 | 15 | 16 | ////////////////////////////////////////////////////////////////////////////////// 17 | 18 | CApiHookMgr* CParasiteApp::sm_pHookMgr = NULL; 19 | 20 | 21 | // CParasiteApp construction 22 | 23 | CParasiteApp::CParasiteApp() 24 | { 25 | // TODO: add construction code here, 26 | // Place all significant initialization in InitInstance 27 | } 28 | 29 | 30 | // The one and only CParasiteApp object 31 | 32 | CParasiteApp theApp; 33 | 34 | DWORD WINAPI CParasiteApp::DumpController( LPVOID pParam ) 35 | { 36 | AFX_MANAGE_STATE( AfxGetStaticModuleState()); 37 | 38 | dlog("DumpController started") 39 | CConfigLoader ConfigLoad; 40 | if(!ConfigLoad.LoadConfig()) 41 | { 42 | dlog("LoadConfig failed!") 43 | dlog("Continuing with default configuration...") 44 | } 45 | 46 | CParasiteApp* thisApp = (CParasiteApp*)pParam; 47 | sm_pHookMgr = new CApiHookMgr(); 48 | 49 | // 50 | // Initially we must hook a few important functions 51 | // 52 | dlog("Hooking system functions.") 53 | if(sm_pHookMgr->HookSystemFuncs()) 54 | { 55 | dlog("System API's hooked.") 56 | } 57 | 58 | 59 | if( HT_MEMORY == g_Config::g_HookType ) 60 | { 61 | dlog("Starting memory leak detection.") 62 | dlog("Hooking memory allocation functions.") 63 | 64 | if(sm_pHookMgr->HookMemAllocFuncs()) 65 | { 66 | dlog("Memory allocation API's hooked.") 67 | } 68 | } 69 | else if( HT_GDI == g_Config::g_HookType ) 70 | { 71 | dlog("Starting GDI object leak detection.") 72 | dlog("Hooking GDI object allocation functions.") 73 | 74 | if(sm_pHookMgr->HookGDIAllocFuncs()) 75 | { 76 | dlog("GDI object allocation API's hooked.") 77 | } 78 | } 79 | else if( HT_HANDLE == g_Config::g_HookType ) 80 | { 81 | dlog("Starting Handle leak detection.") 82 | dlog("Hooking Handle allocation functions.") 83 | 84 | if(sm_pHookMgr->HookHandleAllocFuncs()) 85 | { 86 | dlog("Handle alloc API's hooked.") 87 | } 88 | } 89 | else 90 | { 91 | dlog("Invalid hook type.") 92 | dlog("Setting Handle API hooks.") 93 | 94 | g_Config::g_HookType = HT_HANDLE; 95 | if(sm_pHookMgr->HookHandleAllocFuncs()) 96 | { 97 | dlog("Handle alloc API's hooked.") 98 | } 99 | } 100 | 101 | dlog_v("Hooked API count",sm_pHookMgr->HookedFunctionCount()) 102 | 103 | HANDLE hDumpEvent = CreateEvent( 0, TRUE, FALSE, DUMP_EVENT ); 104 | HANDLE hMemRestEvent = CreateEvent( 0, TRUE, FALSE, CLEAR_LEAKS ); 105 | 106 | HANDLE hArray[2] = { hDumpEvent, hMemRestEvent }; 107 | 108 | g_Config::g_bHooked = true; 109 | while( 1 ) 110 | { 111 | DWORD dwWait = WaitForMultipleObjects( 2, hArray, FALSE, INFINITE ); 112 | CSingleLock lockObj( &g_Config::SyncObj, TRUE ); 113 | g_Config::g_bTrack = false; 114 | lockObj.Unlock(); 115 | if( dwWait == WAIT_OBJECT_0 ) 116 | { 117 | dlog("Dumping leak trace") 118 | ResetEvent( hDumpEvent ); 119 | DumpLeak(); 120 | dlog("Leak trace dumped") 121 | } 122 | else if( dwWait == WAIT_OBJECT_0 + 1) 123 | { 124 | dlog("Clearing leak map") 125 | lockObj.Lock(); 126 | EmptyLeakMap(); 127 | lockObj.Unlock(); 128 | ResetEvent( hMemRestEvent ); 129 | 130 | } 131 | else 132 | { 133 | dlog("Exiting") 134 | break; 135 | } 136 | lockObj.Lock(); 137 | g_Config::g_bTrack = true; 138 | lockObj.Unlock(); 139 | } 140 | 141 | CloseHandle( hDumpEvent ); 142 | CloseHandle( hMemRestEvent ); 143 | return 0; 144 | } 145 | 146 | // CParasiteApp initialization 147 | 148 | BOOL CParasiteApp::InitInstance() 149 | { 150 | 151 | HMODULE hHookDll = GetModuleHandleA( _T("parasite.dll")); 152 | if( GetModuleFileNameA( hHookDll, g_Config::sDllPath.GetBuffer( MAX_PATH), MAX_PATH )) 153 | { 154 | g_Config::sDllPath.ReleaseBuffer(); 155 | int nPos = g_Config::sDllPath.ReverseFind('\\'); 156 | if( 0 < nPos ) 157 | { 158 | g_Config::sDllPath = g_Config::sDllPath.Left( nPos + 1 ); 159 | } 160 | } 161 | 162 | char* pDoLog = getenv ("WINVAL_LOG"); 163 | if(pDoLog!=NULL) 164 | g_bLog = atoi(pDoLog); 165 | 166 | 167 | dlog("Parasite injected") 168 | HANDLE hThread = ::CreateThread(0,0,DumpController,this,0,0); 169 | CloseHandle(hThread); 170 | return CWinApp::InitInstance(); 171 | } 172 | 173 | bool CParasiteApp::Cleanup() 174 | { 175 | dlog("Cleanup") 176 | dlog("Unhooking all functions") 177 | sm_pHookMgr->UnHookAllFuncs(); 178 | 179 | 180 | if(sm_pHookMgr) 181 | delete sm_pHookMgr; 182 | 183 | g_Config::g_bHooked = false; 184 | EmptyLeakMap(); 185 | 186 | return true; 187 | } 188 | int CParasiteApp::ExitInstance() 189 | { 190 | try 191 | { 192 | dlog("DLL_PROCESS_DETACH") 193 | 194 | // Restore the hooks 195 | Cleanup(); 196 | } 197 | catch (...) 198 | { 199 | 200 | } 201 | return CWinApp::ExitInstance(); 202 | } 203 | 204 | CString GetGDIHandleType( HGDIOBJ hObj, SIZE_T nType ) 205 | { 206 | CString csType; 207 | if( nType == IMAGE_ICON ) 208 | { 209 | csType = _T("Icon"); 210 | return csType; 211 | } 212 | else if( nType == IMAGE_CURSOR ) 213 | { 214 | csType = _T("Cursor"); 215 | return csType; 216 | } 217 | 218 | DWORD dwType = GetObjectType( hObj ); 219 | switch( dwType ) 220 | { 221 | case OBJ_BITMAP: 222 | csType = _T("Bitmap"); 223 | break; 224 | case OBJ_BRUSH: 225 | csType = _T("Brush"); 226 | break; 227 | case OBJ_COLORSPACE: 228 | csType = _T("Color space"); 229 | break; 230 | case OBJ_DC: 231 | csType = _T( "Device context"); 232 | break; 233 | case OBJ_ENHMETADC: 234 | csType = _T("Enhanced metafile DC"); 235 | break; 236 | case OBJ_ENHMETAFILE: 237 | csType = _T("Enhanced metafile"); 238 | break; 239 | case OBJ_EXTPEN: 240 | csType = _T("Extended pen"); 241 | break; 242 | case OBJ_FONT: 243 | csType = _T("Font"); 244 | break; 245 | case OBJ_MEMDC: 246 | csType = _T("Memory DC"); 247 | break; 248 | case OBJ_METAFILE: 249 | csType = _T("Metafile"); 250 | break; 251 | case OBJ_METADC: 252 | csType = _T("Metafile DC"); 253 | break; 254 | case OBJ_PAL: 255 | csType = _T("Palette"); 256 | break; 257 | case OBJ_PEN: 258 | csType = _T("Pen"); 259 | break; 260 | case OBJ_REGION: 261 | csType = _T("Region"); 262 | break; 263 | default: 264 | csType = _T("Unknown"); 265 | break; 266 | } 267 | return csType; 268 | 269 | } 270 | 271 | CString GetHandleType( HGDIOBJ hObj, SIZE_T nType ) 272 | { 273 | CString csType; 274 | switch( nType) 275 | { 276 | case TYPE_EVENT_HANDLE: 277 | csType = _T("Event HANDLE"); 278 | break; 279 | case TYPE_MUTEX_HANDLE: 280 | csType = _T("Mutex HANDLE"); 281 | break; 282 | case TYPE_SEMAPHOR_HANDLE: 283 | csType = _T("Semaphore HANDLE"); 284 | break; 285 | case TYPE_CRITICAL_SECTION_HANDLE: 286 | csType = _T("Critical section object"); 287 | break; 288 | case TYPE_WAIT_TIMER_HANDLE: 289 | csType = _T("Waitable timer HANDLE"); 290 | break; 291 | case TYPE_FILE_HANDLE: 292 | csType = _T("File HANDLE"); 293 | break; 294 | case TYPE_TOKEN_HANDLE: 295 | csType = _T("Token HANDLE"); 296 | break; 297 | case TYPE_CHANGE_NOFICATION_HANDLE: 298 | csType = _T("Change Notification HANDLE"); 299 | break; 300 | case TYPE_MEMEORY_MAPPED_FILE_HANDLE: 301 | csType = _T("Memory mapped file HANDLE"); 302 | break; 303 | case TYPE_MEMORY_HANDLE: 304 | csType = _T("Memory HANDLE"); 305 | break; 306 | case TYPE_PROCESS_HANDLE: 307 | csType = _T("Process HANDLE"); 308 | break; 309 | case TYPE_THREAD_HANDLE: 310 | csType = _T("Thread HANDLE"); 311 | break; 312 | case TYPE_JOB_HANDLE: 313 | csType = _T("Job HANDLE"); 314 | break; 315 | case TYPE_MAIL_SLOT_HANDLE: 316 | csType = _T("Mail Slot HANDLE"); 317 | break; 318 | case TYPE_PIPE_HANDLE: 319 | csType = _T("Pipe HANDLE"); 320 | break; 321 | case TYPE_REGISTRY_HANDLE: 322 | csType = _T("Registry HANDLE"); 323 | break; 324 | case TYPE_TIMER_QUEUE: 325 | csType = _T("Timer queue HANDLE"); 326 | break; 327 | default: 328 | csType = _T("unknown type"); 329 | break; 330 | } 331 | return csType; 332 | } 333 | 334 | void DumpLeak() 335 | { 336 | if( 0 == g_Config::m_MemMap.size()) 337 | { 338 | AfxMessageBox( "No leak detected" ); 339 | return; 340 | } 341 | CFileDialog dlg( FALSE, _T(".txt"), _T("Dump.txt")); 342 | if( IDOK != dlg.DoModal()) 343 | { 344 | return; 345 | } 346 | 347 | DumpLeakToFile(dlg.GetPathName()); 348 | } 349 | void DumpLeakToFile(CString fileName) 350 | { 351 | CFile File; 352 | if( !File.Open( fileName, CFile::modeCreate|CFile::modeWrite )) 353 | { 354 | AfxMessageBox( "Failed to create file" ); 355 | return; 356 | } 357 | HANDLE hProcess = GetCurrentProcess(); 358 | DWORD64 dwDisplacement; 359 | 360 | BYTE SymBol[ sizeof(SYMBOL_INFO) + STACKWALK_MAX_NAMELEN ] = {0}; 361 | SYMBOL_INFO* pSymbol = (SYMBOL_INFO*)SymBol; 362 | pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); 363 | pSymbol->MaxNameLen = STACKWALK_MAX_NAMELEN; 364 | 365 | IMAGEHLP_LINE64 Line = {0}; 366 | Line.SizeOfStruct = sizeof( IMAGEHLP_LINE64 ); 367 | 368 | MEM_INFO stInfo; 369 | LPVOID lMem; 370 | map::iterator pos = g_Config::m_MemMap.begin(); 371 | while( pos!=g_Config::m_MemMap.end() ) 372 | { 373 | lMem = pos->first; 374 | stInfo = pos->second; 375 | CString csLength; 376 | if( HT_MEMORY == g_Config::g_HookType ) 377 | { 378 | csLength.Format( "-->Bytes allocated -- %d\r\n\r\n", stInfo.nMemSize ); 379 | } 380 | else if( HT_GDI == g_Config::g_HookType ) 381 | { 382 | CString csType = GetGDIHandleType( lMem, stInfo.nMemSize ); 383 | csLength.Format( "-->%s -- 0x%x\r\n\r\n", csType, lMem ); 384 | //csLength.Format( "Bytes allocated -- %d\r\n\r\n", stInfo.nMemSize ); 385 | } 386 | else if( HT_HANDLE == g_Config::g_HookType ) 387 | { 388 | CString csType = GetHandleType( lMem, stInfo.nMemSize ); 389 | csLength.Format( "-->%s -- 0x%x\r\n\r\n", csType, lMem ); 390 | } 391 | 392 | File.Write( csLength, csLength.GetLength()); 393 | int nCount = (int)stInfo.parCallStack.size(); 394 | for( int nIdx =1;nIdx< nCount;nIdx++ ) 395 | { 396 | DWORD64 dwOffset = stInfo.parCallStack[nIdx]; 397 | 398 | CString cs; 399 | CString csFunctionName; 400 | 401 | if( !SymFromAddr( hProcess, dwOffset, &dwDisplacement, pSymbol )) 402 | { 403 | /*csFunctionName = "Unknown";*/ 404 | MEMORY_BASIC_INFORMATION stMemoryInfo; 405 | HMODULE hModule = 0; 406 | // Get the information about the virtual address space of the calling process 407 | if( VirtualQuery( (void*)dwOffset, &stMemoryInfo, sizeof( stMemoryInfo )) 408 | != 0 ) 409 | { 410 | hModule = reinterpret_cast( 411 | stMemoryInfo.AllocationBase); 412 | } 413 | // Get the exe's or ddl's file name 414 | DWORD dwFileNameLength = GetModuleFileName( hModule, csFunctionName.GetBuffer( MAX_PATH ), MAX_PATH ); 415 | csFunctionName.ReleaseBuffer(); 416 | } 417 | else 418 | { 419 | csFunctionName = pSymbol->Name; 420 | } 421 | 422 | // Get module information 423 | IMAGEHLP_MODULE64 ModuleInfo; 424 | memset(&ModuleInfo, 0, sizeof(ModuleInfo) ); 425 | ModuleInfo.SizeOfStruct = sizeof(ModuleInfo); 426 | BOOL bRet = ::SymGetModuleInfo64( GetCurrentProcess(), pSymbol->ModBase, &ModuleInfo ); 427 | 428 | DWORD dwLine = 0; 429 | if( SymGetLineFromAddr64( hProcess, dwOffset, &dwLine, &Line )) 430 | { 431 | CString csFormatString; 432 | int n = 40 - csFunctionName.GetLength(); 433 | if( !bRet ) 434 | { 435 | csFormatString.Format( _T("%s%d%s"), _T("%s%"), n, _T("s%s(%d)")); 436 | cs.Format( csFormatString, csFunctionName, _T(" "), Line.FileName, Line.LineNumber ); 437 | } 438 | else 439 | { 440 | csFormatString.Format( _T("%s%d%s"), _T("%s%"), n,_T("s%s\t\t%s(%d)")); 441 | cs.Format( csFormatString, ModuleInfo.ModuleName,_T(" "),csFunctionName,Line.FileName, Line.LineNumber ); 442 | } 443 | } 444 | else 445 | { 446 | CString csFormatString; 447 | int n = 40 - csFunctionName.GetLength(); 448 | if(!bRet) 449 | { 450 | csFormatString.Format( _T("%s%d%s"), _T("%"), n, _T("s%s")); 451 | cs.Format(csFormatString,_T(" "),csFunctionName); 452 | } 453 | else 454 | { 455 | csFormatString.Format( _T("%s%d%s"), _T("%s%"), n, _T("s%s")); 456 | cs.Format(csFormatString,ModuleInfo.ModuleName,_T(" "),csFunctionName); 457 | } 458 | } 459 | // CString cs = (*(stInfo.parCallStack)).GetAt( nIdx); 460 | cs += _T("\r\n"); 461 | File.Write( cs, cs.GetLength()); 462 | } 463 | TCHAR tc[] = {"------------------------------------------------\r\n\r\n\r\n\r\n"}; 464 | File.Write( tc, sizeof(tc) - 1); 465 | pos++; 466 | } 467 | File.Close(); 468 | } 469 | 470 | void EmptyLeakMap() 471 | { 472 | map::iterator pos = g_Config::m_MemMap.begin(); 473 | while( pos!=g_Config::m_MemMap.end() ) 474 | { 475 | LPVOID lpMem = pos->first; 476 | MEM_INFO stInfo = pos->second; 477 | 478 | //delete stInfo.parCallStack; 479 | stInfo.parCallStack.clear(); 480 | stInfo.parCallStack.~STACK_ARRAY(); 481 | } 482 | g_Config::m_MemMap.clear(); 483 | } 484 | 485 | 486 | void CopyStack(LPVOID lpExisting, LPVOID lpNew, int nType ) 487 | { 488 | CSingleLock lockObj( &g_Config::SyncObj, TRUE ); 489 | if( g_Config::g_bHooked && g_Config::g_bTrack ) 490 | { 491 | MEM_INFO stInfo; 492 | if( g_Config::m_MemMap.find(lpExisting)!=g_Config::m_MemMap.end()) 493 | { 494 | stInfo = g_Config::m_MemMap[lpExisting]; 495 | MEM_INFO stNew; 496 | stNew.nMemSize = nType; 497 | } 498 | 499 | } 500 | } 501 | 502 | ///////////////////////////////////////////////////////////////////////////////////// 503 | 504 | PARASITE_DLL_EXPORT bool IsLeakDetected( void* pObject ) 505 | { 506 | try 507 | { 508 | if( !pObject ) 509 | { 510 | return false; 511 | } 512 | MEM_INFO stInfo; 513 | if( g_Config::m_MemMap.find(pObject)!=g_Config::m_MemMap.end()) 514 | { 515 | stInfo = g_Config::m_MemMap[pObject]; 516 | return true; 517 | } 518 | } 519 | catch(...) 520 | { 521 | } 522 | return false; 523 | } 524 | 525 | PARASITE_DLL_EXPORT void SetHookType(HOOK_TYPE_e eType ) 526 | { 527 | g_Config::g_HookType = eType; 528 | } -------------------------------------------------------------------------------- /src/Parasite/parasite.def: -------------------------------------------------------------------------------- 1 | ; parasite.def : Declares the module parameters for the DLL. 2 | 3 | LIBRARY 4 | 5 | EXPORTS 6 | ; Explicit exports can go here 7 | -------------------------------------------------------------------------------- /src/Parasite/parasite.h: -------------------------------------------------------------------------------- 1 | // parasite.h : main header file for the parasite DLL 2 | // 3 | 4 | #ifndef _PARASITE_DEF_ 5 | #define _PARASITE_DEF_ 6 | 7 | 8 | #ifndef __AFXWIN_H__ 9 | #error "include 'stdafx.h' before including this file for PCH" 10 | #endif 11 | 12 | #include "resource.h" // main symbols 13 | 14 | // CParasiteApp 15 | // See parasite.cpp for the implementation of this class 16 | // 17 | #include 18 | #include 19 | 20 | 21 | 22 | class CParasiteApp : public CWinApp 23 | { 24 | private: 25 | static CApiHookMgr* sm_pHookMgr; 26 | protected: 27 | static DWORD WINAPI DumpController( LPVOID pParam ); 28 | public: 29 | CParasiteApp(); 30 | bool Cleanup(); 31 | // Overrides 32 | public: 33 | virtual BOOL InitInstance(); 34 | virtual int ExitInstance(); 35 | 36 | DECLARE_MESSAGE_MAP() 37 | }; 38 | 39 | 40 | 41 | void DumpLeak(); 42 | void DumpLeakToFile(CString fileName); 43 | void EmptyLeakMap(); 44 | 45 | #ifdef PARASITE_DLL_SRC 46 | #define PARASITE_DLL_EXPORT extern "C" __declspec(dllexport) 47 | #else 48 | #define PARASITE_DLL_EXPORT extern "C" __declspec(dllimport) 49 | #endif 50 | 51 | PARASITE_DLL_EXPORT bool IsLeakDetected(void* pObject ); 52 | PARASITE_DLL_EXPORT void SetHookType(HOOK_TYPE_e eType ); 53 | 54 | 55 | #endif -------------------------------------------------------------------------------- /src/Parasite/parasite.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshulgoel27/WinValgrind/6a9c89c3295d19343f9250ed9aad1d9bc2867e7c/src/Parasite/parasite.rc -------------------------------------------------------------------------------- /src/Parasite/parasite.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {12AB3998-7533-4B04-A105-E4ACF1A75DE6} 15 | parasite 16 | MFCDLLProj 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | v110_xp 23 | MultiByte 24 | Dynamic 25 | 26 | 27 | DynamicLibrary 28 | false 29 | v110_xp 30 | true 31 | MultiByte 32 | Dynamic 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | true 46 | 47 | 48 | false 49 | 50 | 51 | 52 | NotUsing 53 | Level3 54 | Disabled 55 | WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_DEBUG;_USRDLL;PARASITE_DLL_SRC;%(PreprocessorDefinitions) 56 | .\ApiHooks;.\Common;..\3rdParty 57 | 58 | 59 | Windows 60 | true 61 | .\parasite.def 62 | Dbghelp.lib;mfcs110d.lib;%(AdditionalDependencies) 63 | dbghelp.dll;%(DelayLoadDLLs) 64 | false 65 | 66 | 67 | 68 | false 69 | _DEBUG;%(PreprocessorDefinitions) 70 | 71 | 72 | 0x0409 73 | _DEBUG;%(PreprocessorDefinitions) 74 | $(IntDir);%(AdditionalIncludeDirectories) 75 | 76 | 77 | copy $(SolutionDir)ext-dependencies\$(PlatformTarget)\* $(OutDir) 78 | 79 | 80 | 81 | 82 | Level3 83 | NotUsing 84 | MaxSpeed 85 | true 86 | true 87 | WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;NDEBUG;_USRDLL;PARASITE_DLL_SRC;%(PreprocessorDefinitions) 88 | .\ApiHooks;.\Common;..\3rdParty 89 | 90 | 91 | Windows 92 | true 93 | true 94 | true 95 | .\parasite.def 96 | Dbghelp.lib;mfcs110.lib;%(AdditionalDependencies) 97 | 98 | 99 | false 100 | NDEBUG;%(PreprocessorDefinitions) 101 | 102 | 103 | 0x0409 104 | NDEBUG;%(PreprocessorDefinitions) 105 | $(IntDir);%(AdditionalIncludeDirectories) 106 | 107 | 108 | copy $(SolutionDir)ext-dependencies\$(PlatformTarget)\* $(OutDir) 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | Create 124 | Create 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /src/Parasite/parasite.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;mfcribbon-ms 15 | 16 | 17 | {958d2480-380d-4784-8d97-824a61450464} 18 | 19 | 20 | {0c71bcc9-bbc9-496d-919c-7135b60b50bd} 21 | 22 | 23 | {df5e5c93-46af-4728-ac0f-5baf39527da8} 24 | 25 | 26 | {6cfb754a-3a6a-4af7-abc6-e97135d19017} 27 | 28 | 29 | {e3c008f8-5443-4873-9c18-b18eb9fe5ce1} 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files\Common 44 | 45 | 46 | Source Files\Common 47 | 48 | 49 | Source Files\Common 50 | 51 | 52 | Source Files\ApiHooks 53 | 54 | 55 | Source Files 56 | 57 | 58 | 3rdParty 59 | 60 | 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files\ApiHooks 79 | 80 | 81 | Header Files\Common 82 | 83 | 84 | Header Files\Common 85 | 86 | 87 | Header Files\Common 88 | 89 | 90 | Header Files\Common 91 | 92 | 93 | 3rdParty 94 | 95 | 96 | 3rdParty 97 | 98 | 99 | 100 | 101 | Source Files 102 | 103 | 104 | Resource Files 105 | 106 | 107 | 108 | 109 | Resource Files 110 | 111 | 112 | -------------------------------------------------------------------------------- /src/Parasite/res/parasite.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshulgoel27/WinValgrind/6a9c89c3295d19343f9250ed9aad1d9bc2867e7c/src/Parasite/res/parasite.rc2 -------------------------------------------------------------------------------- /src/Parasite/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshulgoel27/WinValgrind/6a9c89c3295d19343f9250ed9aad1d9bc2867e7c/src/Parasite/resource.h -------------------------------------------------------------------------------- /src/Parasite/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // parasite.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | 8 | int g_bLog = 0; -------------------------------------------------------------------------------- /src/Parasite/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | 5 | 6 | #if !defined(AFX_STDAFX_H__A3056BBB_B70B_466F_985C_20F15AA5B1EC__INCLUDED_) 7 | #define AFX_STDAFX_H__A3056BBB_B70B_466F_985C_20F15AA5B1EC__INCLUDED_ 8 | 9 | #ifndef VC_EXTRALEAN 10 | #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers 11 | #endif 12 | 13 | #include "targetver.h" 14 | 15 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 16 | 17 | #include // MFC core and standard components 18 | #include // MFC extensions 19 | 20 | #ifndef _AFX_NO_OLE_SUPPORT 21 | #include // MFC OLE classes 22 | #include // MFC OLE dialog classes 23 | #include // MFC Automation classes 24 | #endif // _AFX_NO_OLE_SUPPORT 25 | 26 | #ifndef _AFX_NO_DB_SUPPORT 27 | #include // MFC ODBC database classes 28 | #endif // _AFX_NO_DB_SUPPORT 29 | 30 | #ifndef _AFX_NO_DAO_SUPPORT 31 | #include // MFC DAO database classes 32 | #endif // _AFX_NO_DAO_SUPPORT 33 | 34 | #ifndef _AFX_NO_OLE_SUPPORT 35 | #include // MFC support for Internet Explorer 4 Common Controls 36 | #endif 37 | #ifndef _AFX_NO_AFXCMN_SUPPORT 38 | #include // MFC support for Windows Common Controls 39 | #endif // _AFX_NO_AFXCMN_SUPPORT 40 | 41 | #include 42 | #include "pugixml.hpp" 43 | #include 44 | 45 | #define DUMP_EVENT _T("_leak_dump_evt_") 46 | #define CLEAR_LEAKS _T("_clr_all_leaks_evt_") 47 | #define EXIT_PARASITE_DLL _T("_exit_parasite_dll_evt_" ) 48 | 49 | extern int g_bLog; 50 | 51 | #include 52 | 53 | #define dlog(text) \ 54 | { \ 55 | if(g_bLog!=0) \ 56 | { \ 57 | std::ofstream log(g_Config::sDllPath+"Debuglog.txt",std::ios::app); \ 58 | log << __FUNCTION__ << "::" << __LINE__ << "\t" << text << "\n"; \ 59 | log.close(); \ 60 | }\ 61 | } 62 | 63 | 64 | #define dlog_v(name,variable) \ 65 | { \ 66 | if(g_bLog!=0) \ 67 | { \ 68 | std::ofstream log(g_Config::sDllPath+"Debuglog.txt",std::ios::app); \ 69 | log << __FUNCTION__ << "::" << __LINE__ << "\t" << name <<": " << variable << "\n"; \ 70 | log.close(); \ 71 | }\ 72 | } 73 | 74 | 75 | #endif -------------------------------------------------------------------------------- /src/Parasite/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /src/WinValgrind.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinValgrind", "WinValgrind\WinValgrind.vcxproj", "{7F4BAB83-1B36-402E-AF80-05DB82BDFE04}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {12AB3998-7533-4B04-A105-E4ACF1A75DE6} = {12AB3998-7533-4B04-A105-E4ACF1A75DE6} 7 | EndProjectSection 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parasite", "Parasite\parasite.vcxproj", "{12AB3998-7533-4B04-A105-E4ACF1A75DE6}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Win32 = Debug|Win32 14 | Release|Win32 = Release|Win32 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {7F4BAB83-1B36-402E-AF80-05DB82BDFE04}.Debug|Win32.ActiveCfg = Debug|Win32 18 | {7F4BAB83-1B36-402E-AF80-05DB82BDFE04}.Debug|Win32.Build.0 = Debug|Win32 19 | {7F4BAB83-1B36-402E-AF80-05DB82BDFE04}.Release|Win32.ActiveCfg = Release|Win32 20 | {7F4BAB83-1B36-402E-AF80-05DB82BDFE04}.Release|Win32.Build.0 = Release|Win32 21 | {12AB3998-7533-4B04-A105-E4ACF1A75DE6}.Debug|Win32.ActiveCfg = Debug|Win32 22 | {12AB3998-7533-4B04-A105-E4ACF1A75DE6}.Debug|Win32.Build.0 = Debug|Win32 23 | {12AB3998-7533-4B04-A105-E4ACF1A75DE6}.Release|Win32.ActiveCfg = Release|Win32 24 | {12AB3998-7533-4B04-A105-E4ACF1A75DE6}.Release|Win32.Build.0 = Release|Win32 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /src/WinValgrind/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : WinValgrind Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this WinValgrind application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your WinValgrind application. 9 | 10 | 11 | WinValgrind.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | WinValgrind.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | WinValgrind.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | AppWizard has created the following resources: 29 | 30 | WinValgrind.rc 31 | This is a listing of all of the Microsoft Windows resources that the 32 | program uses. It includes the icons, bitmaps, and cursors that are stored 33 | in the RES subdirectory. This file can be directly edited in Microsoft 34 | Visual C++. 35 | 36 | Resource.h 37 | This is the standard header file, which defines new resource IDs. 38 | Microsoft Visual C++ reads and updates this file. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | Other standard files: 42 | 43 | StdAfx.h, StdAfx.cpp 44 | These files are used to build a precompiled header (PCH) file 45 | named WinValgrind.pch and a precompiled types file named StdAfx.obj. 46 | 47 | ///////////////////////////////////////////////////////////////////////////// 48 | Other notes: 49 | 50 | AppWizard uses "TODO:" comments to indicate parts of the source code you 51 | should add to or customize. 52 | 53 | ///////////////////////////////////////////////////////////////////////////// 54 | -------------------------------------------------------------------------------- /src/WinValgrind/Resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by WinValgrind.rc 4 | // 5 | 6 | #define IDS_APP_TITLE 103 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 101 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1000 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /src/WinValgrind/WinValgrind.cpp: -------------------------------------------------------------------------------- 1 | // WinValgrind.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "WinValgrind.h" 6 | #include "WinValgrindCtrl.h" 7 | 8 | #ifdef _DEBUG 9 | #define new DEBUG_NEW 10 | #endif 11 | 12 | const std::string sUsage = "\nusage: winvalgrind [-gc] | [-sm ]\n\n\t-gc\tGenerate the config file template.\n\t-sm\tstart monitoring the process.\n"; 13 | // The one and only application object 14 | 15 | CWinApp theApp; 16 | 17 | using namespace std; 18 | 19 | // Method to enable debug privilages 20 | static void EnableDebugPriv( ) 21 | { 22 | HANDLE hToken; 23 | LUID sedebugnameValue; 24 | TOKEN_PRIVILEGES tkp; 25 | 26 | if( ! OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) 27 | { 28 | return; 29 | } 30 | if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) ) 31 | { 32 | CloseHandle( hToken ); 33 | return; 34 | } 35 | 36 | tkp.PrivilegeCount = 1; 37 | tkp.Privileges[0].Luid = sedebugnameValue; 38 | tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 39 | 40 | AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ); 41 | CloseHandle( hToken ); 42 | } 43 | 44 | int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 45 | { 46 | HANDLE hMutex = CreateMutex( 0, 0, _T("leak_detector_injector_evt_")); 47 | if( GetLastError() == ERROR_ALREADY_EXISTS ) 48 | { 49 | _tprintf( _T("Only one instance of WinValgrind can be run at a time")); 50 | CloseHandle( hMutex ); 51 | return FALSE; 52 | } 53 | 54 | int nRetCode = 0; 55 | EnableDebugPriv(); 56 | HMODULE hModule = ::GetModuleHandle(NULL); 57 | 58 | if (hModule != NULL) 59 | { 60 | // initialize MFC and print and error on failure 61 | if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) 62 | { 63 | _tprintf(_T("Fatal Error: MFC initialization failed\n")); 64 | nRetCode = 1; 65 | } 66 | else 67 | { 68 | 69 | if(argc < 2) 70 | { 71 | _tprintf(_T("The syntax of the command is incorrect.\n")); 72 | _tprintf(sUsage.c_str()); 73 | nRetCode = 1; 74 | } 75 | else 76 | { 77 | int pid; 78 | CWinValgrindCtrl ctrlObj; 79 | if ((_tcsncmp(argv[1],"-gc",3) == 0)) 80 | { 81 | ctrlObj.GenerateDefaultConfigTemplate(); 82 | } 83 | else 84 | if ((_tcsncmp(argv[1],"-sm",3) == 0) && argc == 3 && (pid =atoi(argv[2]))!=0) 85 | { 86 | ctrlObj.InjectParasite(pid); 87 | } 88 | else 89 | { 90 | _tprintf(_T("The syntax of the command is incorrect.\n")); 91 | _tprintf(sUsage.c_str()); 92 | nRetCode = 1; 93 | } 94 | } 95 | 96 | 97 | } 98 | } 99 | else 100 | { 101 | 102 | _tprintf(_T("Fatal Error: GetModuleHandle failed\n")); 103 | nRetCode = 1; 104 | } 105 | 106 | return nRetCode; 107 | } 108 | -------------------------------------------------------------------------------- /src/WinValgrind/WinValgrind.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "resource.h" -------------------------------------------------------------------------------- /src/WinValgrind/WinValgrind.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshulgoel27/WinValgrind/6a9c89c3295d19343f9250ed9aad1d9bc2867e7c/src/WinValgrind/WinValgrind.rc -------------------------------------------------------------------------------- /src/WinValgrind/WinValgrind.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {7F4BAB83-1B36-402E-AF80-05DB82BDFE04} 15 | Win32Proj 16 | WinValgrind 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | MultiByte 24 | Dynamic 25 | 26 | 27 | Application 28 | false 29 | v110_xp 30 | true 31 | MultiByte 32 | Dynamic 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | true 46 | 47 | 48 | false 49 | 50 | 51 | 52 | NotUsing 53 | Level3 54 | Disabled 55 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 56 | true 57 | ..\3rdParty;%(AdditionalIncludeDirectories) 58 | 59 | 60 | Console 61 | true 62 | 63 | 64 | 65 | 66 | Level3 67 | NotUsing 68 | MaxSpeed 69 | true 70 | true 71 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 72 | true 73 | ..\3rdParty 74 | 75 | 76 | Console 77 | true 78 | true 79 | true 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | Create 98 | Create 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/WinValgrind/WinValgrind.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;mfcribbon-ms 15 | 16 | 17 | {102453cd-bf18-4f33-917a-e862d25a5945} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | 3rdParty 41 | 42 | 43 | 3rdParty 44 | 45 | 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | 3rdParty 58 | 59 | 60 | 61 | 62 | Resource Files 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/WinValgrind/WinValgrindCtrl.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "WinValgrindCtrl.h" 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Th_Data 8 | { 9 | int Pid; 10 | DWORD hLibModule; 11 | HINSTANCE hKernel32; 12 | HANDLE hProcess; 13 | void* pLibRemote; 14 | int libLen; 15 | }; 16 | 17 | DWORD WINAPI ConsoleUIThreadProc(LPVOID lpParam) 18 | { 19 | int Pid = *((int*)lpParam); 20 | wcout << _T("Montoring started for pid ")< "); 30 | std::getline(std::wcin,command); 31 | 32 | if(command == L"-d") 33 | { 34 | wcout<< L"Dumping the leak trace.\n"; 35 | HANDLE hDumpEvent = CreateEvent( 0, TRUE, FALSE, DUMP_EVENT ); 36 | SetEvent( hDumpEvent ); 37 | CloseHandle( hDumpEvent ); 38 | } 39 | else 40 | if(command == L"-c") 41 | { 42 | HANDLE hMemRestEvent = CreateEvent( 0, TRUE, FALSE, CLEAR_LEAKS ); 43 | SetEvent( hMemRestEvent ); 44 | CloseHandle( hMemRestEvent ); 45 | } 46 | else 47 | if(command == L"-e") 48 | { 49 | HANDLE hDumpEvent = CreateEvent( 0, TRUE, FALSE, DUMP_EVENT ); 50 | SetEvent( hDumpEvent ); 51 | CloseHandle( hDumpEvent ); 52 | 53 | break; 54 | } 55 | else 56 | { 57 | continue; 58 | } 59 | } 60 | 61 | return 0; 62 | 63 | 64 | } 65 | 66 | bool CWinValgrindCtrl::GenerateDefaultConfigTemplate() 67 | { 68 | pugi::xml_document doc; 69 | if (!doc.load(sConfigTemplate.c_str(), pugi::parse_default | pugi::parse_comments)) return false; 70 | 71 | pugi::xml_node pdb = doc.child("WinValgrind").child("PDBInfo"); 72 | 73 | if(!pdb.child("PDBInfo1").attribute("path").set_value(m_csDllPath)) return false; 74 | if(!pdb.child("PDBInfo2").attribute("path").set_value(m_csSystemPath)) return false; 75 | if(!pdb.child("PDBInfo3").attribute("path").set_value(m_csSymbolPath)) return false; 76 | 77 | doc.save_file(L"config.xml"); 78 | return true; 79 | } 80 | 81 | bool CWinValgrindCtrl::InjectParasite(int nPid) 82 | { 83 | HANDLE hDuumpEvent = CreateEvent( 0, TRUE, FALSE, DUMP_EVENT ); 84 | if( GetLastError() == ERROR_ALREADY_EXISTS) 85 | { 86 | _tprintf( _T("The parasite is already injected in one application.\nPlease close that one before trying to inject again\n")); 87 | CloseHandle( hDuumpEvent ); 88 | return false; 89 | } 90 | CloseHandle( hDuumpEvent ); 91 | 92 | 93 | 94 | CString csPath; 95 | LPSTR lpPath = csPath.GetBuffer( MAX_PATH ); 96 | GetModuleFileName(0,lpPath, MAX_PATH ); 97 | PathRemoveFileSpec( lpPath ); 98 | csPath.ReleaseBuffer(); 99 | csPath += _T("\\parasite.dll"); 100 | 101 | if( !PathFileExists( csPath )) 102 | { 103 | _tprintf( _T("parasite.dll not found in the path ") + csPath + _T("\n\nCannot continue!\n")); 104 | return false; 105 | } 106 | 107 | 108 | 109 | HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION| 110 | PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, 111 | FALSE, nPid ); 112 | if( !hProcess) 113 | { 114 | _tprintf( _T("Failed to open the process %d\n"),nPid); 115 | return false; 116 | } 117 | 118 | HINSTANCE hKernel32 = GetModuleHandleA( "Kernel32.dll" ); 119 | PROC pLoadLib = (PROC)GetProcAddress( hKernel32, "LoadLibraryA" ); 120 | 121 | void* pLibRemote = ::VirtualAllocEx( hProcess, NULL, csPath.GetLength(), 122 | MEM_COMMIT, PAGE_READWRITE ); 123 | ::WriteProcessMemory( hProcess, pLibRemote, (void*)csPath.operator LPCTSTR(), 124 | csPath.GetLength(), NULL ); 125 | HANDLE hThread; 126 | if( !(hThread = CreateRemoteThread( hProcess, 0, 0, (LPTHREAD_START_ROUTINE)pLoadLib, pLibRemote, 0, 0 ))) 127 | { 128 | _tprintf( _T("Create Remote thread Failed") ); 129 | ::VirtualFreeEx( hProcess, pLibRemote,csPath.GetLength(), MEM_RELEASE ); 130 | } 131 | WaitForSingleObject(hThread,INFINITE); 132 | 133 | // Get handle of loaded module 134 | ::CloseHandle( hThread ); 135 | 136 | 137 | HANDLE hUIThread = CreateThread( NULL, 0, 138 | ConsoleUIThreadProc,&nPid, 0, NULL); 139 | 140 | WaitForSingleObject(hUIThread,INFINITE); 141 | 142 | CloseHandle(hUIThread); 143 | 144 | return true; 145 | } 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/WinValgrind/WinValgrindCtrl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdafx.h" 4 | 5 | 6 | 7 | const std::string sConfigTemplate = "HANDLE"; 8 | 9 | class CWinValgrindCtrl 10 | { 11 | private: 12 | CStringA m_csSystemPath; 13 | CStringA m_csSymbolPath; 14 | CStringA m_csDllPath; 15 | public: 16 | CWinValgrindCtrl () 17 | { 18 | 19 | if (GetEnvironmentVariableA("SYSTEMROOT", m_csSystemPath.GetBuffer( MAX_PATH), MAX_PATH) > 0) 20 | { 21 | m_csSystemPath.ReleaseBuffer(); 22 | m_csSystemPath += "\\system32"; 23 | } 24 | else 25 | { 26 | m_csSystemPath.ReleaseBuffer(); 27 | } 28 | 29 | 30 | 31 | if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", m_csSymbolPath.GetBuffer( MAX_PATH), MAX_PATH) > 0) 32 | { 33 | m_csSymbolPath.ReleaseBuffer(); 34 | } 35 | else 36 | { 37 | m_csSymbolPath.ReleaseBuffer(); 38 | m_csSymbolPath = "SRV*c:\\Windows\\Symbols*http://msdl.microsoft.com/download/symbols"; 39 | } 40 | //add the hook dll path so that it can load the pdb of hookdll 41 | 42 | HMODULE hHookDll = GetModuleHandleA( "parasite.dll"); 43 | if( GetModuleFileNameA( hHookDll, m_csDllPath.GetBuffer( MAX_PATH), MAX_PATH )) 44 | { 45 | m_csDllPath.ReleaseBuffer(); 46 | int nPos = m_csDllPath.ReverseFind('\\'); 47 | if( 0 < nPos ) 48 | { 49 | m_csDllPath = m_csDllPath.Left( nPos + 1 ); 50 | } 51 | 52 | } 53 | } 54 | bool GenerateDefaultConfigTemplate (); 55 | bool InjectParasite (int nPid); 56 | 57 | 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /src/WinValgrind/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // WinValgrind.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /src/WinValgrind/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 13 | #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS // remove support for MFC controls in dialogs 14 | 15 | #ifndef VC_EXTRALEAN 16 | #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers 17 | #endif 18 | 19 | #include 20 | #include // MFC core and standard components 21 | #include // MFC extensions 22 | #ifndef _AFX_NO_OLE_SUPPORT 23 | #include // MFC support for Internet Explorer 4 Common Controls 24 | #endif 25 | #ifndef _AFX_NO_AFXCMN_SUPPORT 26 | #include // MFC support for Windows Common Controls 27 | #endif // _AFX_NO_AFXCMN_SUPPORT 28 | 29 | #include 30 | 31 | 32 | #include 33 | #include 34 | 35 | #define DUMP_EVENT _T("_leak_dump_evt_") 36 | #define CLEAR_LEAKS _T("_clr_all_leaks_evt_") 37 | #define EXIT_PARASITE_DLL _T("_exit_parasite_dll_evt_" ) -------------------------------------------------------------------------------- /src/WinValgrind/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /src/ext-dependencies/x86/dbghelp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshulgoel27/WinValgrind/6a9c89c3295d19343f9250ed9aad1d9bc2867e7c/src/ext-dependencies/x86/dbghelp.dll -------------------------------------------------------------------------------- /src/ext-dependencies/x86/symsrv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshulgoel27/WinValgrind/6a9c89c3295d19343f9250ed9aad1d9bc2867e7c/src/ext-dependencies/x86/symsrv.dll -------------------------------------------------------------------------------- /src/svnremove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "recursively removing .svn folders from" 3 | pwd 4 | rm -rf `find . -type d -name .svn` 5 | --------------------------------------------------------------------------------