{"id":17263379,"url":"https://github.com/0vercl0k/udmp-parser","last_synced_at":"2025-09-24T17:25:27.064Z","repository":{"id":64640822,"uuid":"453772278","full_name":"0vercl0k/udmp-parser","owner":"0vercl0k","description":"A Cross-Platform C++ parser library for Windows user minidumps with Python 3 bindings.","archived":false,"fork":false,"pushed_at":"2024-11-20T15:58:21.000Z","size":1068,"stargazers_count":203,"open_issues_count":0,"forks_count":23,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-09T10:07:28.612Z","etag":null,"topics":["cpp","minidump","python","windows"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0vercl0k.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-30T18:56:21.000Z","updated_at":"2025-05-09T07:30:37.000Z","dependencies_parsed_at":"2024-10-15T07:56:44.190Z","dependency_job_id":"920ae851-1b33-41f0-80f6-dbc29edfddfe","html_url":"https://github.com/0vercl0k/udmp-parser","commit_stats":{"total_commits":12,"total_committers":3,"mean_commits":4.0,"dds":0.25,"last_synced_commit":"f7bf64afb1f4371fd23b9645e565be4e4b6dc6d8"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0vercl0k%2Fudmp-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0vercl0k%2Fudmp-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0vercl0k%2Fudmp-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0vercl0k%2Fudmp-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0vercl0k","download_url":"https://codeload.github.com/0vercl0k/udmp-parser/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453655,"owners_count":22073617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","minidump","python","windows"],"created_at":"2024-10-15T07:56:22.510Z","updated_at":"2025-09-24T17:25:21.990Z","avatar_url":"https://github.com/0vercl0k.png","language":"C++","readme":"# udmp-parser: A Cross-Platform C++ parser library for Windows user minidumps\n\n![Build status](https://github.com/0vercl0k/udmp-parser/workflows/Builds/badge.svg)\n[![Downloads](https://static.pepy.tech/badge/udmp-parser/month)](https://pepy.tech/project/udmp-parser)\n\nThis is a cross-platform (Windows / Linux / OSX / x86 / x64) C++ library that parses Windows user [minidump](https://docs.microsoft.com/en-us/windows/win32/debug/minidump-files) dumps (`.dump /m` and **not** `.dump /f` in WinDbg usermode).\n\n![parser](pics/parser.gif)\n\nThe library supports Intel 32-bit / 64-bit dumps and provides read access to things like:\n\n- The thread list and their context records,\n- The virtual memory,\n- The loaded modules.\n\nCompiled binaries are available in the [releases](https://github.com/0vercl0k/udmp-parser/releases) section.\n\n## Parser\n\nThe `parser` application is a small utility to show-case how to use the library and demonstrate its features. You can use it to dump memory, list the loaded modules, dump thread contexts, dump a memory map various, etc.\n\n![parser-usage](pics/parser-usage.gif)\n\nHere are the options supported:\n```\nparser.exe [-a] [-mods] [-mem] [-t [\u003cTID\u003e|main] [-h] [-dump \u003caddr\u003e] \u003cdump path\u003e\n\nExamples:\n  Show all:\n    parser.exe -a user.dmp\n  Show loaded modules:\n    parser.exe -mods user.dmp\n  Show memory map:\n    parser.exe -mem user.dmp\n  Show all threads:\n    parser.exe -t user.dmp\n  Show thread w/ specific TID:\n    parser.exe -t 1337 user.dmp\n  Show foreground thread:\n    parser.exe -t main user.dmp\n  Show a memory page at a specific address:\n    parser.exe -dump 0x7ff00 user.dmp\n```\n\n## Building\n\nYou can build it yourself using the appropriate build script for your platform in the [build](build/) directory. It builds on Linux, Windows, OSX with the [Microsoft](https://visualstudio.microsoft.com/vs/features/cplusplus/), the [LLVM Clang](https://clang.llvm.org/) and [GNU](https://gcc.gnu.org/) compilers.\n\nHere is an example on Windows:\n\n```\nudmp-parser\u003ecd src\\build\nudmp-parser\\src\\build\u003ebuild-release.bat\nudmp-parser\\src\\build\u003ecmake .. -GNinja\n-- The C compiler identification is MSVC 19.29.30139.0\n-- The CXX compiler identification is MSVC 19.29.30139.0\n-- Detecting C compiler ABI info\n-- Detecting C compiler ABI info - done\n-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped\n-- Detecting C compile features\n-- Detecting C compile features - done\n-- Detecting CXX compiler ABI info\n-- Detecting CXX compiler ABI info - done\n-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped\n-- Detecting CXX compile features\n-- Detecting CXX compile features - done\n-- Configuring done\n-- Generating done\n-- Build files have been written to: C:/work/codes/udmp-parser/src/build\nudmp-parser\\src\\build\u003ecmake --build . --config RelWithDebInfo\n[1/2] Building CXX object parser\\CMakeFiles\\parser.dir\\parser.cc.obj\ncl : Command line warning D9025 : overriding '/W3' with '/W4'\n[2/2] Linking CXX executable parser\\parser.exe\n```\n\nAnd here is another example on Linux:\n\n```\n~/udmp-parser$ cd src/build\n~/udmp-parser/src/build$ chmod u+x build-release.sh\n~/udmp-parser/src/build$ ./build-release.sh\n-- The C compiler identification is GNU 9.3.0\n-- The CXX compiler identification is GNU 9.3.0\n-- Check for working C compiler: /usr/bin/cc\n-- Check for working C compiler: /usr/bin/cc -- works\n-- Detecting C compiler ABI info\n-- Detecting C compiler ABI info - done\n-- Detecting C compile features\n-- Detecting C compile features - done\n-- Check for working CXX compiler: /usr/bin/c++\n-- Check for working CXX compiler: /usr/bin/c++ -- works\n-- Detecting CXX compiler ABI info\n-- Detecting CXX compiler ABI info - done\n-- Detecting CXX compile features\n-- Detecting CXX compile features - done\n-- Configuring done\n-- Generating done\n-- Build files have been written to: ~/udmp-parser/src/build\n[2/2] Linking CXX executable parser/parser\n```\n\n## Python bindings\n\n### From PyPI\n\nThe easiest way is simply to:\n\n```\npip install udmp_parser\n```\n\n### Using PIP\n\nTo install the package\n```\ncd src/python\npip install .\n```\n\nTo create a wheel pacakge\n```\ncd src/python\npip wheel .\n```\n\n\n### Usage\n\nThe Python API was built around the C++ code so the names were preserved. Everything lives within the module `udmp_parser`.\nNote: For convenience, a simple [pure Python script](src/python/tests/utils.py) was added to generate minidumps ready to use:\n\n```python\n$ python -i src/python/tests/utils.py\n\u003e\u003e\u003e pid, dmppath = generate_minidump_from_process_name(\"winver.exe\")\nMinidump generated successfully: PID=3232 -\u003e minidump-winver.exe-1687024880.dmp\n\u003e\u003e\u003e pid\n3232\n\u003e\u003e\u003e dmppath\nWindowsPath('minidump-winver.exe-1687024880.dmp'))\n```\n\nParsing a minidump object is as simple as:\n\n```python\n\u003e\u003e\u003e import udmp_parser\n\u003e\u003e\u003e udmp_parser.version.major, udmp_parser.version.minor, udmp_parser.version.release\n(0, 4, '')\n\u003e\u003e\u003e dmp = udmp_parser.UserDumpParser()\n\u003e\u003e\u003e dmp.Parse(pathlib.Path(\"C:/temp/rundll32.dmp\"))\nTrue\n```\n\nFeature-wise, here are some examples of usage:\n\n#### Threads\n\nGet a hashmap of threads (as `{TID: ThreadObject}`), access their information:\n\n```python\n\u003e\u003e\u003e threads = dmp.Threads()\n\u003e\u003e\u003e len(threads)\n14\n\u003e\u003e\u003e threads\n{5292: Thread(Id=0x14ac, SuspendCount=0x1, Teb=0x2e8000),\n 5300: Thread(Id=0x14b4, SuspendCount=0x1, Teb=0x2e5000),\n 5316: Thread(Id=0x14c4, SuspendCount=0x1, Teb=0x2df000),\n 3136: Thread(Id=0xc40, SuspendCount=0x1, Teb=0x2ee000),\n 4204: Thread(Id=0x106c, SuspendCount=0x1, Teb=0x309000),\n 5328: Thread(Id=0x14d0, SuspendCount=0x1, Teb=0x2e2000),\n 1952: Thread(Id=0x7a0, SuspendCount=0x1, Teb=0x2f7000),\n 3888: Thread(Id=0xf30, SuspendCount=0x1, Teb=0x2eb000),\n 1760: Thread(Id=0x6e0, SuspendCount=0x1, Teb=0x2f4000),\n 792: Thread(Id=0x318, SuspendCount=0x1, Teb=0x300000),\n 1972: Thread(Id=0x7b4, SuspendCount=0x1, Teb=0x2fa000),\n 1228: Thread(Id=0x4cc, SuspendCount=0x1, Teb=0x2fd000),\n 516: Thread(Id=0x204, SuspendCount=0x1, Teb=0x303000),\n 2416: Thread(Id=0x970, SuspendCount=0x1, Teb=0x306000)}\n```\n\nAnd access invidual thread, including their register context:\n\n```python\n\u003e\u003e\u003e thread = threads[5292]\n\u003e\u003e\u003e print(f\"RIP={thread.Context.Rip:#x} RBP={thread.Context.Rbp:#x} RSP={thread.Context.Rsp:#x}\")\nRIP=0x7ffc264b0ad4 RBP=0x404fecc RSP=0x7de628\n```\n\n\n#### Modules\n\nGet a hashmap of modules (as `{address: ModuleObject}`), access their information:\n\n```python\n\u003e\u003e\u003e modules = dmp.Modules()\n\u003e\u003e\u003e modules\n{1572864: Module_t(BaseOfImage=0x180000, SizeOfImage=0x3000, ModuleName=C:\\Windows\\SysWOW64\\sfc.dll),\n 10813440: Module_t(BaseOfImage=0xa50000, SizeOfImage=0x14000, ModuleName=C:\\Windows\\SysWOW64\\rundll32.exe),\n 1929052160: Module_t(BaseOfImage=0x72fb0000, SizeOfImage=0x11000, ModuleName=C:\\Windows\\SysWOW64\\wkscli.dll),\n 1929183232: Module_t(BaseOfImage=0x72fd0000, SizeOfImage=0x52000, ModuleName=C:\\Windows\\SysWOW64\\mswsock.dll),\n 1929576448: Module_t(BaseOfImage=0x73030000, SizeOfImage=0xf000, ModuleName=C:\\Windows\\SysWOW64\\browcli.dll),\n 1929641984: Module_t(BaseOfImage=0x73040000, SizeOfImage=0xa000, ModuleName=C:\\Windows\\SysWOW64\\davhlpr.dll),\n 1929707520: Module_t(BaseOfImage=0x73050000, SizeOfImage=0x19000, ModuleName=C:\\Windows\\SysWOW64\\davclnt.dll),\n 1929838592: Module_t(BaseOfImage=0x73070000, SizeOfImage=0x18000, ModuleName=C:\\Windows\\SysWOW64\\ntlanman.dll),\n [...]\n 140720922427392: Module_t(BaseOfImage=0x7ffc24980000, SizeOfImage=0x83000, ModuleName=C:\\Windows\\System32\\wow64win.dll),\n 140720923017216: Module_t(BaseOfImage=0x7ffc24a10000, SizeOfImage=0x59000, ModuleName=C:\\Windows\\System32\\wow64.dll),\n 140720950280192: Module_t(BaseOfImage=0x7ffc26410000, SizeOfImage=0x1f8000, ModuleName=C:\\Windows\\System32\\ntdll.dll)}\n```\n\nAccess directly module info:\n\n```python\n\u003e\u003e\u003e ntdll_modules = [mod for addr, mod in dmp.Modules().items() if mod.ModuleName.lower().endswith(\"ntdll.dll\")]\n\u003e\u003e\u003e len(ntdll_modules)\n2\n\u003e\u003e\u003e for ntdll in ntdll_modules:\n  print(f\"{ntdll.ModuleName=} {ntdll.BaseOfImage=:#x} {ntdll.SizeOfImage=:#x}\")\n\nntdll.ModuleName='C:\\\\Windows\\\\SysWOW64\\\\ntdll.dll' ntdll.BaseOfImage=0x77430000 ntdll.SizeOfImage=0x1a4000\nntdll.ModuleName='C:\\\\Windows\\\\System32\\\\ntdll.dll' ntdll.BaseOfImage=0x7ffc26410000 ntdll.SizeOfImage=0x1f8000\n```\n\nA convenience function under `udmp_parser.UserDumpParser.ReadMemory()` can be used to directly read memory from the dump. The signature of the function is as follow: `def ReadMemory(Address: int, Size: int) -\u003e list[int]`. So to dump for instance the `wow64` module, it would go as follow:\n\n```python\n\u003e\u003e\u003e wow64 = [mod for addr, mod in dmp.Modules().items() if mod.ModuleName.lower() == r\"c:\\windows\\system32\\wow64.dll\"][0]\n\u003e\u003e\u003e print(str(wow64))\nModule_t(BaseOfImage=0x7ffc24a10000, SizeOfImage=0x59000, ModuleName=C:\\Windows\\System32\\wow64.dll)\n\u003e\u003e\u003e wow64_module = bytearray(dmp.ReadMemory(wow64.BaseOfImage, wow64.SizeOfImage))\n\u003e\u003e\u003e assert wow64_module[:2] == b'MZ'\n\u003e\u003e\u003e import hexdump\n\u003e\u003e\u003e hexdump.hexdump(wow64_module[:128])\n00000000: 4D 5A 90 00 03 00 00 00  04 00 00 00 FF FF 00 00  MZ..............\n00000010: B8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  ........@.......\n00000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................\n00000030: 00 00 00 00 00 00 00 00  00 00 00 00 E8 00 00 00  ................\n00000040: 0E 1F BA 0E 00 B4 09 CD  21 B8 01 4C CD 21 54 68  ........!..L.!Th\n00000050: 69 73 20 70 72 6F 67 72  61 6D 20 63 61 6E 6E 6F  is program canno\n00000060: 74 20 62 65 20 72 75 6E  20 69 6E 20 44 4F 53 20  t be run in DOS\n00000070: 6D 6F 64 65 2E 0D 0D 0A  24 00 00 00 00 00 00 00  mode....$.......\n```\n\n\n#### Memory\n\nThe memory blocks can also be enumerated in a hashmap `{address: MemoryBlock}`.\n\n```python\n\u003e\u003e\u003e memory = dmp.Memory()\n\u003e\u003e\u003e len(memory)\n0x260\n\u003e\u003e\u003e memory\n[...]\n 0x7ffc26410000: [MemBlock_t(BaseAddress=0x7ffc26410000, AllocationBase=0x7ffc26410000, AllocationProtect=0x80, RegionSize=0x1000)],\n 0x7ffc26411000: [MemBlock_t(BaseAddress=0x7ffc26411000, AllocationBase=0x7ffc26410000, AllocationProtect=0x80, RegionSize=0x11c000)],\n 0x7ffc2652d000: [MemBlock_t(BaseAddress=0x7ffc2652d000, AllocationBase=0x7ffc26410000, AllocationProtect=0x80, RegionSize=0x49000)],\n 0x7ffc26576000: [MemBlock_t(BaseAddress=0x7ffc26576000, AllocationBase=0x7ffc26410000, AllocationProtect=0x80, RegionSize=0x1000)],\n 0x7ffc26577000: [MemBlock_t(BaseAddress=0x7ffc26577000, AllocationBase=0x7ffc26410000, AllocationProtect=0x80, RegionSize=0x2000)],\n 0x7ffc26579000: [MemBlock_t(BaseAddress=0x7ffc26579000, AllocationBase=0x7ffc26410000, AllocationProtect=0x80, RegionSize=0x9000)],\n 0x7ffc26582000: [MemBlock_t(BaseAddress=0x7ffc26582000, AllocationBase=0x7ffc26410000, AllocationProtect=0x80, RegionSize=0x86000)],\n 0x7ffc26608000: [MemBlock_t(BaseAddress=0x7ffc26608000, AllocationBase=0x0, AllocationProtect=0x0, RegionSize=0x3d99e8000)]}\n```\n\nTo facilitate the parsing in a human-friendly manner, some helper functions are provided:\n * `udmp_parser.utils.TypeToString`: convert the region type to its meaning (from MSDN)\n * `udmp_parser.utils.StateToString`: convert the region state to its meaning (from MSDN)\n * `udmp_parser.utils.ProtectionToString`: convert the region protection to its meaning (from MSDN)\n\nThis allows to search and filter in a more comprehensible way:\n\n\n```python\n# Collect only executable memory regions\n\u003e\u003e\u003e exec_regions = [region for _, region in dmp.Memory().items() if \"PAGE_EXECUTE_READ\" in udmp_parser.utils.ProtectionToString(region.Protect)]\n\n# Pick any, disassemble code using capstone\n\u003e\u003e\u003e exec_region = exec_regions[-1]\n\u003e\u003e\u003e mem = dmp.ReadMemory(exec_region.BaseAddress, 0x100)\n\u003e\u003e\u003e for insn in cs.disasm(bytearray(mem), exec_region.BaseAddress):\n  print(f\"{insn=}\")\n\ninsn=\u003cCsInsn 0x7ffc26582000 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582001 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582002 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582003 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582004 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582005 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582006 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582007 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582008 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582009 [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc2658200a [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc2658200b [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc2658200c [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc2658200d [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc2658200e [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc2658200f [cc]: int3 \u003e\ninsn=\u003cCsInsn 0x7ffc26582010 [48895c2410]: mov qword ptr [rsp + 0x10], rbx\u003e\ninsn=\u003cCsInsn 0x7ffc26582015 [4889742418]: mov qword ptr [rsp + 0x18], rsi\u003e\ninsn=\u003cCsInsn 0x7ffc2658201a [57]: push rdi\u003e\ninsn=\u003cCsInsn 0x7ffc2658201b [4156]: push r14\u003e\ninsn=\u003cCsInsn 0x7ffc2658201d [4157]: push r15\u003e\n[...]\n```\n\n# Authors\n\n* Axel '[@0vercl0k](https://twitter.com/0vercl0k)' Souchet\n\n# Contributors\n\n[ ![contributors-img](https://contrib.rocks/image?repo=0vercl0k/udmp-parser) ](https://github.com/0vercl0k/udmp-parser/graphs/contributors)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0vercl0k%2Fudmp-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0vercl0k%2Fudmp-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0vercl0k%2Fudmp-parser/lists"}